]> gcc.gnu.org Git - gcc.git/commitdiff
cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.
authorZdenek Dvorak <dvorakz@suse.cz>
Mon, 9 Apr 2007 06:51:43 +0000 (08:51 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Mon, 9 Apr 2007 06:51:43 +0000 (06:51 +0000)
* cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.
(create_preheaders): Check that loops are available.
(fix_loop_structure): Clean up, improve comments.
* tree-ssa-loop-manip.c (rewrite_into_loop_closed_ssa):
Check that loops are available.  Set LOOP_CLOSED_SSA to the loops
state flags.
* tree-scalar-evolution.c (scev_finalize): Clear scalar_evolution_info.
* predict.c (tree_estimate_probability): Do not call
calculate_dominance_info.  Call create_preheaders.
* tree-cfgcleanup.c (cleanup_tree_cfg_loop): Only call
rewrite_into_loop_closed_ssa if LOOP_CLOSED_SSA is set in loops state
flags.
* cfgloop.c (loop_preheader_edge): Assert that loops have preheaders.
* cfgloop.h (LOOP_CLOSED_SSA): New constant.
* tree-cfg.c (tree_split_edge): Make an assert more precise.
* tree-ssa-threadedge.c (thread_across_edge): Comment the function
arguments.

From-SVN: r123670

gcc/ChangeLog
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/predict.c
gcc/tree-cfg.c
gcc/tree-cfgcleanup.c
gcc/tree-scalar-evolution.c
gcc/tree-ssa-loop-manip.c
gcc/tree-ssa-threadedge.c

index 6542dc838823b85e8c508241d79fe7801d5d7ee0..0309e9fa92fc9107aa5bb43bbf2628e0d576a88a 100644 (file)
@@ -1,3 +1,23 @@
+2007-04-09  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.
+       (create_preheaders): Check that loops are available.
+       (fix_loop_structure): Clean up, improve comments.
+       * tree-ssa-loop-manip.c (rewrite_into_loop_closed_ssa):
+       Check that loops are available.  Set LOOP_CLOSED_SSA to the loops
+       state flags.
+       * tree-scalar-evolution.c (scev_finalize): Clear scalar_evolution_info.
+       * predict.c (tree_estimate_probability): Do not call
+       calculate_dominance_info.  Call create_preheaders.
+       * tree-cfgcleanup.c (cleanup_tree_cfg_loop): Only call
+       rewrite_into_loop_closed_ssa if LOOP_CLOSED_SSA is set in loops state
+       flags.
+       * cfgloop.c (loop_preheader_edge): Assert that loops have preheaders.
+       * cfgloop.h (LOOP_CLOSED_SSA): New constant.
+       * tree-cfg.c (tree_split_edge): Make an assert more precise.
+       * tree-ssa-threadedge.c (thread_across_edge): Comment the function
+       arguments.
+
 2007-04-08  Jan Hubicka  <jh@suse.cz>
 
        * tree.h (maybe_fold_offset_to_component_ref): Declare.
index 12ce92cdd9ee4726140a30dfc7ee9e858a50f4a1..b30e3527a6c46808ebc0a612e0015ff493e94f92 100644 (file)
@@ -1548,6 +1548,8 @@ loop_preheader_edge (const struct loop *loop)
   edge e;
   edge_iterator ei;
 
+  gcc_assert ((current_loops->state & LOOPS_HAVE_PREHEADERS) != 0);
+
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     if (e->src != loop->latch)
       break;
index cbad81d27f066cbd0871e85553d8ae8c757898ca..15d55890f6a10c6d69b2d91d9799369965f64715 100644 (file)
@@ -169,7 +169,8 @@ enum
   LOOPS_HAVE_SIMPLE_LATCHES = 2,
   LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
   LOOPS_HAVE_RECORDED_EXITS = 8,
-  LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16
+  LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
+  LOOP_CLOSED_SSA = 32
 };
 
 #define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
index 9ca3947a0c60df20dd3b2234c573c1f9f88e2559..0e876e566e1ea0a824a68ad97969f5c0026abe79 100644 (file)
@@ -1105,7 +1105,7 @@ create_preheader (struct loop *loop, int flags)
   int nentry = 0;
   bool irred = false;
   bool latch_edge_was_fallthru;
-  edge one_succ_pred = 0;
+  edge one_succ_pred = NULL, single_entry = NULL;
   edge_iterator ei;
 
   FOR_EACH_EDGE (e, ei, loop->header->preds)
