Skip to content

Commit c72e2a4

Browse files
Alexander Ivchenkohyp
authored andcommitted
[GlobalISel] Rewrite CallLowering::lowerReturn to accept multiple VRegs per Value
This is logical continuation of https://reviews.llvm.org/D46018 (r332449) Differential Revision: https://reviews.llvm.org/D49660 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338685 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit 8c575a1)
1 parent e54c6a4 commit c72e2a4

File tree

16 files changed

+425
-128
lines changed

16 files changed

+425
-128
lines changed

include/llvm/CodeGen/GlobalISel/CallLowering.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,12 @@ class CallLowering {
138138
virtual ~CallLowering() = default;
139139

140140
/// This hook must be implemented to lower outgoing return values, described
141-
/// by \p Val, into the specified virtual register \p VReg.
141+
/// by \p Val, into the specified virtual registers \p VRegs.
142142
/// This hook is used by GlobalISel.
143143
///
144144
/// \return True if the lowering succeeds, false otherwise.
145-
virtual bool lowerReturn(MachineIRBuilder &MIRBuilder,
146-
const Value *Val, unsigned VReg) const {
145+
virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
146+
ArrayRef<unsigned> VRegs) const {
147147
return false;
148148
}
149149

lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,16 @@ bool IRTranslator::translateRet(const User &U, MachineIRBuilder &MIRBuilder) {
323323
const Value *Ret = RI.getReturnValue();
324324
if (Ret && DL->getTypeStoreSize(Ret->getType()) == 0)
325325
Ret = nullptr;
326+
327+
ArrayRef<unsigned> VRegs;
328+
if (Ret)
329+
VRegs = getOrCreateVRegs(*Ret);
330+
326331
// The target may mess up with the insertion point, but
327332
// this is not important as a return is the last instruction
328333
// of the block anyway.
329334

330-
// FIXME: this interface should simplify when CallLowering gets adapted to
331-
// multiple VRegs per Value.
332-
unsigned VReg = Ret ? packRegs(*Ret, MIRBuilder) : 0;
333-
return CLI->lowerReturn(MIRBuilder, Ret, VReg);
335+
return CLI->lowerReturn(MIRBuilder, Ret, VRegs);
334336
}
335337

336338
bool IRTranslator::translateBr(const User &U, MachineIRBuilder &MIRBuilder) {

lib/Target/AArch64/AArch64CallLowering.cpp

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -227,32 +227,45 @@ void AArch64CallLowering::splitToValueTypes(
227227
}
228228

229229
bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
230-
const Value *Val, unsigned VReg) const {
231-
MachineFunction &MF = MIRBuilder.getMF();
232-
const Function &F = MF.getFunction();
233-
230+
const Value *Val,
231+
ArrayRef<unsigned> VRegs) const {
234232
auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
235-
assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
236-
bool Success = true;
237-
if (VReg) {
238-
MachineRegisterInfo &MRI = MF.getRegInfo();
233+
assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
234+
"Return value without a vreg");
239235

240-
// We zero-extend i1s to i8.
241-
if (MRI.getType(VReg).getSizeInBits() == 1)
242-
VReg = MIRBuilder.buildZExt(LLT::scalar(8), VReg)->getOperand(0).getReg();
236+
bool Success = true;
237+
if (!VRegs.empty()) {
238+
MachineFunction &MF = MIRBuilder.getMF();
239+
const Function &F = MF.getFunction();
243240

241+
MachineRegisterInfo &MRI = MF.getRegInfo();
244242
const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
245243
CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
246244
auto &DL = F.getParent()->getDataLayout();
245+
LLVMContext &Ctx = Val->getType()->getContext();
247246

248-
ArgInfo OrigArg{VReg, Val->getType()};
249-
setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
247+
SmallVector<EVT, 4> SplitEVTs;
248+
ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
249+
assert(VRegs.size() == SplitEVTs.size() &&
250+
"For each split Type there should be exactly one VReg.");
250251

251252
SmallVector<ArgInfo, 8> SplitArgs;
252-
splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv(),
253-
[&](unsigned Reg, uint64_t Offset) {
254-
MIRBuilder.buildExtract(Reg, VReg, Offset);
255-
});
253+
for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
254+
// We zero-extend i1s to i8.
255+
unsigned CurVReg = VRegs[i];
256+
if (MRI.getType(VRegs[i]).getSizeInBits() == 1) {
257+
CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg)
258+
->getOperand(0)
259+
.getReg();
260+
}
261+
262+
ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx)};
263+
setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
264+
splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, F.getCallingConv(),
265+
[&](unsigned Reg, uint64_t Offset) {
266+
MIRBuilder.buildExtract(Reg, CurVReg, Offset);
267+
});
268+
}
256269

