Sorry for my late reply (I just came back from vacation last night).

> On Aug 23, 2021, at 8:55 AM, Richard Biener <rguent...@suse.de> wrote:
> 
>>>> 
>>>> 
>>>> Looks like for the following code:
>>>> 
>>>> 3026   if (!reg_lhs)
>>>> 3027     {
>>>> 3028     /* If this is a VLA or the variable is not in register,
>>>> 3029        expand to a memset to initialize it.  */
>>>> 3030       mark_addressable (lhs);
>>>> 3031       tree var_addr = build_fold_addr_expr (lhs);
>>>> 3032 
>>>> 3033       tree value = (init_type == AUTO_INIT_PATTERN) ?
>>>> 3034                     build_int_cst (integer_type_node,
>>>> 3035                                    INIT_PATTERN_VALUE) :
>>>> 3036                     integer_zero_node;
>>>> 3037       tree m_call = build_call_expr (builtin_decl_implicit 
>>>> (BUILT_IN_MEMSET),
>>>> 3038                                      3, var_addr, value, var_size);
>>>> 3039       /* Expand this memset call.  */
>>>> 3040       expand_builtin_memset (m_call, NULL_RTX, TYPE_MODE (var_type));
>>>> 3041     }
>>>> 
>>>> At line 3030, “lhs” could be a SSA_NAME.
>>>> 
>>>> My questions are:
>>>> 
>>>> 1. Could the routine “mark_addressable” and “build_fold_addr_expr” be 
>>>> applied on SSA_NAME?
>>> 
>>> No.
>>> 
>>>> 2. Could the routine “expand_builtin_memset” be applied on the memset call 
>>>> whose “DEST” is
>>>>   an address expression on SSA_NAME? 
>>> 
>>> No.
>>> 
>>>> 3. Within “expand_DEFERRED_INIT”, can I call “expand_builtin_memset” to 
>>>> expand .DEFERRED_INIT?
>>> 
>>> Well, not with "invalid" GENERIC I fear (address of a SSA name).
>>> 
>>>> I suspect that one of the above 3 might be the issue, but not sure which 
>>>> one?
>>> 
>>> All of the above ;)  So while reg_lhs is now precise as to how the
>>> variable will end up (the SSA name will end up as a stack variable in this
>>> case, for whatever reason), expansion via memcpy only works when
>>> working on the RTL representation.  The usual "workaround" (ugh)
>>> is to use make_tree (), so in the !reg_lhs path you'd do
>>> 
>>> /* Get a new GENERIC representation for the RTL.  That's necesary
>>>    in case LHS is an SSA name.  */
>>> lhs = make_tree (TREE_TYPE (lhs), tem);
>> 
>> This resolved the issue.
>> 
>> Another question,
>> 
>> Previously, I used
>> 
>>    if (TREE_CODE (lhs) == SSA_NAME)
>>       lhs = SSA_NAME_VAR (lhs);
>> 
>> To resolve this issue. The purpose looks like the same as “make_tree”, just 
>> get an generic tree for the LHS. 
>> 
>> Why you said using SSA_NAME_VAR is broken?  Is it because SSA_NAME_VAR will 
>> not always return a valid TREE?
> 
> Because it's simply the wrong entity - I have no idea why that even
> worked.  Ah, cfgexpand associates it with some DECL_RTL for the 
> benefit of debug info.  But it's still wrong.
> 
>> I should use as following
>> 
>> 
>>   If (TREE_CODE (lhs) == SSA_NAME) && SSA_NAME_VAR (lhs))
>>      Lhs = SSA_NAME_VAR (lhs)
>> 
>> ?
> 
> No.  A SSA_NAME_VAR can have multiple SSA_NAMEs (obviously) and
> they do not necessarily have to be allocated to the same variable
> partition - that is, there's no 1:1 relationship between SSA_NAME
> and stack slot or (pseudo) register.  You want to initialize the
> storage associated with the SSA_NAME in the .DEFERRED_INIT call,
> not some other storage.

Okay, thanks for the explanation. Now I understand.
> 
>>> 
>>> alternatively you could maybe do
>>> 
>>> if (DECL_P (lhs))
>>>   {
>>> +      rtx tem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
>>> +      reg_lhs = !MEM_P (tem);
>>>   }
>>> else if (TREE_CODE (lhs) == SSA_NAME)
>>>   reg_lhs = true;
>>> else
>>>   reg_lhs = false;
>>> 
>>> thus treat SSA names as register storage always (even if it will end
>>> up on the stack).
>> 
>> My question here, for a complicate structure SSA_NAME, will expanding 
>> through memset better than expand_asssignment? 
> 
> It depends.  In the end I'd consider it a missed-optimization bug on
> the side that generates worse code - but I do expect cases will exist
> for both.
Okay. I agree.

>  Clearly memset will be worse when dealing with register
> initialization (thus the !MEM_P check) and I expect memset to be OK
> for stack where member-wise init esp. with non-zero might turn up
> worse code.

So, for SSA_NAME, since they are all treated as reg_lhs, they will be expanded 
through “expand_assignment” 
as member-wise init, therefore might generate worse code for a SSA_NAME that is 
in stack actually.

Qing

> 
> Richard.
> 
>> Qing
>>> 

Reply via email to