[PATCH][version 3]add -ftrivial-auto-var-init and variable attribute "uninitialized" to gcc

Qing Zhao qing.zhao@oracle.com
Fri Jun 11 17:00:32 GMT 2021



On Jun 11, 2021, at 10:49 AM, Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>> wrote:



On Jun 11, 2021, at 6:12 AM, Richard Biener <rguenther@suse.de<mailto:rguenther@suse.de>> wrote:

On Thu, 10 Jun 2021, Qing Zhao wrote:

Hi, Richard,

I need more discussion on the following comments you raised:

On May 26, 2021, at 6:18 AM, Richard Biener <rguenther@suse.de<mailto:rguenther@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?

Yes.

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?

Yes.  This is why I said you should do it _similar_ to how memcpy
is implemented.  OTOH I don't see a good reason to support patterns
that are bigger than a byte ...

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?

The main point is that you need to avoid building the explicit initializer
only to have it consumed by assignment expansion.  If you want to keep
all the singing and dancing (as opposed to maybe initializing with a
0x1 byte pattern) then I think for efficiency you still want to
block-initialize the variable and then only fixup the special fields.

Yes, this is a good idea.

We can memset the whole structure with repeated pattern “0xAA” first,
Then mixup BOOLEAN_TYPE and POINTER TYPE for 32-bit platform.
That might be more efficient.

However, the paddings will be initialized to “0xAA”.
But this should be fine since with -fauto-var-init,  the paddings can be any value.

So, still should be fine.

Qing



More information about the Gcc-patches mailing list