irgraph: Use get_irg_obstack() instead of accessing irg->obst directly.
[libfirm] / ir / ana / analyze_irg_args.c
index a40cc6a..9cf6b2b 100644 (file)
 /**
  * @file
  * @brief      read/write analyze of graph argument, which have mode reference.
- * @author     Beyhan Veliev, Michael Beck
- * @version    $Id$
+ * @author     Beyhan Veliev
  */
 #include "config.h"
 
 #include <stdlib.h>
 
-#include "adt/raw_bitset.h"
 #include "irouts.h"
 #include "irnode_t.h"
 #include "irmode_t.h"
 #include "array_t.h"
 #include "irprog.h"
 #include "entity_t.h"
-#include "irgwalk.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,
@@ -49,18 +43,19 @@ static void *VISITED = &v;
  * @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.*/
@@ -84,8 +79,8 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) {
                        } else {
                                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) {
@@ -95,14 +90,15 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) {
                                        }
                                } 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) {
+                                               if (is_unknown_entity(meth_ent)) {
                                                        bits |= ptr_access_all;
                                                        break;
                                                }
@@ -178,7 +174,8 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) {
  *
  * @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;
@@ -256,13 +253,8 @@ static void analyze_ent_args(ir_entity *ent) {
 #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())
@@ -276,17 +268,13 @@ void analyze_irg_args(ir_graph *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) {
@@ -319,19 +307,20 @@ enum args_weight {
  *
  * @param arg  The parameter them weight muss be computed.
  */
-static unsigned calc_method_param_weight(ir_node *arg) {
+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.*/
@@ -422,7 +411,8 @@ static unsigned calc_method_param_weight(ir_node *arg) {
  *
  * @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;
@@ -457,28 +447,9 @@ static void analyze_method_params_weight(ir_entity *ent) {
                proj_nr = get_Proj_proj(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.
- *
- * @param ent  the entity to analyze
- * @param pos  the argument number
- *
- * @return the parameter weight or null_weight if pos is greater
- * than the number of arguments.
- */
-unsigned get_method_param_weight(ir_entity *ent, int pos)
+unsigned get_method_param_weight(ir_entity *ent, size_t pos)
 {
        if (ent->attr.mtd_attr.param_weight) {
                if (pos < ARR_LEN(ent->attr.mtd_attr.param_weight))
@@ -495,123 +466,18 @@ unsigned get_method_param_weight(ir_entity *ent, int pos)
                return null_weight;
 }
 
-typedef struct walk_env {
-       unsigned *marks;      /**< raw bitset for nodes that could be analysed */
-       unsigned *param_mask; /**< raw bitset of constant parameters */
-       unsigned mask_len;    /**< length of the parameter bitmask */
-       unsigned weight;      /**< the accumulated weight */
-} walk_env;
-
-/**
- * Walker, evaluates possible constant folding
- */
-static void evaluate_weight(ir_node *irn, void *ctx) {
-       walk_env *env = ctx;
-       int      i, n;
-       ir_node  *ptr;
-
-       if (is_arg_Proj(irn)) {
-               unsigned argnum = (unsigned)get_Proj_proj(irn);
-
-               if (argnum < env->mask_len) {
-                       if (rbitset_is_set(env->param_mask, argnum)) {
-                               /* is a constant parameter */
-                               rbitset_set(env->marks, get_irn_idx(irn));
-                       }
-               }
-               return;
-       }
-       if (is_irn_constlike(irn)) {
-               /* is a constant by itself */
-               rbitset_set(env->marks, get_irn_idx(irn));
-               return;
-       }
-
-       if (is_Block(irn))
+void analyze_irg_args_weight(ir_graph *irg)
+{
+       ir_entity *entity = get_irg_entity(irg);
+       if (entity == NULL)
                return;
 
-       /* handle some special cases */
-       switch (get_irn_opcode(irn)) {
-       case iro_Div:
-       case iro_Quot:
-       case iro_Mod:
-       case iro_DivMod:
-               /* skip the memory input of these nodes */
-               assert(pn_Generic_M_regular == 0);
-               n = 1;
-               break;
-       case iro_Call:
-               ptr = get_Call_ptr(irn);
-               if (! is_SymConst(ptr) && rbitset_is_set(env->marks, get_irn_idx(ptr))) {
-                       /* the arguments is used as an pointer input for a call,
-                       we can probably change an indirect Call into a direct one. */
-                       env->weight += indirect_call_weight;
-               }
-               n = 2;
-               break;
-       default:
-               n = 0;
-               break;
-       }
-       for (i = get_irn_arity(irn) - 1; i >= n; --i) {
-               ir_node *pred = get_irn_n(irn, i);
-
-               if (! rbitset_is_set(env->marks, get_irn_idx(pred))) {
-                       /* not constant predecessor ... */
-                       return;
-               }
-       }
-
-       /* all predecessors are constant, we probably can fold this node */
-       rbitset_set(env->marks, get_irn_idx(irn));
-
-       if (is_binop(irn)) {
-               env->weight += const_binop_weight;
-       } else if (is_unop(irn)) {
-               env->weight += const_binop_weight;
-       } else if (is_Proj(irn)) {
-               ir_node *pred = get_Proj_pred(irn);
-               if (is_Cmp(pred)) {
-                       env->weight += const_cmp_weight;
-               } else if (is_Cond(pred)) {
-                       /* the argument is used for a SwitchCond, a big win */
-                       env->weight += const_cmp_weight;
-               }
-       }
-}
-
-/**
- *
- */
-unsigned analyze_irg_param_weights(ir_graph *irg, unsigned *bitmask, unsigned len) {
-       unsigned nodes = get_irg_last_idx(irg);
-       unsigned *marks = rbitset_malloc(nodes);
-       walk_env env;
-
-       env.marks      = marks;
-       env.param_mask = bitmask;
-       env.mask_len   = len;
-       env.weight     = null_weight;
-
-       irg_walk_graph(irg, NULL, evaluate_weight, &env);
-
-       xfree(marks);
-       return env.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;
-
-       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);
 }