summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorPetar Jovanovic <petar.jovanovic@mips.com>2018-06-06 07:24:52 +0000
committerPetar Jovanovic <petar.jovanovic@mips.com>2018-06-06 07:24:52 +0000
commit326ec32403a0b83999878eeed01dc525974faef5 (patch)
treee56cbabdfe3b6830bc8a41f541e190bfc4dbde42 /llvm/lib/Target
parent2ebe3a0240564af7e5ca34faba81cbd8e58af5d5 (diff)
downloadbcm5719-llvm-326ec32403a0b83999878eeed01dc525974faef5.tar.gz
bcm5719-llvm-326ec32403a0b83999878eeed01dc525974faef5.zip
[MIPS GlobalISel] Add lowerCall
Add minimal support to lower function calls. Support only functions with arguments/return that go through registers and have type i32. Patch by Petar Avramovic. Differential Revision: https://reviews.llvm.org/D45627 llvm-svn: 334071
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp130
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.h4
2 files changed, 133 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index 561b15bacb2..cd751e5825f 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -15,6 +15,7 @@
#include "MipsCallLowering.h"
#include "MipsCCState.h"
+#include "MipsTargetMachine.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
using namespace llvm;
@@ -44,10 +45,25 @@ public:
private:
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;
- void markPhysRegUsed(unsigned PhysReg) {
+ virtual void markPhysRegUsed(unsigned PhysReg) {
MIRBuilder.getMBB().addLiveIn(PhysReg);
}
};
+
+class CallReturnHandler : public IncomingValueHandler {
+public:
+ CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+ MachineInstrBuilder &MIB)
+ : IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
+
+private:
+ virtual void markPhysRegUsed(unsigned PhysReg) override {
+ MIB.addDef(PhysReg, RegState::Implicit);
+ }
+
+ MachineInstrBuilder &MIB;
+};
+
} // end anonymous namespace
void IncomingValueHandler::assignValueToReg(unsigned ValVReg,
@@ -198,6 +214,118 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
return true;
}
+bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
+ CallingConv::ID CallConv,
+ const MachineOperand &Callee,
+ const ArgInfo &OrigRet,
+ ArrayRef<ArgInfo> OrigArgs) const {
+
+ if (CallConv != CallingConv::C)
+ return false;
+
+ for (auto &Arg : OrigArgs) {
+ if (!isSupportedType(Arg.Ty))
+ return false;
+ if (Arg.Flags.isByVal() || Arg.Flags.isSRet())
+ return false;
+ }
+ if (OrigRet.Reg && !isSupportedType(OrigRet.Ty))
+ return false;
+
+ MachineFunction &MF = MIRBuilder.getMF();
+ const Function &F = MF.getFunction();
+ const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
+ const MipsTargetMachine &TM =
+ static_cast<const MipsTargetMachine &>(MF.getTarget());
+ const MipsABIInfo &ABI = TM.getABI();
+
+ MachineInstrBuilder CallSeqStart =
+ MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
+
+ // FIXME: Add support for pic calling sequences, long call sequences for O32,
+ // N32 and N64. First handle the case when Callee.isReg().
+ if (Callee.isReg())
+ return false;
+
+ MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(Mips::JAL);
+ MIB.addDef(Mips::SP, RegState::Implicit);
+ MIB.add(Callee);
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+ MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
+
+ TargetLowering::ArgListTy FuncOrigArgs;
+ FuncOrigArgs.reserve(OrigArgs.size());
+
+ SmallVector<ArgInfo, 8> ArgInfos;
+ SmallVector<unsigned, 8> OrigArgIndices;
+ unsigned i = 0;
+ for (auto &Arg : OrigArgs) {
+
+ TargetLowering::ArgListEntry Entry;
+ Entry.Ty = Arg.Ty;
+ FuncOrigArgs.push_back(Entry);
+
+ splitToValueTypes(Arg, i, ArgInfos, OrigArgIndices);
+ ++i;
+ }
+
+ 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);
+ });
+
+ SmallVector<CCValAssign, 8> ArgLocs;
+ MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
+ F.getContext());
+
+ const char *Call = Callee.isSymbol() ? Callee.getSymbolName() : nullptr;
+ CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
+
+ OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
+ if (!RetHandler.handle(ArgLocs, ArgInfos)) {
+ return false;
+ }
+
+ // TODO: Calculate stack offset.
+ CallSeqStart.addImm(ABI.GetCalleeAllocdArgSizeInBytes(CallConv)).addImm(0);
+ MIRBuilder.insertInstr(MIB);
+
+ if (OrigRet.Reg) {
+
+ ArgInfos.clear();
+ SmallVector<unsigned, 8> OrigRetIndices;
+
+ 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);
+ });
+
+ SmallVector<CCValAssign, 8> ArgLocs;
+ MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
+ F.getContext());
+
+ CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), OrigRet.Ty, Call);
+
+ CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB);
+ if (!Handler.handle(ArgLocs, ArgInfos))
+ return false;
+ }
+
+ MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP)
+ .addImm(ABI.GetCalleeAllocdArgSizeInBytes(CallConv))
+ .addImm(0);
+
+ return true;
+}
+
void MipsCallLowering::subTargetRegTypeForCallingConv(
MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
ArrayRef<unsigned> OrigArgIndices, const FunTy &PushBack) const {
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.h b/llvm/lib/Target/Mips/MipsCallLowering.h
index fe072c7dfc7..cdff19a0eb1 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.h
+++ b/llvm/lib/Target/Mips/MipsCallLowering.h
@@ -48,6 +48,10 @@ public:
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
ArrayRef<unsigned> VRegs) const override;
+ bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv,
+ const MachineOperand &Callee, const ArgInfo &OrigRet,
+ ArrayRef<ArgInfo> OrigArgs) const override;
+
private:
using FunTy =
std::function<void(ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
OpenPOWER on IntegriCloud