[llvm-commits] [llvm] r38506 - in /llvm/trunk: lib/VMCore/Verifier.cpp test/Verifier/byval-1.ll test/Verifier/byval-2.ll test/Verifier/byval-3.ll test/Verifier/byval-4.ll

Duncan Sands baldrick at free.fr
Tue Jul 17 05:47:10 PDT 2007


Hi Rafael,

> > > +    Assert(!Attrs->paramHasAttr(0, ParamAttr::ByVal),
> > > +           "Attribute ByVal should not apply to functions!");
> >
> > why not?
> 
> What does it means to a function to have such an attribute?

I see now that I was mislead by the assertion message which should probably
be "Attribute ByVal should not apply to function return values!".  I thought
you were not allowing this attribute on any parameter of a function.  By the
way, do you catch the case in which a parameter is marked both sret and byval?

> > > +                "Attribute ByVal should only apply to pointer to structs!", &F);
> >
> > Why?  Why are arrays not allowed?
> 
> They can be allowed latter. For now it is only going to be used by
> structures, so I have arbitrary limited it.

OK, fair enough.

> I think that the C standard defines that structures are always passed
> by value. On some architectures that is done by coping into registers.
> In others it is done by putting a copy on the stack.

Sure, but that doesn't mean that byval has be the same thing as
"C said to pass by value".  I was proposing byval to more or less mean
"pass by value if the ABI specifies how to pass such a guy by value".
The question is how to get C semantics out of this.  My suggestion was
to have the parameter marked byval *and* do an explicit copy in the IR,
and let the codegenerators eliminate any unnecessary copies (these occur
when the ABI supports passing the struct by copy, so the explicit copy
wasn't needed).
 
> This is not how the x86_64 ABI works. A copy is generated by the
> caller, and a pointer is passed *implicitly*. It is computed by
> "stack_pointer + know_offset". We would have to change the abi to
> support passing such implicit pointers.

I see, thanks for this information.  However this seems to be more or
less exactly the scheme I was suggesting: an explicit copy of the struct
is made in the IR (done by the caller).  In the IR the copy is passed to
the callee via a pointer which is marked byval.  In the x86_64 code
generator the byval parameter is changed from a pointer to the copy
into whatever special form is required (I didn't understand exactly
how it is supposed to be passed: as an offset from the stack frame?
If so the stack pointer is subtracted from the pointer to the copy,
and the difference is passed).

> > (2) targets that don't have a special way of passing structs by-copy don't
> > have to do anything.
> 
> All of them need to have it in order to implement the C semantics....

Well, indeed llvm-gcc would have to output an explicit alloca on the stack
and a memcpy in the IR for all of them, but only the targets that have special
ABI requirements would actually need to do something special for a parameter
marked byval, eg x86-64 as above.

> > (4) it conceptually unifies the treatment of ByVal and StructReturn parameters.
> 
> Which might not be generic enough. I can imagine a ABI were two
> passing structures to a function is handled in a different way then
> returning structures.

It unifies them at the IR level not at the codegen level.

Anyway, I have to say that my suggested scheme seems similar to your idea of passing
the stack pointer as an explicit argument.

Finally, in order for my scheme to generate efficient code it needs to be possible to
eliminate pointless copies.  These occur for example on a platform where a by-copy struct
which is two words in size is supposed to be passed in two particular registers.  At the
codegen level the explicit copy in the IR (presumably a memcpy) will be lowered to explicit
stores (to the stack) for a struct of this size.  The target will lower the byval call to a
load of the required registers from the stack followed by the call.  How to eliminate storing
the values to the stack and then reading them out again?  As far as I know LLVM codegen
will not eliminate stack stores and reads even if they could in theory be turned into
stores to and reads from a virtual register.  I guess this is why Chris noted elsewhere
that eliminating pointless copies is hard...

Ciao,

Duncan.



More information about the llvm-commits mailing list