mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
[GlobalISel] Get rid of the ifdefs in TargetLowering.
Introduce a new API used only by GlobalISel: CallLowering. This API will contain target hooks dedicated to call lowering. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260922 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
89e84d7221
commit
30880b6d80
@ -28,13 +28,13 @@
|
||||
namespace llvm {
|
||||
// Forward declarations.
|
||||
class BasicBlock;
|
||||
class CallLowering;
|
||||
class Constant;
|
||||
class Instruction;
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineRegisterInfo;
|
||||
class TargetLowering;
|
||||
|
||||
// Technically the pass should run on an hypothetical MachineModule,
|
||||
// since it should translate Global into some sort of MachineGlobal.
|
||||
@ -50,7 +50,7 @@ public:
|
||||
|
||||
private:
|
||||
/// Interface used to lower the everything related to calls.
|
||||
const TargetLowering *TLI;
|
||||
const CallLowering *CLI;
|
||||
/// Mapping of the values of the current LLVM IR function
|
||||
/// to the related virtual registers.
|
||||
ValueToVReg ValToVReg;
|
||||
|
@ -25,17 +25,11 @@
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/CodeGen/DAGCombine.h"
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
#include "llvm/CodeGen/GlobalISel/Types.h"
|
||||
#endif
|
||||
#include "llvm/CodeGen/RuntimeLibcalls.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
# include "llvm/IR/Function.h"
|
||||
#endif
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InlineAsm.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
@ -56,9 +50,6 @@ namespace llvm {
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
class MachineIRBuilder;
|
||||
#endif
|
||||
class MachineJumpTableInfo;
|
||||
class MachineLoop;
|
||||
class Mangler;
|
||||
@ -2515,29 +2506,6 @@ public:
|
||||
llvm_unreachable("Not Implemented");
|
||||
}
|
||||
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
virtual bool LowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
|
||||
unsigned VReg) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// This hook must be implemented to lower the incoming (formal)
|
||||
/// arguments, described by \p Args, for GlobalISel. Each argument
|
||||
/// must end up in the related virtual register described by VRegs.
|
||||
/// In other words, the first argument should end up in VRegs[0],
|
||||
/// the second in VRegs[1], and so on.
|
||||
/// \p MIRBuilder is set to the proper insertion for the argument
|
||||
/// lowering.
|
||||
///
|
||||
/// \return True if the lowering succeeded, false otherwise.
|
||||
virtual bool
|
||||
LowerFormalArguments(MachineIRBuilder &MIRBuilder,
|
||||
const Function::ArgumentListType &Args,
|
||||
const SmallVectorImpl<unsigned> &VRegs) const {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Return true if result of the specified node is used by a return node
|
||||
/// only. It also compute and return the input chain for the tail call.
|
||||
///
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class CallLowering;
|
||||
class DataLayout;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
@ -71,6 +72,7 @@ public:
|
||||
// -- Pipelines and scheduling information
|
||||
// -- Stack frame information
|
||||
// -- Selection DAG lowering information
|
||||
// -- Call lowering information
|
||||
//
|
||||
// N.B. These objects may change during compilation. It's not safe to cache
|
||||
// them between functions.
|
||||
@ -82,6 +84,7 @@ public:
|
||||
virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const {
|
||||
return nullptr;
|
||||
}
|
||||
virtual const CallLowering *getCallLowering() const { return nullptr; }
|
||||
/// Target can subclass this hook to select a different DAG scheduler.
|
||||
virtual RegisterScheduler::FunctionPassCtor
|
||||
getDAGScheduler(CodeGenOpt::Level) const {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
@ -75,7 +76,7 @@ bool IRTranslator::translateReturn(const Instruction &Inst) {
|
||||
// The target may mess up with the insertion point, but
|
||||
// this is not important as a return is the last instruction
|
||||
// of the block anyway.
|
||||
return TLI->LowerReturn(MIRBuilder, Ret,
|
||||
return CLI->LowerReturn(MIRBuilder, Ret,
|
||||
!Ret ? 0 : getOrCreateVReg(Ret));
|
||||
}
|
||||
|
||||
@ -104,7 +105,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
|
||||
const Function &F = *MF.getFunction();
|
||||
if (F.empty())
|
||||
return false;
|
||||
TLI = MF.getSubtarget().getTargetLowering();
|
||||
CLI = MF.getSubtarget().getCallLowering();
|
||||
MIRBuilder.setFunction(MF);
|
||||
MRI = &MF.getRegInfo();
|
||||
// Setup the arguments.
|
||||
@ -113,7 +114,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
|
||||
SmallVector<unsigned, 8> VRegArgs;
|
||||
for (const Argument &Arg: F.args())
|
||||
VRegArgs.push_back(getOrCreateVReg(&Arg));
|
||||
bool Succeeded = TLI->LowerFormalArguments(MIRBuilder, F.getArgumentList(),
|
||||
bool Succeeded = CLI->LowerFormalArguments(MIRBuilder, F.getArgumentList(),
|
||||
VRegArgs);
|
||||
if (!Succeeded)
|
||||
report_fatal_error("Unable to lower arguments");
|
||||
|
111
lib/Target/AArch64/AArch64CallLowering.cpp
Normal file
111
lib/Target/AArch64/AArch64CallLowering.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
//===-- llvm/lib/Target/AArch64/AArch64CallLowering.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 the lowering of LLVM calls to machine code calls for
|
||||
/// GlobalISel.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AArch64CallLowering.h"
|
||||
#include "AArch64ISelLowering.h"
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
|
||||
using namespace llvm;
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
# define EMIT_IMPLEMENTATION 1
|
||||
#else
|
||||
# define EMIT_IMPLEMENTATION 0
|
||||
#endif
|
||||
|
||||
AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
|
||||
: CallLowering(&TLI) {
|
||||
}
|
||||
|
||||
bool AArch64CallLowering::LowerReturn(MachineIRBuilder &MIRBuilder,
|
||||
const Value *Val, unsigned VReg) const {
|
||||
if (!EMIT_IMPLEMENTATION)
|
||||
return false;
|
||||
|
||||
MachineInstr *Return = MIRBuilder.buildInstr(AArch64::RET_ReallyLR);
|
||||
assert(Return && "Unable to build a return instruction?!");
|
||||
|
||||
assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
|
||||
if (VReg) {
|
||||
assert(Val->getType()->isIntegerTy() && "Type not supported yet");
|
||||
unsigned Size = Val->getType()->getPrimitiveSizeInBits();
|
||||
assert((Size == 64 || Size == 32) && "Size not supported yet");
|
||||
unsigned ResReg = (Size == 32) ? AArch64::W0 : AArch64::X0;
|
||||
// Set the insertion point to be right before Return.
|
||||
MIRBuilder.setInstr(*Return, /* Before */ true);
|
||||
MachineInstr *Copy =
|
||||
MIRBuilder.buildInstr(TargetOpcode::COPY, ResReg, VReg);
|
||||
(void)Copy;
|
||||
assert(Copy->getNextNode() == Return &&
|
||||
"The insertion did not happen where we expected");
|
||||
MachineInstrBuilder(MIRBuilder.getMF(), Return)
|
||||
.addReg(ResReg, RegState::Implicit);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AArch64CallLowering::LowerFormalArguments(
|
||||
MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args,
|
||||
const SmallVectorImpl<unsigned> &VRegs) const {
|
||||
if (!EMIT_IMPLEMENTATION)
|
||||
return false;
|
||||
|
||||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
const Function &F = *MF.getFunction();
|
||||
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
|
||||
|
||||
unsigned NumArgs = Args.size();
|
||||
Function::const_arg_iterator CurOrigArg = Args.begin();
|
||||
const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
|
||||
for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
|
||||
MVT ValVT = MVT::getVT(CurOrigArg->getType());
|
||||
CCAssignFn *AssignFn =
|
||||
TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
|
||||
bool Res =
|
||||
AssignFn(i, ValVT, ValVT, CCValAssign::Full, ISD::ArgFlagsTy(), CCInfo);
|
||||
assert(!Res && "Call operand has unhandled type");
|
||||
(void)Res;
|
||||
}
|
||||
assert(ArgLocs.size() == Args.size() &&
|
||||
"We have a different number of location and args?!");
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
assert(VA.isRegLoc() && "Not yet implemented");
|
||||
// Transform the arguments in physical registers into virtual ones.
|
||||
MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
|
||||
MIRBuilder.buildInstr(TargetOpcode::COPY, VRegs[i], VA.getLocReg());
|
||||
|
||||
switch (VA.getLocInfo()) {
|
||||
default:
|
||||
llvm_unreachable("Unknown loc info!");
|
||||
case CCValAssign::Full:
|
||||
break;
|
||||
case CCValAssign::BCvt:
|
||||
// We don't care about bitcast.
|
||||
break;
|
||||
case CCValAssign::AExt:
|
||||
case CCValAssign::SExt:
|
||||
case CCValAssign::ZExt:
|
||||
// Zero/Sign extend the register.
|
||||
assert(0 && "Not yet implemented");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
36
lib/Target/AArch64/AArch64CallLowering.h
Normal file
36
lib/Target/AArch64/AArch64CallLowering.h
Normal file
@ -0,0 +1,36 @@
|
||||
//===-- llvm/lib/Target/AArch64/AArch64CallLowering.h - 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 describes how to lower LLVM calls to machine code calls.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64CALLLOWERING
|
||||
#define LLVM_LIB_TARGET_AARCH64_AARCH64CALLLOWERING
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AArch64TargetLowering;
|
||||
|
||||
class AArch64CallLowering: public CallLowering {
|
||||
public:
|
||||
AArch64CallLowering(const AArch64TargetLowering &TLI);
|
||||
|
||||
bool LowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
|
||||
unsigned VReg) const override;
|
||||
bool
|
||||
LowerFormalArguments(MachineIRBuilder &MIRBuilder,
|
||||
const Function::ArgumentListType &Args,
|
||||
const SmallVectorImpl<unsigned> &VRegs) const override;
|
||||
};
|
||||
} // End of namespace llvm;
|
||||
#endif
|
@ -21,9 +21,6 @@
|
||||
#include "MCTargetDesc/AArch64AddressingModes.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
# include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
||||
#endif
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
@ -3395,81 +3392,6 @@ AArch64TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
return DAG.getNode(AArch64ISD::RET_FLAG, DL, MVT::Other, RetOps);
|
||||
}
|
||||
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
bool AArch64TargetLowering::LowerReturn(MachineIRBuilder &MIRBuilder,
|
||||
const Value *Val, unsigned VReg) const {
|
||||
MachineInstr *Return = MIRBuilder.buildInstr(AArch64::RET_ReallyLR);
|
||||
assert(Return && "Unable to build a return instruction?!");
|
||||
|
||||
assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
|
||||
if (VReg) {
|
||||
assert(Val->getType()->isIntegerTy() && "Type not supported yet");
|
||||
unsigned Size = Val->getType()->getPrimitiveSizeInBits();
|
||||
assert((Size == 64 || Size == 32) && "Size not supported yet");
|
||||
unsigned ResReg = (Size == 32) ? AArch64::W0 : AArch64::X0;
|
||||
// Set the insertion point to be right before Return.
|
||||
MIRBuilder.setInstr(*Return, /* Before */ true);
|
||||
MachineInstr *Copy =
|
||||
MIRBuilder.buildInstr(TargetOpcode::COPY, ResReg, VReg);
|
||||
(void)Copy;
|
||||
assert(Copy->getNextNode() == Return &&
|
||||
"The insertion did not happen where we expected");
|
||||
MachineInstrBuilder(MIRBuilder.getMF(), Return)
|
||||
.addReg(ResReg, RegState::Implicit);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AArch64TargetLowering::LowerFormalArguments(
|
||||
MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args,
|
||||
const SmallVectorImpl<unsigned> &VRegs) const {
|
||||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
const Function &F = *MF.getFunction();
|
||||
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
|
||||
|
||||
unsigned NumArgs = Args.size();
|
||||
Function::const_arg_iterator CurOrigArg = Args.begin();
|
||||
for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
|
||||
MVT ValVT = MVT::getVT(CurOrigArg->getType());
|
||||
CCAssignFn *AssignFn =
|
||||
CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
|
||||
bool Res =
|
||||
AssignFn(i, ValVT, ValVT, CCValAssign::Full, ISD::ArgFlagsTy(), CCInfo);
|
||||
assert(!Res && "Call operand has unhandled type");
|
||||
(void)Res;
|
||||
}
|
||||
assert(ArgLocs.size() == Args.size() &&
|
||||
"We have a different number of location and args?!");
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
assert(VA.isRegLoc() && "Not yet implemented");
|
||||
// Transform the arguments in physical registers into virtual ones.
|
||||
MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
|
||||
MIRBuilder.buildInstr(TargetOpcode::COPY, VRegs[i], VA.getLocReg());
|
||||
|
||||
switch (VA.getLocInfo()) {
|
||||
default:
|
||||
llvm_unreachable("Unknown loc info!");
|
||||
case CCValAssign::Full:
|
||||
break;
|
||||
case CCValAssign::BCvt:
|
||||
// We don't care about bitcast.
|
||||
break;
|
||||
case CCValAssign::AExt:
|
||||
case CCValAssign::SExt:
|
||||
case CCValAssign::ZExt:
|
||||
// Zero/Sign extend the register.
|
||||
assert(0 && "Not yet implemented");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Other Lowering Code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -452,15 +452,6 @@ private:
|
||||
const SmallVectorImpl<SDValue> &OutVals, SDLoc DL,
|
||||
SelectionDAG &DAG) const override;
|
||||
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
bool LowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
|
||||
unsigned VReg) const override;
|
||||
bool
|
||||
LowerFormalArguments(MachineIRBuilder &MIRBuilder,
|
||||
const Function::ArgumentListType &Args,
|
||||
const SmallVectorImpl<unsigned> &VRegs) const override;
|
||||
#endif
|
||||
|
||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerDarwinGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
@ -57,7 +57,14 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
|
||||
StrictAlign(false), ReserveX18(TT.isOSDarwin()), IsLittle(LittleEndian),
|
||||
CPUString(CPU), TargetTriple(TT), FrameLowering(),
|
||||
InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(),
|
||||
TLInfo(TM, *this) {}
|
||||
TLInfo(TM, *this), CallLoweringInfo(nullptr) {}
|
||||
|
||||
const CallLowering *
|
||||
AArch64Subtarget::getCallLowering() const {
|
||||
if (!CallLoweringInfo)
|
||||
CallLoweringInfo.reset(new AArch64CallLowering(TLInfo));
|
||||
return CallLoweringInfo.get();
|
||||
}
|
||||
|
||||
/// ClassifyGlobalReference - Find the target operand flags that describe
|
||||
/// how a global value should be referenced for the current subtarget.
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
|
||||
#define LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
|
||||
|
||||
#include "AArch64CallLowering.h"
|
||||
#include "AArch64FrameLowering.h"
|
||||
#include "AArch64ISelLowering.h"
|
||||
#include "AArch64InstrInfo.h"
|
||||
@ -81,6 +82,7 @@ protected:
|
||||
AArch64InstrInfo InstrInfo;
|
||||
AArch64SelectionDAGInfo TSInfo;
|
||||
AArch64TargetLowering TLInfo;
|
||||
mutable std::unique_ptr<AArch64CallLowering> CallLoweringInfo;
|
||||
private:
|
||||
/// initializeSubtargetDependencies - Initializes using CPUString and the
|
||||
/// passed in feature string so that we can use initializer lists for
|
||||
@ -107,6 +109,7 @@ public:
|
||||
const AArch64RegisterInfo *getRegisterInfo() const override {
|
||||
return &getInstrInfo()->getRegisterInfo();
|
||||
}
|
||||
const CallLowering *getCallLowering() const override;
|
||||
const Triple &getTargetTriple() const { return TargetTriple; }
|
||||
bool enableMachineScheduler() const override { return true; }
|
||||
bool enablePostRAScheduler() const override {
|
||||
|
@ -20,6 +20,7 @@ add_llvm_target(AArch64CodeGen
|
||||
AArch64AdvSIMDScalarPass.cpp
|
||||
AArch64AsmPrinter.cpp
|
||||
AArch64BranchRelaxation.cpp
|
||||
AArch64CallLowering.cpp
|
||||
AArch64CleanupLocalDynamicTLSPass.cpp
|
||||
AArch64CollectLOH.cpp
|
||||
AArch64ConditionalCompares.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user