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> 2013-04-26 Jakub Jelinek <jakub@redhat.com>
* Makefile.in (toplev.o): Depend on diagnostic-color.h. * 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-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 \ $(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \
$(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_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 \ 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) \ $(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) \
$(TREE_PRETTY_PRINT_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 \ $(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) $(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) \ 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) \ tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \
$(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h \ $(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h \
$(HASH_TABLE_H) alloc-pool.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-propagate.h
tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \ $(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) \ $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \
$(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \ $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \
$(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_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) \ $(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \
$(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ $(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \
$(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_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 \ tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \ $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
langhooks.h $(TREE_PRETTY_PRINT_H) langhooks.h $(TREE_PRETTY_PRINT_H)
tree-ssa-copy.o : tree-ssa-copy.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_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) \ $(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 \ $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h tree-ssa-propagate.h \
$(FLAGS_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H) $(FLAGS_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_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) $(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) $(IPA_INLINE_H)
ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.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_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) $(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) \ 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 \ $(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) $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_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) \ $(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) \ $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \
$(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \ $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \
$(GIMPLE_PRETTY_PRINT_H) langhooks.h $(GIMPLE_PRETTY_PRINT_H) langhooks.h
tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_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) \ $(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) \ 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 \ $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \
$(TARGET_H) $(TARGET_DEF_H) tree-iterator.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 "langhooks.h"
#include "hash-table.h" #include "hash-table.h"
#include "alloc-pool.h" #include "alloc-pool.h"
#include "cfgloop.h"
/* AddressSanitizer finds out-of-bounds and use-after-free bugs /* AddressSanitizer finds out-of-bounds and use-after-free bugs
with <2x slowdown on average. 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 cond_bb = e->src;
basic_block fallthru_bb = e->dest; basic_block fallthru_bb = e->dest;
basic_block then_bb = create_empty_bb (cond_bb); 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'. */ /* Set up the newly created 'then block'. */
e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); 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); bool dom_available = dom_info_available_p (CDI_DOMINATORS);
sbitmap visited; 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. */ /* We need up-to-date dominators, compute or verify them. */
if (!dom_available) if (!dom_available)
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);

View File

@ -232,6 +232,7 @@ void rescan_loop_exit (edge, bool, bool);
/* Loop data structure manipulation/querying. */ /* Loop data structure manipulation/querying. */
extern void flow_loop_tree_node_add (struct loop *, struct loop *); extern void flow_loop_tree_node_add (struct loop *, struct loop *);
extern void flow_loop_tree_node_remove (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 void add_loop (struct loop *, struct loop *);
extern bool flow_loop_nested_p (const struct loop *, const 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); 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. */ /* Creates place for a new LOOP in loops structure. */
static void void
place_new_loop (struct loop *loop) place_new_loop (struct loop *loop)
{ {
loop->num = number_of_loops (); 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 "params.h"
#include "gimple-pretty-print.h" #include "gimple-pretty-print.h"
#include "ipa-inline.h" #include "ipa-inline.h"
#include "cfgloop.h"
/* Per basic block info. */ /* 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 = make_edge (new_return_bb, EXIT_BLOCK_PTR, 0);
e->probability = REG_BR_PROB_BASE; e->probability = REG_BR_PROB_BASE;
e->count = new_return_bb->count; 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); bitmap_set_bit (split_point->split_bbs, new_return_bb->index);
} }
/* When we pass around the value, use existing return block. */ /* When we pass around the value, use existing return block. */

View File

@ -91,16 +91,27 @@ loop_optimizer_init (unsigned flags)
} }
else else
{ {
bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS);
gcc_assert (cfun->curr_properties & PROP_loops); gcc_assert (cfun->curr_properties & PROP_loops);
/* Ensure that the dominators are computed, like flow_loops_find does. */ /* Ensure that the dominators are computed, like flow_loops_find does. */
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
{
loops_state_clear (~0U);
fix_loop_structure (NULL);
}
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_loop_structure (); else
verify_loop_structure ();
#endif #endif
/* Clear all flags. */ /* Clear all flags. */
if (recorded_exits)
release_recorded_exits ();
loops_state_clear (~0U); 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) FOR_EACH_VEC_SAFE_ELT (fn->local_decls, i, t)
stream_write_tree (ob, t, true); stream_write_tree (ob, t, true);
/* Output current IL state of the function. */ /* Output current IL state of the function.
streamer_write_uhwi (ob, fn->curr_properties); ??? We don't stream loops. */
streamer_write_uhwi (ob, fn->curr_properties & ~PROP_loops);
/* Write all the attributes for FN. */ /* Write all the attributes for FN. */
bp = bitpack_create (ob->main_stream); 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, then_bb, EDGE_TRUE_VALUE);
make_edge (cond_bb, else_bb, EDGE_FALSE_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_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
e_else = make_edge (else_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); tree vtype = TREE_TYPE (fd->loops[i].v);
bb = create_empty_bb (last_bb); bb = create_empty_bb (last_bb);
if (current_loops)
add_bb_to_loop (bb, last_bb->loop_father);
gsi = gsi_start_bb (bb); gsi = gsi_start_bb (bb);
if (i < fd->collapse - 1) if (i < fd->collapse - 1)
@ -4114,6 +4121,8 @@ expand_omp_for_generic (struct omp_region *region,
remove_edge (e); remove_edge (e);
make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE); 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) if (fd->collapse > 1)
{ {
e = find_edge (cont_bb, l1_bb); e = find_edge (cont_bb, l1_bb);
@ -4902,6 +4911,8 @@ expand_omp_sections (struct omp_region *region)
t = gimple_block_label (default_bb); t = gimple_block_label (default_bb);
u = build_case_label (NULL, NULL, t); u = build_case_label (NULL, NULL, t);
make_edge (l0_bb, default_bb, 0); 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); stmt = gimple_build_switch (vmain, u, label_vec);
gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT); 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)) if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi); 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; return true;
} }

