aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog59
-rw-r--r--gcc/Makefile.in16
-rw-r--r--gcc/asan.c6
-rw-r--r--gcc/cfgloop.c6
-rw-r--r--gcc/cfgloop.h1
-rw-r--r--gcc/cfgloopmanip.c2
-rw-r--r--gcc/ipa-split.c3
-rw-r--r--gcc/loop-init.c13
-rw-r--r--gcc/lto-streamer-out.c5
-rw-r--r--gcc/omp-low.c15
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/graphite/pr33766.c22
-rw-r--r--gcc/testsuite/gcc.dg/pr53265.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/update-loopch.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-38.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr21559.c2
-rw-r--r--gcc/tree-cfg.c18
-rw-r--r--gcc/tree-cfgcleanup.c22
-rw-r--r--gcc/tree-complex.c6
-rw-r--r--gcc/tree-inline.c61
-rw-r--r--gcc/tree-optimize.c4
-rw-r--r--gcc/tree-parloops.c5
-rw-r--r--gcc/tree-ssa-copy.c6
-rw-r--r--gcc/tree-ssa-loop.c4
-rw-r--r--gcc/tree-ssa-phiopt.c12
-rw-r--r--gcc/tree-ssa-tail-merge.c12
-rw-r--r--gcc/tree-switch-conversion.c3
28 files changed, 273 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 749d283..e283c3d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f6fe9aa..36b0062 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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
diff --git a/gcc/asan.c b/gcc/asan.c
index b8acaf7..c068b8c 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -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);
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 54ce2a2..568b7a2 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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);
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 29ac6c4..948e805 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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);
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 13efb75..f2d6a3b 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -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 ();
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index e7d469d..107c7a9 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -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. */
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index 92d621e..664ff29 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -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);
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index ad620c6..afb73f2 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -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);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 3e519db..eaeeaa5 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -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;
}
diff --git a/gcc/passes.c b/gcc/passes.c
index 45e79cc..fd67ee6 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5e568fb..737ef4a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/graphite/pr33766.c b/gcc/testsuite/gcc.dg/graphite/pr33766.c
index f6bb506..47d3dd4 100644
--- a/gcc/testsuite/gcc.dg/graphite/pr33766.c
+++ b/gcc/testsuite/gcc.dg/graphite/pr33766.c
@@ -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];
}
diff --git a/gcc/testsuite/gcc.dg/pr53265.c b/gcc/testsuite/gcc.dg/pr53265.c
index c60a736..7016446 100644
--- a/gcc/testsuite/gcc.dg/pr53265.c
+++ b/gcc/testsuite/gcc.dg/pr53265.c
@@ -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];
diff --git a/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c b/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c
index e2656a3..cc06ea7 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-38.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-38.c
index 7f23031..714696e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-38.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-38.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
index 34f4a01..402c102 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
@@ -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" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index c5c25a7..cbbc5c7 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b355a86..3c69a7d 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -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;
}
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index ee54568..d43172b 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -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. */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 7fa0245..c358cbe 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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);
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index a72369e..d399d8a 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -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;
}
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 088fc46..4a4b02b 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -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 ();
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index d16756c..f58f7b3 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -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);
}
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index fef6883..ae5b500 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -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 */
}
};
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 739e48e..5e99678 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -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. */
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index b20d306..f2ab7444 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -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)
{
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 3fffdf7..9ad7daf 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -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;
}