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>
Reasonably Related 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?