On 2023-08-17 15:27, Qing Zhao wrote:
Yes, that's it.  Maybe it's more correct if instead of MAX_EXPR if for 
OST_MINIMUM we stick with the early_objsz answer if it's non-zero.  I'm not 
sure if that's the case for maximum size though, my gut says it isn't.

So, the major purpose for adding the early object size phase is for computing 
SUBobjects size more precisely before the subobject information lost?

I suppose it's more about being able to do it at all, rather than precision.

Then, I think whatever MIN or MAX, the early phase has more precise information 
than the later phase, we should use its result if it’s NOT UNKNOWN?

We can't be sure about that though, can we? For example for something like this:

struct S
{
  int a;
  char b[10];
  int c;
};

size_t foo (struct S *s)
{
  return __builtin_object_size (s->b, 1);
}

size_t bar ()
{
  struct S *in = malloc (8);

  return foo (in);
}

returns 10 for __builtin_object_size in early_objsz but when it sees the malloc in the later objsz pass, it returns 4:

$ gcc/cc1 -fdump-tree-objsz-details -quiet -o - -O bug.c
...
foo:
.LFB0:
        .cfi_startproc
        movl    $10, %eax
        ret
        .cfi_endproc
...
bar:
.LFB1:
        .cfi_startproc
        movl    $4, %eax
        ret
        .cfi_endproc
...

In fact, this ends up returning the wrong result for OST_MINIMUM:

$ gcc/cc1 -fdump-tree-objsz-details -quiet -o - -O bug.c
...
foo:
.LFB0:
        .cfi_startproc
        movl    $10, %eax
        ret
        .cfi_endproc
...
bar:
.LFB1:
        .cfi_startproc
        movl    $10, %eax
        ret
        .cfi_endproc
...

bar ought to have returned 4 too (and I'm betting the later objsz must have seen that) but it got overridden by the earlier estimate of 10.

We probably need smarter heuristics on choosing between the estimate of the early_objsz and late objsz passes each by itself isn't good enough for subobjects.

Thanks,
Sid

Reply via email to