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

Reply via email to