Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit c95c8c8

Browse files
[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
1 parent ba89ffc commit c95c8c8

File tree

3 files changed

+129
-10
lines changed

3 files changed

+129
-10
lines changed

lib/Target/Mips/MipsCallLowering.cpp

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ bool MipsCallLowering::MipsHandler::assign(const CCValAssign &VA,
2727
unsigned vreg) {
2828
if (VA.isRegLoc()) {
2929
assignValueToReg(vreg, VA.getLocReg());
30+
} else if (VA.isMemLoc()) {
31+
unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
32+
unsigned Offset = VA.getLocMemOffset();
33+
MachinePointerInfo MPO;
34+
unsigned StackAddr = getStackAddress(Size, Offset, MPO);
35+
assignValueToAddress(vreg, StackAddr, Size, MPO);
3036
} else {
3137
return false;
3238
}
@@ -43,11 +49,24 @@ class IncomingValueHandler : public MipsCallLowering::MipsHandler {
4349
ArrayRef<CallLowering::ArgInfo> Args);
4450

4551
private:
46-
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
52+
void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
53+
54+
unsigned getStackAddress(uint64_t Size, int64_t Offset,
55+
MachinePointerInfo &MPO) override;
56+
57+
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
58+
MachinePointerInfo &MPO) override;
4759

4860
virtual void markPhysRegUsed(unsigned PhysReg) {
4961
MIRBuilder.getMBB().addLiveIn(PhysReg);
5062
}
63+
64+
void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment,
65+
MachinePointerInfo &MPO) {
66+
MachineMemOperand *MMO = MIRBuilder.getMF().getMachineMemOperand(
67+
MPO, MachineMemOperand::MOLoad, Size, Alignment);
68+
MIRBuilder.buildLoad(Val, Addr, *MMO);
69+
}
5170
};
5271

5372
class CallReturnHandler : public IncomingValueHandler {
@@ -57,7 +76,7 @@ class CallReturnHandler : public IncomingValueHandler {
5776
: IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
5877

5978
private:
60-
virtual void markPhysRegUsed(unsigned PhysReg) override {
79+
void markPhysRegUsed(unsigned PhysReg) override {
6180
MIB.addDef(PhysReg, RegState::Implicit);
6281
}
6382

@@ -72,6 +91,26 @@ void IncomingValueHandler::assignValueToReg(unsigned ValVReg,
7291
markPhysRegUsed(PhysReg);
7392
}
7493

94+
unsigned IncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
95+
MachinePointerInfo &MPO) {
96+
MachineFrameInfo &MFI = MIRBuilder.getMF().getFrameInfo();
97+
98+
int FI = MFI.CreateFixedObject(Size, Offset, true);
99+
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
100+
101+
unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
102+
MIRBuilder.buildFrameIndex(AddrReg, FI);
103+
104+
return AddrReg;
105+
}
106+
107+
void IncomingValueHandler::assignValueToAddress(unsigned ValVReg, unsigned Addr,
108+
uint64_t Size,
109+
MachinePointerInfo &MPO) {
110+
// If the value is not extended, a simple load will suffice.
111+
buildLoad(ValVReg, Addr, Size, /* Alignment */ 0, MPO);
112+
}
113+
75114
bool IncomingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
76115
ArrayRef<CallLowering::ArgInfo> Args) {
77116
for (unsigned i = 0, ArgsSize = Args.size(); i < ArgsSize; ++i) {
@@ -92,7 +131,13 @@ class OutgoingValueHandler : public MipsCallLowering::MipsHandler {
92131
ArrayRef<CallLowering::ArgInfo> Args);
93132

94133
private:
95-
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
134+
void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
135+
136+
unsigned getStackAddress(uint64_t Size, int64_t Offset,
137+
MachinePointerInfo &MPO) override;
138+
139+
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
140+
MachinePointerInfo &MPO) override;
96141

97142
MachineInstrBuilder &MIB;
98143
};
@@ -104,6 +149,31 @@ void OutgoingValueHandler::assignValueToReg(unsigned ValVReg,
104149
MIB.addUse(PhysReg, RegState::Implicit);
105150
}
106151

152+
unsigned OutgoingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
153+
MachinePointerInfo &MPO) {
154+
LLT p0 = LLT::pointer(0, 32);
155+
LLT s32 = LLT::scalar(32);
156+
unsigned SPReg = MRI.createGenericVirtualRegister(p0);
157+
MIRBuilder.buildCopy(SPReg, Mips::SP);
158+
159+
unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
160+
MIRBuilder.buildConstant(OffsetReg, Offset);
161+
162+
unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
163+
MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
164+
165+
MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
166+
return AddrReg;
167+
}
168+
169+
void OutgoingValueHandler::assignValueToAddress(unsigned ValVReg, unsigned Addr,
170+
uint64_t Size,
171+
MachinePointerInfo &MPO) {
172+
MachineMemOperand *MMO = MIRBuilder.getMF().getMachineMemOperand(
173+
MPO, MachineMemOperand::MOStore, Size, /* Alignment */ 0);
174+
MIRBuilder.buildStore(ValVReg, Addr, *MMO);
175+
}
176+
107177
bool OutgoingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
108178
ArrayRef<CallLowering::ArgInfo> Args) {
109179
for (unsigned i = 0; i < Args.size(); ++i) {
@@ -205,6 +275,11 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
205275
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
206276
F.getContext());
207277

278+
const MipsTargetMachine &TM =
279+
static_cast<const MipsTargetMachine &>(MF.getTarget());
280+
const MipsABIInfo &ABI = TM.getABI();
281+
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
282+
1);
208283
CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());
209284