@@ -1114,21 +1114,20 @@ create_preheader (struct loop *loop, int flags)
        continue;
       irred |= (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
       nentry++;
+      single_entry = e;
       if (single_succ_p (e->src))
        one_succ_pred = e;
     }
   gcc_assert (nentry);
   if (nentry == 1)
     {
-      e = loop_preheader_edge (loop);
-
       if (/* We do not allow entry block to be the loop preheader, since we
             cannot emit code there.  */
-         e->src != ENTRY_BLOCK_PTR
+         single_entry->src != ENTRY_BLOCK_PTR
          /* If we want simple preheaders, also force the preheader to have
             just a single successor.  */
          && !((flags & CP_SIMPLE_PREHEADERS)
-              && !single_succ_p (e->src)))
+              && !single_succ_p (single_entry->src)))
        return NULL;
     }
 
@@ -1177,6 +1176,9 @@ create_preheaders (int flags)
   loop_iterator li;
   struct loop *loop;
 
+  if (!current_loops)
+    return;
+
   FOR_EACH_LOOP (li, loop, 0)
     create_preheader (loop, flags);
   current_loops->state |= LOOPS_HAVE_PREHEADERS;
@@ -1380,19 +1382,33 @@ fix_loop_structure (bitmap changed_bbs)
   basic_block bb;
   struct loop *loop, *ploop;
   loop_iterator li;
+  bool record_exits = false;
+  struct loop **superloop = XNEWVEC (struct loop *, number_of_loops ());
 
-  /* Remove the old bb -> loop mapping.  */
+  gcc_assert (current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES);
+
+  /* Remove the old bb -> loop mapping.  Remember the depth of the blocks in
+     the loop hierarchy, so that we can recognize blocks whose loop nesting
+     relationship has changed.  */
   FOR_EACH_BB (bb)
     {
-      bb->aux = (void *) (size_t) bb->loop_father->depth;
+      if (changed_bbs)
+       bb->aux = (void *) (size_t) bb->loop_father->depth;
       bb->loop_father = current_loops->tree_root;
     }
 
-  /* Remove the dead loops from structures.  */
-  current_loops->tree_root->num_nodes = n_basic_blocks;
-  FOR_EACH_LOOP (li, loop, 0)
+  if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
+    {
+      release_recorded_exits ();
+      record_exits = true;
+    }
+
+  /* Remove the dead loops from structures.  We start from the innermost
+     loops, so that when we remove the loops, we know that the loops inside
+     are preserved, and do not waste time relinking loops that will be
+     removed later.  */
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
-      loop->num_nodes = 0;
       if (loop->header)
        continue;
 
@@ -1407,39 +1423,52 @@ fix_loop_structure (bitmap changed_bbs)
       delete_loop (loop);
     }
 
-  /* Rescan the bodies of loops, starting from the outermost.  */
+  /* Rescan the bodies of loops, starting from the outermost ones.  We assume
+     that no optimization interchanges the order of the loops, i.e., it cannot
+     happen that L1 was superloop of L2 before and it is subloop of L2 now
+     (without explicitly updating loop information).  At the same time, we also
+     determine the new loop structure.  */
+  current_loops->tree_root->num_nodes = n_basic_blocks;
   FOR_EACH_LOOP (li, loop, 0)
     {
+      superloop[loop->num] = loop->header->loop_father;
       loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
     }
 
   /* Now fix the loop nesting.  */
   FOR_EACH_LOOP (li, loop, 0)
     {
-      bb = loop_preheader_edge (loop)->src;
-      if (bb->loop_father != loop->outer)
+      ploop = superloop[loop->num];
+      if (ploop != loop->outer)
        {
          flow_loop_tree_node_remove (loop);
-         flow_loop_tree_node_add (bb->loop_father, loop);
+         flow_loop_tree_node_add (ploop, loop);
        }
     }
+  free (superloop);
 
   /* Mark the blocks whose loop has changed.  */
-  FOR_EACH_BB (bb)
+  if (changed_bbs)
     {
-      if (changed_bbs
-         && (void *) (size_t) bb->loop_father->depth != bb->aux)
-       bitmap_set_bit (changed_bbs, bb->index);
+      FOR_EACH_BB (bb)
+       {
+         if ((void *) (size_t) bb->loop_father->depth != bb->aux)
+           bitmap_set_bit (changed_bbs, bb->index);
 
-      bb->aux = NULL;
+         bb->aux = NULL;
+       }
     }
 
+  if (current_loops->state & LOOPS_HAVE_PREHEADERS)
+    create_preheaders (CP_SIMPLE_PREHEADERS);
+
   if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
     mark_irreducible_loops ();
 
-  if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
-    {
-      release_recorded_exits ();
-      record_loop_exits ();
-    }
+  if (record_exits)
+    record_loop_exits ();
+
+#ifdef ENABLE_CHECKING
+  verify_loop_structure ();
+#endif
 }
