Index: lib/Target/AMDGPU/AMDGPUCallLowering.h =================================================================== --- /dev/null +++ lib/Target/AMDGPU/AMDGPUCallLowering.h @@ -0,0 +1,36 @@ +//===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.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_AMDGPU_AMDGPUCALLLOWERING +#define LLVM_LIB_TARGET_AMDGPU_AMDGPUCALLLOWERING + +#include "llvm/CodeGen/GlobalISel/CallLowering.h" + +namespace llvm { + +class AMDGPUTargetLowering; + +class AMDGPUCallLowering: public CallLowering { + public: + AMDGPUCallLowering(const AMDGPUTargetLowering &TLI); + + bool LowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, + unsigned VReg) const override; + bool + LowerFormalArguments(MachineIRBuilder &MIRBuilder, + const Function::ArgumentListType &Args, + const SmallVectorImpl &VRegs) const override; +}; +} // End of namespace llvm; +#endif Index: lib/Target/AMDGPU/AMDGPUCallLowering.cpp =================================================================== --- /dev/null +++ lib/Target/AMDGPU/AMDGPUCallLowering.cpp @@ -0,0 +1,42 @@ +//===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.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 "AMDGPUCallLowering.h" +#include "AMDGPUISelLowering.h" + +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" + +using namespace llvm; + +#ifndef LLVM_BUILD_GLOBAL_ISEL +#error "This shouldn't be built without GISel" +#endif + +AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI) + : CallLowering(&TLI) { +} + +bool AMDGPUCallLowering::LowerReturn(MachineIRBuilder &MIRBuilder, + const Value *Val, unsigned VReg) const { + return true; +} + +bool AMDGPUCallLowering::LowerFormalArguments( + MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args, + const SmallVectorImpl &VRegs) const { + // TODO: Implement once there are generic loads/stores. + return true; +} Index: lib/Target/AMDGPU/AMDGPUSubtarget.h =================================================================== --- lib/Target/AMDGPU/AMDGPUSubtarget.h +++ lib/Target/AMDGPU/AMDGPUSubtarget.h @@ -17,6 +17,7 @@ #include "AMDGPU.h" #include "AMDGPUFrameLowering.h" +#include "AMDGPUGISelAccessor.h" #include "AMDGPUInstrInfo.h" #include "AMDGPUISelLowering.h" #include "AMDGPUSubtarget.h" @@ -98,6 +99,7 @@ std::unique_ptr FrameLowering; std::unique_ptr TLInfo; std::unique_ptr InstrInfo; + std::unique_ptr GISelAccessor; InstrItineraryData InstrItins; Triple TargetTriple; @@ -107,6 +109,11 @@ AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT, StringRef GPU, StringRef FS); + /// This object will take onwership of \p GISelAccessor. + void setGISelAccessor(AMDGPUGISelAccessor &GISelAccessor) { + this->GISelAccessor.reset(&GISelAccessor); + } + const AMDGPUFrameLowering *getFrameLowering() const override { return FrameLowering.get(); } @@ -123,6 +130,8 @@ return &InstrItins; } + const CallLowering *getCallLowering() const override; + void ParseSubtargetFeatures(StringRef CPU, StringRef FS); bool hasVertexCache() const { Index: lib/Target/AMDGPU/AMDGPUSubtarget.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUSubtarget.cpp +++ lib/Target/AMDGPU/AMDGPUSubtarget.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "AMDGPUSubtarget.h" +#include "AMDGPUCallLowering.h" #include "R600ISelLowering.h" #include "R600InstrInfo.h" #include "R600MachineScheduler.h" @@ -32,6 +33,17 @@ #define GET_SUBTARGETINFO_CTOR #include "AMDGPUGenSubtargetInfo.inc" +#ifdef LLVM_BUILD_GLOBAL_ISEL +namespace { +struct AMDGPUGISelActualAccessor : public AMDGPUGISelAccessor { + std::unique_ptr CallLoweringInfo; + const CallLowering *getCallLowering() const override { + return CallLoweringInfo.get(); + } +}; +} // End anonymous namespace. +#endif + AMDGPUSubtarget & AMDGPUSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef GPU, StringRef FS) { @@ -86,6 +98,7 @@ LDSBankCount(0), IsaVersion(ISAVersion0_0_0), EnableSIScheduler(false), FrameLowering(nullptr), + GISelAccessor(), InstrItins(getInstrItineraryForCPU(GPU)), TargetTriple(TT) { initializeSubtargetDependencies(TT, GPU, FS); @@ -108,9 +121,23 @@ TargetFrameLowering::StackGrowsUp, MaxStackAlign, 0)); +#ifndef LLVM_BUILD_GLOBAL_ISEL + AMDGPUGISelAccessor *GISelAccessor = new AMDGPUGISelAccessor(); +#else + AMDGPUGISelActualAccessor *GISelAccessor = + new AMDGPUGISelActualAccessor(); + GISelAccessor->CallLoweringInfo.reset( + new AMDGPUCallLowering(*getTargetLowering())); +#endif + setGISelAccessor(*GISelAccessor); } } +const CallLowering *AMDGPUSubtarget::getCallLowering() const { + assert(GISelAccessor && "Access to GlobalISel APIs not set"); + return GISelAccessor->getCallLowering(); +} + unsigned AMDGPUSubtarget::getStackEntrySize() const { assert(getGeneration() <= NORTHERN_ISLANDS); switch(getWavefrontSize()) { Index: lib/Target/AMDGPU/AMDGPUTargetMachine.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -23,6 +23,7 @@ #include "SIISelLowering.h" #include "SIInstrInfo.h" #include "llvm/Analysis/Passes.h" +#include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -202,6 +203,10 @@ : AMDGPUPassConfig(TM, PM) { } bool addPreISel() override; bool addInstSelector() override; +#ifdef LLVM_BUILD_GLOBAL_ISEL + bool addIRTranslator() override; + bool addRegBankSelect() override; +#endif void addFastRegAlloc(FunctionPass *RegAllocPass) override; void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override; void addPreRegAlloc() override; @@ -326,6 +331,17 @@ return false; } +#ifdef LLVM_BUILD_GLOBAL_ISEL +bool GCNPassConfig::addIRTranslator() { + addPass(new IRTranslator()); + return false; +} + +bool GCNPassConfig::addRegBankSelect() { + return false; +} +#endif + void GCNPassConfig::addPreRegAlloc() { const AMDGPUSubtarget &ST = *getAMDGPUTargetMachine().getSubtargetImpl(); Index: lib/Target/AMDGPU/CMakeLists.txt =================================================================== --- lib/Target/AMDGPU/CMakeLists.txt +++ lib/Target/AMDGPU/CMakeLists.txt @@ -13,6 +13,20 @@ tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler) add_public_tablegen_target(AMDGPUCommonTableGen) +# List of all GlobalISel files. +set(GLOBAL_ISEL_FILES + AMDGPUCallLowering.cpp + ) + +# Add GlobalISel files to the dependencies if the user wants to build it. +if(LLVM_BUILD_GLOBAL_ISEL) + set(GLOBAL_ISEL_BUILD_FILES ${GLOBAL_ISEL_FILES}) +else() + set(GLOBAL_ISEL_BUILD_FILES"") + set(LLVM_OPTIONAL_SOURCES LLVMGlobalISel ${GLOBAL_ISEL_FILES}) +endif() + + add_llvm_target(AMDGPUCodeGen AMDILCFGStructurizer.cpp AMDGPUAlwaysInlinePass.cpp @@ -63,6 +77,7 @@ SIShrinkInstructions.cpp SITypeRewriter.cpp SIWholeQuadMode.cpp + ${GLOBAL_ISEL_BUILD_FILES} ) add_subdirectory(AsmParser) Index: test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll @@ -0,0 +1,12 @@ +; RUN: llc -march=amdgcn -mcpu=fiji -O0 -stop-after=irtranslator -global-isel %s -o - 2>&1 | FileCheck %s +; REQUIRES: global-isel +; This file checks that the translation from llvm IR to generic MachineInstr +; is correct. + +; Tests for add. +; CHECK: name: addi32 +; CHECK: G_ADD i32 +define i32 @addi32(i32 %arg1, i32 %arg2) { + %res = add i32 %arg1, %arg2 + ret i32 %res +}