2013-03-26 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Apr 2013 08:01:19 +0000 (08:01 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Apr 2013 08:01:19 +0000 (08:01 +0000)
* tree-cfg.c (execute_build_cfg): Build the loop tree.
(pass_build_cfg): Provide PROP_loops.
(move_sese_region_to_fn): Remove loops that are outlined into fn
for now.
* tree-inline.c: Include cfgloop.h.
(initialize_cfun): Do not drop PROP_loops.
(copy_loops): New function.
(copy_cfg_body): Copy loop structure.
(tree_function_versioning): Initialize destination loop tree.
* tree-ssa-loop.c (pass_tree_loop_init): Do not provide PROP_loops.
(pass_parallelize_loops): Do IL verification.
* loop-init.c (loop_optimizer_init): Fixup loops if required.
* tree-optimize.c (execute_fixup_cfg): If we need to cleanup
the CFG make sure we fixup loops as well.
* tree-ssa-tail-merge.c: Include cfgloop.h.
(replace_block_by): When merging loop latches mark loops for fixup.
* lto-streamer-out.c (output_struct_function_base): Drop
PROP_loops for now.
* tree-ssa-phiopt.c: Include tree-scalar-evolution.h.
(tree_ssa_cs_elim): Initialize the loop optimizer and SCEV.
* ipa-split.c: Include cfgloop.h.
(split_function): Add the new return block to the loop tree root.
* tree-cfgcleanup.c (remove_forwarder_block_with_phi): Return
whether we have removed the forwarder block.
(merge_phi_nodes): If we removed a forwarder mark loops for fixup.
* cfgloop.h (place_new_loop): Declare.
* cfgloopmanip.c (place_new_loop): Export.
* Makefile.in (asan.o): Add $(CFGLOOP_H) dependency.
(tree-switch-conversion.o): Likewise.
(tree-complex.o): Likewise.
(tree-inline.o): Likewise.
(tree-ssa-tailmerge.o): Likewise.
(ipa-split.o): Likewise.
(tree-ssa-phiopt.o): Add $(SCEV_H) dependency.
(tree-ssa-copy.o): Likewise.
* tree-switch-conversion.c: Include cfgloop.h
(process_switch): If we emit a bit-test cascade, schedule loops
for fixup.
* tree-complex.c: Include cfgloop.h.
(expand_complex_div_wide): Properly add new basic-blocks to loops.
* asan.c: Include cfgloop.h.
(create_cond_insert_point): Properly add new basic-blocks to
loops, schedule loop fixup.
* cfgloop.c (verify_loop_structure): Check that looks are not
marked for fixup.
* omp-low.c (expand_parallel_call): Properly add new basic-blocks
to loops.
(expand_omp_for_generic): Likewise.
(expand_omp_sections): Likewise.
(expand_omp_atomic_pipeline): Schedule loops for fixup.
* tree-ssa-copy.c: Include tree-scalar-evolution.h.
(fini_copy_prop): Disable DCE in substitute_and_fold if SCEV
is initialized, not when loops are present.
* tree-parloops.c (parallelize_loops): Remove checking here.
* passes.c (init_optimization_passes): Schedule a copy-propagation
pass before complete unrolling of inner loops.

* gcc.dg/tree-prof/update-loopch.c: Revert last change.
* gcc.dg/graphite/pr33766.c: Fix undefined behavior.
* gcc.dg/pr53265.c: Remove XFAILs.
* gcc.dg/tree-ssa/loop-38.c: Remove unreliable dump scanning.
* gcc.dg/tree-ssa/pr21559.c: Change back to two expected jump threads.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198333 138bc75d-0d04-0410-961f-82ee72b054a4

28 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/asan.c
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/ipa-split.c
gcc/loop-init.c
gcc/lto-streamer-out.c
gcc/omp-low.c
gcc/passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/graphite/pr33766.c
gcc/testsuite/gcc.dg/pr53265.c
gcc/testsuite/gcc.dg/tree-prof/update-loopch.c
gcc/testsuite/gcc.dg/tree-ssa/loop-38.c
gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
gcc/tree-cfg.c
gcc/tree-cfgcleanup.c
gcc/tree-complex.c
gcc/tree-inline.c
gcc/tree-optimize.c
gcc/tree-parloops.c
gcc/tree-ssa-copy.c
gcc/tree-ssa-loop.c
gcc/tree-ssa-phiopt.c
gcc/tree-ssa-tail-merge.c
gcc/tree-switch-conversion.c

index 749d283..e283c3d 100644 (file)
@@ -1,3 +1,62 @@
+2013-03-26  Richard Biener  <rguenther@suse.de>
+
+       * tree-cfg.c (execute_build_cfg): Build the loop tree.
+       (pass_build_cfg): Provide PROP_loops.
+       (move_sese_region_to_fn): Remove loops that are outlined into fn
+       for now.
+       * tree-inline.c: Include cfgloop.h.
+       (initialize_cfun): Do not drop PROP_loops.
+       (copy_loops): New function.
+       (copy_cfg_body): Copy loop structure.
+       (tree_function_versioning): Initialize destination loop tree.
+       * tree-ssa-loop.c (pass_tree_loop_init): Do not provide PROP_loops.
+       (pass_parallelize_loops): Do IL verification.
+       * loop-init.c (loop_optimizer_init): Fixup loops if required.
+       * tree-optimize.c (execute_fixup_cfg): If we need to cleanup
+       the CFG make sure we fixup loops as well.
+       * tree-ssa-tail-merge.c: Include cfgloop.h.
+       (replace_block_by): When merging loop latches mark loops for fixup.
+       * lto-streamer-out.c (output_struct_function_base): Drop
+       PROP_loops for now.
+       * tree-ssa-phiopt.c: Include tree-scalar-evolution.h.
+       (tree_ssa_cs_elim): Initialize the loop optimizer and SCEV.
+       * ipa-split.c: Include cfgloop.h.
+       (split_function): Add the new return block to the loop tree root.
+       * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Return
+       whether we have removed the forwarder block.
+       (merge_phi_nodes): If we removed a forwarder mark loops for fixup.
+       * cfgloop.h (place_new_loop): Declare.
+       * cfgloopmanip.c (place_new_loop): Export.
+       * Makefile.in (asan.o): Add $(CFGLOOP_H) dependency.
+       (tree-switch-conversion.o): Likewise.
+       (tree-complex.o): Likewise.
+       (tree-inline.o): Likewise.
+       (tree-ssa-tailmerge.o): Likewise.
+       (ipa-split.o): Likewise.
+       (tree-ssa-phiopt.o): Add $(SCEV_H) dependency.
+       (tree-ssa-copy.o): Likewise.
+       * tree-switch-conversion.c: Include cfgloop.h
+       (process_switch): If we emit a bit-test cascade, schedule loops
+       for fixup.
+       * tree-complex.c: Include cfgloop.h.
+       (expand_complex_div_wide): Properly add new basic-blocks to loops.
+       * asan.c: Include cfgloop.h.
+       (create_cond_insert_point): Properly add new basic-blocks to
+       loops, schedule loop fixup.
+       * cfgloop.c (verify_loop_structure): Check that looks are not
+       marked for fixup.
+       * omp-low.c (expand_parallel_call): Properly add new basic-blocks
+       to loops.
+       (expand_omp_for_generic): Likewise.
+       (expand_omp_sections): Likewise.
+       (expand_omp_atomic_pipeline): Schedule loops for fixup.
+       * tree-ssa-copy.c: Include tree-scalar-evolution.h.
+       (fini_copy_prop): Disable DCE in substitute_and_fold if SCEV
+       is initialized, not when loops are present.
+       * tree-parloops.c (parallelize_loops): Remove checking here.
+       * passes.c (init_optimization_passes): Schedule a copy-propagation
+       pass before complete unrolling of inner loops.
+
 2013-04-26  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile.in (toplev.o): Depend on diagnostic-color.h.
index f6fe9aa..36b0062 100644 (file)
@@ -2225,7 +2225,7 @@ tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
 tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \
    $(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \
-   intl.h $(FUNCTION_H) $(GIMPLE_H) \
+   intl.h $(FUNCTION_H) $(GIMPLE_H) $(CFGLOOP_H) \
    debug.h $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \
    $(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) \
    $(TREE_PRETTY_PRINT_H)
@@ -2237,7 +2237,7 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \
    $(DIAGNOSTIC_CORE_H) $(CGRAPH_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(GIMPLE_H)
 asan.o : asan.c asan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \
-   output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) \
+   output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) $(CFGLOOP_H) \
    tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \
    $(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h \
    $(HASH_TABLE_H) alloc-pool.h
@@ -2250,7 +2250,7 @@ tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
    tree-ssa-propagate.h
 tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
    $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \
-   $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+   $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
    $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \
    $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \
    $(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H)
@@ -2314,14 +2314,14 @@ tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \
    $(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \
    $(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \
-   insn-config.h $(EXPR_H) $(OPTABS_H)
+   insn-config.h $(EXPR_H) $(OPTABS_H) $(SCEV_H)
 tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \
    $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
    langhooks.h $(TREE_PRETTY_PRINT_H)
 tree-ssa-copy.o : tree-ssa-copy.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(TM_P_H) $(GGC_H) $(DIAGNOSTIC_H) \
-   $(FUNCTION_H) $(TM_H) coretypes.h \
+   $(FUNCTION_H) $(TM_H) coretypes.h $(SCEV_H) \
    $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h tree-ssa-propagate.h \
    $(FLAGS_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \
@@ -2929,7 +2929,7 @@ ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h  \
    $(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) $(IPA_INLINE_H)
 ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \
-   $(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \
+   $(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) $(CFGLOOP_H) \
    $(TREE_INLINE_H) $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H)
 ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
@@ -3058,13 +3058,13 @@ tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
    $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
-    $(TM_H) coretypes.h $(GIMPLE_H) \
+    $(TM_H) coretypes.h $(GIMPLE_H) $(CFGLOOP_H) \
     $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \
     $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \
     $(GIMPLE_PRETTY_PRINT_H) langhooks.h
 tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
     $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(TREE_HASHER_H) $(GIMPLE_H) \
-    tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h
+    $(CFGLOOP_H) tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h
 tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
     $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \
     $(TARGET_H) $(TARGET_DEF_H) tree-iterator.h
index b8acaf7..c068b8c 100644 (file)
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "hash-table.h"
 #include "alloc-pool.h"
+#include "cfgloop.h"
 
 /* AddressSanitizer finds out-of-bounds and use-after-free bugs
    with <2x slowdown on average.
@@ -1220,6 +1221,11 @@ create_cond_insert_point (gimple_stmt_iterator *iter,
   basic_block cond_bb = e->src;
   basic_block fallthru_bb = e->dest;
   basic_block then_bb = create_empty_bb (cond_bb);
+  if (current_loops)
+    {
+      add_bb_to_loop (then_bb, cond_bb->loop_father);
+      loops_state_set (LOOPS_NEED_FIXUP);
+    }
 
   /* Set up the newly created 'then block'.  */
   e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
index 54ce2a2..568b7a2 100644 (file)
@@ -1329,6 +1329,12 @@ verify_loop_structure (void)
   bool dom_available = dom_info_available_p (CDI_DOMINATORS);
   sbitmap visited;
 
+  if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+    {
+      error ("loop verification on loop tree that needs fixup");
+      err = 1;
+    }
+
   /* We need up-to-date dominators, compute or verify them.  */
   if (!dom_available)
     calculate_dominance_info (CDI_DOMINATORS);
index 29ac6c4..948e805 100644 (file)
@@ -232,6 +232,7 @@ void rescan_loop_exit (edge, bool, bool);
 /* Loop data structure manipulation/querying.  */
 extern void flow_loop_tree_node_add (struct loop *, struct loop *);
 extern void flow_loop_tree_node_remove (struct loop *);
+extern void place_new_loop (struct loop *);
 extern void add_loop (struct loop *, struct loop *);
 extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
 extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
index 13efb75..f2d6a3b 100644 (file)
@@ -410,7 +410,7 @@ remove_path (edge e)
 
 /* Creates place for a new LOOP in loops structure.  */
 
-static void
+void
 place_new_loop (struct loop *loop)
 {
   loop->num = number_of_loops ();
index e7d469d..107c7a9 100644 (file)
@@ -90,6 +90,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "gimple-pretty-print.h"
 #include "ipa-inline.h"
+#include "cfgloop.h"
 
 /* Per basic block info.  */
 
@@ -1131,6 +1132,8 @@ split_function (struct split_point *split_point)
       e = make_edge (new_return_bb, EXIT_BLOCK_PTR, 0);
       e->probability = REG_BR_PROB_BASE;
       e->count = new_return_bb->count;
+      if (current_loops)
+       add_bb_to_loop (new_return_bb, current_loops->tree_root);
       bitmap_set_bit (split_point->split_bbs, new_return_bb->index);
     }
   /* When we pass around the value, use existing return block.  */
index 92d621e..664ff29 100644 (file)
@@ -91,16 +91,27 @@ loop_optimizer_init (unsigned flags)
     }
   else
     {
+      bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS);
+
       gcc_assert (cfun->curr_properties & PROP_loops);
 
       /* Ensure that the dominators are computed, like flow_loops_find does.  */
       calculate_dominance_info (CDI_DOMINATORS);
 
+      if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+       {
+         loops_state_clear (~0U);
+         fix_loop_structure (NULL);
+       }
+
 #ifdef ENABLE_CHECKING
-      verify_loop_structure ();
+      else
+       verify_loop_structure ();
 #endif
 
       /* Clear all flags.  */
+      if (recorded_exits)
+       release_recorded_exits ();
       loops_state_clear (~0U);
     }
 
index ad620c6..afb73f2 100644 (file)
@@ -733,8 +733,9 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
   FOR_EACH_VEC_SAFE_ELT (fn->local_decls, i, t)
     stream_write_tree (ob, t, true);
 
-  /* Output current IL state of the function.  */
-  streamer_write_uhwi (ob, fn->curr_properties);
+  /* Output current IL state of the function.
+     ???  We don't stream loops.  */
+  streamer_write_uhwi (ob, fn->curr_properties & ~PROP_loops);
 
   /* Write all the attributes for FN.  */
   bp = bitpack_create (ob->main_stream);
index 3e519db..eaeeaa5 100644 (file)
@@ -3056,6 +3056,11 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
 
          make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
          make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
+         if (current_loops)
+           {
+             add_bb_to_loop (then_bb, cond_bb->loop_father);
+             add_bb_to_loop (else_bb, cond_bb->loop_father);
+           }
          e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
          e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
 
@@ -4011,6 +4016,8 @@ expand_omp_for_generic (struct omp_region *region,
              tree vtype = TREE_TYPE (fd->loops[i].v);
 
              bb = create_empty_bb (last_bb);
+             if (current_loops)
+               add_bb_to_loop (bb, last_bb->loop_father);
              gsi = gsi_start_bb (bb);
 
              if (i < fd->collapse - 1)
@@ -4114,6 +4121,8 @@ expand_omp_for_generic (struct omp_region *region,
       remove_edge (e);
 
       make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
+      if (current_loops)
+       add_bb_to_loop (l2_bb, cont_bb->loop_father);
       if (fd->collapse > 1)
        {
          e = find_edge (cont_bb, l1_bb);
@@ -4902,6 +4911,8 @@ expand_omp_sections (struct omp_region *region)
   t = gimple_block_label (default_bb);
   u = build_case_label (NULL, NULL, t);
   make_edge (l0_bb, default_bb, 0);
+  if (current_loops)
+    add_bb_to_loop (default_bb, l0_bb->loop_father);
 
   stmt = gimple_build_switch (vmain, u, label_vec);
   gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
@@ -5438,6 +5449,10 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
   if (gimple_in_ssa_p (cfun))
     update_ssa (TODO_update_ssa_no_phi);
 
+  /* ???  The above could use loop construction primitives.  */
+  if (current_loops)
+    loops_state_set (LOOPS_NEED_FIXUP);
+
   return true;
 }
 
index 45e79cc..fd67ee6 100644 (file)
@@ -1397,6 +1397,7 @@ init_optimization_passes (void)
         They ensure memory accesses are not indirect wherever possible.  */
       NEXT_PASS (pass_strip_predict_hints);
       NEXT_PASS (pass_rename_ssa_copies);
+      NEXT_PASS (pass_copy_prop);
       NEXT_PASS (pass_complete_unrolli);
       NEXT_PASS (pass_ccp);
       /* After CCP we rewrite no longer addressed locals into SSA
index 5e568fb..737ef4a 100644 (file)
@@ -1,3 +1,11 @@
+2013-03-26  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-prof/update-loopch.c: Revert last change.
+       * gcc.dg/graphite/pr33766.c: Fix undefined behavior.
+       * gcc.dg/pr53265.c: Remove XFAILs.
+       * gcc.dg/tree-ssa/loop-38.c: Remove unreliable dump scanning.
+       * gcc.dg/tree-ssa/pr21559.c: Change back to two expected jump threads.
+
 2013-04-26  Jakub Jelinek  <jakub@redhat.com>
 
        * lib/prune.exp: Add -fdiagnostics-color=never to TEST_ALWAYS_FLAGS.
index f6bb506..47d3dd4 100644 (file)
@@ -4,16 +4,16 @@
 float
 fxt1_quantize_ALPHA1()
 {
-        int j1;
-        int i;
-        float *tv;
-        for (j1 = 1; j1; j1++) {
-                float e;
-                for (i = 1; i; i++)
-                        e = tv[i];
-                if (e)
-                        i = j1;
-        }
-        return tv[i];
+  int j1;
+  int i;
+  float *tv;
+  for (j1 = 1; j1 < 2048; j1++) {
+      float e;
+      for (i = 1; i < 2048; i++)
+       e = tv[i];
+      if (e)
+       i = j1;
+  }
+  return tv[i];
 }
 
index c60a736..7016446 100644 (file)
@@ -49,9 +49,9 @@ fn4 (void)
   unsigned int *a[32], *o, i;
 
   bar (a);
-  for (i = 0; i <= sizeof (a) / sizeof (a[0]); i++)    /* { dg-message "note: containing loop" "" { xfail *-*-* } } */
+  for (i = 0; i <= sizeof (a) / sizeof (a[0]); i++)    /* { dg-message "note: containing loop" "" } */
     {
-      o = a[i];        /* { dg-warning "invokes undefined behavior" "" { xfail *-*-* } } */
+      o = a[i];        /* { dg-warning "invokes undefined behavior" "" } */
       bar (o);
     }
 }
@@ -85,11 +85,11 @@ fn7 (void)
 {
   int a[16], b, c;
   bar (a);
-  for (b = a[c = 0]; c < 16; b = a[++c])       /* { dg-warning "invokes undefined behavior" "" { xfail *-*-* } } */
+  for (b = a[c = 0]; c < 16; b = a[++c])       /* { dg-warning "invokes undefined behavior" "" } */
     baz (b);
 }
 
-/* { dg-message "note: containing loop" "" { xfail *-*-* } 88 } */
+/* { dg-message "note: containing loop" "" { target *-*-* } 88 } */
 
 const void *va, *vb, *vc, *vd, *ve;
 const void *vf[4];
index e2656a3..cc06ea7 100644 (file)
@@ -14,7 +14,7 @@ main ()
 /* Loop header copying will peel away the initial conditional, so the loop body
    is once reached directly from entry point of function, rest via loopback
    edge.  */
-/* { dg-final-use { scan-ipa-dump "loop depth 0, count 33334" "profile"} } */
+/* { dg-final-use { scan-ipa-dump "loop depth 1, count 33334" "profile"} } */
 /* { dg-final-use { scan-tree-dump "loop depth 1, count 33332" "optimized"} } */
 /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
 /* { dg-final-use { cleanup-ipa-dump "profile" } } */
index 7f23031..714696e 100644 (file)
@@ -13,6 +13,5 @@ t(int n)
        sum+=b[i];
   return sum;
 }
-/* { dg-final { scan-tree-dump "Found better loop bound 11" "cunrolli" } } */
 /* { dg-final { scan-tree-dump "Loop 1 iterates at most 11 times" "cunrolli" } } */
 /* { dg-final { cleanup-tree-dump "cunrolli" } } */
index 34f4a01..402c102 100644 (file)
@@ -37,7 +37,7 @@ void foo (void)
 /* Second, we should thread the edge out of the loop via the break
    statement.  We also realize that the final bytes == 0 test is useless,
    and thread over it.  */
-/* { dg-final { scan-tree-dump-times "Threaded jump" 3 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "Threaded jump" 2 "vrp1" } } */
 
 /* { dg-final { cleanup-tree-dump "vrp1" } } */
 
index c5c25a7..cbbc5c7 100644 (file)
@@ -247,6 +247,8 @@ execute_build_cfg (void)
       fprintf (dump_file, "Scope blocks:\n");
       dump_scope_blocks (dump_file, dump_flags);
     }
+  cleanup_tree_cfg ();
+  loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
   return 0;
 }
 
@@ -263,10 +265,10 @@ struct gimple_opt_pass pass_build_cfg =
   0,                                   /* static_pass_number */
   TV_TREE_CFG,                         /* tv_id */
   PROP_gimple_leh,                     /* properties_required */
-  PROP_cfg,                            /* properties_provided */
+  PROP_cfg | PROP_loops,               /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_verify_stmts | TODO_cleanup_cfg  /* todo_flags_finish */
+  TODO_verify_stmts                    /* todo_flags_finish */
  }
 };
 
