mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-27 09:17:11 +00:00
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:
@@ -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 TargetMachine;
|
||||||
class CallInst;
|
class CallInst;
|
||||||
|
class GlobalValue;
|
||||||
|
|
||||||
/// TargetAsmInfo - This class is intended to be used as a base class for asm
|
/// TargetAsmInfo - This class is intended to be used as a base class for asm
|
||||||
/// properties and features specific to the target.
|
/// properties and features specific to the target.
|
||||||
@@ -427,7 +441,11 @@ namespace llvm {
|
|||||||
/// if the symbol can be relocated.
|
/// if the symbol can be relocated.
|
||||||
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
|
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
|
||||||
bool Global) const;
|
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.
|
// Accessors.
|
||||||
//
|
//
|
||||||
const char *getTextSection() const {
|
const char *getTextSection() const {
|
||||||
@@ -642,7 +660,7 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
const char *getDwarfSectionOffsetDirective() const {
|
const char *getDwarfSectionOffsetDirective() const {
|
||||||
return DwarfSectionOffsetDirective;
|
return DwarfSectionOffsetDirective;
|
||||||
}
|
}
|
||||||
const char *getDwarfAbbrevSection() const {
|
const char *getDwarfAbbrevSection() const {
|
||||||
return DwarfAbbrevSection;
|
return DwarfAbbrevSection;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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/TargetAsmInfo.h"
|
||||||
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/Support/Dwarf.h"
|
#include "llvm/Support/Dwarf.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -142,3 +148,46 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
|
|||||||
return dwarf::DW_EH_PE_absptr;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user