Xiangyang Guo via llvm-dev
2015-Nov-25 22:06 UTC
[llvm-dev] need help for customized backend LowerFormalArguments
Hi, All, I'm trying to build a customized backend and I need to lower the formal arguments like this: There are several specific registers just for storing formal arguments. And also there are several general purpose registers for computation. If there is an instruction which uses parameters, I should first use a move instruction, which moves the value to general purpose register. For example, in RegisterInfo.td , I have following register classes: // this is for storing parameters only def PRegs : RegisterClass<"FOO", [i32], 32, (add P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)>; // this is general purpose register class def GRRegs : RegisterClass<"FOO", [i32], 32, (add R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10)>; // this is also general purpose register class def GRRegsAdditional : RegisterClass<"FOO", [i32], 32, (add R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, SP)>; If I have a piece of bitcode looks like this: define i32 @_Z3fooii(i32 %a, i32 %b) #0 { %1 = add nsw i32 %a, %b ret i32 %1 } I want the assembly looks like this: move v0, p0 move v1, p1 add-int v10, v0, v1 return v10 So far, I have tried is to implement the LowerFormalArguments() like this: SDValue FOOTargetLowering::LowerFormalArguments( SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); assert(!isVarArg && "VarArg not supported"); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext()); CCInfo.AnalyzeFormalArguments(Ins, CC_FOO); for (auto &VA : ArgLocs) { if (VA.isRegLoc()) { // Arguments passed in registers EVT RegVT = VA.getLocVT(); const unsigned VReg RegInfo.createVirtualRegister(&FOO::PRegsRegClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); SDValue ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); InVals.push_back(ArgIn); continue; } // assume the parameter registers are enough, no need to store in frame right now } return Chain; } In the above function, CC_FOO is defined in CallingConv.td and "CCIfType<[i32], CCAssignToReg<[P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15]>>" is used. Also I define a move instruction which move the value from PRegs to GRRegs because my add instruction's source registers should belong to GRRegs or GRRegsAdditional. I define 'move' and 'add' instructions like this: def MoveRRTy : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisInt<0>]>; def moverr : SDNode<"FOOISD::MOVERR", MoveRRTy>; def MOVE : InstFOO<(outs GRRegsAdditional:$dst), (ins PRegs:$src), "move $dst, $src",[(set i32:$dst, (moverr i32:$src))]>; def ADDINT: InstFOO<(outs GRRegsAdditional:$dst), (ins GRRegsAdditional:$src1, GRRegsAdditional:$src2), "add-int $dst, $src1, $src2", [(set i32:$dst, (add i32:$src1, i32:$src2))]>; I assume this could work. However, when I use llc and print-after-all to check the machine instructions. At very beginning, the machine instructions look like this: %vreg1<def> = COPY %P1; PRegs:%vreg1 %vreg0<def> = COPY %P0; PRegs:%vreg0 %vreg3<def> = COPY %vreg0; GRRegsAdditional:%vreg3 PRegs:%vreg0 %vreg4<def> = COPY %vreg1; GRRegsAdditional:%vreg4 PRegs:%vreg1 %vreg2<def> = ADDINT %vreg3, %vreg4; GRRegsAdditional:%vreg2,%vreg3,%vreg4 %R10<def> = COPY %vreg2; GRRegsAdditional:%vreg2 RET %R10 And after "Post-RA pseudo instruction expansion pass", it looks like this Function Live Ins: %P0 in %vreg0, %P1 in %vreg1 BB#0: derived from LLVM BB %0 Live Ins: %P0 %P1 %R10<def> = ADDINT %R0<kill>, %R1<kill> RET %R10 And eventually, the assembly file .s looks like this # BB#0: add-int v10, v0, v1 return v10 It seems that there is no "move v0, p0" and "move v1, p1" at all. But I'm not sure why is this. I appreciate any suggestions and points. Regards, Xiangyang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151125/c14231a7/attachment.html>
Tim Northover via llvm-dev
2015-Nov-25 22:27 UTC
[llvm-dev] need help for customized backend LowerFormalArguments
On 25 November 2015 at 14:06, Xiangyang Guo via llvm-dev <llvm-dev at lists.llvm.org> wrote:> const unsigned VReg = RegInfo.createVirtualRegister(&FOO::PRegsRegClass); > RegInfo.addLiveIn(VA.getLocReg(), VReg); > SDValue ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);Using MachineFunction::addLiveIn would probably be simpler, but I *think* this ought to be OK too.> However, when I use llc and print-after-all to check the machine > instructions. At very beginning, the machine instructions look like this: > > %vreg1<def> = COPY %P1; PRegs:%vreg1 > %vreg0<def> = COPY %P0; PRegs:%vreg0 > %vreg3<def> = COPY %vreg0; GRRegsAdditional:%vreg3 PRegs:%vreg0 > %vreg4<def> = COPY %vreg1; GRRegsAdditional:%vreg4 PRegs:%vreg1 > %vreg2<def> = ADDINT %vreg3, %vreg4; GRRegsAdditional:%vreg2,%vreg3,%vreg4 > %R10<def> = COPY %vreg2; GRRegsAdditional:%vreg2 RET %R10This looks fine to me.> And after "Post-RA pseudo instruction expansion pass", it looks like thisI don't suppose your copyPhysReg implementation does something degenerate for these? That's the callback that'll be used to actually implement any COPY pseudo-instructions that need to be materialised, not any TableGen related patterns you might have (as a general guideline, if you're writing a pattern for a MOV instruction, you're probably doing something wrong). It's a good idea for copyPhysReg to assert for anything it can't handle corrrectly. If it's not that, the entire output of "llc -debug" would be useful. Obviously a lot goes on between the two dumps you pasted here. Maybe some other pass is doing something slightly wrong. Cheers. Tim.
Xiangyang Guo via llvm-dev
2015-Nov-29 02:25 UTC
[llvm-dev] need help for customized backend LowerFormalArguments
Hi, Tim, Thanks for your reply. You are right, my MOVE and copyPhysReg are wrong. After I fix that, it works. Regards, Xiangyang 2015-11-25 17:27 GMT-05:00 Tim Northover <t.p.northover at gmail.com>:> On 25 November 2015 at 14:06, Xiangyang Guo via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > const unsigned VReg > RegInfo.createVirtualRegister(&FOO::PRegsRegClass); > > RegInfo.addLiveIn(VA.getLocReg(), VReg); > > SDValue ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); > > Using MachineFunction::addLiveIn would probably be simpler, but I > *think* this ought to be OK too. > > > However, when I use llc and print-after-all to check the machine > > instructions. At very beginning, the machine instructions look like this: > > > > %vreg1<def> = COPY %P1; PRegs:%vreg1 > > %vreg0<def> = COPY %P0; PRegs:%vreg0 > > %vreg3<def> = COPY %vreg0; GRRegsAdditional:%vreg3 PRegs:%vreg0 > > %vreg4<def> = COPY %vreg1; GRRegsAdditional:%vreg4 PRegs:%vreg1 > > %vreg2<def> = ADDINT %vreg3, %vreg4; > GRRegsAdditional:%vreg2,%vreg3,%vreg4 > > %R10<def> = COPY %vreg2; GRRegsAdditional:%vreg2 RET %R10 > > This looks fine to me. > > > And after "Post-RA pseudo instruction expansion pass", it looks like this > > I don't suppose your copyPhysReg implementation does something > degenerate for these? That's the callback that'll be used to actually > implement any COPY pseudo-instructions that need to be materialised, > not any TableGen related patterns you might have (as a general > guideline, if you're writing a pattern for a MOV instruction, you're > probably doing something wrong). > > It's a good idea for copyPhysReg to assert for anything it can't > handle corrrectly. > > If it's not that, the entire output of "llc -debug" would be useful. > Obviously a lot goes on between the two dumps you pasted here. Maybe > some other pass is doing something slightly wrong. > > Cheers. > > Tim. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151128/f842411c/attachment.html>
Possibly Parallel Threads
- TableGen customized node with mayStore attribute is deleted if there is no use
- [LLVMdev] instructions requiring specific physical registers for operands
- [LLVMdev] instructions requiring specific physical registers for operands
- dlmSum(...) and non-constant state space models
- [LLVMdev] Is it possible to tie two defs together?