@@ -6713,6 +6715,18 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
   d.eh_map = eh_map;
   d.remap_decls_p = true;
 
+  /* Cancel all loops inside the SESE region.
+     ???  We rely on loop fixup because loop structure is not 100%
+     up-to-date when called from OMP lowering and thus cancel_loop_tree
+     will not work.
+     ???  Properly move loops to the outlined function.  */
+  FOR_EACH_VEC_ELT (bbs, i, bb)
+    if (bb->loop_father->header == bb)
+      {
+       bb->loop_father->header = NULL;
+       bb->loop_father->latch = NULL;
+       loops_state_set (LOOPS_NEED_FIXUP);
+      }
   FOR_EACH_VEC_ELT (bbs, i, bb)
     {
       /* No need to update edge counts on the last block.  It has
index b355a86..3c69a7d 100644 (file)
@@ -748,9 +748,10 @@ cleanup_tree_cfg (void)
   return changed;
 }
 
-/* Merge the PHI nodes at BB into those at BB's sole successor.  */
+/* Tries to merge the PHI nodes at BB into those at BB's sole successor.
+   Returns true if successful.  */
 
-static void
+static bool
 remove_forwarder_block_with_phi (basic_block bb)
 {
   edge succ = single_succ_edge (bb);
@@ -762,7 +763,7 @@ remove_forwarder_block_with_phi (basic_block bb)
      However it may happen that the infinite loop is created
      afterwards due to removal of forwarders.  */
   if (dest == bb)
-    return;
+    return false;
 
   /* If the destination block consists of a nonlocal label, do not
      merge it.  */
@@ -770,7 +771,7 @@ remove_forwarder_block_with_phi (basic_block bb)
   if (label
       && gimple_code (label) == GIMPLE_LABEL
       && DECL_NONLOCAL (gimple_label_label (label)))
-    return;
+    return false;
 
   /* Redirect each incoming edge to BB to DEST.  */
   while (EDGE_COUNT (bb->preds) > 0)
@@ -859,6 +860,8 @@ remove_forwarder_block_with_phi (basic_block bb)
   /* Remove BB since all of BB's incoming edges have been redirected
      to DEST.  */
   delete_basic_block (bb);
+
+  return true;
 }
 
 /* This pass merges PHI nodes if one feeds into another.  For example,
@@ -960,13 +963,20 @@ merge_phi_nodes (void)
     }
 
   /* Now let's drain WORKLIST.  */
+  bool changed = false;
   while (current != worklist)
     {
       bb = *--current;
-      remove_forwarder_block_with_phi (bb);
+      changed |= remove_forwarder_block_with_phi (bb);
     }
-
   free (worklist);
+
+  /* Removing forwarder blocks can cause formerly irreducible loops
+     to become reducible if we merged two entry blocks.  */
+  if (changed
+      && current_loops)
+    loops_state_set (LOOPS_NEED_FIXUP);
+
   return 0;
 }
 