257270
OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn);
258271
Success = handleAssignments(MIRBuilder, SplitArgs, Handler);

lib/Target/AArch64/AArch64CallLowering.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class AArch64CallLowering: public CallLowering {
3434
public:
3535
AArch64CallLowering(const AArch64TargetLowering &TLI);
3636

37-
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
38-
unsigned VReg) const override;
37+
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
38+
ArrayRef<unsigned> VRegs) const override;
3939

4040
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
4141
ArrayRef<unsigned> VRegs) const override;

lib/Target/AMDGPU/AMDGPUCallLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
3232
}
3333

3434
bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
35-
const Value *Val, unsigned VReg) const {
35+
const Value *Val,
36+
ArrayRef<unsigned> VRegs) const {
3637
// FIXME: Add support for non-void returns.
3738
if (Val)
3839
return false;

lib/Target/AMDGPU/AMDGPUCallLowering.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class AMDGPUCallLowering: public CallLowering {
3535
public:
3636
AMDGPUCallLowering(const AMDGPUTargetLowering &TLI);
3737

38-
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
39-
unsigned VReg) const override;
38+
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
39+
ArrayRef<unsigned> VRegs) const override;
4040
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
4141
ArrayRef<unsigned> VRegs) const override;
4242
static CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg);

lib/Target/ARM/ARMCallLowering.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ void ARMCallLowering::splitToValueTypes(
237237
/// Lower the return value for the already existing \p Ret. This assumes that
238238
/// \p MIRBuilder's insertion point is correct.
239239
bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
240-
const Value *Val, unsigned VReg,
240+
const Value *Val, ArrayRef<unsigned> VRegs,
241241
MachineInstrBuilder &Ret) const {
242242
if (!Val)
243243
// Nothing to do here.
@@ -251,16 +251,24 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
251251
if (!isSupportedType(DL, TLI, Val->getType()))
252252
return false;
253253

254-
SmallVector<ArgInfo, 4> SplitVTs;
255-
SmallVector<unsigned, 4> Regs;
256-
ArgInfo RetInfo(VReg, Val->getType());
257-
setArgFlags(RetInfo, AttributeList::ReturnIndex, DL, F);
258-
splitToValueTypes(RetInfo, SplitVTs, MF, [&](unsigned Reg, uint64_t Offset) {
259-
Regs.push_back(Reg);
260-
});
254+
SmallVector<EVT, 4> SplitEVTs;
255+
ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
256+
assert(VRegs.size() == SplitEVTs.size() &&
257+
"For each split Type there should be exactly one VReg.");
261258

262-
if (Regs.size() > 1)
263-
MIRBuilder.buildUnmerge(Regs, VReg);
259+
SmallVector<ArgInfo, 4> SplitVTs;
260+
LLVMContext &Ctx = Val->getType()->getContext();
261+
for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
262+
ArgInfo CurArgInfo(VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx));
263+
setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
264+
265+
SmallVector<unsigned, 4> Regs;
266+
splitToValueTypes(
267+
CurArgInfo, SplitVTs, MF,
268+
[&](unsigned Reg, uint64_t Offset) { Regs.push_back(Reg); });
269+
if (Regs.size() > 1)
270+
MIRBuilder.buildUnmerge(Regs, VRegs[i]);
271+
}
264272

