From: Tim Northover Date: Mon, 10 Oct 2016 21:50:00 +0000 (+0000) Subject: GlobalISel: select G_GLOBAL_VALUE uses on AArch64. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b725b3cddfc7e7595274c4d7507592442d908330;p=llvm GlobalISel: select G_GLOBAL_VALUE uses on AArch64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283809 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/lib/CodeGen/GlobalISel/InstructionSelector.cpp index 9d2630f2fca..9149864817c 100644 --- a/lib/CodeGen/GlobalISel/InstructionSelector.cpp +++ b/lib/CodeGen/GlobalISel/InstructionSelector.cpp @@ -32,8 +32,8 @@ bool InstructionSelector::constrainSelectedInstRegOperands( for (unsigned OpI = 0, OpE = I.getNumExplicitOperands(); OpI != OpE; ++OpI) { MachineOperand &MO = I.getOperand(OpI); - // There's nothing to be done on immediates and frame indexes. - if (MO.isImm() || MO.isFI()) + // There's nothing to be done on non-register operands. + if (!MO.isReg()) continue; DEBUG(dbgs() << "Converting operand: " << MO << '\n'); diff --git a/lib/Target/AArch64/AArch64InstructionSelector.cpp b/lib/Target/AArch64/AArch64InstructionSelector.cpp index 628e1708684..b534f248e40 100644 --- a/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -17,6 +17,7 @@ #include "AArch64RegisterBankInfo.h" #include "AArch64RegisterInfo.h" #include "AArch64Subtarget.h" +#include "AArch64TargetMachine.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" @@ -35,8 +36,9 @@ using namespace llvm; #endif AArch64InstructionSelector::AArch64InstructionSelector( - const AArch64Subtarget &STI, const AArch64RegisterBankInfo &RBI) - : InstructionSelector(), TII(*STI.getInstrInfo()), + const AArch64TargetMachine &TM, const AArch64Subtarget &STI, + const AArch64RegisterBankInfo &RBI) + : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI) {} /// Check whether \p I is a currently unsupported binary operation: @@ -256,6 +258,26 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return constrainSelectedInstRegOperands(I, TII, TRI, RBI); } + + case TargetOpcode::G_GLOBAL_VALUE: { + auto GV = I.getOperand(1).getGlobal(); + if (GV->isThreadLocal()) { + // FIXME: we don't support TLS yet. + return false; + } + unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM); + if (OpFlags & AArch64II::MO_GOT) + I.setDesc(TII.get(AArch64::LOADgot)); + else { + I.setDesc(TII.get(AArch64::MOVaddr)); + I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE); + MachineInstrBuilder MIB(MF, I); + MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(), + OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + } + return constrainSelectedInstRegOperands(I, TII, TRI, RBI); + } + case TargetOpcode::G_LOAD: case TargetOpcode::G_STORE: { LLT MemTy = Ty; diff --git a/lib/Target/AArch64/AArch64InstructionSelector.h b/lib/Target/AArch64/AArch64InstructionSelector.h index 8b9a90d7f2f..97e1b58400e 100644 --- a/lib/Target/AArch64/AArch64InstructionSelector.h +++ b/lib/Target/AArch64/AArch64InstructionSelector.h @@ -21,15 +21,19 @@ class AArch64InstrInfo; class AArch64RegisterBankInfo; class AArch64RegisterInfo; class AArch64Subtarget; +class AArch64TargetMachine; class AArch64InstructionSelector : public InstructionSelector { public: - AArch64InstructionSelector(const AArch64Subtarget &STI, + AArch64InstructionSelector(const AArch64TargetMachine &TM, + const AArch64Subtarget &STI, const AArch64RegisterBankInfo &RBI); virtual bool select(MachineInstr &I) const override; private: + const AArch64TargetMachine &TM; + const AArch64Subtarget &STI; const AArch64InstrInfo &TII; const AArch64RegisterInfo &TRI; const AArch64RegisterBankInfo &RBI; diff --git a/lib/Target/AArch64/AArch64TargetMachine.cpp b/lib/Target/AArch64/AArch64TargetMachine.cpp index 6c906b43ebe..f0fd0543351 100644 --- a/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -254,7 +254,7 @@ AArch64TargetMachine::getSubtargetImpl(const Function &F) const { // 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 AArch64InstructionSelector(*I, *RBI)); + GISel->InstSelector.reset(new AArch64InstructionSelector(*this, *I, *RBI)); GISel->RegBankInfo.reset(RBI); #endif diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir index dd12bc833d6..8f280ecf88a 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir +++ b/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir @@ -5,7 +5,7 @@ --- | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" - target triple = "aarch64--" + target triple = "aarch64-apple-ios" define void @add_s32_gpr() { ret void } define void @add_s64_gpr() { ret void } @@ -71,6 +71,12 @@ define i64 @const_s64() { ret i64 1234567890123 } define i8* @gep(i8* %in) { ret i8* undef } + + @var_local = global i8 0 + define i8* @global_local() { ret i8* undef } + + @var_got = external global i8 + define i8* @global_got() { ret i8* undef } ... --- @@ -1142,3 +1148,34 @@ body: | %1(s64) = G_CONSTANT 42 %2(p0) = G_GEP %0, %1(s64) ... + +--- +# Global defined in the same linkage unit so no GOT is needed +# CHECK-LABEL: name: global_local +name: global_local +legalized: true +regBankSelected: true +registers: + - { id: 0, class: gpr } + +# CHECK: body: +# CHECK: %0 = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local +body: | + bb.0: + %0(p0) = G_GLOBAL_VALUE @var_local +... + +--- +# CHECK-LABEL: name: global_got +name: global_got +legalized: true +regBankSelected: true +registers: + - { id: 0, class: gpr } + +# CHECK: body: +# CHECK: %0 = LOADgot @var_got +body: | + bb.0: + %0(p0) = G_GLOBAL_VALUE @var_got +...