index ee54568..d43172b 100644 (file)
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "tree-ssa-propagate.h"
 #include "tree-hasher.h"
+#include "cfgloop.h"
 
 
 /* For each complex ssa name, a lattice value.  We're interested in finding
@@ -1139,6 +1140,11 @@ expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
       make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
       make_edge (bb_true, bb_join, EDGE_FALLTHRU);
       make_edge (bb_false, bb_join, EDGE_FALLTHRU);
+      if (current_loops)
+       {
+         add_bb_to_loop (bb_true, bb_cond->loop_father);
+         add_bb_to_loop (bb_false, bb_cond->loop_father);
+       }
 
       /* Update dominance info.  Note that bb_join's data was
          updated by split_block.  */
index 7fa0245..c358cbe 100644 (file)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "value-prof.h"
 #include "tree-pass.h"
 #include "target.h"
+#include "cfgloop.h"
 
 #include "rtl.h"       /* FIXME: For asm_str_count.  */
 
@@ -2088,7 +2089,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
   cfun->static_chain_decl = src_cfun->static_chain_decl;
   cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area;
   cfun->function_end_locus = src_cfun->function_end_locus;
-  cfun->curr_properties = src_cfun->curr_properties & ~PROP_loops;
+  cfun->curr_properties = src_cfun->curr_properties;
   cfun->last_verified = src_cfun->last_verified;
   cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
   cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
