summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-23 08:11:41 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-23 08:11:41 +0000
commitc063b0b0d3346d2a50e2ef28ec0147d6d53f399d (patch)
tree2a4206617dc800788ca4c826037ce7a2e8a0b9e4 /llvm/lib
parent0e490ae0a93c8b6ec48366ac7d46da442542b902 (diff)
downloadbcm5719-llvm-c063b0b0d3346d2a50e2ef28ec0147d6d53f399d.tar.gz
bcm5719-llvm-c063b0b0d3346d2a50e2ef28ec0147d6d53f399d.zip
[MIPS GlobalISel] VarArg argument lowering, select G_VASTART and vacopy
CC_Mips doesn't accept vararg functions for O32, so we have to explicitly use CC_Mips_FixedArg. For lowerCall we now properly figure out whether callee function is vararg or not, this has no effect for O32 since we always use CC_Mips_FixedArg. For lower formal arguments we need to copy arguments in register to stack and save pointer to start for argument list into MipsMachineFunction object so that G_VASTART could use it during instruction select. For vacopy we need to copy content from one vreg to another, load and store are used for that purpose. Differential Revision: https://reviews.llvm.org/D67756 llvm-svn: 372555
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp45
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsInstructionSelector.cpp23
-rw-r--r--llvm/lib/Target/Mips/MipsLegalizerInfo.cpp15
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp1
5 files changed, 80 insertions, 6 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index aac29967f59..646c4785458 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -454,10 +454,6 @@ bool MipsCallLowering::lowerFormalArguments(
if (F.arg_empty())
return true;
- if (F.isVarArg()) {
- return false;
- }
-
for (auto &Arg : F.args()) {
if (!isSupportedType(Arg.getType()))
return false;
@@ -496,6 +492,40 @@ bool MipsCallLowering::lowerFormalArguments(
if (!Handler.handle(ArgLocs, ArgInfos))
return false;
+ if (F.isVarArg()) {
+ ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
+ unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
+
+ int VaArgOffset;
+ unsigned RegSize = 4;
+ if (ArgRegs.size() == Idx)
+ VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize);
+ else {
+ VaArgOffset =
+ (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
+ (int)(RegSize * (ArgRegs.size() - Idx));
+ }
+
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
+ MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
+
+ for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
+ MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
+
+ MachineInstrBuilder Copy =
+ MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I]));
+ FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
+ MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI);
+ MachineInstrBuilder FrameIndex =
+ MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI);
+ MachineMemOperand *MMO =
+ MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, RegSize,
+ /* Alignment */ RegSize);
+ MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
+ }
+ }
+
return true;
}
@@ -566,7 +596,12 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
SmallVector<CCValAssign, 8> ArgLocs;
- MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
+ bool IsCalleeVarArg = false;
+ if (Info.Callee.isGlobal()) {
+ const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
+ IsCalleeVarArg = CF->isVarArg();
+ }
+ MipsCCState CCInfo(F.getCallingConv(), IsCalleeVarArg, MF, ArgLocs,
F.getContext());
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), 1);
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index c22b00a479a..57e2c88b2ab 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -2869,7 +2869,7 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,
#include "MipsGenCallingConv.inc"
CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{
- return CC_Mips;
+ return CC_Mips_FixedArg;
}
CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 524a58b2d3e..33e2d2ac4c5 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -773,6 +773,29 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
break;
}
+ case G_VASTART: {
+ MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
+ int FI = FuncInfo->getVarArgsFrameIndex();
+
+ Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
+ MachineInstr *LEA_ADDiu =
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
+ .addDef(LeaReg)
+ .addFrameIndex(FI)
+ .addImm(0);
+ if (!constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI))
+ return false;
+
+ MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
+ .addUse(LeaReg)
+ .addUse(I.getOperand(0).getReg())
+ .addImm(0);
+ if (!constrainSelectedInstRegOperands(*Store, TII, TRI, RBI))
+ return false;
+
+ I.eraseFromParent();
+ return true;
+ }
default:
return false;
}
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index 2c9fc8ea4ad..3186b1b59c1 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -122,6 +122,9 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
getActionDefinitionsBuilder(G_DYN_STACKALLOC)
.lowerFor({{p0, s32}});
+ getActionDefinitionsBuilder(G_VASTART)
+ .legalFor({p0});
+
// FP instructions
getActionDefinitionsBuilder(G_FCONSTANT)
.legalFor({s32, s64});
@@ -252,6 +255,18 @@ bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
MI.eraseFromParent();
return constrainSelectedInstRegOperands(*Trap, TII, TRI, RBI);
}
+ case Intrinsic::vacopy: {
+ Register Tmp = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
+ MachinePointerInfo MPO;
+ MIRBuilder.buildLoad(Tmp, MI.getOperand(2),
+ *MI.getMF()->getMachineMemOperand(
+ MPO, MachineMemOperand::MOLoad, 4, 4));
+ MIRBuilder.buildStore(Tmp, MI.getOperand(1),
+ *MI.getMF()->getMachineMemOperand(
+ MPO, MachineMemOperand::MOStore, 4, 4));
+ MI.eraseFromParent();
+ return true;
+ }
default:
break;
}
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 9c76a892cf9..f8ce80b044c 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -403,6 +403,7 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_SREM:
case G_UREM:
case G_BRINDIRECT:
+ case G_VASTART:
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
break;
case G_LOAD: {
OpenPOWER on IntegriCloud