Message ID | alpine.LSU.2.11.1408141348430.20733@zhemvz.fhfr.qr |
---|---|
State | New |
Headers | show |
Richard Biener wrote: > > The following fixes missing dominator computation before fixing loops. > Rather than doing even more such weird stuff in a pass gate function > this puts this into a new pass scheduled before the loop passes gate. > Ok. > +unsigned int > +pass_fix_loops::execute (function *) > +{ I would add an early exit if there are no loops in the function (like in the original code below...) if (!loops_for_fn (fn)) return 0; > + if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) > + { > + calculate_dominance_info (CDI_DOMINATORS); > + fix_loop_structure (NULL); > + } > + return 0; > +} [...] > /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize > but we also avoid running it when the IL doesn't contain any loop. */ > > @@ -57,9 +107,6 @@ gate_loop (function *fn) > if (!loops_for_fn (fn)) > return true; ... here. > > - /* Make sure to drop / re-discover loops when necessary. */ > - if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) > - fix_loop_structure (NULL); > return number_of_loops (fn) > 1; > }
On Thu, 14 Aug 2014, Sebastian Pop wrote: > Richard Biener wrote: > > > > The following fixes missing dominator computation before fixing loops. > > Rather than doing even more such weird stuff in a pass gate function > > this puts this into a new pass scheduled before the loop passes gate. > > > > Ok. > > > +unsigned int > > +pass_fix_loops::execute (function *) > > +{ > > I would add an early exit if there are no loops in the function > (like in the original code below...) > > if (!loops_for_fn (fn)) > return 0; Note that's not how things work today - loops_for_fn () returns non-NULL even for zero-loop functions as soon as we have CFG. The "hack" below was for -fdump-passes which calls each gate of every pass before the CFG is set up and thus would crash gate_loop if we didn't do that check. Of course -fdump-passes reports sth that is not true for all functions here. Richard. > > + if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) > > + { > > + calculate_dominance_info (CDI_DOMINATORS); > > + fix_loop_structure (NULL); > > + } > > + return 0; > > +} > > [...] > > > /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize > > but we also avoid running it when the IL doesn't contain any loop. */ > > > > @@ -57,9 +107,6 @@ gate_loop (function *fn) > > if (!loops_for_fn (fn)) > > return true; > > ... here. > > > > > - /* Make sure to drop / re-discover loops when necessary. */ > > - if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) > > - fix_loop_structure (NULL); > > return number_of_loops (fn) > 1; > > } >
Index: gcc/tree-ssa-loop.c =================================================================== --- gcc/tree-ssa-loop.c (revision 213956) +++ gcc/tree-ssa-loop.c (working copy) @@ -43,6 +43,56 @@ along with GCC; see the file COPYING3. #include "tree-vectorizer.h" +/* A pass making sure loops are fixed up. */ + +namespace { + +const pass_data pass_data_fix_loops = +{ + GIMPLE_PASS, /* type */ + "fix_loops", /* name */ + OPTGROUP_LOOP, /* optinfo_flags */ + TV_TREE_LOOP, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_fix_loops : public gimple_opt_pass +{ +public: + pass_fix_loops (gcc::context *ctxt) + : gimple_opt_pass (pass_data_fix_loops, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_tree_loop_optimize; } + + virtual unsigned int execute (function *fn); +}; // class pass_fix_loops + +unsigned int +pass_fix_loops::execute (function *) +{ + if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) + { + calculate_dominance_info (CDI_DOMINATORS); + fix_loop_structure (NULL); + } + return 0; +} + +} // anon namespace + +gimple_opt_pass * +make_pass_fix_loops (gcc::context *ctxt) +{ + return new pass_fix_loops (ctxt); +} + + /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize but we also avoid running it when the IL doesn't contain any loop. */ @@ -57,9 +107,6 @@ gate_loop (function *fn) if (!loops_for_fn (fn)) return true; - /* Make sure to drop / re-discover loops when necessary. */ - if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) - fix_loop_structure (NULL); return number_of_loops (fn) > 1; } Index: gcc/passes.def =================================================================== --- gcc/passes.def (revision 213956) +++ gcc/passes.def (working copy) @@ -200,7 +200,10 @@ along with GCC; see the file COPYING3. NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); /* Pass group that runs when 1) enabled, 2) there are loops - in the function. */ + in the function. Make sure to run pass_fix_loops before + to discover/remove loops before running the gate function + of pass_tree_loop. */ + NEXT_PASS (pass_fix_loops); NEXT_PASS (pass_tree_loop); PUSH_INSERT_PASSES_WITHIN (pass_tree_loop) NEXT_PASS (pass_tree_loop_init); Index: gcc/tree-pass.h =================================================================== --- gcc/tree-pass.h (revision 213956) +++ gcc/tree-pass.h (working copy) @@ -349,6 +349,7 @@ extern gimple_opt_pass *make_pass_sra_ea extern gimple_opt_pass *make_pass_early_ipa_sra (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tail_recursion (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tail_calls (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_fix_loops (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tree_loop (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tree_no_loop (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tree_loop_init (gcc::context *ctxt);