@@ -2193,6 +2194,45 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
     }
 }
 
+/* Make a copy of the sub-loops of SRC_PARENT and place them
+   as siblings of DEST_PARENT.  */
+
+static void
+copy_loops (bitmap blocks_to_copy,
+           struct loop *dest_parent, struct loop *src_parent)
+{
+  struct loop *src_loop = src_parent->inner;
+  while (src_loop)
+    {
+      if (!blocks_to_copy
+         || bitmap_bit_p (blocks_to_copy, src_loop->header->index))
+       {
+         struct loop *dest_loop = alloc_loop ();
+
+         /* Assign the new loop its header and latch and associate
+            those with the new loop.  */
+         dest_loop->header = (basic_block)src_loop->header->aux;
+         dest_loop->header->loop_father = dest_loop;
+         if (src_loop->latch != NULL)
+           {
+             dest_loop->latch = (basic_block)src_loop->latch->aux;
+             dest_loop->latch->loop_father = dest_loop;
+           }
+
+         /* Copy loop meta-data.  */
+         copy_loop_info (src_loop, dest_loop);
+
+         /* Finally place it into the loop array and the loop tree.  */
+         place_new_loop (dest_loop);
+         flow_loop_tree_node_add (dest_parent, dest_loop);
+
+         /* Recurse.  */
+         copy_loops (blocks_to_copy, dest_loop, src_loop);
+       }
+      src_loop = src_loop->next;
+    }
+}
+
 /* Make a copy of the body of FN so that it can be inserted inline in
    another function.  Walks FN via CFG, returns new fndecl.  */
 
@@ -2270,6 +2310,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
        basic_block new_bb = copy_bb (id, bb, frequency_scale, count_scale);
        bb->aux = new_bb;
        new_bb->aux = bb;
+       new_bb->loop_father = entry_block_map->loop_father;
       }
 
   last = last_basic_block;
@@ -2290,6 +2331,16 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
       e->count = incoming_count;
     }
 
+  /* Duplicate the loop tree, if available and wanted.  */
+  if (id->src_cfun->x_current_loops != NULL
+      && current_loops != NULL)
+    {
+      copy_loops (blocks_to_copy, entry_block_map->loop_father,
+                 id->src_cfun->x_current_loops->tree_root);
+      /* Defer to cfgcleanup to update loop-father fields of basic-blocks.  */
+      loops_state_set (LOOPS_NEED_FIXUP);
+    }
+
   if (gimple_in_ssa_p (cfun))
     FOR_ALL_BB_FN (bb, cfun_to_copy)
       if (!blocks_to_copy
@@ -5147,6 +5198,14 @@ tree_function_versioning (tree old_decl, tree new_decl,
        }
     }
 
+  /* Set up the destination functions loop tree.  */
+  if (DECL_STRUCT_FUNCTION (old_decl)->x_current_loops)
+    {
+      cfun->curr_properties &= ~PROP_loops;
+      loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+      cfun->curr_properties |= PROP_loops;
+    }
+
   /* Copy the Function's body.  */
   copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE,
             ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry);
