Hi, Richard,

I need more discussion on the following comments you raised:

> On May 26, 2021, at 6:18 AM, Richard Biener <rguent...@suse.de> wrote:
> 
> +/* Expand the IFN_DEFERRED_INIT function according to its second 
> argument.  */
> +static void
> +expand_DEFERRED_INIT (internal_fn, gcall *stmt)
> +{
> +  tree var = gimple_call_lhs (stmt);
> +  tree init = NULL_TREE;
> +  enum auto_init_type init_type
> +    = (enum auto_init_type) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1));
> +
> +  switch (init_type)
> +    {
> +    default:
> +      gcc_unreachable ();
> +    case AUTO_INIT_PATTERN:
> +      init = build_pattern_cst_for_auto_init (TREE_TYPE (var));
> +      expand_assignment (var, init, false);
> +      break;
> +    case AUTO_INIT_ZERO:
> +      init = build_zero_cst (TREE_TYPE (var));
> +      expand_assignment (var, init, false);
> +      break;
> +    }
> 
> I think actually building build_pattern_cst_for_auto_init can generate
> massive garbage and for big auto vars code size is also a concern and
> ideally on x86 you'd produce rep movq.  So I don't think going
> via expand_assignment is good.  Instead you possibly want to lower
> .DEFERRED_INIT to MEMs following expand_builtin_memset and
> eventually enhance that to allow storing pieces larger than a byte.

When I tried to lower .DEFERRED_INIT to MEMs for  “AUTO_INIT_PATTERN”, I have 
the following questions:

1. If .DEFERRED_INIT will be lowered to MEMS through “memset”, then we 
basically initialize the whole memory covering the
auto variable, including paddings. Right?
2. Only when the value that is used to initialization has a repeated 
byte-pattern, we can lower it through “memset”. Otherwise,
If the value that is used to initialization does Not have a repeated 
byte-pattern, we can NOT lower it through “memset”, right?

Currently, for the values that are used to initialize for “AUTO_INIT_PATTERN”, 
we have:

  /* The following value is a guaranteed unmappable pointer value and has a
     repeated byte-pattern which makes it easier to synthesize.  We use it for
     pointers as well as integers so that aggregates are likely to be
     initialized with this repeated value.  */
  uint64_t largevalue = 0xAAAAAAAAAAAAAAAAull;
  /* For 32-bit platforms it's a bit trickier because, across systems, only the
     zero page can reasonably be expected to be unmapped, and even then we need
     a very low address.  We use a smaller value, and that value sadly doesn't
     have a repeated byte-pattern.  We don't use it for integers.  */
  uint32_t smallvalue = 0x000000AA;

In additional to the above, for BOOLEAN_TYPE:

    case BOOLEAN_TYPE:
      /* We think that initializing the boolean variable to 0 other than 1
         is better even for pattern initialization.  */

Due to “BOOLEAN_TYPE” and “POINTER_TYPE”,  we cannot always have a repeated 
byte-pattern for variables that include BOOLEAN_TYPE
Or Pointer types. Therefore, lowering the .DEFERRED_INIT for “PATTERN” 
initialization through “memset” is not always possible. 

Let me know if I miss anything in the above. Do you have other suggestions?

thanks.

Qing

Reply via email to