mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
GlobalISel: rework CallLowering so that it can be used for libcalls too.
There should be no functional change here, I'm just making the implementation of "frem" (to libcall) legalization easier for a followup. llvm-svn: 279987
This commit is contained in:
parent
2e0aaa6df5
commit
05f74b5dbe
@ -16,11 +16,13 @@
|
||||
#define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
|
||||
namespace llvm {
|
||||
// Forward declarations.
|
||||
class MachineIRBuilder;
|
||||
class MachineOperand;
|
||||
class TargetLowering;
|
||||
class Value;
|
||||
|
||||
@ -70,9 +72,31 @@ class CallLowering {
|
||||
/// This hook must be implemented to lower the given call instruction,
|
||||
/// including argument and return value marshalling.
|
||||
///
|
||||
/// \p CalleeReg is a virtual-register containing the destination if
|
||||
/// `CI.getCalledFunction()` returns null (i.e. if the call is indirect);
|
||||
/// otherwise it is 0.
|
||||
/// \p Callee is the destination of the call. It should be either a register,
|
||||
/// globaladdress, or externalsymbol.
|
||||
///
|
||||
/// \p ResTys is a list of the individual result types this function call will
|
||||
/// produce. The types are used to assign physical registers to each slot.
|
||||
///
|
||||
/// \p ResRegs is a list of the virtual registers that we expect to be defined
|
||||
/// by this call, one per entry in \p ResTys.
|
||||
///
|
||||
/// \p ArgTys is a list of the types each member of \p ArgRegs has; used by
|
||||
/// the target to decide which register/stack slot should be allocated.
|
||||
///
|
||||
/// \p ArgRegs is a list of virtual registers containing each argument that
|
||||
/// needs to be passed.
|
||||
///
|
||||
/// \return true if the lowering succeeded, false otherwise.
|
||||
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, MachineOperand &Callee,
|
||||
ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs,
|
||||
ArrayRef<MVT> ArgTys,
|
||||
ArrayRef<unsigned> ArgRegs) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// This hook must be implemented to lower the given call instruction,
|
||||
/// including argument and return value marshalling.
|
||||
///
|
||||
/// \p ResReg is a register where the call's return value should be stored (or
|
||||
/// 0 if there is no return value).
|
||||
@ -80,12 +104,15 @@ class CallLowering {
|
||||
/// \p ArgRegs is a list of virtual registers containing each argument that
|
||||
/// needs to be passed.
|
||||
///
|
||||
/// \p GetCalleeReg is a callback to materialize a register for the callee if
|
||||
/// the target determines it cannot jump to the destination based purely on \p
|
||||
/// CI. This might be because \p CI is indirect, or because of the limited
|
||||
/// range of an immediate jump.
|
||||
///
|
||||
/// \return true if the lowering succeeded, false otherwise.
|
||||
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
|
||||
unsigned CalleeReg, unsigned ResReg,
|
||||
ArrayRef<unsigned> ArgRegs) const {
|
||||
return false;
|
||||
}
|
||||
unsigned ResReg, ArrayRef<unsigned> ArgRegs,
|
||||
std::function<unsigned()> GetCalleeReg) const;
|
||||
};
|
||||
} // End namespace llvm.
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
# List of all GlobalISel files.
|
||||
set(GLOBAL_ISEL_FILES
|
||||
CallLowering.cpp
|
||||
IRTranslator.cpp
|
||||
InstructionSelect.cpp
|
||||
InstructionSelector.cpp
|
||||
|
40
lib/CodeGen/GlobalISel/CallLowering.cpp
Normal file
40
lib/CodeGen/GlobalISel/CallLowering.cpp
Normal file
@ -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);
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user