add a parameter to limit the maximum size of methods when inlining, otherwise some...
[libfirm] / ir / ir / iropt.c
index 69da73d..c2cecb1 100644 (file)
@@ -722,10 +722,16 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
 static ir_node *equivalent_node_Block(ir_node *n)
 {
        ir_node *oldn = n;
-       int n_preds   = get_Block_n_cfgpreds(n);
+       int     n_preds;
 
-       /* The Block constructor does not call optimize, but mature_immBlock
-       calls the optimization. */
+       /* don't optimize dead blocks */
+       if (is_Block_dead(n))
+               return n;
+
+       n_preds = get_Block_n_cfgpreds(n);
+
+       /* The Block constructor does not call optimize, but mature_immBlock()
+          calls the optimization. */
        assert(get_Block_matured(n));
 
        /* Straightening: a single entry Block following a single exit Block
@@ -1297,45 +1303,36 @@ static ir_node *equivalent_node_Phi(ir_node *n) {
  *   themselves.
  */
 static ir_node *equivalent_node_Sync(ir_node *n) {
-       int i, n_preds;
-
-       ir_node *oldn = n;
-       ir_node *first_val = NULL; /* to shutup gcc */
-
-       if (!get_opt_normalize()) return n;
+       int arity = get_Sync_n_preds(n);
+       int i;
 
-       n_preds = get_Sync_n_preds(n);
+       for (i = 0; i < arity;) {
+               ir_node *pred = get_Sync_pred(n, i);
+               int      j;
 
-       /* Find first non-self-referencing input */
-       for (i = 0; i < n_preds; ++i) {
-               first_val = get_Sync_pred(n, i);
-               if ((first_val != n)  /* not self pointer */ &&
-                   (! is_Bad(first_val))
-                  ) {                /* value not dead */
-                       break;            /* then found first value. */
+               /* Remove Bad predecessors */
+               if (is_Bad(pred)) {
+                       del_Sync_n(n, i);
+                       --arity;
+                       continue;
                }
-       }
-
-       if (i >= n_preds)
-               /* A totally Bad or self-referencing Sync (we didn't break the above loop) */
-               return new_Bad();
 
-       /* search the rest of inputs, determine if any of these
-          are non-self-referencing */
-       while (++i < n_preds) {
-               ir_node *scnd_val = get_Sync_pred(n, i);
-               if ((scnd_val != n) &&
-                   (scnd_val != first_val) &&
-                   (! is_Bad(scnd_val))
-                  )
-                       break;
+               /* Remove duplicate predecessors */
+               for (j = 0;; ++j) {
+                       if (j >= i) {
+                               ++i;
+                               break;
+                       }
+                       if (get_Sync_pred(n, j) == pred) {
+                               del_Sync_n(n, i);
+                               --arity;
+                               break;
+                       }
+               }
        }
 
-       if (i >= n_preds) {
-               /* Fold, if no multiple distinct non-self-referencing inputs */
-               n = first_val;
-               DBG_OPT_SYNC(oldn, n);
-       }
+       if (arity == 0) return new_Bad();
+       if (arity == 1) return get_Sync_pred(n, 0);
        return n;
 }  /* equivalent_node_Sync */
 
@@ -3656,11 +3653,9 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) {
                break;
        }
 
-       /* remove Casts */
-       if (is_Cast(left))
-               left = get_Cast_op(left);
-       if (is_Cast(right))
-               right = get_Cast_op(right);
+       /* remove Casts of both sides */
+       left  = skip_Cast(left);
+       right = skip_Cast(right);
 
        /* Remove unnecessary conversions */
        /* TODO handle constants */
@@ -3695,7 +3690,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) {
                }
        }
 
-       /* remove operation of both sides if possible */
+       /* remove operation on both sides if possible */
        if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
                /*
                 * The following operations are NOT safe for floating point operations, for instance
@@ -4873,28 +4868,35 @@ static ir_node *transform_node_Psi(ir_node *n) {
  * of the other sync to our own inputs
  */
 static ir_node *transform_node_Sync(ir_node *n) {
-       int i, arity;
+       int arity = get_Sync_n_preds(n);
+       int i;
 
-       arity = get_irn_arity(n);
-       for(i = 0; i < get_irn_arity(n); /*empty*/) {
-               int i2, arity2;
-               ir_node *in = get_irn_n(n, i);
-               if(!is_Sync(in)) {
+       for (i = 0; i < arity;) {
+               ir_node *pred = get_Sync_pred(n, i);
+               int      pred_arity;
+               int      j;
+
+               if (!is_Sync(pred)) {
                        ++i;
                        continue;
                }
 
-               /* set sync input 0 instead of the sync */
-               set_irn_n(n, i, get_irn_n(in, 0));
-               /* so we check this input again for syncs */
-
-               /* append all other inputs of the sync to our sync */
-               arity2 = get_irn_arity(in);
-               for(i2 = 1; i2 < arity2; ++i2) {
-                       ir_node *in_in = get_irn_n(in, i2);
-                       add_irn_n(n, in_in);
-                       /* increase arity so we also check the new inputs for syncs */
-                       arity++;
+               del_Sync_n(n, i);
+               --arity;
+
+               pred_arity = get_Sync_n_preds(pred);
+               for (j = 0; j < pred_arity; ++j) {
+                       ir_node *pred_pred = get_Sync_pred(pred, j);
+                       int      k;
+
+                       for (k = 0;; ++k) {
+                               if (k >= arity) {
+                                       add_irn_n(n, pred_pred);
+                                       ++arity;
+                                       break;
+                               }
+                               if (get_Sync_pred(n, k) == pred_pred) break;
+                       }
                }
        }
 
@@ -5020,7 +5022,7 @@ static int node_cmp_attr_Free(ir_node *a, ir_node *b) {
 static int node_cmp_attr_SymConst(ir_node *a, ir_node *b) {
        const symconst_attr *pa = get_irn_symconst_attr(a);
        const symconst_attr *pb = get_irn_symconst_attr(b);
-       return (pa->num        != pb->num)
+       return (pa->kind       != pb->kind)
            || (pa->sym.type_p != pb->sym.type_p)
            || (pa->tp         != pb->tp);
 }  /* node_cmp_attr_SymConst */