[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:
Quentin Colombet 2016-02-16 00:57:44 +00:00
parent 89e84d7221
commit 30880b6d80
11 changed files with 168 additions and 125 deletions

View File

@ -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;

View File

@ -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.
///

View File

@ -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 {

View File

@ -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");

View 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;
}

View 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

View File

@ -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
//===----------------------------------------------------------------------===//

View File

@ -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;

View File

@ -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.

View File

@ -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 {

View File

@ -20,6 +20,7 @@ add_llvm_target(AArch64CodeGen
AArch64AdvSIMDScalarPass.cpp
AArch64AsmPrinter.cpp
AArch64BranchRelaxation.cpp
AArch64CallLowering.cpp
AArch64CleanupLocalDynamicTLSPass.cpp
AArch64CollectLOH.cpp
AArch64ConditionalCompares.cpp