tree-cfg.c (execute_build_cfg): Build the loop tree.

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.

	* 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.

From-SVN: r198333
This commit is contained in:
Richard Biener 2013-04-26 08:01:19 +00:00 committed by Richard Biener
parent a2e836b2ac
commit a9e0d84371
28 changed files with 273 additions and 50 deletions

View 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.

View 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

View 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);

View 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);

View 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);

View 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 ();

View 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. */

View 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);
}

View 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);

View 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;
}

View 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

View 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.

View 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];
}

View 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];

View 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" } } */

View 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" } } */

View 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" } } */

View 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

View 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;
}

View 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. */

View 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);

View 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;
}

View 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 ();

View 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);
}

View 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 */
}
};

View 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. */

View 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)
{

View 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;
}