summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CMakeLists.txt1
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CallLowering.cpp40
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp6
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.cpp25
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.h5
5 files changed, 55 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
index bad5c03e566..87b47087db0 100644
--- a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
+++ b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
@@ -1,5 +1,6 @@
# List of all GlobalISel files.
set(GLOBAL_ISEL_FILES
+ CallLowering.cpp
IRTranslator.cpp
InstructionSelect.cpp
InstructionSelector.cpp
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
new file mode 100644
index 00000000000..9d1c1e7402d
--- /dev/null
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -0,0 +1,40 @@
+//===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements some simple delegations needed for call lowering.
+///
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace llvm;
+
+bool CallLowering::lowerCall(
+ MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg,
+ ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const {
+ // First step is to marshall all the function's parameters into the correct
+ // physregs and memory locations. Gather the sequence of argument types that
+ // we'll pass to the assigner function.
+ SmallVector<MVT, 8> ArgTys;
+ for (auto &Arg : CI.arg_operands())
+ ArgTys.push_back(MVT::getVT(Arg->getType()));
+
+ MachineOperand Callee = MachineOperand::CreateImm(0);
+ if (Function *F = CI.getCalledFunction())
+ Callee = MachineOperand::CreateGA(F, 0);
+ else
+ Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
+
+ return lowerCall(MIRBuilder, Callee, MVT::getVT(CI.getType()),
+ ResReg ? ResReg : ArrayRef<unsigned>(), ArgTys, ArgRegs);
+}
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 64316a15b8d..a27d53941a4 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -347,9 +347,9 @@ bool IRTranslator::translateCall(const User &U) {
for (auto &Arg: CI.arg_operands())
Args.push_back(getOrCreateVReg(*Arg));
- return CLI->lowerCall(MIRBuilder, CI,
- F ? 0 : getOrCreateVReg(*CI.getCalledValue()), Res,
- Args);
+ return CLI->lowerCall(MIRBuilder, CI, Res, Args, [&]() {
+ return getOrCreateVReg(*CI.getCalledValue());
+ });
}
Intrinsic::ID ID = F->getIntrinsicID();
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
index 4f2add28ff8..6fa29754f70 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -131,19 +131,14 @@ bool AArch64CallLowering::lowerFormalArguments(
}
bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
- const CallInst &CI, unsigned CalleeReg,
- unsigned ResReg,
+ MachineOperand &Callee,
+ ArrayRef<MVT> ResTys,
+ ArrayRef<unsigned> ResRegs,
+ ArrayRef<MVT> ArgTys,
ArrayRef<unsigned> ArgRegs) const {
MachineFunction &MF = MIRBuilder.getMF();
const Function &F = *MF.getFunction();
- // First step is to marshall all the function's parameters into the correct
- // physregs and memory locations. Gather the sequence of argument types that
- // we'll pass to the assigner function.
- SmallVector<MVT, 8> ArgTys;
- for (auto &Arg : CI.arg_operands())
- ArgTys.push_back(MVT::getVT(Arg->getType()));
-
// Find out which ABI gets to decide where things go.
const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
CCAssignFn *CallAssignFn =
@@ -160,12 +155,8 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
});
// Now we can build the actual call instruction.
- MachineInstrBuilder MIB;
- if (CalleeReg)
- MIB = MIRBuilder.buildInstr(AArch64::BLR).addUse(CalleeReg);
- else
- MIB = MIRBuilder.buildInstr(AArch64::BL)
- .addGlobalAddress(CI.getCalledFunction());
+ auto MIB = MIRBuilder.buildInstr(Callee.isReg() ? AArch64::BLR : AArch64::BL);
+ MIB.addOperand(Callee);
// Tell the call which registers are clobbered.
auto TRI = MF.getSubtarget().getRegisterInfo();
@@ -178,9 +169,9 @@ 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 (!CI.getType()->isVoidTy())
+ if (!ResRegs.empty())
handleAssignments(
- MIRBuilder, RetAssignFn, MVT::getVT(CI.getType()), ResReg,
+ MIRBuilder, RetAssignFn, ResTys, ResRegs,
[&](MachineIRBuilder &MIRBuilder, unsigned ValReg, unsigned PhysReg) {
MIRBuilder.buildCopy(ValReg, PhysReg);
MIB.addDef(PhysReg, RegState::Implicit);
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.h b/llvm/lib/Target/AArch64/AArch64CallLowering.h
index e5cf8de4202..1fe929d1fad 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.h
@@ -34,8 +34,9 @@ class AArch64CallLowering: public CallLowering {
const Function::ArgumentListType &Args,
ArrayRef<unsigned> VRegs) const override;
- bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
- unsigned CalleeReg, unsigned ResReg,
+ bool lowerCall(MachineIRBuilder &MIRBuilder, MachineOperand &Callee,
+ ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs,
+ ArrayRef<MVT> ArgTys,
ArrayRef<unsigned> ArgRegs) const override;
private:
OpenPOWER on IntegriCloud