On 6 July 2016 at 14:24, Richard Biener <richard.guent...@gmail.com> wrote: > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghan...@gmail.com> > wrote: >> On 30 June 2016 at 17:10, Richard Biener <richard.guent...@gmail.com> wrote: >>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal >>> <prasad.ghan...@gmail.com> wrote: >>>> On 29 June 2016 at 22:15, Richard Biener <richard.guent...@gmail.com> >>>> wrote: >>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni >>>>> <prathamesh.kulka...@linaro.org> wrote: >>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghan...@gmail.com> >>>>>>wrote: >>>>>>> Hi, >>>>>>> >>>>>>> I tried hacking pass manager to execute only given passes. For this I >>>>>>> am adding new member as opt_pass *custom_pass_list to the function >>>>>>> structure to store passes need to execute and providing the >>>>>>> custom_pass_list to execute_pass_list() function instead of all >>>>>>passes >>>>>>> >>>>>>> for test case like- >>>>>>> >>>>>>> int a; >>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo() >>>>>>> { >>>>>>> bb_1: >>>>>>> a = 1 + a; >>>>>>> } >>>>>>> >>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the >>>>>>function >>>>>>> >>>>>>> and for test case like - >>>>>>> >>>>>>> int a; >>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo() >>>>>>> { >>>>>>> bb_1: >>>>>>> a = 1 + a; >>>>>>> } >>>>>>> >>>>>>> it will act as a entry point to the pipeline and will execute passes >>>>>>> starting from given pass. >>>>>>Bike-shedding: >>>>>>Would it make sense to have syntax for defining pass ranges to execute >>>>>>? >>>>>>for instance: >>>>>>void __GIMPLE(execute (pass_start : pass_end)) >>>>>>which would execute all the passes within range [pass_start, pass_end], >>>>>>which would be convenient if the range is large. >>>>> >>>>> But it would rely on a particular pass pipeline, f.e. pass-start >>>>> appearing before pass-end. >>>>> >>>>> Currently control doesn't work 100% as it only replaces all_optimizations >>>>> but not lowering passes or early opts, nor IPA opts. >>>>> >>>> >>>> Each pass needs GIMPLE in some specific form. So I am letting lowering >>>> and early opt passes to execute. I think we have to execute some >>>> passes (like cfg) anyway to represent GIMPLE into proper form >>> >>> Yes, that's true. Note that early opt passes only optimize but we need >>> pass_build_ssa_passes at least (for into-SSA). For proper unit-testing >>> of GIMPLE passes we do need to guard off early opts somehow >>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do >>> that). >>> >>> Then there is of course the question about IPA passes which I think is >>> somewhat harder (one could always disable all IPA passes manually >>> via flags of course or finally have a global -fipa/no-ipa like most >>> other compilers). >>> >> Can we iterate through all ipa passes and do -fdisable-ipa-pass or >> -fenable-ipa-pass equivalent for each? > > We could do that, yes. But let's postpone this issue. I think that > startwith is going to be most useful and rather than constructing > a pass list for it "native" support for it in the pass manager is > likely to produce better results (add a 'startwith' member alongside > the pass list member and if it is set the pass manager skips all > passes that do not match 'startwith' and once it reaches it it clears > the field). > > In the future I hope we can get away from a static pass list and more > towards rule-driven pass execution (we have all those PROP_* stuff > already but it isn't really used for example). But well, that would be > a separate GSoC project ;) > > IMHO startwith will provide everything needed for unit-testing. We can > add a flag on whether further passes should be executed or not and > even a pass list like execute ("ccp1", "fre") can be implemented by > startwith ccp1 and then from there executing the rest of the passes in the > list and stopping at the end. > > As said, unit-testing should exercise a single pass if we can control > its input. > In this patch I am skipping execution of passes until pass_startwith is found. Unlike previous build, now pass manager executes all passes in pipeline starting from pass_startwith instead of just sub passes.
> Thanks, > Richard. > >> Thanks, >> Prasad >> >>> Richard. >>> >>>>> Richard. >>>>> >>>>>>Thanks, >>>>>>Prathamesh >>>>>>> >>>>>>> >>>>>>> >>>>>>> Thanks, >>>>>>> Prasad Ghangal >>>>> >>>>>
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 00e0bc5..d7ffdce 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1413,7 +1413,7 @@ static c_expr c_parser_gimple_unary_expression (c_parser *); static struct c_expr c_parser_gimple_postfix_expression (c_parser *); static struct c_expr c_parser_gimple_postfix_expression_after_primary (c_parser *, struct c_expr); -static void c_parser_gimple_pass_list (c_parser *, opt_pass **); +static void c_parser_gimple_pass_list (c_parser *, opt_pass **, bool *); static opt_pass *c_parser_gimple_pass_list_params (c_parser *, opt_pass **); static void c_parser_gimple_declaration (c_parser *); static void c_parser_gimple_goto_stmt (location_t, tree, gimple_seq *); @@ -1666,6 +1666,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, location_t here = c_parser_peek_token (parser)->location; bool gimple_body_p = false; opt_pass *pass = NULL; + bool startwith_p; if (static_assert_ok && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) @@ -1722,8 +1723,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (kw_token->keyword == RID_GIMPLE) { gimple_body_p = true; + startwith_p = false; c_parser_consume_token (parser); - c_parser_gimple_pass_list (parser, &pass); + c_parser_gimple_pass_list (parser, &pass, &startwith_p); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } @@ -2137,7 +2139,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, store_parm_decls (); if (pass) - cfun->custom_pass_list = pass; + { + cfun->pass_startwith = pass; + cfun->startwith = startwith_p; + } if (omp_declare_simd_clauses.exists () || !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) @@ -18797,9 +18802,8 @@ c_parser_gimple_label (c_parser *parser, gimple_seq *seq) /* Parse gimple pass list */ static void -c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass) +c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass, bool *startwith_p) { - opt_pass *pass_start; if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { return; @@ -18814,17 +18818,11 @@ c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass) { const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); c_parser_consume_token (parser); - if (!strcmp (op, "execute")) - { - pass_start = c_parser_gimple_pass_list_params (parser, pass); - if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) - return; - (*pass)->next = NULL; - *pass = pass_start; - } - else if (!strcmp (op, "startwith")) + if (!strcmp (op, "startwith")) { *pass = c_parser_gimple_pass_list_params (parser, pass); + (*pass)->next = NULL; + *startwith_p = true; if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) return; } diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 7effd71..2bb112e 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1980,10 +1980,7 @@ cgraph_node::expand (void) /* Signal the start of passes. */ invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL); - if (flag_gimple && cfun->custom_pass_list) - execute_pass_list (cfun, cfun->custom_pass_list); - else - execute_pass_list (cfun, g->get_passes ()->all_passes); + execute_pass_list (cfun, g->get_passes ()->all_passes, true); /* Signal the end of passes. */ invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL); @@ -2037,7 +2034,7 @@ cgraph_node::expand (void) /* Make sure that BE didn't give up on compiling. */ - if (!(flag_gimple && cfun->custom_pass_list)) /* FIXME : for gimplefe custom_pass_list */ + if (!(flag_gimple && cfun->pass_startwith)) /* FIXME : for gimplefe custom_pass_list */ gcc_assert (TREE_ASM_WRITTEN (decl)); if (cfun) diff --git a/gcc/function.h b/gcc/function.h index f84b97b..0adbd68 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -228,8 +228,11 @@ struct GTY(()) function { /* GIMPLE body for this function. */ gimple_seq gimple_body; - /* GIMPLEFE Passes */ - opt_pass *custom_pass_list = NULL; + /* GIMPLEFE pass to start with */ + opt_pass *pass_startwith = NULL; + + /* Startwith flag */ + bool startwith; /* SSA and dataflow information. */ struct gimple_df *gimple_df; diff --git a/gcc/passes.c b/gcc/passes.c index c84b4b1..c4588bb 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -114,7 +114,7 @@ pass_manager::execute_early_local_passes () execute_pass_list (cfun, pass_build_ssa_passes_1->sub); if (flag_check_pointer_bounds) execute_pass_list (cfun, pass_chkp_instrumentation_passes_1->sub); - if (flag_gimple && cfun->custom_pass_list) + if (!flag_gimple && !cfun->pass_startwith) execute_pass_list (cfun, pass_local_optimization_passes_1->sub); } @@ -2281,8 +2281,18 @@ override_gate_status (opt_pass *pass, tree func, bool gate_status) /* Execute PASS. */ bool -execute_one_pass (opt_pass *pass) +execute_one_pass (opt_pass *pass, bool startwith_p) { + /* For skipping passes until startwith pass */ + if (startwith_p && cfun->startwith) + { + if (pass->name == cfun->pass_startwith->name + || pass->name == "*clean_state") + cfun->startwith = false; + else + return true; + } + unsigned int todo_after = 0; bool gate_status; @@ -2419,7 +2429,7 @@ execute_one_pass (opt_pass *pass) } static void -execute_pass_list_1 (opt_pass *pass) +execute_pass_list_1 (opt_pass *pass, bool startwith_p) { do { @@ -2428,18 +2438,18 @@ execute_pass_list_1 (opt_pass *pass) if (cfun == NULL) return; - if (execute_one_pass (pass) && pass->sub) - execute_pass_list_1 (pass->sub); + if (execute_one_pass (pass, startwith_p) && pass->sub) + execute_pass_list_1 (pass->sub, startwith_p); pass = pass->next; } while (pass); } void -execute_pass_list (function *fn, opt_pass *pass) +execute_pass_list (function *fn, opt_pass *pass, bool startwith_p) { gcc_assert (fn == cfun); - execute_pass_list_1 (pass); + execute_pass_list_1 (pass, startwith_p); if (cfun && fn->cfg) { free_dominance_info (CDI_DOMINATORS); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 36299a6..1c68485 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -615,8 +615,8 @@ extern gimple_opt_pass *make_pass_lower_vaarg (gcc::context *ctxt); /* Current optimization pass. */ extern opt_pass *current_pass; -extern bool execute_one_pass (opt_pass *); -extern void execute_pass_list (function *, opt_pass *); +extern bool execute_one_pass (opt_pass *, bool startwith_p = false); +extern void execute_pass_list (function *, opt_pass *, bool startwith_p = false); extern void execute_ipa_pass_list (opt_pass *); extern void execute_ipa_summary_passes (ipa_opt_pass_d *); extern void execute_all_ipa_transforms (void);