Index: lib/Target/AMDGPU/AMDGPUCallLowering.h =================================================================== --- /dev/null +++ lib/Target/AMDGPU/AMDGPUCallLowering.h @@ -0,0 +1,36 @@ +//===- lib/Target/AMDGPU/AMDGPUCallLowering.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_LIB_TARGET_AMDGPU_AMDGPUCALLLOWERING_H +#define LLVM_LIB_TARGET_AMDGPU_AMDGPUCALLLOWERING_H + +#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 @@ -22,6 +22,7 @@ #include "AMDGPUSubtarget.h" #include "Utils/AMDGPUBaseInfo.h" #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/Target/TargetSubtargetInfo.h" #define GET_SUBTARGETINFO_HEADER @@ -98,6 +99,7 @@ std::unique_ptr FrameLowering; std::unique_ptr TLInfo; std::unique_ptr InstrInfo; + std::unique_ptr GISel; InstrItineraryData InstrItins; Triple TargetTriple; @@ -107,6 +109,10 @@ AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT, StringRef GPU, StringRef FS); + void setGISelAccessor(GISelAccessor &GISel) { + this->GISel.reset(&GISel); + } + const AMDGPUFrameLowering *getFrameLowering() const override { return FrameLowering.get(); } @@ -123,6 +129,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 GISelAccessor { + 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), + GISel(), InstrItins(getInstrItineraryForCPU(GPU)), TargetTriple(TT) { initializeSubtargetDependencies(TT, GPU, FS); @@ -108,9 +121,23 @@ TargetFrameLowering::StackGrowsUp, MaxStackAlign, 0)); +#ifndef LLVM_BUILD_GLOBAL_ISEL + GISelAccessor *GISel = new GISelAccessor(); +#else + AMDGPUGISelActualAccessor *GISel = + new AMDGPUGISelActualAccessor(); + GISel->CallLoweringInfo.reset( + new AMDGPUCallLowering(*getTargetLowering())); +#endif + setGISelAccessor(*GISel); } } +const CallLowering *AMDGPUSubtarget::getCallLowering() const { + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->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 +}