View File

@ -1397,6 +1397,7 @@ init_optimization_passes (void)
They ensure memory accesses are not indirect wherever possible. */ They ensure memory accesses are not indirect wherever possible. */
NEXT_PASS (pass_strip_predict_hints); NEXT_PASS (pass_strip_predict_hints);
NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_complete_unrolli); NEXT_PASS (pass_complete_unrolli);
NEXT_PASS (pass_ccp); NEXT_PASS (pass_ccp);
/* After CCP we rewrite no longer addressed locals into SSA /* 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> 2013-04-26 Jakub Jelinek <jakub@redhat.com>
* lib/prune.exp: Add -fdiagnostics-color=never to TEST_ALWAYS_FLAGS. * lib/prune.exp: Add -fdiagnostics-color=never to TEST_ALWAYS_FLAGS.

View File

@ -4,16 +4,16 @@
float float
fxt1_quantize_ALPHA1() fxt1_quantize_ALPHA1()
{ {
int j1; int j1;
int i; int i;
float *tv; float *tv;
for (j1 = 1; j1; j1++) { for (j1 = 1; j1 < 2048; j1++) {
float e; float e;
for (i = 1; i; i++) for (i = 1; i < 2048; i++)
e = tv[i]; e = tv[i];
if (e) if (e)
i = j1; i = j1;
} }
return tv[i]; return tv[i];
} }

View File

@ -49,9 +49,9 @@ fn4 (void)
unsigned int *a[32], *o, i; unsigned int *a[32], *o, i;
bar (a); 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); bar (o);
} }
} }
@ -85,11 +85,11 @@ fn7 (void)
{ {
int a[16], b, c; int a[16], b, c;
bar (a); 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); 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 *va, *vb, *vc, *vd, *ve;
const void *vf[4]; const void *vf[4];

View File

@ -14,7 +14,7 @@ main ()
/* Loop header copying will peel away the initial conditional, so the loop body /* 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 is once reached directly from entry point of function, rest via loopback
edge. */ 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 "loop depth 1, count 33332" "optimized"} } */
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
/* { dg-final-use { cleanup-ipa-dump "profile" } } */ /* { dg-final-use { cleanup-ipa-dump "profile" } } */

View File

