Commit a9e0d843 by Richard Biener Committed by Richard Biener

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
parent a2e836b2
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.
......
...@@ -2225,7 +2225,7 @@ tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \ ...@@ -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) \ ...@@ -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) \ ...@@ -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 \ ...@@ -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 \ ...@@ -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 \ ...@@ -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
......
...@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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, ...@@ -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);
......
...@@ -1329,6 +1329,12 @@ verify_loop_structure (void) ...@@ -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);
......
...@@ -232,6 +232,7 @@ void rescan_loop_exit (edge, bool, bool); ...@@ -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);
......
...@@ -410,7 +410,7 @@ remove_path (edge e) ...@@ -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 ();
......
...@@ -90,6 +90,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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) ...@@ -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. */
......
...@@ -91,16 +91,27 @@ loop_optimizer_init (unsigned flags) ...@@ -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
else
verify_loop_structure (); 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);
} }
......
...@@ -733,8 +733,9 @@ output_struct_function_base (struct output_block *ob, struct function *fn) ...@@ -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);
......
...@@ -3056,6 +3056,11 @@ expand_parallel_call (struct omp_region *region, basic_block bb, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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;
} }
......
...@@ -1397,6 +1397,7 @@ init_optimization_passes (void) ...@@ -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
......
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.
......
...@@ -7,9 +7,9 @@ fxt1_quantize_ALPHA1() ...@@ -7,9 +7,9 @@ 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;
......
...@@ -49,9 +49,9 @@ fn4 (void) ...@@ -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) ...@@ -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];
......
...@@ -14,7 +14,7 @@ main () ...@@ -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" } } */
......
...@@ -13,6 +13,5 @@ t(int n) ...@@ -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" } } */
...@@ -37,7 +37,7 @@ void foo (void) ...@@ -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" } } */
...@@ -247,6 +247,8 @@ execute_build_cfg (void) ...@@ -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 = ...@@ -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, ...@@ -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
......
...@@ -748,9 +748,10 @@ cleanup_tree_cfg (void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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, ...@@ -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. */
......
...@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
...@@ -204,6 +204,10 @@ execute_fixup_cfg (void) ...@@ -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;
} }
......
...@@ -2216,11 +2216,6 @@ parallelize_loops (void) ...@@ -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 ();
......
...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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) ...@@ -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);
} }
......
...@@ -93,7 +93,7 @@ struct gimple_opt_pass pass_tree_loop_init = ...@@ -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 = ...@@ -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 */
} }
}; };
......
...@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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) ...@@ -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. */
......
...@@ -197,6 +197,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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) ...@@ -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)
{ {
......
...@@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment