From a224de06bc816812a5918c146b351c92b05d6ed8 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 26 May 2016 12:42:55 +0000 Subject: [PATCH] Use shouldAssumeDSOLocal on AArch64. This reduces code duplication and now AArch64 also handles PIE. llvm-svn: 270844 --- llvm/include/llvm/CodeGen/Analysis.h | 5 +++ llvm/lib/CodeGen/Analysis.cpp | 43 +++++++++++++++++++ llvm/lib/Target/AArch64/AArch64Subtarget.cpp | 25 +++-------- llvm/lib/Target/X86/X86Subtarget.cpp | 44 +------------------- llvm/test/CodeGen/AArch64/pie.ll | 14 +++++++ 5 files changed, 69 insertions(+), 62 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/pie.ll diff --git a/llvm/include/llvm/CodeGen/Analysis.h b/llvm/include/llvm/CodeGen/Analysis.h index 38e64ad3be29..d425fed42125 100644 --- a/llvm/include/llvm/CodeGen/Analysis.h +++ b/llvm/include/llvm/CodeGen/Analysis.h @@ -17,10 +17,12 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" +#include "llvm/Support/CodeGen.h" namespace llvm { class GlobalValue; @@ -118,6 +120,9 @@ bool returnTypeIsEligibleForTailCall(const Function *F, // or we are in LTO. bool canBeOmittedFromSymbolTable(const GlobalValue *GV); +bool shouldAssumeDSOLocal(Reloc::Model RM, const Triple &TT, const Module &M, + const GlobalValue *GV); + DenseMap getFuncletMembership(const MachineFunction &MF); diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp index 292142b848c7..ef405484e84c 100644 --- a/llvm/lib/CodeGen/Analysis.cpp +++ b/llvm/lib/CodeGen/Analysis.cpp @@ -650,6 +650,49 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) { return !GS.IsCompared; } +// FIXME: make this a proper option +static bool CanUseCopyRelocWithPIE = false; + +bool llvm::shouldAssumeDSOLocal(Reloc::Model RM, const Triple &TT, + const Module &M, const GlobalValue *GV) { + // DLLImport explicitly marks the GV as external. + if (GV && GV->hasDLLImportStorageClass()) + return false; + + // Every other GV is local on COFF + if (TT.isOSBinFormatCOFF()) + return true; + + if (RM == Reloc::Static) + return true; + + if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility())) + return true; + + if (TT.isOSBinFormatELF()) { + assert(RM != Reloc::DynamicNoPIC); + // Some linkers can use copy relocations with pie executables. + if (M.getPIELevel() != PIELevel::Default) { + if (CanUseCopyRelocWithPIE) + return true; + + // If the symbol is defined, it cannot be preempted. + if (GV && !GV->isDeclarationForLinker()) + return true; + return false; + } + + // ELF supports preemption of other symbols. + return false; + } + + assert(TT.isOSBinFormatMachO()); + if (GV && GV->isStrongDefinitionForLinker()) + return true; + + return false; +} + static void collectFuncletMembers( DenseMap &FuncletMembership, int Funclet, const MachineBasicBlock *MBB) { diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp index 3cd03e8edd1d..7d8aa0c94856 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp @@ -14,6 +14,7 @@ #include "AArch64Subtarget.h" #include "AArch64InstrInfo.h" #include "AArch64PBQPRegAlloc.h" +#include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/MachineScheduler.h" #include "llvm/IR/GlobalValue.h" #include "llvm/Support/TargetRegistry.h" @@ -73,39 +74,25 @@ const RegisterBankInfo *AArch64Subtarget::getRegBankInfo() const { unsigned char AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { - bool isDef = GV->isStrongDefinitionForLinker(); - // MachO large model always goes via a GOT, simply to get a single 8-byte // absolute relocation on all global addresses. if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) return AArch64II::MO_GOT; + Reloc::Model RM = TM.getRelocationModel(); + if (!shouldAssumeDSOLocal(RM, TargetTriple, *GV->getParent(), GV)) + return AArch64II::MO_GOT; + // The small code mode's direct accesses use ADRP, which cannot necessarily // produce the value 0 (if the code is above 4GB). if (TM.getCodeModel() == CodeModel::Small && GV->hasExternalWeakLinkage()) { // In PIC mode use the GOT, but in absolute mode use a constant pool load. - if (TM.getRelocationModel() == Reloc::Static) + if (RM == Reloc::Static) return AArch64II::MO_CONSTPOOL; else return AArch64II::MO_GOT; } - // If symbol visibility is hidden, the extra load is not needed if - // the symbol is definitely defined in the current translation unit. - - // The handling of non-hidden symbols in PIC mode is rather target-dependent: - // + On MachO, if the symbol is defined in this module the GOT can be - // skipped. - // + On ELF, the R_AARCH64_COPY relocation means that even symbols actually - // defined could end up in unexpected places. Use a GOT. - if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) { - if (isTargetMachO()) - return isDef ? AArch64II::MO_NO_FLAG : AArch64II::MO_GOT; - else - // No need to go through the GOT for local symbols on ELF. - return GV->hasLocalLinkage() ? AArch64II::MO_NO_FLAG : AArch64II::MO_GOT; - } - return AArch64II::MO_NO_FLAG; } diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index a24b425a4e83..99adf9c459af 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -14,6 +14,7 @@ #include "X86Subtarget.h" #include "X86InstrInfo.h" #include "X86TargetMachine.h" +#include "llvm/CodeGen/Analysis.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" @@ -50,49 +51,6 @@ unsigned char X86Subtarget::classifyBlockAddressReference() const { return classifyLocalReference(nullptr); } -// FIXME: make this a proper option -static bool CanUseCopyRelocWithPIE = false; - -static bool shouldAssumeDSOLocal(Reloc::Model RM, const Triple &TT, - const Module &M, const GlobalValue *GV) { - // DLLImport explicitly marks the GV as external. - if (GV && GV->hasDLLImportStorageClass()) - return false; - - // Every other GV is local on COFF - if (TT.isOSBinFormatCOFF()) - return true; - - if (RM == Reloc::Static) - return true; - - if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility())) - return true; - - if (TT.isOSBinFormatELF()) { - assert(RM != Reloc::DynamicNoPIC); - // Some linkers can use copy relocations with pie executables. - if (M.getPIELevel() != PIELevel::Default) { - if (CanUseCopyRelocWithPIE) - return true; - - // If the symbol is defined, it cannot be preempted. - if (GV && !GV->isDeclarationForLinker()) - return true; - return false; - } - - // ELF supports preemption of other symbols. - return false; - } - - assert(TT.isOSBinFormatMachO()); - if (GV && GV->isStrongDefinitionForLinker()) - return true; - - return false; -} - /// Classify a global variable reference for the current subtarget according to /// how we should reference it in a non-pcrel context. unsigned char diff --git a/llvm/test/CodeGen/AArch64/pie.ll b/llvm/test/CodeGen/AArch64/pie.ll new file mode 100644 index 000000000000..5cd27a8761cc --- /dev/null +++ b/llvm/test/CodeGen/AArch64/pie.ll @@ -0,0 +1,14 @@ +; RUN: llc -mtriple aarch64-pc-linux -relocation-model=pic < %s | FileCheck %s + +@g1 = global i32 42 + +define i32* @get_g1() { +; CHECK: get_g1: +; CHECK: adrp x0, g1 +; CHECK-NEXT: add x0, x0, :lo12:g1 + ret i32* @g1 +} + +!llvm.module.flags = !{!0} + +!0 = !{i32 1, !"PIE Level", i32 2}