@ -13,6 +13,5 @@ t(int n)
sum+=b[i]; sum+=b[i];
return sum; 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 { scan-tree-dump "Loop 1 iterates at most 11 times" "cunrolli" } } */
/* { dg-final { cleanup-tree-dump "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 /* 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, statement. We also realize that the final bytes == 0 test is useless,
and thread over it. */ 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" } } */ /* { dg-final { cleanup-tree-dump "vrp1" } } */

View File

@ -247,6 +247,8 @@ execute_build_cfg (void)
fprintf (dump_file, "Scope blocks:\n"); fprintf (dump_file, "Scope blocks:\n");
dump_scope_blocks (dump_file, dump_flags); dump_scope_blocks (dump_file, dump_flags);
} }
cleanup_tree_cfg ();
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
return 0; return 0;
} }
@ -263,10 +265,10 @@ struct gimple_opt_pass pass_build_cfg =
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_CFG, /* tv_id */ TV_TREE_CFG, /* tv_id */
PROP_gimple_leh, /* properties_required */ PROP_gimple_leh, /* properties_required */
PROP_cfg, /* properties_provided */ PROP_cfg | PROP_loops, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 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.eh_map = eh_map;
d.remap_decls_p = true; 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) FOR_EACH_VEC_ELT (bbs, i, bb)
{ {
/* No need to update edge counts on the last block. It has /* No need to update edge counts on the last block. It has

View File

@ -748,9 +748,10 @@ cleanup_tree_cfg (void)
return changed; 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) remove_forwarder_block_with_phi (basic_block bb)
{ {
edge succ = single_succ_edge (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 However it may happen that the infinite loop is created
afterwards due to removal of forwarders. */ afterwards due to removal of forwarders. */
if (dest == bb) if (dest == bb)
return; return false;
/* If the destination block consists of a nonlocal label, do not /* If the destination block consists of a nonlocal label, do not
merge it. */ merge it. */
@ -770,7 +771,7 @@ remove_forwarder_block_with_phi (basic_block bb)
if (label if (label
&& gimple_code (label) == GIMPLE_LABEL && gimple_code (label) == GIMPLE_LABEL
&& DECL_NONLOCAL (gimple_label_label (label))) && DECL_NONLOCAL (gimple_label_label (label)))
return; return false;
/* Redirect each incoming edge to BB to DEST. */ /* Redirect each incoming edge to BB to DEST. */
while (EDGE_COUNT (bb->preds) > 0) 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 /* Remove BB since all of BB's incoming edges have been redirected
to DEST. */ to DEST. */
delete_basic_block (bb); delete_basic_block (bb);
return true;
} }
/* This pass merges PHI nodes if one feeds into another. For example, /* 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. */ /* Now let's drain WORKLIST. */
bool changed = false;
while (current != worklist) while (current != worklist)
{ {
bb = *--current; bb = *--current;
remove_forwarder_block_with_phi (bb); changed |= remove_forwarder_block_with_phi (bb);
} }
free (worklist); 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; return 0;
} }

View File

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h" #include "tree-pass.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "tree-hasher.h" #include "tree-hasher.h"
#include "cfgloop.h"
/* For each complex ssa name, a lattice value. We're interested in finding /* 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_cond, bb_false, EDGE_FALSE_VALUE);
make_edge (bb_true, bb_join, EDGE_FALLTHRU); make_edge (bb_true, bb_join, EDGE_FALLTHRU);
make_edge (bb_false, 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 /* Update dominance info. Note that bb_join's data was
updated by split_block. */ 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 "value-prof.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "target.h" #include "target.h"
#include "cfgloop.h"
#include "rtl.h" /* FIXME: For asm_str_count. */ #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->static_chain_decl = src_cfun->static_chain_decl;
cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area; cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area;
cfun->function_end_locus = src_cfun->function_end_locus; 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->last_verified = src_cfun->last_verified;
cfun->va_list_gpr_size = src_cfun->va_list_gpr_size; cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
cfun->va_list_fpr_size = src_cfun->va_list_fpr_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 /* 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. */ 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); basic_block new_bb = copy_bb (id, bb, frequency_scale, count_scale);
bb->aux = new_bb; bb->aux = new_bb;
new_bb->aux = bb; new_bb->aux = bb;
new_bb->loop_father = entry_block_map->loop_father;
} }
last = last_basic_block; 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; 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)) if (gimple_in_ssa_p (cfun))
FOR_ALL_BB_FN (bb, cfun_to_copy) FOR_ALL_BB_FN (bb, cfun_to_copy)
if (!blocks_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 the Function's body. */
copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE, copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE,
ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry); ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry);