index a72369e..d399d8a 100644 (file)
@@ -204,6 +204,10 @@ execute_fixup_cfg (void)
   if (dump_file)
     gimple_dump_cfg (dump_file, dump_flags);
 
+  if (current_loops
+      && (todo & TODO_cleanup_cfg))
+    loops_state_set (LOOPS_NEED_FIXUP);
+
   return todo;
 }
 
index 088fc46..4a4b02b 100644 (file)
@@ -2216,11 +2216,6 @@ parallelize_loops (void)
       }
       gen_parallel_loop (loop, reduction_list,
                         n_threads, &niter_desc);
-#ifdef ENABLE_CHECKING
-      verify_flow_info ();
-      verify_loop_structure ();
-      verify_loop_closed_ssa (true);
-#endif
     }
 
   free_stmt_vec_info_vec ();
index d16756c..f58f7b3 100644 (file)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-propagate.h"
 #include "langhooks.h"
 #include "cfgloop.h"
+#include "tree-scalar-evolution.h"
 
 /* This file implements the copy propagation pass and provides a
    handful of interfaces for performing const/copy propagation and
@@ -771,9 +772,8 @@ fini_copy_prop (void)
        duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
     }
 
-  /* Don't do DCE if we have loops.  That's the simplest way to not
-     destroy the scev cache.  */
-  substitute_and_fold (get_value, NULL, !current_loops);
+  /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
+  substitute_and_fold (get_value, NULL, !scev_initialized_p ());
 
   free (copy_of);
 }
