typo removed
[libfirm] / ir / ir / irgopt.c
index c63a524..4cb15d2 100644 (file)
@@ -529,6 +529,8 @@ copy_node_inline (ir_node *n, void *env) {
   }
 }
 
+#include "irdump.h"
+
 void inline_method(ir_node *call, ir_graph *called_graph) {
   ir_node *pre_call;
   ir_node *post_call, *post_bl;
@@ -761,38 +763,43 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   free(res_pred);
   free(cf_pred);
 
-/* --
-       If the exception control flow from the Call directly branched to the
-       end block we now have the following control flow predecessor pattern:
-       ProjX -> Tuple -> Jmp.
-       We must remove the Jmp along with it's empty block and add Jmp's
-       predecessors as predecessors of this end block. -- */
-  /* find the problematic predecessor of the end block. */
-  end_bl = get_irg_end_block(current_ir_graph);
-  for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
-    cf_op = get_Block_cfgpred(end_bl, i);
-    if (get_irn_op(cf_op) == op_Proj) {
-      cf_op = get_Proj_pred(cf_op);
-      if (get_irn_op(cf_op) == op_Tuple) {
-       cf_op = get_Tuple_pred(cf_op, 1);
-       assert(get_irn_op(cf_op) == op_Jmp);
-       break;
+  if (n_exc > 0) {
+    /* -- If the exception control flow from the inlined Call directly
+       branched to the end block we now have the following control
+       flow predecessor pattern: ProjX -> Tuple -> Jmp.  We must
+       remove the Jmp along with it's empty block and add Jmp's
+       predecessors as predecessors of this end block.  No problem if
+       there is no exception, because then branches Bad to End which
+       is fine. -- */
+    /* find the problematic predecessor of the end block. */
+    end_bl = get_irg_end_block(current_ir_graph);
+    for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
+      cf_op = get_Block_cfgpred(end_bl, i);
+      if (get_irn_op(cf_op) == op_Proj) {
+       cf_op = get_Proj_pred(cf_op);
+       if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
+           // There are unoptimized tuples from inlineing before when no exc
+         assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
+         cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
+         assert(get_irn_op(cf_op) == op_Jmp);
+         break;
+       }
       }
     }
-  }
-  /* repair */
-  if (i < get_Block_n_cfgpreds(end_bl)) {
-    bl = get_nodes_Block(cf_op);
-    arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
-    cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
-    for (j = 0; j < i; j++)
-      cf_pred[j] = get_Block_cfgpred(end_bl, j);
-    for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
-      cf_pred[j] = get_Block_cfgpred(bl, j-i);
-    for (j = j; j < arity; j++)
-      cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
-    set_irn_in(end_bl, arity, cf_pred);
-    free(cf_pred);
+    /* repair */
+    if (i < get_Block_n_cfgpreds(end_bl)) {
+      bl = get_nodes_Block(cf_op);
+      arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
+      cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
+      for (j = 0; j < i; j++)
+       cf_pred[j] = get_Block_cfgpred(end_bl, j);
+      for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
+       cf_pred[j] = get_Block_cfgpred(bl, j-i);
+      for (j = j; j < arity; j++)
+       cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
+      set_irn_in(end_bl, arity, cf_pred);
+      free(cf_pred);
+    }
   }
 
   /* --  Turn cse back on. -- */
@@ -880,6 +887,8 @@ void inline_small_irgs(ir_graph *irg, int size) {
 /*  will be executed only if needed.                                */
 /********************************************************************/
 
+#include "irdump.h"
+
 static pdeq *worklist;         /* worklist of ir_node*s */
 
 /* Find the earliest correct block for N.  --- Place N into the
@@ -902,7 +911,8 @@ place_floats_early (ir_node *n)
 
     if ((get_irn_op(n) == op_Const) ||
        (get_irn_op(n) == op_SymConst) ||
-       (is_Bad(n))) {
+       (is_Bad(n)) ||
+       (get_irn_op(n) == op_Unknown)) {
       /* These nodes will not be placed by the loop below. */
       b = get_irg_start_block(current_ir_graph);
       depth = 1;
@@ -1176,7 +1186,9 @@ static void merge_blocks(ir_node *n, void *env) {
     while (irn_not_visited(b) && (!is_Bad(new)) && (new != b)) {
       /* We would have to run gigo if new is bad, so we
         promote it directly below. */
-      assert(((b == new) || get_opt_control_flow_straightening() || get_opt_control_flow_weak_simplification()) &&
+      assert(((b == new) ||
+             get_opt_control_flow_straightening() ||
+             get_opt_control_flow_weak_simplification()) &&
             ("strange flag setting"));
       exchange (b, new);
       b = new;
@@ -1485,10 +1497,15 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
       (get_irn_arity(n) > 1)) {
     arity = get_irn_arity(n);
 
+    if (n == get_irg_end_block(current_ir_graph))
+      return;  // No use to add a block here.
+
     for (i=0; i<arity; i++) {
       pre = get_irn_n(n, i);
       /* Predecessor has multiple sucessors. Insert new flow edge */
-      if ((NULL != pre) && (op_Proj == get_irn_op(pre))) {
+      if ((NULL != pre) &&
+         (op_Proj == get_irn_op(pre)) &&
+         op_Raise != get_irn_op(skip_Proj(pre))) {
 
        /* set predecessor array for new block */
        in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);