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
This commit is contained in:
Anton Korobeynikov 2008-06-28 13:45:57 +00:00
parent 4d580651b3
commit 28a2b54580
2 changed files with 69 additions and 2 deletions

View File

@ -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;
}

View File

@ -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);
}