llvm.org GIT mirror llvm / c95c8c8
[MIPS GlobalISel] Lower arguments using stack Lower more than 4 arguments using stack. This patch targets MIPS32. It supports only functions with arguments of type i32. Patch by Petar Avramovic. Differential Revision: https://reviews.llvm.org/D47934 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336185 91177308-0d34-0410-b5e6-96231b3b80d8 Petar Jovanovic 1 year, 4 months ago
3 changed file(s) with 129 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
2626 unsigned vreg) {
2727 if (VA.isRegLoc()) {
2828 assignValueToReg(vreg, VA.getLocReg());
29 } else if (VA.isMemLoc()) {
30 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
31 unsigned Offset = VA.getLocMemOffset();
32 MachinePointerInfo MPO;
33 unsigned StackAddr = getStackAddress(Size, Offset, MPO);
34 assignValueToAddress(vreg, StackAddr, Size, MPO);
2935 } else {
3036 return false;
3137 }
4248 ArrayRef Args);
4349
4450 private:
45 virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
51 void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
52
53 unsigned getStackAddress(uint64_t Size, int64_t Offset,
54 MachinePointerInfo &MPO) override;
55
56 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
57 MachinePointerInfo &MPO) override;
4658
4759 virtual void markPhysRegUsed(unsigned PhysReg) {
4860 MIRBuilder.getMBB().addLiveIn(PhysReg);
61 }
62
63 void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment,
64 MachinePointerInfo &MPO) {
65 MachineMemOperand *MMO = MIRBuilder.getMF().getMachineMemOperand(
66 MPO, MachineMemOperand::MOLoad, Size, Alignment);
67 MIRBuilder.buildLoad(Val, Addr, *MMO);
4968 }
5069 };
5170
5675 : IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
5776
5877 private:
59 virtual void markPhysRegUsed(unsigned PhysReg) override {
78 void markPhysRegUsed(unsigned PhysReg) override {
6079 MIB.addDef(PhysReg, RegState::Implicit);
6180 }
6281
6988 unsigned PhysReg) {
7089 MIRBuilder.buildCopy(ValVReg, PhysReg);
7190 markPhysRegUsed(PhysReg);
91 }
92
93 unsigned IncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
94 MachinePointerInfo &MPO) {
95 MachineFrameInfo &MFI = MIRBuilder.getMF().getFrameInfo();
96
97 int FI = MFI.CreateFixedObject(Size, Offset, true);
98 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
99
100 unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
101 MIRBuilder.buildFrameIndex(AddrReg, FI);
102
103 return AddrReg;
104 }
105
106 void IncomingValueHandler::assignValueToAddress(unsigned ValVReg, unsigned Addr,
107 uint64_t Size,
108 MachinePointerInfo &MPO) {
109 // If the value is not extended, a simple load will suffice.
110 buildLoad(ValVReg, Addr, Size, /* Alignment */ 0, MPO);
72111 }
73112
74113 bool IncomingValueHandler::handle(ArrayRef ArgLocs,
91130 ArrayRef Args);
92131
93132 private:
94 virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
133 void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
134
135 unsigned getStackAddress(uint64_t Size, int64_t Offset,
136 MachinePointerInfo &MPO) override;
137
138 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
139 MachinePointerInfo &MPO) override;
95140
96141 MachineInstrBuilder &MIB;
97142 };
101146 unsigned PhysReg) {
102147 MIRBuilder.buildCopy(PhysReg, ValVReg);
103148 MIB.addUse(PhysReg, RegState::Implicit);
149 }
150
151 unsigned OutgoingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
152 MachinePointerInfo &MPO) {
153 LLT p0 = LLT::pointer(0, 32);
154 LLT s32 = LLT::scalar(32);
155 unsigned SPReg = MRI.createGenericVirtualRegister(p0);
156 MIRBuilder.buildCopy(SPReg, Mips::SP);
157
158 unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
159 MIRBuilder.buildConstant(OffsetReg, Offset);
160
161 unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
162 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
163
164 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
165 return AddrReg;
166 }
167
168 void OutgoingValueHandler::assignValueToAddress(unsigned ValVReg, unsigned Addr,
169 uint64_t Size,
170 MachinePointerInfo &MPO) {
171 MachineMemOperand *MMO = MIRBuilder.getMF().getMachineMemOperand(
172 MPO, MachineMemOperand::MOStore, Size, /* Alignment */ 0);
173 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
104174 }
105175
106176 bool OutgoingValueHandler::handle(ArrayRef ArgLocs,
204274 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
205275 F.getContext());
206276
277 const MipsTargetMachine &TM =
278 static_cast(MF.getTarget());
279 const MipsABIInfo &ABI = TM.getABI();
280 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
281 1);
207282 CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());
208283
209284 IncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
280355 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
281356 F.getContext());
282357
358 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1);
283359 const char *Call = Callee.isSymbol() ? Callee.getSymbolName() : nullptr;
284360 CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
285361
288364 return false;
289365 }
290366
291 // TODO: Calculate stack offset.
292 CallSeqStart.addImm(ABI.GetCalleeAllocdArgSizeInBytes(CallConv)).addImm(0);
367 unsigned NextStackOffset = CCInfo.getNextStackOffset();
368 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
369 unsigned StackAlignment = TFL->getStackAlignment();
370 NextStackOffset = alignTo(NextStackOffset, StackAlignment);
371 CallSeqStart.addImm(NextStackOffset).addImm(0);
372
293373 MIRBuilder.insertInstr(MIB);
294374
295375 if (OrigRet.Reg) {
318398 return false;
319399 }
320400
321 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP)
322 .addImm(ABI.GetCalleeAllocdArgSizeInBytes(CallConv))
323 .addImm(0);
401 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0);
324402
325403 return true;
326404 }
3131 virtual ~MipsHandler() = default;
3232
3333 protected:
34 virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) = 0;
35
3634 bool assign(const CCValAssign &VA, unsigned vreg);
3735
3836 MachineIRBuilder &MIRBuilder;
3937 MachineRegisterInfo &MRI;
38
39 private:
40 virtual unsigned getStackAddress(uint64_t Size, int64_t Offset,
41 MachinePointerInfo &MPO) = 0;
42
43 virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) = 0;
44
45 virtual void assignValueToAddress(unsigned ValVReg, unsigned Addr,
46 uint64_t Size,
47 MachinePointerInfo &MPO) = 0;
4048 };
4149
4250 MipsCallLowering(const MipsTargetLowering &TLI);
0 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 ; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
2
3 declare i32 @f(i32, i32, i32, i32, i32)
4
5 define i32 @g(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5){
6 ; MIPS32-LABEL: name: g
7 ; MIPS32: bb.1.entry:
8 ; MIPS32: liveins: $a0, $a1, $a2, $a3
9 ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
10 ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
11 ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
12 ; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
13 ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
14 ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 0)
15 ; MIPS32: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
16 ; MIPS32: $a0 = COPY [[COPY]](s32)
17 ; MIPS32: $a1 = COPY [[COPY1]](s32)
18 ; MIPS32: $a2 = COPY [[COPY2]](s32)
19 ; MIPS32: $a3 = COPY [[COPY3]](s32)
20 ; MIPS32: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
21 ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
22 ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY4]], [[C]](s32)
23 ; MIPS32: G_STORE [[LOAD]](s32), [[GEP]](p0) :: (store 4 into stack + 16, align 0)
24 ; MIPS32: JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
25 ; MIPS32: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
26 ; MIPS32: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
27 ; MIPS32: $v0 = COPY [[COPY5]](s32)
28 ; MIPS32: RetRA implicit $v0
29 entry:
30 %call = call i32 @f(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5)
31 ret i32 %call
32 }