--- /dev/null
+//===-- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering --*- C++ -*-===//
+//
+// 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_CODEGEN_GLOBALISEL_CALLLOWERING_H
+#define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Function.h"
+
+namespace llvm {
+// Forward declarations.
+class MachineIRBuilder;
+class TargetLowering;
+class Value;
+
+class CallLowering {
+ const TargetLowering *TLI;
+ protected:
+ /// Getter for generic TargetLowering class.
+ const TargetLowering *getTLI() const {
+ return TLI;
+ }
+
+ /// Getter for target specific TargetLowering class.
+ template <class XXXTargetLowering>
+ const XXXTargetLowering *getTLI() const {
+ return static_cast<const XXXTargetLowering *>(TLI);
+ }
+ public:
+ CallLowering(const TargetLowering *TLI) : TLI(TLI) {}
+ virtual ~CallLowering() {}
+
+ /// This hook must be implemented to lower outgoing return values, described
+ /// by \p Val, into the specified virtual register \p VReg.
+ /// This hook is used by GlobalISel.
+ ///
+ /// \return True if the lowering succeeds, false otherwise.
+ 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;
+ }
+};
+} // End namespace llvm.
+
+#endif
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.
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;
#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"
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
-#ifdef LLVM_BUILD_GLOBAL_ISEL
- class MachineIRBuilder;
-#endif
class MachineJumpTableInfo;
class MachineLoop;
class Mangler;
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.
///
namespace llvm {
+class CallLowering;
class DataLayout;
class MachineFunction;
class MachineInstr;
// -- 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.
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 {
#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"
// 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,
- !Ret ? 0 : getOrCreateVReg(Ret));
+ return CLI->LowerReturn(MIRBuilder, Ret, !Ret ? 0 : getOrCreateVReg(Ret));
}
bool IRTranslator::translate(const Instruction &Inst) {
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.
SmallVector<unsigned, 8> VRegArgs;
for (const Argument &Arg: F.args())
VRegArgs.push_back(getOrCreateVReg(&Arg));
- bool Succeeded = TLI->LowerFormalArguments(MIRBuilder, F.getArgumentList(),
- VRegArgs);
+ bool Succeeded =
+ CLI->LowerFormalArguments(MIRBuilder, F.getArgumentList(), VRegArgs);
if (!Succeeded)
report_fatal_error("Unable to lower arguments");
--- /dev/null
+//===-- 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;
+
+AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
+ : CallLowering(&TLI) {
+}
+
+#ifndef LLVM_BUILD_GLOBAL_ISEL
+bool AArch64CallLowering::LowerReturn(MachineIRBuilder &MIRBuilder,
+ const Value *Val, unsigned VReg) const {
+ return false;
+}
+
+bool AArch64CallLowering::LowerFormalArguments(
+ MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args,
+ const SmallVectorImpl<unsigned> &VRegs) const {
+ return false;
+}
+#else
+bool AArch64CallLowering::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 AArch64CallLowering::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();
+ 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;
+}
+#endif
--- /dev/null
+//===-- 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
#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"
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
//===----------------------------------------------------------------------===//
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;
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.
#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"
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
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 {
AArch64AdvSIMDScalarPass.cpp
AArch64AsmPrinter.cpp
AArch64BranchRelaxation.cpp
+ AArch64CallLowering.cpp
AArch64CleanupLocalDynamicTLSPass.cpp
AArch64CollectLOH.cpp
AArch64ConditionalCompares.cpp