210285
IncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
@@ -281,6 +356,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
281356
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
282357
F.getContext());
283358

359+
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1);
284360
const char *Call = Callee.isSymbol() ? Callee.getSymbolName() : nullptr;
285361
CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
286362

@@ -289,8 +365,12 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
289365
return false;
290366
}
291367

292-
// TODO: Calculate stack offset.
293-
CallSeqStart.addImm(ABI.GetCalleeAllocdArgSizeInBytes(CallConv)).addImm(0);
368+
unsigned NextStackOffset = CCInfo.getNextStackOffset();
369+
const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
370+
unsigned StackAlignment = TFL->getStackAlignment();
371+
NextStackOffset = alignTo(NextStackOffset, StackAlignment);
372+
CallSeqStart.addImm(NextStackOffset).addImm(0);
373+
294374
MIRBuilder.insertInstr(MIB);
295375

296376
if (OrigRet.Reg) {
@@ -319,9 +399,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
319399
return false;
320400
}
321401

322-
MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP)
323-
.addImm(ABI.GetCalleeAllocdArgSizeInBytes(CallConv))
324-
.addImm(0);
402+
MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0);
325403

326404
return true;
327405
}

lib/Target/Mips/MipsCallLowering.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,20 @@ class MipsCallLowering : public CallLowering {
3232
virtual ~MipsHandler() = default;
3333

3434
protected:
35-
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) = 0;
36-
3735
bool assign(const CCValAssign &VA, unsigned vreg);
3836

3937
MachineIRBuilder &MIRBuilder;
4038
MachineRegisterInfo &MRI;
39+
40+
private:
41+
virtual unsigned getStackAddress(uint64_t Size, int64_t Offset,
42+
MachinePointerInfo &MPO) = 0;
43+
44+
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) = 0;
45+
46+
virtual void assignValueToAddress(unsigned ValVReg, unsigned Addr,
47+
uint64_t Size,
48+
MachinePointerInfo &MPO) = 0;
4149
};
4250

4351
MipsCallLowering(const MipsTargetLowering &TLI);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
3+
4+
declare i32 @f(i32, i32, i32, i32, i32)
5+
6+
define i32 @g(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5){
7+
; MIPS32-LABEL: name: g
8+
; MIPS32: bb.1.entry:
9+
; MIPS32: liveins: $a0, $a1, $a2, $a3
10+
; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
11+
; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
12+
; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
13+
; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
14+
; MIPS32: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
15+
; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 0)
16+
; MIPS32: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
17+
; MIPS32: $a0 = COPY [[COPY]](s32)
18+
; MIPS32: $a1 = COPY [[COPY1]](s32)
19+
; MIPS32: $a2 = COPY [[COPY2]](s32)
20+
; MIPS32: $a3 = COPY [[COPY3]](s32)
21+
; MIPS32: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
22+
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
23+
; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY4]], [[C]](s32)
24+
; MIPS32: G_STORE [[LOAD]](s32), [[GEP]](p0) :: (store 4 into stack + 16, align 0)
25+
; MIPS32: JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
26+
; MIPS32: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
27+
; MIPS32: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
28+
; MIPS32: $v0 = COPY [[COPY5]](s32)
29+
; MIPS32: RetRA implicit $v0
30+
entry:
31+
%call = call i32 @f(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5)
32+
ret i32 %call
33+
}

0 commit comments

Comments
 (0)