From f6b5ea76fb1561cace8c00bad6b7f5c4e69ce79c Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Tue, 8 Aug 2017 22:22:30 +0000 Subject: [PATCH] Revert "[GlobalISel] Remove the GISelAccessor API." This reverts commit r310115. It causes a linker failure for the one of the unittests of AArch64 on one of the linux bot: http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/3429 : && /home/fedora/gcc/install/gcc-7.1.0/bin/g++ -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -L/home/fedora/gcc/install/gcc-7.1.0/lib64 -Wl,-allow-shlib-undefined -Wl,-O3 -Wl,--gc-sections unittests/Target/AArch64/CMakeFiles/AArch64Tests.dir/InstSizes.cpp.o -o unittests/Target/AArch64/AArch64Tests lib/libLLVMAArch64CodeGen.so.6.0.0svn lib/libLLVMAArch64Desc.so.6.0.0svn lib/libLLVMAArch64Info.so.6.0.0svn lib/libLLVMCodeGen.so.6.0.0svn lib/libLLVMCore.so.6.0.0svn lib/libLLVMMC.so.6.0.0svn lib/libLLVMMIRParser.so.6.0.0svn lib/libLLVMSelectionDAG.so.6.0.0svn lib/libLLVMTarget.so.6.0.0svn lib/libLLVMSupport.so.6.0.0svn -lpthread lib/libgtest_main.so.6.0.0svn lib/libgtest.so.6.0.0svn -lpthread -Wl,-rpath,/home/buildbots/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib && : unittests/Target/AArch64/CMakeFiles/AArch64Tests.dir/InstSizes.cpp.o:(.toc+0x0): undefined reference to `vtable for llvm::LegalizerInfo' unittests/Target/AArch64/CMakeFiles/AArch64Tests.dir/InstSizes.cpp.o:(.toc+0x8): undefined reference to `vtable for llvm::RegisterBankInfo' The particularity of this bot is that it is built with BUILD_SHARED_LIBS=ON However, I was not able to reproduce the problem so far. Reverting to unblock the bot. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310425 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/GlobalISel.rst | 2 + .../llvm/CodeGen/GlobalISel/GISelAccessor.h | 39 +++++++++++++ lib/Target/AArch64/AArch64Subtarget.cpp | 57 +++++++++++++++---- lib/Target/AArch64/AArch64Subtarget.h | 20 +++---- lib/Target/AMDGPU/AMDGPUSubtarget.cpp | 37 ++++++++++-- lib/Target/AMDGPU/AMDGPUSubtarget.h | 28 ++++----- lib/Target/ARM/ARMSubtarget.cpp | 50 +++++++++++++--- lib/Target/ARM/ARMSubtarget.h | 17 +++--- lib/Target/X86/X86Subtarget.cpp | 49 +++++++++++++--- lib/Target/X86/X86Subtarget.h | 17 +++--- 10 files changed, 241 insertions(+), 75 deletions(-) create mode 100644 include/llvm/CodeGen/GlobalISel/GISelAccessor.h diff --git a/docs/GlobalISel.rst b/docs/GlobalISel.rst index 52ca9a02ba5..176bd4edea3 100644 --- a/docs/GlobalISel.rst +++ b/docs/GlobalISel.rst @@ -633,3 +633,5 @@ Additionally: * ``TargetPassConfig`` --- create the passes constituting the pipeline, including additional passes not included in the :ref:`pipeline`. +* ``GISelAccessor`` --- setup the various subtarget-provided classes, with a + graceful fallback to no-op when GlobalISel isn't enabled. diff --git a/include/llvm/CodeGen/GlobalISel/GISelAccessor.h b/include/llvm/CodeGen/GlobalISel/GISelAccessor.h new file mode 100644 index 00000000000..8dea38059ea --- /dev/null +++ b/include/llvm/CodeGen/GlobalISel/GISelAccessor.h @@ -0,0 +1,39 @@ +//===-- GISelAccessor.h - GISel Accessor ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// This file declares the API to access the various APIs related +/// to GlobalISel. +// +//===----------------------------------------------------------------------===/ + +#ifndef LLVM_CODEGEN_GLOBALISEL_GISELACCESSOR_H +#define LLVM_CODEGEN_GLOBALISEL_GISELACCESSOR_H + +namespace llvm { +class CallLowering; +class InstructionSelector; +class LegalizerInfo; +class RegisterBankInfo; + +/// The goal of this helper class is to gather the accessor to all +/// the APIs related to GlobalISel. +/// It should be derived to feature an actual accessor to the GISel APIs. +/// The reason why this is not simply done into the subtarget is to avoid +/// spreading ifdefs around. +struct GISelAccessor { + virtual ~GISelAccessor() {} + virtual const CallLowering *getCallLowering() const { return nullptr;} + virtual const InstructionSelector *getInstructionSelector() const { + return nullptr; + } + virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } + virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr;} +}; +} // End namespace llvm; +#endif diff --git a/lib/Target/AArch64/AArch64Subtarget.cpp b/lib/Target/AArch64/AArch64Subtarget.cpp index 5d0482918e0..4fb4991da69 100644 --- a/lib/Target/AArch64/AArch64Subtarget.cpp +++ b/lib/Target/AArch64/AArch64Subtarget.cpp @@ -21,6 +21,7 @@ #include "AArch64CallLowering.h" #include "AArch64LegalizerInfo.h" #include "AArch64RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/CodeGen/GlobalISel/Legalizer.h" @@ -140,42 +141,76 @@ void AArch64Subtarget::initializeProperties() { } } +namespace { + +struct AArch64GISelActualAccessor : public GISelAccessor { + std::unique_ptr CallLoweringInfo; + std::unique_ptr InstSelector; + std::unique_ptr Legalizer; + std::unique_ptr RegBankInfo; + + const CallLowering *getCallLowering() const override { + return CallLoweringInfo.get(); + } + + const InstructionSelector *getInstructionSelector() const override { + return InstSelector.get(); + } + + const LegalizerInfo *getLegalizerInfo() const override { + return Legalizer.get(); + } + + const RegisterBankInfo *getRegBankInfo() const override { + return RegBankInfo.get(); + } +}; + +} // end anonymous namespace + AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const TargetMachine &TM, bool LittleEndian) : AArch64GenSubtargetInfo(TT, CPU, FS), - ReserveX18(TT.isOSDarwin() || TT.isOSWindows()), IsLittle(LittleEndian), - TargetTriple(TT), FrameLowering(), + ReserveX18(TT.isOSDarwin() || TT.isOSWindows()), + IsLittle(LittleEndian), TargetTriple(TT), FrameLowering(), InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(), - TLInfo(TM, *this) { - CallLoweringInfo.reset(new AArch64CallLowering(*getTargetLowering())); - Legalizer.reset(new AArch64LegalizerInfo()); + TLInfo(TM, *this), GISel() { + AArch64GISelActualAccessor *AArch64GISel = new AArch64GISelActualAccessor(); + AArch64GISel->CallLoweringInfo.reset( + new AArch64CallLowering(*getTargetLowering())); + AArch64GISel->Legalizer.reset(new AArch64LegalizerInfo()); auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo()); // FIXME: At this point, we can't rely on Subtarget having RBI. // It's awkward to mix passing RBI and the Subtarget; should we pass // TII/TRI as well? - InstSelector.reset(createAArch64InstructionSelector( + AArch64GISel->InstSelector.reset(createAArch64InstructionSelector( *static_cast(&TM), *this, *RBI)); - RegBankInfo.reset(RBI); + AArch64GISel->RegBankInfo.reset(RBI); + setGISelAccessor(*AArch64GISel); } const CallLowering *AArch64Subtarget::getCallLowering() const { - return CallLoweringInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getCallLowering(); } const InstructionSelector *AArch64Subtarget::getInstructionSelector() const { - return InstSelector.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getInstructionSelector(); } const LegalizerInfo *AArch64Subtarget::getLegalizerInfo() const { - return Legalizer.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getLegalizerInfo(); } const RegisterBankInfo *AArch64Subtarget::getRegBankInfo() const { - return RegBankInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getRegBankInfo(); } /// Find the target operand flags that describe how a global value should be diff --git a/lib/Target/AArch64/AArch64Subtarget.h b/lib/Target/AArch64/AArch64Subtarget.h index c50588e0445..5a1f45ee255 100644 --- a/lib/Target/AArch64/AArch64Subtarget.h +++ b/lib/Target/AArch64/AArch64Subtarget.h @@ -19,10 +19,7 @@ #include "AArch64InstrInfo.h" #include "AArch64RegisterInfo.h" #include "AArch64SelectionDAGInfo.h" -#include "llvm/CodeGen/GlobalISel/CallLowering.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" -#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/IR/DataLayout.h" #include "llvm/Target/TargetSubtargetInfo.h" #include @@ -127,12 +124,10 @@ protected: AArch64InstrInfo InstrInfo; AArch64SelectionDAGInfo TSInfo; AArch64TargetLowering TLInfo; - - /// GlobalISel related APIs. - std::unique_ptr CallLoweringInfo; - std::unique_ptr InstSelector; - std::unique_ptr Legalizer; - std::unique_ptr RegBankInfo; + /// Gather the accessor points to GlobalISel-related APIs. + /// This is used to avoid ifndefs spreading around while GISel is + /// an optional library. + std::unique_ptr GISel; private: /// initializeSubtargetDependencies - Initializes using CPUString and the @@ -151,6 +146,11 @@ public: const std::string &FS, const TargetMachine &TM, bool LittleEndian); + /// This object will take onwership of \p GISelAccessor. + void setGISelAccessor(GISelAccessor &GISel) { + this->GISel.reset(&GISel); + } + const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override { return &TSInfo; } diff --git a/lib/Target/AMDGPU/AMDGPUSubtarget.cpp b/lib/Target/AMDGPU/AMDGPUSubtarget.cpp index deba76a207c..12557cf1442 100644 --- a/lib/Target/AMDGPU/AMDGPUSubtarget.cpp +++ b/lib/Target/AMDGPU/AMDGPUSubtarget.cpp @@ -90,6 +90,29 @@ AMDGPUSubtarget::initializeSubtargetDependencies(const Triple &TT, return *this; } +namespace { + +struct SIGISelActualAccessor : public GISelAccessor { + std::unique_ptr CallLoweringInfo; + std::unique_ptr InstSelector; + std::unique_ptr Legalizer; + std::unique_ptr RegBankInfo; + const AMDGPUCallLowering *getCallLowering() const override { + return CallLoweringInfo.get(); + } + const InstructionSelector *getInstructionSelector() const override { + return InstSelector.get(); + } + const LegalizerInfo *getLegalizerInfo() const override { + return Legalizer.get(); + } + const RegisterBankInfo *getRegBankInfo() const override { + return RegBankInfo.get(); + } +}; + +} // end anonymous namespace + AMDGPUSubtarget::AMDGPUSubtarget(const Triple &TT, StringRef GPU, StringRef FS, const TargetMachine &TM) : AMDGPUGenSubtargetInfo(TT, GPU, FS), @@ -342,12 +365,14 @@ SISubtarget::SISubtarget(const Triple &TT, StringRef GPU, StringRef FS, : AMDGPUSubtarget(TT, GPU, FS, TM), InstrInfo(*this), FrameLowering(TargetFrameLowering::StackGrowsUp, getStackAlignment(), 0), TLInfo(TM, *this) { - CallLoweringInfo.reset(new AMDGPUCallLowering(*getTargetLowering())); - Legalizer.reset(new AMDGPULegalizerInfo()); - - RegBankInfo.reset(new AMDGPURegisterBankInfo(*getRegisterInfo())); - InstSelector.reset(new AMDGPUInstructionSelector( - *this, *static_cast(RegBankInfo.get()))); + SIGISelActualAccessor *GISel = new SIGISelActualAccessor(); + GISel->CallLoweringInfo.reset(new AMDGPUCallLowering(*getTargetLowering())); + GISel->Legalizer.reset(new AMDGPULegalizerInfo()); + + GISel->RegBankInfo.reset(new AMDGPURegisterBankInfo(*getRegisterInfo())); + GISel->InstSelector.reset(new AMDGPUInstructionSelector( + *this, *static_cast(GISel->RegBankInfo.get()))); + setGISelAccessor(*GISel); } void SISubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, diff --git a/lib/Target/AMDGPU/AMDGPUSubtarget.h b/lib/Target/AMDGPU/AMDGPUSubtarget.h index 8aad97caa97..82d2c543025 100644 --- a/lib/Target/AMDGPU/AMDGPUSubtarget.h +++ b/lib/Target/AMDGPU/AMDGPUSubtarget.h @@ -16,7 +16,6 @@ #define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H #include "AMDGPU.h" -#include "AMDGPUCallLowering.h" #include "R600FrameLowering.h" #include "R600ISelLowering.h" #include "R600InstrInfo.h" @@ -26,9 +25,7 @@ #include "SIMachineFunctionInfo.h" #include "Utils/AMDGPUBaseInfo.h" #include "llvm/ADT/Triple.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" -#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/MC/MCInstrItineraries.h" @@ -633,12 +630,7 @@ private: SIInstrInfo InstrInfo; SIFrameLowering FrameLowering; SITargetLowering TLInfo; - - /// GlobalISel related APIs. - std::unique_ptr CallLoweringInfo; - std::unique_ptr InstSelector; - std::unique_ptr Legalizer; - std::unique_ptr RegBankInfo; + std::unique_ptr GISel; public: SISubtarget(const Triple &TT, StringRef CPU, StringRef FS, @@ -657,25 +649,33 @@ public: } const CallLowering *getCallLowering() const override { - return CallLoweringInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getCallLowering(); } const InstructionSelector *getInstructionSelector() const override { - return InstSelector.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getInstructionSelector(); } const LegalizerInfo *getLegalizerInfo() const override { - return Legalizer.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getLegalizerInfo(); } const RegisterBankInfo *getRegBankInfo() const override { - return RegBankInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getRegBankInfo(); } const SIRegisterInfo *getRegisterInfo() const override { return &InstrInfo.getRegisterInfo(); } + void setGISelAccessor(GISelAccessor &GISel) { + this->GISel.reset(&GISel); + } + // XXX - Why is this here if it isn't in the default pass set? bool enableEarlyIfConversion() const override { return true; diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 682eb38e714..29d6d148d91 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/CodeGen/GlobalISel/Legalizer.h" @@ -96,6 +97,33 @@ ARMFrameLowering *ARMSubtarget::initializeFrameLowering(StringRef CPU, return new ARMFrameLowering(STI); } +namespace { + +struct ARMGISelActualAccessor : public GISelAccessor { + std::unique_ptr CallLoweringInfo; + std::unique_ptr InstSelector; + std::unique_ptr Legalizer; + std::unique_ptr RegBankInfo; + + const CallLowering *getCallLowering() const override { + return CallLoweringInfo.get(); + } + + const InstructionSelector *getInstructionSelector() const override { + return InstSelector.get(); + } + + const LegalizerInfo *getLegalizerInfo() const override { + return Legalizer.get(); + } + + const RegisterBankInfo *getRegBankInfo() const override { + return RegBankInfo.get(); + } +}; + +} // end anonymous namespace + ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const ARMBaseTargetMachine &TM, bool IsLittle) @@ -113,34 +141,40 @@ ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU, assert((isThumb() || hasARMOps()) && "Target must either be thumb or support ARM operations!"); - CallLoweringInfo.reset(new ARMCallLowering(*getTargetLowering())); - Legalizer.reset(new ARMLegalizerInfo(*this)); + ARMGISelActualAccessor *GISel = new ARMGISelActualAccessor(); + GISel->CallLoweringInfo.reset(new ARMCallLowering(*getTargetLowering())); + GISel->Legalizer.reset(new ARMLegalizerInfo(*this)); auto *RBI = new ARMRegisterBankInfo(*getRegisterInfo()); // FIXME: At this point, we can't rely on Subtarget having RBI. // It's awkward to mix passing RBI and the Subtarget; should we pass // TII/TRI as well? - InstSelector.reset(createARMInstructionSelector( + GISel->InstSelector.reset(createARMInstructionSelector( *static_cast(&TM), *this, *RBI)); - RegBankInfo.reset(RBI); + GISel->RegBankInfo.reset(RBI); + setGISelAccessor(*GISel); } const CallLowering *ARMSubtarget::getCallLowering() const { - return CallLoweringInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getCallLowering(); } const InstructionSelector *ARMSubtarget::getInstructionSelector() const { - return InstSelector.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getInstructionSelector(); } const LegalizerInfo *ARMSubtarget::getLegalizerInfo() const { - return Legalizer.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getLegalizerInfo(); } const RegisterBankInfo *ARMSubtarget::getRegBankInfo() const { - return RegBankInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getRegBankInfo(); } bool ARMSubtarget::isXRaySupported() const { diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index b07b42c3e85..c49ea133836 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -20,10 +20,7 @@ #include "ARMISelLowering.h" #include "ARMSelectionDAGInfo.h" #include "llvm/ADT/Triple.h" -#include "llvm/CodeGen/GlobalISel/CallLowering.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" -#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCSchedule.h" @@ -422,6 +419,9 @@ public: ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const ARMBaseTargetMachine &TM, bool IsLittle); + /// This object will take onwership of \p GISelAccessor. + void setGISelAccessor(GISelAccessor &GISel) { this->GISel.reset(&GISel); } + /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size /// that still makes it profitable to inline the call. unsigned getMaxInlineSizeThreshold() const { @@ -469,11 +469,10 @@ private: std::unique_ptr InstrInfo; ARMTargetLowering TLInfo; - /// GlobalISel related APIs. - std::unique_ptr CallLoweringInfo; - std::unique_ptr InstSelector; - std::unique_ptr Legalizer; - std::unique_ptr RegBankInfo; + /// Gather the accessor points to GlobalISel-related APIs. + /// This is used to avoid ifndefs spreading around while GISel is + /// an optional library. + std::unique_ptr GISel; void initializeEnvironment(); void initSubtargetFeatures(StringRef CPU, StringRef FS); diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index bada96df869..493084f795f 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -353,6 +353,33 @@ X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU, return *this; } +namespace { + +struct X86GISelActualAccessor : public GISelAccessor { + std::unique_ptr CallLoweringInfo; + std::unique_ptr Legalizer; + std::unique_ptr RegBankInfo; + std::unique_ptr InstSelector; + + const CallLowering *getCallLowering() const override { + return CallLoweringInfo.get(); + } + + const InstructionSelector *getInstructionSelector() const override { + return InstSelector.get(); + } + + const LegalizerInfo *getLegalizerInfo() const override { + return Legalizer.get(); + } + + const RegisterBankInfo *getRegBankInfo() const override { + return RegBankInfo.get(); + } +}; + +} // end anonymous namespace + X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS, const X86TargetMachine &TM, unsigned StackAlignOverride) @@ -377,29 +404,35 @@ X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS, setPICStyle(PICStyles::StubPIC); else if (isTargetELF()) setPICStyle(PICStyles::GOT); + X86GISelActualAccessor *GISel = new X86GISelActualAccessor(); - CallLoweringInfo.reset(new X86CallLowering(*getTargetLowering())); - Legalizer.reset(new X86LegalizerInfo(*this, TM)); + GISel->CallLoweringInfo.reset(new X86CallLowering(*getTargetLowering())); + GISel->Legalizer.reset(new X86LegalizerInfo(*this, TM)); auto *RBI = new X86RegisterBankInfo(*getRegisterInfo()); - RegBankInfo.reset(RBI); - InstSelector.reset(createX86InstructionSelector(TM, *this, *RBI)); + GISel->RegBankInfo.reset(RBI); + GISel->InstSelector.reset(createX86InstructionSelector(TM, *this, *RBI)); + setGISelAccessor(*GISel); } const CallLowering *X86Subtarget::getCallLowering() const { - return CallLoweringInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getCallLowering(); } const InstructionSelector *X86Subtarget::getInstructionSelector() const { - return InstSelector.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getInstructionSelector(); } const LegalizerInfo *X86Subtarget::getLegalizerInfo() const { - return Legalizer.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getLegalizerInfo(); } const RegisterBankInfo *X86Subtarget::getRegBankInfo() const { - return RegBankInfo.get(); + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getRegBankInfo(); } bool X86Subtarget::enableEarlyIfConversion() const { diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 2d9eef978df..427a0001bef 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -20,10 +20,7 @@ #include "X86SelectionDAGInfo.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" -#include "llvm/CodeGen/GlobalISel/CallLowering.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" -#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/IR/CallingConv.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Target/TargetMachine.h" @@ -317,11 +314,10 @@ protected: /// Instruction itineraries for scheduling InstrItineraryData InstrItins; - /// GlobalISel related APIs. - std::unique_ptr CallLoweringInfo; - std::unique_ptr Legalizer; - std::unique_ptr RegBankInfo; - std::unique_ptr InstSelector; + /// Gather the accessor points to GlobalISel-related APIs. + /// This is used to avoid ifndefs spreading around while GISel is + /// an optional library. + std::unique_ptr GISel; private: /// Override the stack alignment. @@ -350,6 +346,9 @@ public: X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS, const X86TargetMachine &TM, unsigned StackAlignOverride); + /// This object will take onwership of \p GISelAccessor. + void setGISelAccessor(GISelAccessor &GISel) { this->GISel.reset(&GISel); } + const X86TargetLowering *getTargetLowering() const override { return &TLInfo; } -- 2.50.1