summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp144
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.h27
2 files changed, 110 insertions, 61 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index 648dec5428d..8babdbf902a 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -36,15 +36,58 @@ bool MipsCallLowering::MipsHandler::assign(unsigned VReg,
return true;
}
+bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<unsigned> VRegs,
+ ArrayRef<CCValAssign> ArgLocs,
+ unsigned ArgLocsStartIndex) {
+ for (unsigned i = 0; i < VRegs.size(); ++i)
+ if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i]))
+ return false;
+ return true;
+}
+
+void MipsCallLowering::MipsHandler::setMostSignificantFirst(
+ SmallVectorImpl<unsigned> &VRegs) {
+ if (MIRBuilder.getMF().getDataLayout().isLittleEndian())
+ std::reverse(VRegs.begin(), VRegs.end());
+}
+
+bool MipsCallLowering::MipsHandler::handle(
+ ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) {
+ SmallVector<unsigned, 4> VRegs;
+ unsigned SplitLength;
+ const Function &F = MIRBuilder.getMF().getFunction();
+ const DataLayout &DL = F.getParent()->getDataLayout();
+ const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>(
+ MIRBuilder.getMF().getSubtarget().getTargetLowering());
+
+ for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size();
+ ++ArgsIndex, ArgLocsIndex += SplitLength) {
+ EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty);
+ SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(),
+ F.getCallingConv(), VT);
+ if (SplitLength > 1) {
+ VRegs.clear();
+ MVT RegisterVT = TLI.getRegisterTypeForCallingConv(
+ F.getContext(), F.getCallingConv(), VT);
+ for (unsigned i = 0; i < SplitLength; ++i)
+ VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT}));
+
+ if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg))
+ return false;
+ } else {
+ if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex]))
+ return false;
+ }
+ }
+ return true;
+}
+
namespace {
class IncomingValueHandler : public MipsCallLowering::MipsHandler {
public:
IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
: MipsHandler(MIRBuilder, MRI) {}
- bool handle(ArrayRef<CCValAssign> ArgLocs,
- ArrayRef<CallLowering::ArgInfo> Args);
-
private:
void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
@@ -53,6 +96,10 @@ private:
void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
+ bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
+ ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
+ unsigned ArgsReg) override;
+
virtual void markPhysRegUsed(unsigned PhysReg) {
MIRBuilder.getMBB().addLiveIn(PhysReg);
}
@@ -128,12 +175,14 @@ void IncomingValueHandler::assignValueToAddress(unsigned ValVReg,
buildLoad(ValVReg, VA);
}
-bool IncomingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
- ArrayRef<CallLowering::ArgInfo> Args) {
- for (unsigned i = 0, ArgsSize = Args.size(); i < ArgsSize; ++i) {
- if (!assign(Args[i].Reg, ArgLocs[i]))
- return false;
- }
+bool IncomingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs,
+ ArrayRef<CCValAssign> ArgLocs,
+ unsigned ArgLocsStartIndex,
+ unsigned ArgsReg) {
+ if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex))
+ return false;
+ setMostSignificantFirst(VRegs);
+ MIRBuilder.buildMerge(ArgsReg, VRegs);
return true;
}
@@ -144,9 +193,6 @@ public:
MachineInstrBuilder &MIB)
: MipsHandler(MIRBuilder, MRI), MIB(MIB) {}
- bool handle(ArrayRef<CCValAssign> ArgLocs,
- ArrayRef<CallLowering::ArgInfo> Args);
-
private:
void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
@@ -155,6 +201,10 @@ private:
void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
+ bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
+ ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
+ unsigned ArgsReg) override;
+
unsigned extendRegister(unsigned ValReg, const CCValAssign &VA);
MachineInstrBuilder &MIB;
@@ -228,17 +278,20 @@ unsigned OutgoingValueHandler::extendRegister(unsigned ValReg,
llvm_unreachable("unable to extend register");
}
-bool OutgoingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
- ArrayRef<CallLowering::ArgInfo> Args) {
- for (unsigned i = 0; i < Args.size(); ++i) {
- if (!assign(Args[i].Reg, ArgLocs[i]))
- return false;
- }
+bool OutgoingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs,
+ ArrayRef<CCValAssign> ArgLocs,
+ unsigned ArgLocsStartIndex,
+ unsigned ArgsReg) {
+ MIRBuilder.buildUnmerge(VRegs, ArgsReg);
+ setMostSignificantFirst(VRegs);
+ if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex))
+ return false;
+
return true;
}
static bool isSupportedType(Type *T) {
- if (T->isIntegerTy() && T->getScalarSizeInBits() <= 32)
+ if (T->isIntegerTy())
return true;
if (T->isPointerTy())
return true;
@@ -247,7 +300,9 @@ static bool isSupportedType(Type *T) {
CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT,
const ISD::ArgFlagsTy &Flags) {
- if (VT.getSizeInBits() == RegisterVT.getSizeInBits())
+ // > does not mean loss of information as type RegisterVT can't hold type VT,
+ // it means that type VT is split into multiple registers of type RegisterVT
+ if (VT.getSizeInBits() >= RegisterVT.getSizeInBits())
return CCValAssign::LocInfo::Full;
if (Flags.isSExt())
return CCValAssign::LocInfo::SExt;
@@ -304,12 +359,7 @@ bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
}
SmallVector<ISD::OutputArg, 8> Outs;
- subTargetRegTypeForCallingConv(
- MIRBuilder, RetInfos, OrigArgIndices,
- [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
- unsigned origIdx, unsigned partOffs) {
- Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
- });
+ subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs);
SmallVector<CCValAssign, 16> ArgLocs;
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -358,12 +408,7 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
}
SmallVector<ISD::InputArg, 8> Ins;
- subTargetRegTypeForCallingConv(
- MIRBuilder, ArgInfos, OrigArgIndices,
- [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
- unsigned partOffs) {
- Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
- });
+ subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins);
SmallVector<CCValAssign, 16> ArgLocs;
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -440,12 +485,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
}
SmallVector<ISD::OutputArg, 8> Outs;
- subTargetRegTypeForCallingConv(
- MIRBuilder, ArgInfos, OrigArgIndices,
- [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
- unsigned partOffs) {
- Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
- });
+ subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
SmallVector<CCValAssign, 8> ArgLocs;
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -477,12 +517,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
splitToValueTypes(OrigRet, 0, ArgInfos, OrigRetIndices);
SmallVector<ISD::InputArg, 8> Ins;
- subTargetRegTypeForCallingConv(
- MIRBuilder, ArgInfos, OrigRetIndices,
- [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
- unsigned origIdx, unsigned partOffs) {
- Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
- });
+ subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins);
SmallVector<CCValAssign, 8> ArgLocs;
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -501,11 +536,10 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
return true;
}
+template <typename T>
void MipsCallLowering::subTargetRegTypeForCallingConv(
- MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
- ArrayRef<unsigned> OrigArgIndices, const FunTy &PushBack) const {
- MachineFunction &MF = MIRBuilder.getMF();
- const Function &F = MF.getFunction();
+ const Function &F, ArrayRef<ArgInfo> Args,
+ ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
const DataLayout &DL = F.getParent()->getDataLayout();
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
@@ -515,12 +549,20 @@ void MipsCallLowering::subTargetRegTypeForCallingConv(
EVT VT = TLI.getValueType(DL, Arg.Ty);
MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
F.getCallingConv(), VT);
+ unsigned NumRegs = TLI.getNumRegistersForCallingConv(
+ F.getContext(), F.getCallingConv(), VT);
- ISD::ArgFlagsTy Flags = Arg.Flags;
- Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
+ for (unsigned i = 0; i < NumRegs; ++i) {
+ ISD::ArgFlagsTy Flags = Arg.Flags;
- PushBack(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo], 0);
+ if (i == 0)
+ Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
+ else
+ Flags.setOrigAlign(1);
+ ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
+ 0);
+ }
++ArgNo;
}
}
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.h b/llvm/lib/Target/Mips/MipsCallLowering.h
index 6481e4258cf..389db3a3b68 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.h
+++ b/llvm/lib/Target/Mips/MipsCallLowering.h
@@ -31,13 +31,21 @@ public:
virtual ~MipsHandler() = default;
+ bool handle(ArrayRef<CCValAssign> ArgLocs,
+ ArrayRef<CallLowering::ArgInfo> Args);
+
protected:
- bool assign(unsigned VReg, const CCValAssign &VA);
+ bool assignVRegs(ArrayRef<unsigned> VRegs, ArrayRef<CCValAssign> ArgLocs,
+ unsigned Index);
+
+ void setMostSignificantFirst(SmallVectorImpl<unsigned> &VRegs);
MachineIRBuilder &MIRBuilder;
MachineRegisterInfo &MRI;
private:
+ bool assign(unsigned VReg, const CCValAssign &VA);
+
virtual unsigned getStackAddress(const CCValAssign &VA,
MachineMemOperand *&MMO) = 0;
@@ -45,6 +53,10 @@ public:
virtual void assignValueToAddress(unsigned ValVReg,
const CCValAssign &VA) = 0;
+
+ virtual bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
+ ArrayRef<CCValAssign> ArgLocs,
+ unsigned ArgLocsStartIndex, unsigned ArgsReg) = 0;
};
MipsCallLowering(const MipsTargetLowering &TLI);
@@ -60,18 +72,13 @@ public:
ArrayRef<ArgInfo> OrigArgs) const override;
private:
- using FunTy =
- std::function<void(ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
- unsigned origIdx, unsigned partOffs)>;
-
/// Based on registers available on target machine split or extend
/// type if needed, also change pointer type to appropriate integer
- /// type. Lambda will fill some info so we can tell MipsCCState to
- /// assign physical registers.
- void subTargetRegTypeForCallingConv(MachineIRBuilder &MIRBuilder,
- ArrayRef<ArgInfo> Args,
+ /// type.
+ template <typename T>
+ void subTargetRegTypeForCallingConv(const Function &F, ArrayRef<ArgInfo> Args,
ArrayRef<unsigned> OrigArgIndices,
- const FunTy &PushBack) const;
+ SmallVectorImpl<T> &ISDArgs) const;
/// Split structures and arrays, save original argument indices since
/// Mips calling conv needs info about original argument type.
OpenPOWER on IntegriCloud