index 097cfb860703c66a61f134a47d49cb9352177225..7cae1b720ed3aa496da05b7c0f2020d8bf73a69e 100644 (file)
@@ -1290,7 +1290,9 @@ tree_estimate_probability (void)
 
   add_noreturn_fake_exit_edges ();
   connect_infinite_loops_to_exit ();
-  calculate_dominance_info (CDI_DOMINATORS);
+  /* We use loop_niter_by_eval, which requires that the loops have
+     preheaders.  */
+  create_preheaders (CP_SIMPLE_PREHEADERS);
   calculate_dominance_info (CDI_POST_DOMINATORS);
 
   tree_bb_level_predictions ();
index fa4800e00c241dc45320dfba58744b14134a1b52..a0af80442e8f30fb7b3118029cc0d2f10c540802 100644 (file)
@@ -3118,7 +3118,7 @@ tree_split_edge (edge edge_in)
   new_edge->count = edge_in->count;
 
   e = redirect_edge_and_branch (edge_in, new_bb);
-  gcc_assert (e);
+  gcc_assert (e == edge_in);
   reinstall_phi_args (new_edge, e);
 
   return new_bb;
index 8cf66cb4a270c5bddef8b7ffcee0e9d11dcf5144..39dcfe7c3abf1caffa65badd75cf32e46a4dde26 100644 (file)
@@ -599,7 +599,7 @@ cleanup_tree_cfg_loop (void)
 {
   bool changed = cleanup_tree_cfg ();
 
-  if (changed)
+  if (changed && current_loops != NULL)
     {
       bitmap changed_bbs = BITMAP_ALLOC (NULL);
       calculate_dominance_info (CDI_DOMINATORS);
@@ -608,7 +608,8 @@ cleanup_tree_cfg_loop (void)
       /* This usually does nothing.  But sometimes parts of cfg that originally
         were inside a loop get out of it due to edge removal (since they
         become unreachable by back edges from latch).  */
-      rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
+      if ((current_loops->state & LOOP_CLOSED_SSA) != 0)
+       rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
 
       BITMAP_FREE (changed_bbs);
 
index 846d27414d50ac72a63ffd6a741956ec2f4cba5a..955240b68952296fb7b0bc431a5c29e28d52f9d7 100644 (file)
@@ -2862,6 +2862,7 @@ scev_finalize (void)
 {
   htab_delete (scalar_evolution_info);
   BITMAP_FREE (already_instantiated);
+  scalar_evolution_info = NULL;
 }
 
 /* Replace ssa names for that scev can prove they are constant by the
index bce9890d6a48d22b3ee70c1a91b884e9831ee868..30f853469fceed67fca120d9d2320e05cfcd7daa 100644 (file)
@@ -355,10 +355,16 @@ find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks, bitmap need_phis)
 void
 rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
 {
-  bitmap loop_exits = get_loops_exits ();
+  bitmap loop_exits;
   bitmap *use_blocks;
   unsigned i, old_num_ssa_names;
-  bitmap names_to_rename = BITMAP_ALLOC (NULL);
+  bitmap names_to_rename;
+
+  if (!current_loops)
+    return;
+
+  loop_exits = get_loops_exits ();
+  names_to_rename = BITMAP_ALLOC (NULL);
 
   /* If the pass has caused the SSA form to be out-of-date, update it
      now.  */
@@ -383,6 +389,8 @@ rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
   /* Fix up all the names found to be used outside their original
      loops.  */
   update_ssa (TODO_update_ssa);
+
+  current_loops->state |= LOOP_CLOSED_SSA;
 }
 
 /* Check invariants of the loop closed ssa form for the USE in BB.  */
index 777685af6522dacad68350d301fc842cee20d800..86b265627543b6c86f95daa6c4c26639395a8367 100644 (file)
@@ -488,7 +488,19 @@ simplify_control_stmt_condition (edge e,
    Note it is quite common for the first block inside a loop to
    end with a conditional which is either always true or always
    false when reached via the loop backedge.  Thus we do not want
-   to blindly disable threading across a loop backedge.  */
+   to blindly disable threading across a loop backedge.
+   DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
+   to avoid allocating memory.
+   HANDLE_DOMINATING_ASSERTS is true if we should try to replace operands of
+   the simplified condition with left-hand sides of ASSERT_EXPRs they are
+   used in.
+   STACK is used to undo temporary equivalences created during the walk of
+   E->dest.
+
+   SIMPLIFY is a pass-specific function used to simplify statements.  */
 
 void
 thread_across_edge (tree dummy_cond,
This page took 0.096245 seconds and 5 git commands to generate.