265273
CCAssignFn *AssignFn =
266274
TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
@@ -270,14 +278,15 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
270278
}
271279

272280
bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
273-
const Value *Val, unsigned VReg) const {
274-
assert(!Val == !VReg && "Return value without a vreg");
281+
const Value *Val,
282+
ArrayRef<unsigned> VRegs) const {
283+
assert(!Val == VRegs.empty() && "Return value without a vreg");
275284

276285
auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
277286
unsigned Opcode = ST.getReturnOpcode();
278287
auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
279288

280-
if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
289+
if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
281290
return false;
282291

283292
MIRBuilder.insertInstr(Ret);

lib/Target/ARM/ARMCallLowering.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ class ARMCallLowering : public CallLowering {
3333
public:
3434
ARMCallLowering(const ARMTargetLowering &TLI);
3535

36-
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
37-
unsigned VReg) const override;
36+
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
37+
ArrayRef<unsigned> VRegs) const override;
3838

3939
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
4040
ArrayRef<unsigned> VRegs) const override;
@@ -45,7 +45,8 @@ class ARMCallLowering : public CallLowering {
4545

4646
private:
4747
bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val,
48-
unsigned VReg, MachineInstrBuilder &Ret) const;
48+
ArrayRef<unsigned> VRegs,
49+
MachineInstrBuilder &Ret) const;
4950

5051
using SplitArgTy = std::function<void(unsigned Reg, uint64_t Offset)>;
5152

lib/Target/Mips/MipsCallLowering.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "MipsCallLowering.h"
1717
#include "MipsCCState.h"
1818
#include "MipsTargetMachine.h"
19+
#include "llvm/CodeGen/Analysis.h"
1920
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2021

2122
using namespace llvm;
@@ -192,25 +193,34 @@ static bool isSupportedType(Type *T) {
192193
}
193194

194195
bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
195-
const Value *Val, unsigned VReg) const {
196+
const Value *Val,
197+
ArrayRef<unsigned> VRegs) const {
196198

197199
MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
198200

199-
if (Val != nullptr) {
200-
if (!isSupportedType(Val->getType()))
201-
return false;
201+
if (Val != nullptr && !isSupportedType(Val->getType()))
202+
return false;
202203

204+
if (!VRegs.empty()) {
203205
MachineFunction &MF = MIRBuilder.getMF();
204206
const Function &F = MF.getFunction();
205207
const DataLayout &DL = MF.getDataLayout();
206208
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
209+
LLVMContext &Ctx = Val->getType()->getContext();
210+
211+
SmallVector<EVT, 4> SplitEVTs;
212+
ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
213+
assert(VRegs.size() == SplitEVTs.size() &&
214+
"For each split Type there should be exactly one VReg.");
207215

208216
SmallVector<ArgInfo, 8> RetInfos;
209217
SmallVector<unsigned, 8> OrigArgIndices;
210218

211-
ArgInfo ArgRetInfo(VReg, Val->getType());
212-
setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);
213-
splitToValueTypes(ArgRetInfo, 0, RetInfos, OrigArgIndices);
219+
for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
220+
ArgInfo CurArgInfo = ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)};
221+
setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
222+
splitToValueTypes(CurArgInfo, 0, RetInfos, OrigArgIndices);
223+
}
214224

215225
SmallVector<ISD::OutputArg, 8> Outs;
216226
subTargetRegTypeForCallingConv(

lib/Target/Mips/MipsCallLowering.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class MipsCallLowering : public CallLowering {
5050

5151
MipsCallLowering(const MipsTargetLowering &TLI);
5252

53-
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
54-
unsigned VReg) const override;
53+
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
54+
ArrayRef<unsigned> VRegs) const;
5555

5656
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
5757
ArrayRef<unsigned> VRegs) const override;

0 commit comments

Comments
 (0)