diff options
author | Chris Lattner <sabre@nondot.org> | 2009-07-24 19:15:47 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-07-24 19:15:47 +0000 |
commit | b303504a562c98b3ce465d0bfcbd3d9334193e1f (patch) | |
tree | 07c90407b9f6d32bc0911555e4d4140a3d946271 /lib/Target/TargetAsmInfo.cpp | |
parent | 49f846805efe101ae8e6dcff6311cc480072845b (diff) | |
download | external_llvm-b303504a562c98b3ce465d0bfcbd3d9334193e1f.zip external_llvm-b303504a562c98b3ce465d0bfcbd3d9334193e1f.tar.gz external_llvm-b303504a562c98b3ce465d0bfcbd3d9334193e1f.tar.bz2 |
make SectionKindForGlobal target independent, and therefore non-virtual.
It's classifications now include elf-specific discriminators. Targets
that don't have these features (like darwin and pecoff) simply treat
data.rel like data, etc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76993 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/TargetAsmInfo.cpp')
-rw-r--r-- | lib/Target/TargetAsmInfo.cpp | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 9893bf9..c52297e 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -232,33 +232,72 @@ TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { return SectionKind::Text; bool isThreadLocal = GVar->isThreadLocal(); - assert(GVar && "Invalid global value for section selection"); - if (isSuitableForBSS(GVar)) { - // Variable can be easily put to BSS section. + // Variable can be easily put to BSS section. + if (isSuitableForBSS(GVar)) return isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS; - } else if (GVar->isConstant() && !isThreadLocal) { - // Now we know, that variable has initializer and it is constant. We need to - // check its initializer to decide, which section to output it into. Also - // note, there is no thread-local r/o section. - Constant *C = GVar->getInitializer(); - if (C->getRelocationInfo() != 0) { - // Decide whether it is still possible to put symbol into r/o section. - if (TM.getRelocationModel() != Reloc::Static) - return SectionKind::Data; - else - return SectionKind::ROData; - } else { - // Check, if initializer is a null-terminated string + + // If this is thread-local, put it in the general "thread_data" section. + if (isThreadLocal) + return SectionKind::ThreadData; + + Constant *C = GVar->getInitializer(); + + // If the global is marked constant, we can put it into a mergable section, + // a mergable string section, or general .data if it contains relocations. + if (GVar->isConstant()) { + // If the initializer for the global contains something that requires a + // relocation, then we may have to drop this into a wriable data section + // even though it is marked const. + switch (C->getRelocationInfo()) { + default: llvm_unreachable("unknown relocation info kind"); + case Constant::NoRelocation: + // If initializer is a null-terminated string, put it in a "cstring" + // section if the target has it. if (isConstantString(C)) return SectionKind::RODataMergeStr; - else - return SectionKind::RODataMergeConst; + + // Otherwise, just drop it into a mergable constant section. + return SectionKind::RODataMergeConst; + + case Constant::LocalRelocation: + // In static relocation model, the linker will resolve all addresses, so + // the relocation entries will actually be constants by the time the app + // starts up. + if (TM.getRelocationModel() == Reloc::Static) + return SectionKind::ROData; + + // Otherwise, the dynamic linker needs to fix it up, put it in the + // writable data.rel.local section. + return SectionKind::DataRelROLocal; + + case Constant::GlobalRelocations: + // In static relocation model, the linker will resolve all addresses, so + // the relocation entries will actually be constants by the time the app + // starts up. + if (TM.getRelocationModel() == Reloc::Static) + return SectionKind::ROData; + + // Otherwise, the dynamic linker needs to fix it up, put it in the + // writable data.rel section. + return SectionKind::DataRelRO; } } - // Variable either is not constant or thread-local - output to data section. - return isThreadLocal ? SectionKind::ThreadData : SectionKind::Data; + // Okay, this isn't a constant. If the initializer for the global is going + // to require a runtime relocation by the dynamic linker, put it into a more + // specific section to improve startup time of the app. This coalesces these + // globals together onto fewer pages, improving the locality of the dynamic + // linker. + if (TM.getRelocationModel() == Reloc::Static) + return SectionKind::Data; + + switch (C->getRelocationInfo()) { + default: llvm_unreachable("unknown relocation info kind"); + case Constant::NoRelocation: return SectionKind::Data; + case Constant::LocalRelocation: return SectionKind::DataRelLocal; + case Constant::GlobalRelocations: return SectionKind::DataRel; + } } |