Robert Lytton
2013-Jul-04 20:43 UTC
[LLVMdev] making a copy of a byval aggregate on the callee's frame
Hi Tim,
Thank you for the input.
I think I follow you.
I believe the LowerCall is doing what it needs to do - passing pointer either on
the stack or in register as per ABI.
The LowerFormalArguments() is where I am stuck.
LowerFormalArguments () calls CCInfo.AnalyzeFormalArguments(Ins, CC_XCore),
which calls the CC_XCore().
This is where I placed the CCIfByVal<CCPassByVal<0,4>> which only
pushed the pointer to the stack.
However, I don't want to push the pointer to the stack but COPY the pointee.
Indeed, I want to keep the pointer where it is BUT re-point it to a new object
copied onto the callee's stack.
Hmmm
What I really want it something like:
static bool CC_XCore(...) {
if (ArgFlags.isByVal()) { // a 'CCCustom' function
Size = ValNo.pointee.size; // where do I get the
pointee's info from?
NewVal = State.AllocateStack( Size, 4); // how do I create space on the
callee stack?
memcpy(NewVal, ValNo.pointee, Size); // how do I copy from caller's
stack to callee's stack?
ValNo.pointee=NewVal; // how re-point the pointer at
the callee's stack (rather than caller's data)?
}
If this is the correct way to do it, I will continue to plough ahead.
As you can see, I have no idea what api functions I should be using :-)
Thank you
robert
________________________________________
From: Tim Northover [t.p.northover at gmail.com]
Sent: 04 July 2013 20:24
To: Robert Lytton
Cc: <llvmdev at cs.uiuc.edu>
Subject: Re: [LLVMdev] making a copy of a byval aggregate on the callee's
frame
Hi Robert,
> I tried adding to the XCoreCallingConv.td:
> CCIfByVal<CCPassByVal<0,4>> // pushes pointer to the
stack
This looks sensible to me. After that it comes down to cooperation
between XCoreISelLowering's LowerFormalArguments and LowerCall
functions. LowerFormalArguments is at the beginning of a function and
is responsible for taking arguments out of registers and putting them
into sensible places for the rest of the function to use. LowerCall is
responsible for putting call arguments where callees will expect them
and making the call.
On most targets, for byval, LowerCall would store the argument by
value on the stack (likely with a memcpy equivalent from the actual
pointer that's being passed); and LowerFormalArguments would create a
fixed FrameIndex pointing there and record that as the address for use
by everything else.
You'll want to do basically the reverse: LowerCall will just put the
pointer it's given on the stack; LowerFormalArguments will do the
memcpy like operation into a local variable created for the purpose
(also a FrameIndex, but of a different kind), then it'll record that
frame-index as the address for everything else to use.
Hope this helps; come back if there's still stuff you don't understand.
Cheers.
Tim.
Tim Northover
2013-Jul-04 21:25 UTC
[LLVMdev] making a copy of a byval aggregate on the callee's frame
Hi,> I believe the LowerCall is doing what it needs to do - passing pointer either on the stack or in register as per ABI.>From very quick test-cases with no understanding of XCore, that looks plausible.> LowerFormalArguments () calls CCInfo.AnalyzeFormalArguments(Ins, CC_XCore), which calls the CC_XCore(). > This is where I placed the CCIfByVal<CCPassByVal<0,4>> which only pushed the pointer to the stack.Really, all it did was ask LowerCall and LowerFormalArguments to pass the pointer on the stack (well, strictly "ByVal") as they see fit.> static bool CC_XCore(...) { > <does weird and wonderful stuff> > }I think you're misinterpreting the purpose of these CC_* functions. They don't actually do any of the work themselves. Their job is to decide in broad terms where an argument goes and to record that decision for the LowerWhatever functions. In fact, they don't have access to any of the CodeGen or SelectionDAG machinery necessary to do the job themselves. The idea is that the DAG nodes we need to produce are actually different in caller and callee, but whether some argument goes in R0 or R1 (or a stack slot) should hopefully be the same. So the CC_* functions (& TableGen) take care of the first bit and then the Lower* functions interpret those results in a target-specific way (often). There are usually special checks for byval in those functions which make copies at the appropriate points.> As you can see, I have no idea what api functions I should be using :-)I *think* you'll be fine with using CCPassByVal and won't need a custom handler from what I've heard. At the very least you should be focussing your attention on these Lower* functions for now. They're horribly complicated, but I'm afraid that's something you just have to deal with. They're where the real meaning of "byval" is decided. Cheers. Tim.
Robert Lytton
2013-Jul-04 21:48 UTC
[LLVMdev] making a copy of a byval aggregate on the callee's frame
Hi Tim,
I may be missing something but using CCPassByVal is moving the pointer onto the
stack - not what I'm after.
I need to add an operation to the function prolog that actually makes a copy of
the pointed to data.
It is the responsibility of the callee to make the copy, not the caller - hence
my trouble.
(currently the callee can corrupt the original data viz pass-by-reference!)
This should ideally be done early on in the IR in my thinking - to allow
optimisation if the data is only ever read.
FYI, the clang hack is - notice the "CreateMemCpy":
CodeGenFunction::EmitFunctionProlog(){
...
if (ArgI.getIndirectByVal()) {
llvm::AllocaInst *ByValue = CreateMemTemp(Ty, V->getName() +
"agg.tmp");
llvm::ConstantInt * size = llvm::ConstantInt::get(IntPtrTy,
getContext().getTypeSizeInChars(Ty).getQuantity());
Builder.CreateMemCpy(ByValue, V, size, 4 );
V = ByValue; // and point the pointer to the new pointee!
}
So, can it be done in the llvm?
Should it be done in the llvm?
I probably need to go away and read up on the llvm AST handling (is that the
right name?).
robert
_______________________________________
From: Tim Northover [t.p.northover at gmail.com]
Sent: 04 July 2013 22:25
To: Robert Lytton
Cc: <llvmdev at cs.uiuc.edu>
Subject: Re: [LLVMdev] making a copy of a byval aggregate on the callee's
frame
Hi,
> I believe the LowerCall is doing what it needs to do - passing pointer
either on the stack or in register as per ABI.
>From very quick test-cases with no understanding of XCore, that looks
plausible.
> LowerFormalArguments () calls CCInfo.AnalyzeFormalArguments(Ins, CC_XCore),
which calls the CC_XCore().
> This is where I placed the CCIfByVal<CCPassByVal<0,4>> which
only pushed the pointer to the stack.
Really, all it did was ask LowerCall and LowerFormalArguments to pass
the pointer on the stack (well, strictly "ByVal") as they see fit.
> static bool CC_XCore(...) {
> <does weird and wonderful stuff>
> }
I think you're misinterpreting the purpose of these CC_* functions.
They don't actually do any of the work themselves. Their job is to
decide in broad terms where an argument goes and to record that
decision for the LowerWhatever functions. In fact, they don't have
access to any of the CodeGen or SelectionDAG machinery necessary to do
the job themselves.
The idea is that the DAG nodes we need to produce are actually
different in caller and callee, but whether some argument goes in R0
or R1 (or a stack slot) should hopefully be the same.
So the CC_* functions (& TableGen) take care of the first bit and then
the Lower* functions interpret those results in a target-specific way
(often). There are usually special checks for byval in those functions
which make copies at the appropriate points.
> As you can see, I have no idea what api functions I should be using :-)
I *think* you'll be fine with using CCPassByVal and won't need a
custom handler from what I've heard. At the very least you should be
focussing your attention on these Lower* functions for now. They're
horribly complicated, but I'm afraid that's something you just have to
deal with. They're where the real meaning of "byval" is decided.
Cheers.
Tim.
Maybe Matching Threads
- [LLVMdev] making a copy of a byval aggregate on the callee's frame
- [LLVMdev] making a copy of a byval aggregate on the callee's frame
- [LLVMdev] making a copy of a byval aggregate on the callee's frame
- [LLVMdev] making a copy of a byval aggregate on the callee's frame
- [LLVMdev] making a copy of a byval aggregate on the callee's frame