* @file
* @brief read/write analyze of graph argument, which have mode reference.
* @author Beyhan Veliev
- * @version $Id$
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
+#include <stdlib.h>
#include "irouts.h"
#include "irnode_t.h"
#include "irmode_t.h"
-#include "array.h"
+#include "array_t.h"
#include "irprog.h"
#include "entity_t.h"
-#include "xmalloc.h"
#include "analyze_irg_args.h"
-static char v;
-static void *VISITED = &v;
-
/**
* Walk recursive the successors of a graph argument
* with mode reference and mark if it will be read,
* @param arg The graph argument with mode reference,
* that must be checked.
*/
-static unsigned analyze_arg(ir_node *arg, unsigned bits) {
+static ptr_access_kind analyze_arg(ir_node *arg, ptr_access_kind bits)
+{
int i, p;
ir_node *succ;
/* We must visit a node once to avoid endless recursion.*/
- set_irn_link(arg, VISITED);
+ mark_irn_visited(arg);
for (i = get_irn_n_outs(arg) - 1; i >= 0; --i) {
succ = get_irn_out(arg, i);
/* We was here.*/
- if (get_irn_link(succ) == VISITED)
+ if (irn_visited(succ))
continue;
/* We should not walk over the memory edge.*/
/* Hmm: not sure what this is, most likely a read */
bits |= ptr_access_read;
} else {
- ir_op *op = get_irn_op(ptr);
ir_entity *meth_ent;
- if (is_Global(ptr)) {
- meth_ent = get_Global_entity(ptr);
+ if (is_SymConst_addr_ent(ptr)) {
+ meth_ent = get_SymConst_entity(ptr);
for (p = get_Call_n_params(succ) - 1; p >= 0; --p) {
if (get_Call_param(succ, p) == arg) {
}
} else if (is_Sel(ptr) && get_irp_callee_info_state() == irg_callee_info_consistent) {
/* is be a polymorphic call but callee information is available */
- int i, n_params = get_Call_n_params(succ);
+ int n_params = get_Call_n_params(succ);
+ int c;
/* simply look into ALL possible callees */
- for (i = get_Call_n_callees(succ) - 1; i >= 0; --i) {
- meth_ent = get_Call_callee(succ, i);
+ for (c = get_Call_n_callees(succ) - 1; c >= 0; --c) {
+ meth_ent = get_Call_callee(succ, c);
/* unknown_entity is used to signal that we don't know what is called */
if (meth_ent == unknown_entity) {
*
* @param irg The ir graph to analyze.
*/
-static void analyze_ent_args(ir_entity *ent) {
+static void analyze_ent_args(ir_entity *ent)
+{
ir_graph *irg;
ir_node *irg_args, *arg;
ir_mode *arg_mode;
#endif
}
-/**
- * Analyze how pointer arguments of a given
- * ir graph are accessed.
- *
- * @param irg The ir graph to analyze.
- */
-void analyze_irg_args(ir_graph *irg) {
+void analyze_irg_args(ir_graph *irg)
+{
ir_entity *ent;
if (irg == get_const_code_irg())
analyze_ent_args(ent);
}
-/*
- * Compute for a method with pointer parameter(s)
- * if they will be read or written.
- */
-ptr_access_kind get_method_param_access(ir_entity *ent, int pos)
+ptr_access_kind get_method_param_access(ir_entity *ent, size_t pos)
{
#ifndef NDEBUG
ir_type *mtp = get_entity_type(ent);
int is_variadic = get_method_variadicity(mtp) == variadicity_variadic;
- assert(0 <= pos && (is_variadic || pos < get_method_n_params(mtp)));
+ assert(is_variadic || pos < get_method_n_params(mtp));
#endif
if (ent->attr.mtd_attr.param_access) {
*
* @param arg The parameter them weight muss be computed.
*/
-static unsigned calc_method_param_weight(ir_node *arg) {
- int i;
+static unsigned calc_method_param_weight(ir_node *arg)
+{
+ int i, j, k;
ir_node *succ, *op;
unsigned weight = null_weight;
/* We mark the nodes to avoid endless recursion */
- set_irn_link(arg, VISITED);
+ mark_irn_visited(arg);
for (i = get_irn_n_outs(arg) - 1; i >= 0; i--) {
succ = get_irn_out(arg, i);
/* We was here.*/
- if (get_irn_link(succ) == VISITED)
+ if (irn_visited(succ))
continue;
/* We should not walk over the memory edge.*/
if (get_irn_mode(succ) == mode_M)
continue;
- if (is_Call(succ) && get_Call_ptr(succ) == arg) {
- /* the arguments is used as an pointer input for a call,
- we can probably change an indirect Call into a direct one. */
- weight += indirect_call_weight;
- } else if (is_Cmp(succ)) {
+ switch (get_irn_opcode(succ)) {
+ case iro_Call:
+ if (get_Call_ptr(succ) == arg) {
+ /* the arguments is used as an pointer input for a call,
+ we can probably change an indirect Call into a direct one. */
+ weight += indirect_call_weight;
+ }
+ break;
+ case iro_Cmp:
/* We have reached a cmp and we must increase the
weight with the cmp_weight. */
if (get_Cmp_left(succ) == arg)
weight += const_cmp_weight;
} else
weight += cmp_weight;
- } else if (is_Cond(succ)) {
+ break;
+ case iro_Cond:
/* the argument is used for a SwitchCond, a big win */
weight += const_cmp_weight * get_irn_n_outs(succ);
- } else if (is_binop(succ)) {
- /* We have reached a BinOp and we must increase the
- weight with the binop_weight. If the other operand of the
- BinOp is a constant we increase the weight with const_binop_weight
- and call the function recursive.
- */
- if (get_binop_left(succ) == arg)
- op = get_binop_right(succ);
- else
- op = get_binop_left(succ);
-
- if (is_irn_constlike(op)) {
+ break;
+ case iro_Id:
+ /* when looking backward we might find Id nodes */
+ weight += calc_method_param_weight(succ);
+ break;
+ case iro_Tuple:
+ /* unoptimized tuple */
+ for (j = get_Tuple_n_preds(succ) - 1; j >= 0; --j) {
+ ir_node *pred = get_Tuple_pred(succ, j);
+ if (pred == arg) {
+ /* look for Proj(j) */
+ for (k = get_irn_n_outs(succ) - 1; k >= 0; --k) {
+ ir_node *succ_succ = get_irn_out(succ, k);
+ if (is_Proj(succ_succ)) {
+ if (get_Proj_proj(succ_succ) == j) {
+ /* found */
+ weight += calc_method_param_weight(succ_succ);
+ }
+ } else {
+ /* this should NOT happen */
+ }
+ }
+ }
+ }
+ break;
+ default:
+ if (is_binop(succ)) {
+ /* We have reached a BinOp and we must increase the
+ weight with the binop_weight. If the other operand of the
+ BinOp is a constant we increase the weight with const_binop_weight
+ and call the function recursive.
+ */
+ if (get_binop_left(succ) == arg)
+ op = get_binop_right(succ);
+ else
+ op = get_binop_left(succ);
+
+ if (is_irn_constlike(op)) {
+ weight += const_binop_weight;
+ weight += calc_method_param_weight(succ);
+ } else
+ weight += binop_weight;
+ } else if (is_unop(succ)) {
+ /* We have reached a binop and we must increase the
+ weight with the const_binop_weight and call the function recursive.*/
weight += const_binop_weight;
weight += calc_method_param_weight(succ);
- } else
- weight += binop_weight;
- } else if (is_unop(succ)) {
- /* We have reached a binop and we must increase the
- weight with the const_binop_weight and call the function recursive.*/
- weight += const_binop_weight;
- weight += calc_method_param_weight(succ);
+ }
+ break;
}
}
set_irn_link(arg, NULL);
*
* @param ent The entity of the ir_graph.
*/
-static void analyze_method_params_weight(ir_entity *ent) {
+static void analyze_method_params_weight(ir_entity *ent)
+{
ir_type *mtp;
ir_graph *irg;
int nparams, i, proj_nr;
assure_irg_outs(irg);
irg_args = get_irg_args(irg);
-
for (i = get_irn_n_outs(irg_args) - 1; i >= 0; --i) {
arg = get_irn_out(irg_args, i);
proj_nr = get_Proj_proj(arg);
- ent->attr.mtd_attr.param_weight[proj_nr] += calc_method_param_weight(arg);
+ ent->attr.mtd_attr.param_weight[proj_nr] += calc_method_param_weight(arg);
}
-
-#if 0
- printf("\n%s:\n", get_entity_name(ent));
- for (i = nparams - 1; i >= 0; --i)
- printf("The weight of argument %i is %f \n", i, ent->param_weight[i]);
-#endif
}
-/*
- * Returns for a method the 'weight' that every parameter
- * has on optimization possibility. Higher values allows
- * higher optimization with procedure cloning.
- *
- * The values are calculation on demand only.
- */
-unsigned get_method_param_weight(ir_entity *ent, int pos)
+unsigned get_method_param_weight(ir_entity *ent, size_t pos)
{
-#ifndef NDEBUG
- ir_type *mtp = get_entity_type(ent);
- int is_variadic = get_method_variadicity(mtp) == variadicity_variadic;
- assert(0 <= pos && (is_variadic || pos < get_method_n_params(mtp)));
-#endif
-
if (ent->attr.mtd_attr.param_weight) {
if (pos < ARR_LEN(ent->attr.mtd_attr.param_weight))
return ent->attr.mtd_attr.param_weight[pos];
return null_weight;
}
-/**
- * Analyze argument's weight of a given
- * ir graph.
- *
- * @param irg The ir graph to analyze.
- */
-void analyze_irg_args_weight(ir_graph *irg) {
- ir_entity *ent;
+void analyze_irg_args_weight(ir_graph *irg)
+{
+ ir_entity *entity = get_irg_entity(irg);
+ if (entity == NULL)
+ return;
- ent = get_irg_entity(irg);
- if (ent == NULL)
+ assert(is_method_entity(entity));
+ if (entity->attr.mtd_attr.param_weight != NULL)
return;
- if (! ent->attr.mtd_attr.param_weight)
- analyze_method_params_weight(ent);
+ ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
+ inc_irg_visited(irg);
+ analyze_method_params_weight(entity);
+ ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
}