View File

@ -204,6 +204,10 @@ execute_fixup_cfg (void)
if (dump_file) if (dump_file)
gimple_dump_cfg (dump_file, dump_flags); gimple_dump_cfg (dump_file, dump_flags);
if (current_loops
&& (todo & TODO_cleanup_cfg))
loops_state_set (LOOPS_NEED_FIXUP);
return todo; return todo;
} }

View File

@ -2216,11 +2216,6 @@ parallelize_loops (void)
} }
gen_parallel_loop (loop, reduction_list, gen_parallel_loop (loop, reduction_list,
n_threads, &niter_desc); n_threads, &niter_desc);
#ifdef ENABLE_CHECKING
verify_flow_info ();
verify_loop_structure ();
verify_loop_closed_ssa (true);
#endif
} }
free_stmt_vec_info_vec (); 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 "tree-ssa-propagate.h"
#include "langhooks.h" #include "langhooks.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-scalar-evolution.h"
/* This file implements the copy propagation pass and provides a /* This file implements the copy propagation pass and provides a
handful of interfaces for performing const/copy propagation and 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)); 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 /* Don't do DCE if SCEV is initialized. It would destroy the scev cache. */
destroy the scev cache. */ substitute_and_fold (get_value, NULL, !scev_initialized_p ());
substitute_and_fold (get_value, NULL, !current_loops);
free (copy_of); free (copy_of);
} }

View File

@ -93,7 +93,7 @@ struct gimple_opt_pass pass_tree_loop_init =
0, /* static_pass_number */ 0, /* static_pass_number */
TV_NONE, /* tv_id */ TV_NONE, /* tv_id */
PROP_cfg, /* properties_required */ PROP_cfg, /* properties_required */
PROP_loops, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
0 /* todo_flags_finish */ 0 /* todo_flags_finish */
@ -577,7 +577,7 @@ struct gimple_opt_pass pass_parallelize_loops =
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 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 "insn-config.h"
#include "expr.h" #include "expr.h"
#include "optabs.h" #include "optabs.h"
#include "tree-scalar-evolution.h"
#ifndef HAVE_conditional_move #ifndef HAVE_conditional_move
#define HAVE_conditional_move (0) #define HAVE_conditional_move (0)
@ -242,7 +243,16 @@ tree_ssa_phiopt (void)
static unsigned int static unsigned int
tree_ssa_cs_elim (void) 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. */ /* 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 "gimple-pretty-print.h"
#include "tree-ssa-sccvn.h" #include "tree-ssa-sccvn.h"
#include "tree-dump.h" #include "tree-dump.h"
#include "cfgloop.h"
/* ??? This currently runs as part of tree-ssa-pre. Why is this not /* ??? This currently runs as part of tree-ssa-pre. Why is this not
a stand-alone GIMPLE pass? */ 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 the basic block as deleted. */
mark_basic_block_deleted (bb1); 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. */ /* Redirect the incoming edges of bb1 to bb2. */
for (i = EDGE_COUNT (bb1->preds); i > 0 ; --i) 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-ssa-operands.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "gimple-pretty-print.h" #include "gimple-pretty-print.h"
#include "cfgloop.h"
/* ??? For lang_hooks.types.type_for_mode, but is there a word_mode /* ??? For lang_hooks.types.type_for_mode, but is there a word_mode
type in the GIMPLE type system that is language-independent? */ 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); fputs (" expanding as bit test is preferable\n", dump_file);
emit_case_bit_tests (swtch, info.index_expr, emit_case_bit_tests (swtch, info.index_expr,
info.range_min, info.range_size); info.range_min, info.range_size);
if (current_loops)
loops_state_set (LOOPS_NEED_FIXUP);
return NULL; return NULL;
} }