mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-22 11:55:12 +00:00
[GlobalISel] Allow multiple VRegs in ArgInfo. NFC
Allow CallLowering::ArgInfo to contain more than one virtual register. This is useful when passes split aggregates into several virtual registers, but need to also provide information about the original type to the call lowering. Used in follow-up patches. Differential Revision: https://reviews.llvm.org/D63548 llvm-svn: 364509
This commit is contained in:
parent
12313627d3
commit
18237a33fd
@ -15,6 +15,7 @@
|
||||
#define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/TargetCallingConv.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
@ -42,15 +43,17 @@ class CallLowering {
|
||||
virtual void anchor();
|
||||
public:
|
||||
struct ArgInfo {
|
||||
Register Reg;
|
||||
SmallVector<Register, 4> Regs;
|
||||
Type *Ty;
|
||||
ISD::ArgFlagsTy Flags;
|
||||
bool IsFixed;
|
||||
|
||||
ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{},
|
||||
bool IsFixed = true)
|
||||
: Reg(Reg), Ty(Ty), Flags(Flags), IsFixed(IsFixed) {
|
||||
assert((Ty->isVoidTy() == (Reg == 0)) &&
|
||||
ArgInfo(ArrayRef<Register> Regs, Type *Ty,
|
||||
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}, bool IsFixed = true)
|
||||
: Regs(Regs.begin(), Regs.end()), Ty(Ty), Flags(Flags),
|
||||
IsFixed(IsFixed) {
|
||||
assert(Regs.size() == 1 && "Can't handle multiple regs yet");
|
||||
assert((Ty->isVoidTy() == (Regs[0] == 0)) &&
|
||||
"only void types should have no register");
|
||||
}
|
||||
};
|
||||
|
@ -150,6 +150,12 @@ bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(Args[i].Regs.size() == 1 &&
|
||||
"Can't handle multiple virtual regs yet");
|
||||
|
||||
// FIXME: Pack registers if we have more than one.
|
||||
unsigned ArgReg = Args[i].Regs[0];
|
||||
|
||||
if (VA.isRegLoc()) {
|
||||
MVT OrigVT = MVT::getVT(Args[i].Ty);
|
||||
MVT VAVT = VA.getValVT();
|
||||
@ -172,12 +178,12 @@ bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
|
||||
return false;
|
||||
}
|
||||
auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
|
||||
MIRBuilder.buildCopy(Args[i].Reg, Unmerge.getReg(0));
|
||||
MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
|
||||
} else {
|
||||
MIRBuilder.buildTrunc(Args[i].Reg, {NewReg}).getReg(0);
|
||||
MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
|
||||
}
|
||||
} else {
|
||||
Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
|
||||
Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
|
||||
}
|
||||
} else if (VA.isMemLoc()) {
|
||||
MVT VT = MVT::getVT(Args[i].Ty);
|
||||
@ -186,7 +192,7 @@ bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
|
||||
unsigned Offset = VA.getLocMemOffset();
|
||||
MachinePointerInfo MPO;
|
||||
unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO);
|
||||
Handler.assignValueToAddress(Args[i].Reg, StackAddr, Size, MPO, VA);
|
||||
Handler.assignValueToAddress(ArgReg, StackAddr, Size, MPO, VA);
|
||||
} else {
|
||||
// FIXME: Support byvals and other weirdness
|
||||
return false;
|
||||
|
@ -1160,7 +1160,7 @@ bool IRTranslator::translateMemfunc(const CallInst &CI,
|
||||
|
||||
return CLI->lowerCall(MIRBuilder, CI.getCallingConv(),
|
||||
MachineOperand::CreateES(Callee),
|
||||
CallLowering::ArgInfo(0, CI.getType()), Args);
|
||||
CallLowering::ArgInfo({0}, CI.getType()), Args);
|
||||
}
|
||||
|
||||
void IRTranslator::getStackGuard(Register DstReg,
|
||||
|
@ -203,11 +203,12 @@ void AArch64CallLowering::splitToValueTypes(
|
||||
SmallVector<EVT, 4> SplitVTs;
|
||||
SmallVector<uint64_t, 4> Offsets;
|
||||
ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
|
||||
assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
if (SplitVTs.size() == 1) {
|
||||
// No splitting to do, but we want to replace the original type (e.g. [1 x
|
||||
// double] -> double).
|
||||
SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx),
|
||||
SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
|
||||
OrigArg.Flags, OrigArg.IsFixed);
|
||||
return;
|
||||
}
|
||||
@ -227,7 +228,7 @@ void AArch64CallLowering::splitToValueTypes(
|
||||
SplitArgs.back().Flags.setInConsecutiveRegsLast();
|
||||
|
||||
for (unsigned i = 0; i < Offsets.size(); ++i)
|
||||
PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8);
|
||||
PerformArgSplit(SplitArgs[FirstRegIdx + i].Regs[0], Offsets[i] * 8);
|
||||
}
|
||||
|
||||
bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
|
||||
@ -326,8 +327,8 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CurVReg != CurArgInfo.Reg) {
|
||||
CurArgInfo.Reg = CurVReg;
|
||||
if (CurVReg != CurArgInfo.Regs[0]) {
|
||||
CurArgInfo.Regs[0] = CurVReg;
|
||||
// Reset the arg flags after modifying CurVReg.
|
||||
setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
|
||||
}
|
||||
@ -435,9 +436,10 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
|
||||
SmallVector<ArgInfo, 8> SplitArgs;
|
||||
for (auto &OrigArg : OrigArgs) {
|
||||
assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
splitToValueTypes(OrigArg, SplitArgs, DL, MRI, CallConv,
|
||||
[&](Register Reg, uint64_t Offset) {
|
||||
MIRBuilder.buildExtract(Reg, OrigArg.Reg, Offset);
|
||||
MIRBuilder.buildExtract(Reg, OrigArg.Regs[0], Offset);
|
||||
});
|
||||
// AAPCS requires that we zero-extend i1 to 8 bits by the caller.
|
||||
if (OrigArg.Ty->isIntegerTy(1))
|
||||
@ -491,7 +493,8 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
// symmetry with the arugments, the physical register must be an
|
||||
// implicit-define of the call instruction.
|
||||
CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
|
||||
if (OrigRet.Reg) {
|
||||
assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
if (OrigRet.Regs[0]) {
|
||||
SplitArgs.clear();
|
||||
|
||||
SmallVector<uint64_t, 8> RegOffsets;
|
||||
@ -507,7 +510,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
return false;
|
||||
|
||||
if (!RegOffsets.empty())
|
||||
MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets);
|
||||
MIRBuilder.buildSequence(OrigRet.Regs[0], SplitRegs, RegOffsets);
|
||||
}
|
||||
|
||||
if (SwiftErrorVReg) {
|
||||
|
@ -137,6 +137,8 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {
|
||||
|
||||
unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
|
||||
ArrayRef<CCValAssign> VAs) override {
|
||||
assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
CCValAssign VA = VAs[0];
|
||||
assert(VA.needsCustom() && "Value doesn't need custom handling");
|
||||
assert(VA.getValVT() == MVT::f64 && "Unsupported type");
|
||||
@ -153,7 +155,7 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {
|
||||
|
||||
Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
|
||||
MRI.createGenericVirtualRegister(LLT::scalar(32))};
|
||||
MIRBuilder.buildUnmerge(NewRegs, Arg.Reg);
|
||||
MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
|
||||
|
||||
bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
|
||||
if (!IsLittle)
|
||||
@ -193,6 +195,7 @@ void ARMCallLowering::splitToValueTypes(
|
||||
|
||||
SmallVector<EVT, 4> SplitVTs;
|
||||
ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, nullptr, nullptr, 0);
|
||||
assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
if (SplitVTs.size() == 1) {
|
||||
// Even if there is no splitting to do, we still want to replace the
|
||||
@ -200,8 +203,8 @@ void ARMCallLowering::splitToValueTypes(
|
||||
auto Flags = OrigArg.Flags;
|
||||
unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty);
|
||||
Flags.setOrigAlign(OriginalAlignment);
|
||||
SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags,
|
||||
OrigArg.IsFixed);
|
||||
SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
|
||||
Flags, OrigArg.IsFixed);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -222,7 +225,7 @@ void ARMCallLowering::splitToValueTypes(
|
||||
Flags.setInConsecutiveRegsLast();
|
||||
}
|
||||
|
||||
unsigned PartReg =
|
||||
Register PartReg =
|
||||
MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL));
|
||||
SplitArgs.push_back(ArgInfo{PartReg, SplitTy, Flags, OrigArg.IsFixed});
|
||||
PerformArgSplit(PartReg);
|
||||
@ -372,6 +375,8 @@ struct IncomingValueHandler : public CallLowering::ValueHandler {
|
||||
|
||||
unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
|
||||
ArrayRef<CCValAssign> VAs) override {
|
||||
assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
CCValAssign VA = VAs[0];
|
||||
assert(VA.needsCustom() && "Value doesn't need custom handling");
|
||||
assert(VA.getValVT() == MVT::f64 && "Unsupported type");
|
||||
@ -396,7 +401,7 @@ struct IncomingValueHandler : public CallLowering::ValueHandler {
|
||||
if (!IsLittle)
|
||||
std::swap(NewRegs[0], NewRegs[1]);
|
||||
|
||||
MIRBuilder.buildMerge(Arg.Reg, NewRegs);
|
||||
MIRBuilder.buildMerge(Arg.Regs[0], NewRegs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -568,12 +573,14 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
if (Arg.Flags.isByVal())
|
||||
return false;
|
||||
|
||||
assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
SmallVector<Register, 8> Regs;
|
||||
splitToValueTypes(Arg, ArgInfos, MF,
|
||||
[&](unsigned Reg) { Regs.push_back(Reg); });
|
||||
|
||||
if (Regs.size() > 1)
|
||||
MIRBuilder.buildUnmerge(Regs, Arg.Reg);
|
||||
MIRBuilder.buildUnmerge(Regs, Arg.Regs[0]);
|
||||
}
|
||||
|
||||
auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, IsVarArg);
|
||||
@ -601,7 +608,8 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
if (!SplitRegs.empty()) {
|
||||
// We have split the value and allocated each individual piece, now build
|
||||
// it up again.
|
||||
MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs);
|
||||
assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
MIRBuilder.buildMerge(OrigRet.Regs[0], SplitRegs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,8 @@ bool MipsCallLowering::MipsHandler::handle(
|
||||
EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty);
|
||||
SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(),
|
||||
F.getCallingConv(), VT);
|
||||
assert(Args[ArgsIndex].Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
if (SplitLength > 1) {
|
||||
VRegs.clear();
|
||||
MVT RegisterVT = TLI.getRegisterTypeForCallingConv(
|
||||
@ -73,10 +75,11 @@ bool MipsCallLowering::MipsHandler::handle(
|
||||
for (unsigned i = 0; i < SplitLength; ++i)
|
||||
VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT}));
|
||||
|
||||
if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg, VT))
|
||||
if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Regs[0],
|
||||
VT))
|
||||
return false;
|
||||
} else {
|
||||
if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex], VT))
|
||||
if (!assign(Args[ArgsIndex].Regs[0], ArgLocs[ArgLocsIndex], VT))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -510,7 +513,9 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
if (Arg.Flags.isByVal() || Arg.Flags.isSRet())
|
||||
return false;
|
||||
}
|
||||
if (OrigRet.Reg && !isSupportedType(OrigRet.Ty))
|
||||
|
||||
assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
if (OrigRet.Regs[0] && !isSupportedType(OrigRet.Ty))
|
||||
return false;
|
||||
|
||||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
@ -595,8 +600,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
*STI.getRegBankInfo());
|
||||
}
|
||||
|
||||
if (OrigRet.Reg) {
|
||||
|
||||
if (OrigRet.Regs[0]) {
|
||||
ArgInfos.clear();
|
||||
SmallVector<unsigned, 8> OrigRetIndices;
|
||||
|
||||
|
@ -61,6 +61,7 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
|
||||
SmallVector<EVT, 4> SplitVTs;
|
||||
SmallVector<uint64_t, 4> Offsets;
|
||||
ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
|
||||
assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
if (OrigArg.Ty->isVoidTy())
|
||||
return true;
|
||||
@ -70,7 +71,7 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
|
||||
|
||||
if (NumParts == 1) {
|
||||
// replace the original type ( pointer -> GPR ).
|
||||
SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context),
|
||||
SplitArgs.emplace_back(OrigArg.Regs[0], VT.getTypeForEVT(Context),
|
||||
OrigArg.Flags, OrigArg.IsFixed);
|
||||
return true;
|
||||
}
|
||||
@ -85,7 +86,7 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
|
||||
ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)),
|
||||
PartTy, OrigArg.Flags};
|
||||
SplitArgs.push_back(Info);
|
||||
SplitRegs.push_back(Info.Reg);
|
||||
SplitRegs.push_back(Info.Regs[0]);
|
||||
}
|
||||
|
||||
PerformArgSplit(SplitRegs);
|
||||
@ -408,9 +409,10 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
if (OrigArg.Flags.isByVal())
|
||||
return false;
|
||||
|
||||
assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
|
||||
[&](ArrayRef<Register> Regs) {
|
||||
MIRBuilder.buildUnmerge(Regs, OrigArg.Reg);
|
||||
MIRBuilder.buildUnmerge(Regs, OrigArg.Regs[0]);
|
||||
}))
|
||||
return false;
|
||||
}
|
||||
@ -450,7 +452,9 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
// symmetry with the arguments, the physical register must be an
|
||||
// implicit-define of the call instruction.
|
||||
|
||||
if (OrigRet.Reg) {
|
||||
if (!OrigRet.Ty->isVoidTy()) {
|
||||
assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet");
|
||||
|
||||
SplitArgs.clear();
|
||||
SmallVector<Register, 8> NewRegs;
|
||||
|
||||
@ -465,7 +469,7 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
return false;
|
||||
|
||||
if (!NewRegs.empty())
|
||||
MIRBuilder.buildMerge(OrigRet.Reg, NewRegs);
|
||||
MIRBuilder.buildMerge(OrigRet.Regs[0], NewRegs);
|
||||
}
|
||||
|
||||
CallSeqStart.addImm(Handler.getStackSize())
|
||||
|
Loading…
x
Reference in New Issue
Block a user