Index: llvm/trunk/lib/Target/X86/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Target/X86/CMakeLists.txt +++ llvm/trunk/lib/Target/X86/CMakeLists.txt @@ -12,6 +12,19 @@ tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) add_public_tablegen_target(X86CommonTableGen) +# Add GlobalISel files if the build option was enabled. +set(GLOBAL_ISEL_FILES + X86CallLowering.cpp + ) + +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() + + set(sources X86AsmPrinter.cpp X86CallFrameOptimization.cpp @@ -41,6 +54,7 @@ X86VZeroUpper.cpp X86WinAllocaExpander.cpp X86WinEHState.cpp + ${GLOBAL_ISEL_BUILD_FILES} ) add_llvm_target(X86CodeGen ${sources}) Index: llvm/trunk/lib/Target/X86/LLVMBuild.txt =================================================================== --- llvm/trunk/lib/Target/X86/LLVMBuild.txt +++ llvm/trunk/lib/Target/X86/LLVMBuild.txt @@ -31,5 +31,5 @@ type = Library name = X86CodeGen parent = X86 -required_libraries = Analysis AsmPrinter CodeGen Core MC SelectionDAG Support Target X86AsmPrinter X86Desc X86Info X86Utils +required_libraries = Analysis AsmPrinter CodeGen Core MC SelectionDAG Support Target X86AsmPrinter X86Desc X86Info X86Utils GlobalISel add_to_library_groups = X86 Index: llvm/trunk/lib/Target/X86/X86CallLowering.h =================================================================== --- llvm/trunk/lib/Target/X86/X86CallLowering.h +++ llvm/trunk/lib/Target/X86/X86CallLowering.h @@ -0,0 +1,39 @@ +//===-- llvm/lib/Target/X86/X86CallLowering.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_X86_X86CALLLOWERING +#define LLVM_LIB_TARGET_X86_X86CALLLOWERING + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" + +namespace llvm { + +class Function; +class MachineIRBuilder; +class X86TargetLowering; +class Value; + +class X86CallLowering : public CallLowering { +public: + X86CallLowering(const X86TargetLowering &TLI); + + bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, + unsigned VReg) const override; + + bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, + ArrayRef VRegs) const override; +}; +} // End of namespace llvm; +#endif Index: llvm/trunk/lib/Target/X86/X86CallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86CallLowering.cpp +++ llvm/trunk/lib/Target/X86/X86CallLowering.cpp @@ -0,0 +1,46 @@ +//===-- llvm/lib/Target/X86/X86CallLowering.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 "X86CallLowering.h" +#include "X86ISelLowering.h" +#include "X86InstrInfo.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" + +using namespace llvm; + +#ifndef LLVM_BUILD_GLOBAL_ISEL +#error "This shouldn't be built without GISel" +#endif + +X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) + : CallLowering(&TLI) {} + +bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, + const Value *Val, unsigned VReg) const { + // TODO: handle functions returning non-void values. + if (Val) + return false; + + MIRBuilder.buildInstr(X86::RET).addImm(0); + + return true; +} + +bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, + const Function &F, + ArrayRef VRegs) const { + // TODO: handle functions with one or more arguments. + return F.arg_empty(); +} Index: llvm/trunk/lib/Target/X86/X86Subtarget.h =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h +++ llvm/trunk/lib/Target/X86/X86Subtarget.h @@ -19,6 +19,7 @@ #include "X86InstrInfo.h" #include "X86SelectionDAGInfo.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" #include "llvm/IR/CallingConv.h" #include "llvm/Target/TargetSubtargetInfo.h" #include @@ -298,6 +299,10 @@ /// Instruction itineraries for scheduling InstrItineraryData InstrItins; + /// 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. @@ -326,6 +331,9 @@ 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; } @@ -353,6 +361,11 @@ /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef FS); + /// Methods used by Global ISel + const CallLowering *getCallLowering() const override; + const InstructionSelector *getInstructionSelector() const override; + const LegalizerInfo *getLegalizerInfo() const override; + const RegisterBankInfo *getRegBankInfo() const override; private: /// Initialize the full set of dependencies so we can use an initializer /// list for X86Subtarget. Index: llvm/trunk/lib/Target/X86/X86Subtarget.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp @@ -331,6 +331,26 @@ setPICStyle(PICStyles::GOT); } +const CallLowering *X86Subtarget::getCallLowering() const { + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getCallLowering(); +} + +const InstructionSelector *X86Subtarget::getInstructionSelector() const { + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getInstructionSelector(); +} + +const LegalizerInfo *X86Subtarget::getLegalizerInfo() const { + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getLegalizerInfo(); +} + +const RegisterBankInfo *X86Subtarget::getRegBankInfo() const { + assert(GISel && "Access to GlobalISel APIs not set"); + return GISel->getRegBankInfo(); +} + bool X86Subtarget::enableEarlyIfConversion() const { return hasCMov() && X86EarlyIfConv; } Index: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp @@ -13,8 +13,11 @@ #include "X86TargetMachine.h" #include "X86.h" +#include "X86CallLowering.h" #include "X86TargetObjectFile.h" #include "X86TargetTransformInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" +#include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Function.h" @@ -39,6 +42,7 @@ RegisterTargetMachine Y(getTheX86_64Target()); PassRegistry &PR = *PassRegistry::getPassRegistry(); + initializeGlobalISel(PR); initializeWinEHStatePassPass(PR); initializeFixupBWInstPassPass(PR); } @@ -173,6 +177,29 @@ X86TargetMachine::~X86TargetMachine() {} +#ifdef LLVM_BUILD_GLOBAL_ISEL +namespace { +struct X86GISelActualAccessor : public GISelAccessor { + std::unique_ptr CL; + X86GISelActualAccessor(CallLowering* CL): CL(CL) {} + const CallLowering *getCallLowering() const override { + return CL.get(); + } + const InstructionSelector *getInstructionSelector() const override { + //TODO: Implement + return nullptr; + } + const class LegalizerInfo *getLegalizerInfo() const override { + //TODO: Implement + return nullptr; + } + const RegisterBankInfo *getRegBankInfo() const override { + //TODO: Implement + return nullptr; + } +}; +} // End anonymous namespace. +#endif const X86Subtarget * X86TargetMachine::getSubtargetImpl(const Function &F) const { Attribute CPUAttr = F.getFnAttribute("target-cpu"); @@ -212,6 +239,13 @@ resetTargetOptions(F); I = llvm::make_unique(TargetTriple, CPU, FS, *this, Options.StackAlignmentOverride); +#ifndef LLVM_BUILD_GLOBAL_ISEL + GISelAccessor *GISel = new GISelAccessor(); +#else + X86GISelActualAccessor *GISel = new X86GISelActualAccessor( + new X86CallLowering(*I->getTargetLowering())); +#endif + I->setGISelAccessor(*GISel); } return I.get(); } @@ -252,7 +286,13 @@ void addIRPasses() override; bool addInstSelector() override; - bool addILPOpts() override; +#ifdef LLVM_BUILD_GLOBAL_ISEL + bool addIRTranslator() override; + bool addLegalizeMachineIR() override; + bool addRegBankSelect() override; + bool addGlobalInstructionSelect() override; +#endif +bool addILPOpts() override; bool addPreISel() override; void addPreRegAlloc() override; void addPostRegAlloc() override; @@ -287,6 +327,28 @@ return false; } +#ifdef LLVM_BUILD_GLOBAL_ISEL +bool X86PassConfig::addIRTranslator() { + addPass(new IRTranslator()); + return false; +} + +bool X86PassConfig::addLegalizeMachineIR() { + //TODO: Implement + return false; +} + +bool X86PassConfig::addRegBankSelect() { + //TODO: Implement + return false; +} + +bool X86PassConfig::addGlobalInstructionSelect() { + //TODO: Implement + return false; +} +#endif + bool X86PassConfig::addILPOpts() { addPass(&EarlyIfConverterID); if (EnableMachineCombinerPass) Index: llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll +++ llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll @@ -0,0 +1,31 @@ +; RUN: llc -mtriple i386 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s +; RUN: llc -mtriple x86_64 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s + +define void @test_void_return() { +; CHECK-LABEL: name: test_void_return +; CHECK: alignment: 4 +; CHECK-NEXT: exposesReturnsTwice: false +; CHECK-NEXT: legalized: false +; CHECK-NEXT: regBankSelected: false +; CHECK-NEXT: selected: false +; CHECK-NEXT: tracksRegLiveness: true +; CHECK-NEXT: frameInfo: +; CHECK-NEXT: isFrameAddressTaken: false +; CHECK-NEXT: isReturnAddressTaken: false +; CHECK-NEXT: hasStackMap: false +; CHECK-NEXT: hasPatchPoint: false +; CHECK-NEXT: stackSize: 0 +; CHECK-NEXT: offsetAdjustment: 0 +; CHECK-NEXT: maxAlignment: 0 +; CHECK-NEXT: adjustsStack: false +; CHECK-NEXT: hasCalls: false +; CHECK-NEXT: maxCallFrameSize: 0 +; CHECK-NEXT: hasOpaqueSPAdjustment: false +; CHECK-NEXT: hasVAStart: false +; CHECK-NEXT: hasMustTailInVarArgFunc: false +; CHECK-NEXT: body: +; CHECK-NEXT: bb.0: +; CHECK-NEXT: RET 0 +entry: + ret void +} Index: llvm/trunk/test/CodeGen/X86/GlobalISel/lit.local.cfg =================================================================== --- llvm/trunk/test/CodeGen/X86/GlobalISel/lit.local.cfg +++ llvm/trunk/test/CodeGen/X86/GlobalISel/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'global-isel' in config.root.available_features: + config.unsupported = True