[LLVMdev] PROPOSAL: struct-access-path aware TBAA

Daniel Berlin dberlin at dberlin.org
Wed Mar 13 13:39:43 PDT 2013

On Wed, Mar 13, 2013 at 11:07 AM, Shuxin Yang <shuxin.llvm at gmail.com> wrote:
>> The program I gave was well typed :)
> Hi, Daniel:
>    Thank you for sharing your insight.  I didn't realized it is well-typed
> -- I'm basically a big nut of any std.
> I'd admit std/spec is one of the most boring material on this planet:-).
>    So, if I understand correct, your point is:
>        if a std call a type-casting (could be one which is in bad-taste:-),
> TBAA has to respect such std.


>   If that is strictly true, TBAA has to reply on point-to analysis.

We actually disable TBAA in some cases, and rely on points-to in some others.
It's "complicated" :)
I can go back through the code and list the cases and reasons if you
think it would be helpful.

> However,
> that would virtually disable
> TBAA as most point-to set has "unknown" element.
Well, the program you gave in the last message is fine.
It's okay to promote p->x even though it points-to non-local
variables, in *C*, because any
read from q that actually read the same memory would be undefined.

C++ has cases where it's possible they are legally allowed to point to
the same *memory*, though
they cannot be objects that are live at the *same time*.
So basically, you have motion barriers, and you may not be able to see them :)

>    Going back to my previous mail,
>> In the below example, GCC assumes p and q point to anything because
>> they are incoming arguments.

I misspoke, it actually assumes they point to non-local variables.
Flow-insensitive points-to information

p_1(D), points-to non-local
q_2(D), points-to non-local
>>> ------------------------------
>>> typedef struct {
>>>      int x;
>>> }T1;
>>> typedef struct {
>>>      int y;
>>> }T2;
>>> int foo(T1 *p, T2 *q) {
>>>      p->x = 1;
>>>      q->y = 4;
>>>      return p->x;
>>> }
>>> --------------------------
> Yes, gcc should assume p and q point to anything, however, the result
> contradict to the assumption --
> It promote the p->x expression.
In both C and C++, the a load from q->y would be undefined if they
accessed the same memory.
This is different than the example I gave :)
Note that it actually just propagates p->x, because it knows the other
store can't legally affect the *read*.
It doesn't delete either store :)

>   If I fabricate a caller by stealing some code from your previous example,
> see bellow.
> I think these code & your previous example (about placement new) share the
> same std.  I'm wondering
> if gcc can give a correct result.
>    foo_caller() {
>        T1 t1;
>        T1 *pt1;
>        T2 *pt2 = new (pt1) T2;
>        foo(pt1, pt2);
>     }

pt1 is not allowed to be read in foo in this case.

The original example I gave was one where using the alias info causes
it to reorder a  store to a live object above a store to a dead one,
because it does not know it is dead.

More information about the llvm-dev mailing list