index fef6883..ae5b500 100644 (file)
@@ -93,7 +93,7 @@ struct gimple_opt_pass pass_tree_loop_init =
   0,                                   /* static_pass_number */
   TV_NONE,                             /* tv_id */
   PROP_cfg,                            /* properties_required */
-  PROP_loops,                          /* properties_provided */
+  0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0                                    /* todo_flags_finish */
@@ -577,7 +577,7 @@ struct gimple_opt_pass pass_parallelize_loops =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  0                                    /* todo_flags_finish */
+  TODO_verify_flow                     /* todo_flags_finish */
  }
 };
 
index 739e48e..5e99678 100644 (file)
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-config.h"
 #include "expr.h"
 #include "optabs.h"
+#include "tree-scalar-evolution.h"
 
 #ifndef HAVE_conditional_move
 #define HAVE_conditional_move (0)
@@ -242,7 +243,16 @@ tree_ssa_phiopt (void)
 static unsigned int
 tree_ssa_cs_elim (void)
 {
-  return tree_ssa_phiopt_worker (true, false);
+  unsigned todo;
+  /* ???  We are not interested in loop related info, but the following
+     will create it, ICEing as we didn't init loops with pre-headers.
+     An interfacing issue of find_data_references_in_bb.  */
+  loop_optimizer_init (LOOPS_NORMAL);
+  scev_initialize ();
+  todo = tree_ssa_phiopt_worker (true, false);
+  scev_finalize ();
+  loop_optimizer_finalize ();
+  return todo;
 }
 
 /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
