On 10/29/2015 02:15 PM, Richard Biener wrote:
> On Thu, Oct 29, 2015 at 10:49 AM, Martin Liška <mli...@suse.cz> wrote:
>> On 10/28/2015 04:23 PM, Richard Biener wrote:
>>> On Tue, Oct 27, 2015 at 4:30 PM, Martin Liška <mli...@suse.cz> wrote:
>>>> On 10/27/2015 03:49 PM, Richard Biener wrote:
>>>>> On Tue, Oct 27, 2015 at 1:36 PM, Martin Liška <mli...@suse.cz> wrote:
>>>>>> On 10/26/2015 02:48 PM, Richard Biener wrote:
>>>>>>> On Thu, Oct 22, 2015 at 1:02 PM, Martin Liška <mli...@suse.cz> wrote:
>>>>>>>> On 10/21/2015 04:06 PM, Richard Biener wrote:
>>>>>>>>> On Wed, Oct 21, 2015 at 1:24 PM, Martin Liška <mli...@suse.cz> wrote:
>>>>>>>>>> On 10/21/2015 11:59 AM, Richard Biener wrote:
>>>>>>>>>>> On Wed, Oct 21, 2015 at 11:19 AM, Martin Liška <mli...@suse.cz> 
>>>>>>>>>>> wrote:
>>>>>>>>>>>> On 10/20/2015 03:39 PM, Richard Biener wrote:
>>>>>>>>>>>>> On Tue, Oct 20, 2015 at 3:00 PM, Martin Liška <mli...@suse.cz> 
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>> Hello.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> As part of upcoming merge of HSA branch, we would like to have 
>>>>>>>>>>>>>> possibility to terminate
>>>>>>>>>>>>>> pass manager after execution of the HSA generation pass. The HSA 
>>>>>>>>>>>>>> back-end is implemented
>>>>>>>>>>>>>> as a tree pass that directly emits HSAIL from gimple tree 
>>>>>>>>>>>>>> representation. The pass operates
>>>>>>>>>>>>>> on clones created by HSA IPA pass and the pass manager should 
>>>>>>>>>>>>>> stop execution of further
>>>>>>>>>>>>>> RTL passes.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Suggested patch survives bootstrap and regression tests on 
>>>>>>>>>>>>>> x86_64-linux-pc.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> What do you think about it?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Are you sure it works this way?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Btw, you will miss executing of all the cleanup passes that will
>>>>>>>>>>>>> eventually free memory
>>>>>>>>>>>>> associated with the function.  So I'd rather support a
>>>>>>>>>>>>> TODO_discard_function which
>>>>>>>>>>>>> should basically release the body from the cgraph.
>>>>>>>>>>>>
>>>>>>>>>>>> Hi.
>>>>>>>>>>>>
>>>>>>>>>>>> Agree with you that I should execute all TODOs, which can be 
>>>>>>>>>>>> easily done.
>>>>>>>>>>>> However, if I just try to introduce the suggested TODO and handle 
>>>>>>>>>>>> it properly
>>>>>>>>>>>> by calling cgraph_node::release_body, then for instance 
>>>>>>>>>>>> fn->gimple_df, fn->cfg are
>>>>>>>>>>>> released and I hit ICEs on many places.
>>>>>>>>>>>>
>>>>>>>>>>>> Stopping the pass manager looks necessary, or do I miss something?
>>>>>>>>>>>
>>>>>>>>>>> "Stopping the pass manager" is necessary after 
>>>>>>>>>>> TODO_discard_function, yes.
>>>>>>>>>>> But that may be simply done via a has_body () check then?
>>>>>>>>>>
>>>>>>>>>> Thanks, there's second version of the patch. I'm going to start 
>>>>>>>>>> regression tests.
>>>>>>>>>
>>>>>>>>> As release_body () will free cfun you should pop_cfun () before
>>>>>>>>> calling it (and thus
>>>>>>>>
>>>>>>>> Well, release_function_body calls both push & pop, so I think calling 
>>>>>>>> pop
>>>>>>>> before cgraph_node::release_body is not necessary.
>>>>>>>
>>>>>>> (ugh).
>>>>>>>
>>>>>>>> If tried to call pop_cfun before cgraph_node::release_body, I have 
>>>>>>>> cfun still
>>>>>>>> pointing to the same (function *) (which is gcc_freed, but cfun != 
>>>>>>>> NULL).
>>>>>>>
>>>>>>> Hmm, I meant to call pop_cfun then after it (unless you want to fix the 
>>>>>>> above,
>>>>>>> none of the freeing functions should techincally need 'cfun', just add
>>>>>>> 'fn' parameters ...).
>>>>>>>
>>>>>>> I expected pop_cfun to eventually set cfun to NULL if it popped the
>>>>>>> "last" cfun.  Why
>>>>>>> doesn't it do that?
>>>>>>>
>>>>>>>>> drop its modification).  Also TODO_discard_functiuon should be only 
>>>>>>>>> set for
>>>>>>>>> local passes thus you should probably add a gcc_assert (cfun).
>>>>>>>>> I'd move its handling earlier, definitely before the ggc_collect, 
>>>>>>>>> eventually
>>>>>>>>> before the pass_fini_dump_file () (do we want a last dump of the
>>>>>>>>> function or not?).
>>>>>>>>
>>>>>>>> Fully agree, moved here.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> @@ -2397,6 +2410,10 @@ execute_pass_list_1 (opt_pass *pass)
>>>>>>>>>      {
>>>>>>>>>        gcc_assert (pass->type == GIMPLE_PASS
>>>>>>>>>                   || pass->type == RTL_PASS);
>>>>>>>>> +
>>>>>>>>> +
>>>>>>>>> +      if (!gimple_has_body_p (current_function_decl))
>>>>>>>>> +       return;
>>>>>>>>>
>>>>>>>>> too much vertical space.  With popping cfun before releasing the body 
>>>>>>>>> the check
>>>>>>>>> might just become if (!cfun) and
>>>>>>>>
>>>>>>>> As mentioned above, as release body is symmetric (calling push & pop), 
>>>>>>>> the suggested
>>>>>>>> guard will not work.
>>>>>>>
>>>>>>> I suggest to fix it.  If it calls push/pop it should leave with the
>>>>>>> original cfun, popping again
>>>>>>> should make it NULL?
>>>>>>>
>>>>>>>>>
>>>>>>>>> @@ -2409,7 +2426,7 @@ execute_pass_list (function *fn, opt_pass *pass)
>>>>>>>>>  {
>>>>>>>>>    push_cfun (fn);
>>>>>>>>>    execute_pass_list_1 (pass);
>>>>>>>>> -  if (fn->cfg)
>>>>>>>>> +  if (gimple_has_body_p (current_function_decl) && fn->cfg)
>>>>>>>>>      {
>>>>>>>>>        free_dominance_info (CDI_DOMINATORS);
>>>>>>>>>        free_dominance_info (CDI_POST_DOMINATORS);
>>>>>>>>>
>>>>>>>>> here you'd need to guard the pop_cfun call on cfun != NULL.  IMHO 
>>>>>>>>> it's better
>>>>>>>>> to not let cfun point to deallocated data.
>>>>>>>>
>>>>>>>> As I've read the code, since we gcc_free 'struct function', one can 
>>>>>>>> just rely on
>>>>>>>> gimple_has_body_p (current_function_decl) as it correctly realizes that
>>>>>>>> DECL_STRUCT_FUNCTION (current_function_decl) == NULL.
>>>>>>>
>>>>>>> I'm sure that with some GC checking ggc_free makes them #deadbeef or so:
>>>>>>>
>>>>>>> void
>>>>>>> ggc_free (void *p)
>>>>>>> {
>>>>>>> ...
>>>>>>> #ifdef ENABLE_GC_CHECKING
>>>>>>>   /* Poison the data, to indicate the data is garbage.  */
>>>>>>>   VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (p, size));
>>>>>>>   memset (p, 0xa5, size);
>>>>>>> #endif
>>>>>>>
>>>>>>> so I don't think that's a good thing to rely on ;)
>>>>>>>
>>>>>>> Richard.
>>>>>>
>>>>>> Hi Richi, fully agree that relying of 0xdeadbeaf is not good.
>>>>>> I'm sending quite simple patch v4 where I enable popping up
>>>>>> the stack to eventually set cfun = current_function_decl = NULL.
>>>>>>
>>>>>> Question of using push & pop in cgraph_node::release_body should
>>>>>> be orthogonal as there are other places where the function is used.
>>>>>>
>>>>>> What do you think about the patch?
>>>>>
>>>>> @@ -4763,6 +4763,13 @@ push_cfun (struct function *new_cfun)
>>>>>  void
>>>>>  pop_cfun (void)
>>>>>  {
>>>>> +  if (cfun_stack.is_empty ())
>>>>> +    {
>>>>> +      set_cfun (NULL);
>>>>> +      current_function_decl = NULL_TREE;
>>>>> +      return;
>>>>> +    }
>>>>> +
>>>>>
>>>>> I'd like to avoid this by...
>>>>>
>>>>> @@ -2405,11 +2428,12 @@ execute_pass_list (function *fn, opt_pass *pass)
>>>>>  {
>>>>>    push_cfun (fn);
>>>>>    execute_pass_list_1 (pass);
>>>>> -  if (fn->cfg)
>>>>> +  if (current_function_decl && fn->cfg)
>>>>>      {
>>>>>        free_dominance_info (CDI_DOMINATORS);
>>>>>        free_dominance_info (CDI_POST_DOMINATORS);
>>>>>      }
>>>>> +
>>>>>    pop_cfun ();
>>>>>
>>>>> making this conditional on if (cfun).  Btw, please check cfun against 
>>>>> NULL,
>>>>> not current_function_decl.
>>>>
>>>> Done.
>>>>
>>>>>
>>>>> +      if (dom_info_available_p (CDI_POST_DOMINATORS))
>>>>> +       free_dominance_info (CDI_POST_DOMINATORS);
>>>>> +
>>>>> +      /* Pop function inserted in execute_pass_list.  */
>>>>> +      pop_cfun ();
>>>>> +
>>>>> +      cgraph_node::get (cfun->decl)->release_body ();
>>>>> +
>>>>> +      /* Set cfun and current_function_decl to be NULL.  */
>>>>> +      pop_cfun ();
>>>>> +    }
>>>>>
>>>>> this also looks weird.  Because you pop_cfun and then access cfun and
>>>>> then you pop cfun again?  I'd say most clean would be
>>>>>
>>>>> +      if (dom_info_available_p (CDI_POST_DOMINATORS))
>>>>> +       free_dominance_info (CDI_POST_DOMINATORS);
>>>>> +       tree fn = cfun->decl;
>>>>>          pop_cfun ();
>>>>>         cgraph_node::get (fn)->release_body ();
>>>>>       }
>>>>>
>>>>> or does the comment say that the current function is on the stack
>>>>> twice somehow?  How can that happen?
>>>>
>>>> You are right, your change applied.
>>>>
>>>> Sending V5. If OK, I'll create corresponding changelog entry
>>>> and run regression tests.
>>>
>>> You still have
>>>
>>> @@ -4763,6 +4763,13 @@ push_cfun (struct function *new_cfun)
>>>  void
>>>  pop_cfun (void)
>>>  {
>>> +  if (cfun_stack.is_empty ())
>>> +    {
>>> +      set_cfun (NULL);
>>> +      current_function_decl = NULL_TREE;
>>> +      return;
>>> +    }
>>>
>>> and popping of cfun twice in execute_one_pass.
>>>
>>> Richard.
>>
>> Right and that's the way how I set current_function_decl = cfun = NULL
>> (both pop_cfun are commented what they do).
>> As the popping is done at the end of execute_pass_list and having empty
>> stack just sets to NULL, it should be fine.
> 
> popping it once should have that effect already.  If not then go
> figure why it does not.

Hello.

So the problem is that init_function_start calls set_cfun:

#0  set_cfun (new_cfun=0x7ffff66efbd0) at ../../gcc/function.c:4740
#1  0x0000000000a500b8 in init_function_start (subr=0x7ffff66ec1c0) at 
../../gcc/function.c:4972
#2  0x0000000000911ee3 in cgraph_node::expand (this=0x7ffff6a0ee60) at 
../../gcc/cgraphunit.c:1970

So that first popping removes the function set in execute_pass_list and after 
that the stack is empty,
but cfun is set to 0x7ffff66efbd0.

Should I replace the second pop with set_cfun(NULL) or is it acceptable to call 
the popping for
second time?

Thanks,
Martin


> 
> Richard.
> 
>> Martin
>>
>>>
>>>> Thanks,
>>>> Martin
>>>>
>>>>>
>>>>> Richard.
>>>>>
>>>>>
>>>>>> Thanks,
>>>>>> Martin
>>>>>>
>>>>>>>
>>>>>>>> I'm attaching v3.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Martin
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Otherwise looks good to me.
>>>>>>>>>
>>>>>>>>> Richard.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> Martin
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Martin
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Richard.
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Martin
>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>
>>

Reply via email to