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.
Tim Northover
2013-Jul-05 06:43 UTC
[LLVMdev] making a copy of a byval aggregate on the callee's frame
Hi Robert,> This should ideally be done early on in the IR in my thinking - to allow optimisation if the data is only ever read.I've thought that once or twice when dealing with ABIs myself. That's certainly another possibility in your case. You could create a separate FunctionPass that gets executed early on and replaces all byval calls and functions with the correct memcpys. It wouldn't work for other targets because they need more control over just where the copy ends up, but it sounds like you shouldn't have an issue.> So, can it be done in the llvm?Yes, in multiple ways.> Should it be done in the llvm?I think so, one way or the other. Tim.
Robert Lytton
2013-Jul-05 07:52 UTC
[LLVMdev] making a copy of a byval aggregate on the callee's frame
Hi Tim, Thought about it last night and was coming to the same conclusion. 1. it cant be done at the end during lowering (target backend). 2. it should be part of llvm as the byVal needs to be handled. As a twist, I have been told that llvm-gcc can lower byVal into memcpy in the callee. I may take a look at this. I wonder if it ever emits 'byVal'... I still feel I don't understand enough about where byVal is used or what it means. Is it *only* used as an attribute of an argument pointer to argument data that is pending a copy? Once the memcpy is made, I assume the byVal is removed viz the arg pointer is replaced with a new arg pointer to the copied data. Thus, must *all* byVal attributes be replaced in the IR? I need to do more reading about other attributes and get more familiar with the IR in general... robert ________________________________________ From: Tim Northover [t.p.northover at gmail.com] Sent: 05 July 2013 07:43 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,> This should ideally be done early on in the IR in my thinking - to allow optimisation if the data is only ever read.I've thought that once or twice when dealing with ABIs myself. That's certainly another possibility in your case. You could create a separate FunctionPass that gets executed early on and replaces all byval calls and functions with the correct memcpys. It wouldn't work for other targets because they need more control over just where the copy ends up, but it sounds like you shouldn't have an issue.> So, can it be done in the llvm?Yes, in multiple ways.> Should it be done in the llvm?I think so, one way or the other. Tim.
Apparently Analagous 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