diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-06-28 13:45:57 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-06-28 13:45:57 +0000 |
commit | 2e052a81fd806c90605abaef19f40feb54aa825c (patch) | |
tree | 4c554be8360d2690096287ca0534ff05e2155d13 | |
parent | 3c21b05225e454a125dc37f69d01293d7a3203fb (diff) | |
download | bcm5719-llvm-2e052a81fd806c90605abaef19f40feb54aa825c.tar.gz bcm5719-llvm-2e052a81fd806c90605abaef19f40feb54aa825c.zip |
Start refactoring of asmprinters: provide a TAI hook, which will select a 'section kind' for a global.
llvm-svn: 52868
-rw-r--r-- | llvm/include/llvm/Target/TargetAsmInfo.h | 22 | ||||
-rw-r--r-- | llvm/lib/Target/TargetAsmInfo.cpp | 49 |
2 files changed, 69 insertions, 2 deletions
diff --git a/llvm/include/llvm/Target/TargetAsmInfo.h b/llvm/include/llvm/Target/TargetAsmInfo.h index 9b5ba4819cb..3b16ef1645f 100644 --- a/llvm/include/llvm/Target/TargetAsmInfo.h +++ b/llvm/include/llvm/Target/TargetAsmInfo.h @@ -29,8 +29,22 @@ namespace llvm { }; } + namespace SectionKind { + enum Kind { + Text, ///< Text section + Data, ///< Data section + BSS, ///< BSS section + ROData, ///< Readonly data section + RODataMergeStr, ///< Readonly data section (mergeable strings) + RODataMergeConst, ///< Readonly data section (mergeable constants) + ThreadData, ///< Initialized TLS data objects + ThreadBSS ///< Uninitialized TLS data objects + }; + } + class TargetMachine; class CallInst; + class GlobalValue; /// TargetAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. @@ -427,7 +441,11 @@ namespace llvm { /// if the symbol can be relocated. virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, bool Global) const; - + + /// SectionKindForGlobal - This hook allows the target to select proper + /// section kind used for global emission. + SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const; + // Accessors. // const char *getTextSection() const { @@ -642,7 +660,7 @@ namespace llvm { } const char *getDwarfSectionOffsetDirective() const { return DwarfSectionOffsetDirective; - } + } const char *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } diff --git a/llvm/lib/Target/TargetAsmInfo.cpp b/llvm/lib/Target/TargetAsmInfo.cpp index 67f0cfa5be8..2adad3d7baa 100644 --- a/llvm/lib/Target/TargetAsmInfo.cpp +++ b/llvm/lib/Target/TargetAsmInfo.cpp @@ -12,7 +12,13 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constants.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Function.h" +#include "llvm/Module.h" +#include "llvm/Type.h" #include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Support/Dwarf.h" #include <cctype> #include <cstring> @@ -142,3 +148,46 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, return dwarf::DW_EH_PE_absptr; } +static bool isSuitableForBSS(const GlobalVariable *GV) { + if (!GV->hasInitializer()) + return true; + + // Leave constant zeros in readonly constant sections, so they can be shared + Constant *C = GV->getInitializer(); + return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS); +} + +SectionKind::Kind +TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { + // Early exit - functions should be always in text sections. + if (isa<Function>(GV)) + return SectionKind::Text; + + const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV); + bool isThreadLocal = GVar->isThreadLocal(); + assert(GVar && "Invalid global value for section selection"); + + SectionKind::Kind kind; + if (isSuitableForBSS(GVar)) { + // Variable can be easily put to BSS section. + return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS); + } else if (GVar->isConstant() && !isThreadLocal) { + // Now we know, that varible 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->ContainsRelocations()) + kind = SectionKind::ROData; + else { + const ConstantArray *CVA = dyn_cast<ConstantArray>(C); + // Check, if initializer is a null-terminated string + if (CVA && CVA->isCString()) + kind = SectionKind::RODataMergeStr; + else + kind = SectionKind::RODataMergeConst; + } + } + + // Variable is not constant or thread-local - emit to generic data section. + return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data); +} |