From d6b43a317e71246380db55a50b799b062b53cdce Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 19 Jun 2012 00:48:28 +0000 Subject: Move the support for using .init_array from ARM to the generic TargetLoweringObjectFileELF. Use this to support it on X86. Unlike ARM, on X86 it is not easy to find out if .init_array should be used or not, so the decision is made via TargetOptions and defaults to off. Add a command line option to llc that enables it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158692 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/CodeGen/TargetLoweringObjectFileImpl.h | 3 ++ include/llvm/Target/TargetOptions.h | 6 ++- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 48 ++++++++++++++++++---- lib/Target/ARM/ARMTargetObjectFile.cpp | 43 +------------------ lib/Target/ARM/ARMTargetObjectFile.h | 4 -- lib/Target/X86/X86ISelLowering.cpp | 2 + lib/Target/X86/X86TargetObjectFile.cpp | 9 ++++ lib/Target/X86/X86TargetObjectFile.h | 6 +++ test/CodeGen/X86/constructor.ll | 27 ++++++++++++ tools/llc/llc.cpp | 5 +++ 10 files changed, 99 insertions(+), 54 deletions(-) create mode 100644 test/CodeGen/X86/constructor.ll diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 5a4213625b..9849e92f7d 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -33,6 +33,8 @@ namespace llvm { class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { + bool UseInitArray; + public: virtual ~TargetLoweringObjectFileELF() {} @@ -66,6 +68,7 @@ public: getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const; + void InitializeELF(bool UseInitArray_); virtual const MCSection * getStaticCtorSection(unsigned Priority = 65535) const; virtual const MCSection * diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 12a2757315..bc60673589 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -43,7 +43,7 @@ namespace llvm { StackAlignmentOverride(0), RealignStack(true), DisableJumpTables(false), EnableFastISel(false), PositionIndependentExecutable(false), EnableSegmentedStacks(false), - TrapFuncName(""), FloatABIType(FloatABI::Default) + UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -172,6 +172,10 @@ namespace llvm { unsigned EnableSegmentedStacks : 1; + /// UseInitArray - Use .init_array instead of .ctors for static + /// constructors. + unsigned UseInitArray : 1; + /// getTrapFunctionName - If this returns a non-empty string, this means /// isel should lower Intrinsic::trap to a call to the specified function /// name instead of an ISD::TRAP node. diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 7a89e3ca63..6842eec486 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -349,10 +349,17 @@ TargetLoweringObjectFileELF::getStaticCtorSection(unsigned Priority) const { if (Priority == 65535) return StaticCtorSection; - std::string Name = std::string(".ctors.") + utostr(65535 - Priority); - return getContext().getELFSection(Name, ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); + if (UseInitArray) { + std::string Name = std::string(".init_array.") + utostr(Priority); + return getContext().getELFSection(Name, ELF::SHT_INIT_ARRAY, + ELF::SHF_ALLOC | ELF::SHF_WRITE, + SectionKind::getDataRel()); + } else { + std::string Name = std::string(".ctors.") + utostr(65535 - Priority); + return getContext().getELFSection(Name, ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getDataRel()); + } } const MCSection * @@ -362,10 +369,35 @@ TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const { if (Priority == 65535) return StaticDtorSection; - std::string Name = std::string(".dtors.") + utostr(65535 - Priority); - return getContext().getELFSection(Name, ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); + if (UseInitArray) { + std::string Name = std::string(".fini_array.") + utostr(Priority); + return getContext().getELFSection(Name, ELF::SHT_FINI_ARRAY, + ELF::SHF_ALLOC | ELF::SHF_WRITE, + SectionKind::getDataRel()); + } else { + std::string Name = std::string(".dtors.") + utostr(65535 - Priority); + return getContext().getELFSection(Name, ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getDataRel()); + } +} + +void +TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { + UseInitArray = UseInitArray_; + if (!UseInitArray) + return; + + StaticCtorSection = + getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY, + ELF::SHF_WRITE | + ELF::SHF_ALLOC, + SectionKind::getDataRel()); + StaticDtorSection = + getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, + ELF::SHF_WRITE | + ELF::SHF_ALLOC, + SectionKind::getDataRel()); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMTargetObjectFile.cpp b/lib/Target/ARM/ARMTargetObjectFile.cpp index a5ea1c202e..3d85ca7d69 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -24,20 +24,11 @@ using namespace dwarf; void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { + bool isAAPCS_ABI = TM.getSubtarget().isAAPCS_ABI(); TargetLoweringObjectFileELF::Initialize(Ctx, TM); - isAAPCS_ABI = TM.getSubtarget().isAAPCS_ABI(); + InitializeELF(isAAPCS_ABI); if (isAAPCS_ABI) { - StaticCtorSection = - getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getDataRel()); - StaticDtorSection = - getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getDataRel()); LSDASection = NULL; } @@ -47,33 +38,3 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, 0, SectionKind::getMetadata()); } - -const MCSection * -ARMElfTargetObjectFile::getStaticCtorSection(unsigned Priority) const { - if (!isAAPCS_ABI) - return TargetLoweringObjectFileELF::getStaticCtorSection(Priority); - - if (Priority == 65535) - return StaticCtorSection; - - // Emit ctors in priority order. - std::string Name = std::string(".init_array.") + utostr(Priority); - return getContext().getELFSection(Name, ELF::SHT_INIT_ARRAY, - ELF::SHF_ALLOC | ELF::SHF_WRITE, - SectionKind::getDataRel()); -} - -const MCSection * -ARMElfTargetObjectFile::getStaticDtorSection(unsigned Priority) const { - if (!isAAPCS_ABI) - return TargetLoweringObjectFileELF::getStaticDtorSection(Priority); - - if (Priority == 65535) - return StaticDtorSection; - - // Emit dtors in priority order. - std::string Name = std::string(".fini_array.") + utostr(Priority); - return getContext().getELFSection(Name, ELF::SHT_FINI_ARRAY, - ELF::SHF_ALLOC | ELF::SHF_WRITE, - SectionKind::getDataRel()); -} diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h index ff21060414..c6a7261439 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.h +++ b/lib/Target/ARM/ARMTargetObjectFile.h @@ -20,7 +20,6 @@ class TargetMachine; class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF { protected: const MCSection *AttributesSection; - bool isAAPCS_ABI; public: ARMElfTargetObjectFile() : TargetLoweringObjectFileELF(), @@ -32,9 +31,6 @@ public: virtual const MCSection *getAttributesSection() const { return AttributesSection; } - - const MCSection * getStaticCtorSection(unsigned Priority) const; - const MCSection * getStaticDtorSection(unsigned Priority) const; }; } // end namespace llvm diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 74902c69ca..dec8d07d99 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -140,6 +140,8 @@ static TargetLoweringObjectFile *createTLOF(X86TargetMachine &TM) { return new TargetLoweringObjectFileMachO(); } + if (Subtarget->isTargetLinux()) + return new X86LinuxTargetObjectFile(); if (Subtarget->isTargetELF()) return new TargetLoweringObjectFileELF(); if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho()) diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp index 718f35ea84..b8d673facc 100644 --- a/lib/Target/X86/X86TargetObjectFile.cpp +++ b/lib/Target/X86/X86TargetObjectFile.cpp @@ -9,12 +9,15 @@ #include "X86TargetObjectFile.h" #include "X86TargetMachine.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Target/Mangler.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/ELF.h" using namespace llvm; using namespace dwarf; @@ -42,3 +45,9 @@ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const { return Mang->getSymbol(GV); } + +void +X86LinuxTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); +} diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h index a02a36809e..7698b59d69 100644 --- a/lib/Target/X86/X86TargetObjectFile.h +++ b/lib/Target/X86/X86TargetObjectFile.h @@ -32,6 +32,12 @@ namespace llvm { MachineModuleInfo *MMI) const; }; + /// X86LinuxTargetObjectFile - This implementation is used for linux x86 + /// and x86-64. + class X86LinuxTargetObjectFile : public TargetLoweringObjectFileELF { + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + }; + } // end namespace llvm #endif diff --git a/test/CodeGen/X86/constructor.ll b/test/CodeGen/X86/constructor.ll new file mode 100644 index 0000000000..f6dec160e9 --- /dev/null +++ b/test/CodeGen/X86/constructor.ll @@ -0,0 +1,27 @@ +; RUN: llc < %s | FileCheck --check-prefix=CTOR %s +; RUN: llc -use-init-array < %s | FileCheck --check-prefix=INIT-ARRAY %s +@llvm.global_ctors = appending global [2 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }, { i32, void ()* } { i32 15, void ()* @g }] + +define void @f() { +entry: + ret void +} + +define void @g() { +entry: + ret void +} + +; CTOR: .section .ctors.65520,"aw",@progbits +; CTOR-NEXT: .align 8 +; CTOR-NEXT: .quad g +; CTOR-NEXT: .section .ctors,"aw",@progbits +; CTOR-NEXT: .align 8 +; CTOR-NEXT: .quad f + +; INIT-ARRAY: .section .init_array.15,"aw",@init_array +; INIT-ARRAY-NEXT: .align 8 +; INIT-ARRAY-NEXT: .quad g +; INIT-ARRAY-NEXT: .section .init_array,"aw",@init_array +; INIT-ARRAY-NEXT: .align 8 +; INIT-ARRAY-NEXT: .quad f diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index a99d0b787a..d0880913ba 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -244,6 +244,10 @@ SegmentedStacks("segmented-stacks", cl::desc("Use segmented stacks if possible."), cl::init(false)); +static cl::opt +UseInitArray("use-init-array", + cl::desc("Use .init_array instead of .ctors."), + cl::init(false)); // GetFileNameRoot - Helper function to get the basename of a filename. static inline std::string @@ -418,6 +422,7 @@ int main(int argc, char **argv) { Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; std::auto_ptr target(TheTarget->createTargetMachine(TheTriple.getTriple(), -- cgit v1.2.3