index b20d306..f2ab744 100644 (file)
@@ -197,6 +197,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "tree-ssa-sccvn.h"
 #include "tree-dump.h"
+#include "cfgloop.h"
 
 /* ??? This currently runs as part of tree-ssa-pre.  Why is this not
    a stand-alone GIMPLE pass?  */
@@ -1459,6 +1460,17 @@ replace_block_by (basic_block bb1, basic_block bb2)
   /* Mark the basic block as deleted.  */
   mark_basic_block_deleted (bb1);
 
+  /* ???  If we merge the loop preheader with the loop latch we are creating
+     additional entries into the loop, eventually rotating it.
+     Mark loops for fixup in this case.
+     ???  This is a completely unwanted transform and will wreck most
+     loops at this point - but with just not considering loop latches as
+     merge candidates we fail to commonize the two loops in gcc.dg/pr50763.c.
+     A better fix to avoid that regression is needed.  */
+  if (current_loops
+      && bb2->loop_father->latch == bb2)
+    loops_state_set (LOOPS_NEED_FIXUP);
+
   /* Redirect the incoming edges of bb1 to bb2.  */
   for (i = EDGE_COUNT (bb1->preds); i > 0 ; --i)
     {
index 3fffdf7..9ad7daf 100644 (file)
@@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tree-ssa-operands.h"
 #include "tree-pass.h"
 #include "gimple-pretty-print.h"
+#include "cfgloop.h"
 
 /* ??? For lang_hooks.types.type_for_mode, but is there a word_mode
    type in the GIMPLE type system that is language-independent?  */
@@ -1351,6 +1352,8 @@ process_switch (gimple swtch)
            fputs ("  expanding as bit test is preferable\n", dump_file);
          emit_case_bit_tests (swtch, info.index_expr,
                               info.range_min, info.range_size);
+         if (current_loops)
+           loops_state_set (LOOPS_NEED_FIXUP);
          return NULL;
        }