memory lifetime and invariance

FYI, I wrote up some thoughts on this here:
http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txt

The intention is to allow front-ends to express things like "I know this memory is a constant in this region" and to allow the optimizer/codegen to perform more aggressive stack slot merging.

-Chris

Chris Lattner wrote:

FYI, I wrote up some thoughts on this here:
http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txt

The intention is to allow front-ends to express things like "I know this memory is a constant in this region" and to allow the optimizer/ codegen to perform more aggressive stack slot merging.

Very nice!

Why does @llvm.invariant.end restate the size when it already takes the call to @llvm.invariant.start as its first argument? Did you really mean to allow for the case where part of an object is still invariant and part isn't? If so, isn't it missing an offset as well?

Nick

It is basically because the invariant.start may not be the immediate operand of the invariant.end. You may end up having phi nodes connecting the two when various phi translation cases occur.

-Chris

Chris Lattner wrote:

It seems no more prone to abuse to reserve an address space for const
memory. Within a const region, all pointers to the const data are in
the const address space. So rather than starting with a intrinsic,
you start with a ptrcast. This would also make checking trivial
stores to const regions easy in the verifier.

Andrew

This would also make it very easy for a front-end to handle write-once data.

Is there a design document about address spaces?

John.

I don't see how this helps. Fundamentally, you have something like this:

   store x -> ptr
   <many loads and stores>
   load ptr
...

The trick is to know that ptr does not alias the loads and stores. The further issue is that you don't know when the load is generated whether it is in the const section or not, so you couldn't bitcast its pointer operand even if you knew that. A silly C++ example is:

class foo{
   int ivar;
   foo() ...

   int bar() { return ivar; }
};

If "bar" is called from the constructor, then the load is from a potentially varying value, if it is called from code after the constructor, it is known const (assuming the instance was declared const).

-Chris

That sounds like a serious bug then: {} should be a first class value just like {i32}.

-Chris

But in any case, it doesn't really make sense; wouldn't any value of
type {} fold to the constant "{} {}"? If you need an opaque value,
i8* seems much more appropriate.

-Eli

Chris Lattner wrote:

Why not separate the two patches: making {} legal shouldn't be tied to the new MD type switchover.

-Chris

Or better yet, {} undef. :slight_smile: This is a vacuous truth, but it doesn't mean that we don't have to use it and perform the substitution. Per design, if someone did that transformation, the IR would still be correct, just not very useful.

-Chris

Chris Lattner wrote:

You can reject that in different ways!

-Chris

Chris Lattner wrote:

Chris Lattner wrote:

That sounds like a serious bug then: {} should be a first class value
just like {i32}.

Okay then. I've just posted a patch to llvm-commits which would do
that:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090518/077934.html

Why not separate the two patches: making {} legal shouldn't be tied to
the new MD type switchover.

That would allow people to use metadata in their instructions.

You can reject that in different ways!

I'm a total liar. This program passes the verifier:

   define {} @foo({}* %x) {
     %A = load {}* %x
     store {} {}, {}* %x
     ret {} %A
   }

However, if you switch the store to say:

   store {} !"foo", {}* %x

it complains about invalid use of metadata. So everything's good in the tree right now, ignore me.

Nick