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 | 28a2b54580b28be10c536def7f49b5599adf3631 (patch) | |
tree | d336d72bf1e8f9b58635f4d5447d8edc0dcb9774 /lib | |
parent | 4d580651b3309d6b6a943f6a2b0153bfeab9ef33 (diff) |
Start refactoring of asmprinters: provide a TAI hook, which will select a 'section kind' for a global.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52868 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/TargetAsmInfo.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 67f0cfa5be..2adad3d7ba 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/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); +} |