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