82 changes: 80 additions & 2 deletions llvm/lib/Target/ARM/ARMTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,28 @@
//
//===----------------------------------------------------------------------===//

#include "ARMTargetMachine.h"
#include "ARM.h"
#include "ARMCallLowering.h"
#include "ARMFrameLowering.h"
#include "ARMTargetMachine.h"
#include "ARMInstructionSelector.h"
#include "ARMLegalizerInfo.h"
#include "ARMRegisterBankInfo.h"
#include "ARMTargetObjectFile.h"
#include "ARMTargetTransformInfo.h"
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;
Expand Down Expand Up @@ -57,6 +65,7 @@ extern "C" void LLVMInitializeARMTarget() {
RegisterTargetMachine<ThumbBETargetMachine> B(getTheThumbBETarget());

PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeGlobalISel(Registry);
initializeARMLoadStoreOptPass(Registry);
initializeARMPreAllocLoadStoreOptPass(Registry);
}
Expand Down Expand Up @@ -231,6 +240,29 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,

ARMBaseTargetMachine::~ARMBaseTargetMachine() {}

#ifdef LLVM_BUILD_GLOBAL_ISEL
namespace {
struct ARMGISelActualAccessor : public GISelAccessor {
std::unique_ptr<CallLowering> CallLoweringInfo;
std::unique_ptr<InstructionSelector> InstSelector;
std::unique_ptr<LegalizerInfo> Legalizer;
std::unique_ptr<RegisterBankInfo> RegBankInfo;
const CallLowering *getCallLowering() const override {
return CallLoweringInfo.get();
}
const InstructionSelector *getInstructionSelector() const override {
return InstSelector.get();
}
const class LegalizerInfo *getLegalizerInfo() const override {
return Legalizer.get();
}
const RegisterBankInfo *getRegBankInfo() const override {
return RegBankInfo.get();
}
};
} // End anonymous namespace.
#endif

const ARMSubtarget *
ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
Expand Down Expand Up @@ -263,6 +295,24 @@ ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
resetTargetOptions(F);
I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle);
}

#ifndef LLVM_BUILD_GLOBAL_ISEL
GISelAccessor *GISel = new GISelAccessor();
#else
ARMGISelActualAccessor *GISel = new ARMGISelActualAccessor();
GISel->CallLoweringInfo.reset(new ARMCallLowering(*I->getTargetLowering()));
GISel->Legalizer.reset(new ARMLegalizerInfo());

auto *RBI = new ARMRegisterBankInfo(*I->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?
GISel->InstSelector.reset(new ARMInstructionSelector(*this, *I, *RBI));

GISel->RegBankInfo.reset(RBI);
#endif
I->setGISelAccessor(*GISel);
return I.get();
}

Expand Down Expand Up @@ -353,6 +403,12 @@ class ARMPassConfig : public TargetPassConfig {
void addIRPasses() override;
bool addPreISel() override;
bool addInstSelector() override;
#ifdef LLVM_BUILD_GLOBAL_ISEL
bool addIRTranslator() override;
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
#endif
void addPreRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
Expand Down Expand Up @@ -413,6 +469,28 @@ bool ARMPassConfig::addInstSelector() {
return false;
}

#ifdef LLVM_BUILD_GLOBAL_ISEL
bool ARMPassConfig::addIRTranslator() {
addPass(new IRTranslator());
return false;
}

bool ARMPassConfig::addLegalizeMachineIR() {
addPass(new Legalizer());
return false;
}

bool ARMPassConfig::addRegBankSelect() {
addPass(new RegBankSelect());
return false;
}

bool ARMPassConfig::addGlobalInstructionSelect() {
addPass(new InstructionSelect());
return false;
}
#endif

void ARMPassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOpt::None) {
addPass(createMLxExpansionPass());
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/Target/ARM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ tablegen(LLVM ARMGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler)
add_public_tablegen_target(ARMCommonTableGen)

# Add GlobalISel files if the user wants to build it.
set(GLOBAL_ISEL_FILES
ARMCallLowering.cpp
ARMInstructionSelector.cpp
ARMLegalizerInfo.cpp
ARMRegisterBankInfo.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()

add_llvm_target(ARMCodeGen
A15SDOptimizer.cpp
ARMAsmPrinter.cpp
Expand Down Expand Up @@ -45,6 +60,7 @@ add_llvm_target(ARMCodeGen
Thumb2InstrInfo.cpp
Thumb2SizeReduction.cpp
ARMComputeBlockSize.cpp
${GLOBAL_ISEL_BUILD_FILES}
)

add_subdirectory(TargetInfo)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/LLVMBuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ has_jit = 1
type = Library
name = ARMCodeGen
parent = ARM
required_libraries = ARMAsmPrinter ARMDesc ARMInfo Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target
required_libraries = ARMAsmPrinter ARMDesc ARMInfo Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target GlobalISel
add_to_library_groups = ARM
9 changes: 9 additions & 0 deletions llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; RUN: llc -mtriple arm-unknown -global-isel -stop-after=irtranslator %s -o - | FileCheck %s

define void @test_void_return() {
; CHECK-LABEL: name: test_void_return
; CHECK: BX_RET 14, _
entry:
ret void
}

2 changes: 2 additions & 0 deletions llvm/test/CodeGen/ARM/GlobalISel/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
if not 'global-isel' in config.root.available_features:
config.unsupported = True