OSDN Git Service

bb-reorder: Split EH edges crossing partitions.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-im.c
index 57f9897..3a5608e 100644 (file)
@@ -197,9 +197,10 @@ static bool ref_indep_loop_p (struct loop *, mem_ref_p);
 /* Minimum cost of an expensive expression.  */
 #define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
 
-/* The outermost loop for that execution of the header guarantees that the
+/* The outermost loop for which execution of the header guarantees that the
    block will be executed.  */
 #define ALWAYS_EXECUTED_IN(BB) ((struct loop *) (BB)->aux)
+#define SET_ALWAYS_EXECUTED_IN(BB, VAL) ((BB)->aux = (void *) (VAL))
 
 static struct lim_aux_data *
 init_lim_data (gimple stmt)
@@ -676,31 +677,38 @@ extract_true_false_args_from_phi (basic_block dom, gimple phi,
      by the true edge of the predicate block and the other edge
      dominated by the false edge.  This ensures that the PHI argument
      we are going to take is completely determined by the path we
-     take from the predicate block.  */
+     take from the predicate block.
+     We can only use BB dominance checks below if the destination of
+     the true/false edges are dominated by their edge, thus only
+     have a single predecessor.  */
   extract_true_false_edges_from_block (dom, &true_edge, &false_edge);
   tem = EDGE_PRED (bb, 0);
   if (tem == true_edge
-      || tem->src == true_edge->dest
-      || dominated_by_p (CDI_DOMINATORS,
-                        tem->src, true_edge->dest))
+      || (single_pred_p (true_edge->dest)
+         && (tem->src == true_edge->dest
+             || dominated_by_p (CDI_DOMINATORS,
+                                tem->src, true_edge->dest))))
     arg0 = PHI_ARG_DEF (phi, tem->dest_idx);
   else if (tem == false_edge
-          || tem->src == false_edge->dest
-          || dominated_by_p (CDI_DOMINATORS,
-                             tem->src, false_edge->dest))
+          || (single_pred_p (false_edge->dest)
+              && (tem->src == false_edge->dest
+                  || dominated_by_p (CDI_DOMINATORS,
+                                     tem->src, false_edge->dest))))
     arg1 = PHI_ARG_DEF (phi, tem->dest_idx);
   else
     return false;
   tem = EDGE_PRED (bb, 1);
   if (tem == true_edge
-      || tem->src == true_edge->dest
-      || dominated_by_p (CDI_DOMINATORS,
-                        tem->src, true_edge->dest))
+      || (single_pred_p (true_edge->dest)
+         && (tem->src == true_edge->dest
+             || dominated_by_p (CDI_DOMINATORS,
+                                tem->src, true_edge->dest))))
     arg0 = PHI_ARG_DEF (phi, tem->dest_idx);
   else if (tem == false_edge
-          || tem->src == false_edge->dest
-          || dominated_by_p (CDI_DOMINATORS,
-                             tem->src, false_edge->dest))
+          || (single_pred_p (false_edge->dest)
+              && (tem->src == false_edge->dest
+                  || dominated_by_p (CDI_DOMINATORS,
+                                     tem->src, false_edge->dest))))
     arg1 = PHI_ARG_DEF (phi, tem->dest_idx);
   else
     return false;
@@ -1974,6 +1982,7 @@ gen_lsm_tmp_name (tree ref)
   switch (TREE_CODE (ref))
     {
     case MEM_REF:
+    case TARGET_MEM_REF:
       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
       lsm_tmp_name_add ("_");
       break;
@@ -2433,7 +2442,7 @@ fill_always_executed_in (struct loop *loop, sbitmap contains_call)
   edge e;
   struct loop *inn_loop = loop;
 
-  if (!loop->header->aux)
+  if (ALWAYS_EXECUTED_IN (loop->header) == NULL)
     {
       bbs = get_loop_body_in_dom_order (loop);
 
@@ -2475,7 +2484,7 @@ fill_always_executed_in (struct loop *loop, sbitmap contains_call)
 
       while (1)
        {
-         last->aux = loop;
+         SET_ALWAYS_EXECUTED_IN (last, loop);
          if (last == loop->header)
            break;
          last = get_immediate_dominator (CDI_DOMINATORS, last);
@@ -2530,9 +2539,7 @@ tree_ssa_lim_finalize (void)
   htab_t h;
 
   FOR_EACH_BB (bb)
-    {
-      bb->aux = NULL;
-    }
+    SET_ALWAYS_EXECUTED_IN (bb, NULL);
 
   pointer_map_destroy (lim_aux_data_map);