mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-21 03:32:21 +00:00
reimplement Constant::ContainsRelocations as
Constant::getRelocationInfo(), which has a much simpler to use API. It still should not be part of libvmcore, but is better than it was. Also teach it to be smart about hidden visibility. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76700 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9c5beed5f5
commit
7cf12c7efd
@ -20,20 +20,6 @@ namespace llvm {
|
|||||||
template<typename T> class SmallVectorImpl;
|
template<typename T> class SmallVectorImpl;
|
||||||
class LLVMContext;
|
class LLVMContext;
|
||||||
|
|
||||||
/// If object contains references to other objects, then relocations are
|
|
||||||
/// usually required for emission of such object (especially in PIC mode). One
|
|
||||||
/// usually distinguishes local and global relocations. Local relocations are
|
|
||||||
/// made wrt objects in the same module and these objects have local (internal
|
|
||||||
/// or private) linkage. Global relocations are made wrt externally visible
|
|
||||||
/// objects. In most cases local relocations can be resolved via so-called
|
|
||||||
/// 'pre-link' technique.
|
|
||||||
namespace Reloc {
|
|
||||||
const unsigned None = 0;
|
|
||||||
const unsigned Local = 1 << 0; ///< Local relocations are required
|
|
||||||
const unsigned Global = 1 << 1; ///< Global relocations are required
|
|
||||||
const unsigned LocalOrGlobal = Local | Global;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is an important base class in LLVM. It provides the common facilities
|
/// This is an important base class in LLVM. It provides the common facilities
|
||||||
/// of all constant values in an LLVM program. A constant is a value that is
|
/// of all constant values in an LLVM program. A constant is a value that is
|
||||||
/// immutable at runtime. Functions are constants because their address is
|
/// immutable at runtime. Functions are constants because their address is
|
||||||
@ -73,12 +59,21 @@ public:
|
|||||||
/// true for things like constant expressions that could divide by zero.
|
/// true for things like constant expressions that could divide by zero.
|
||||||
bool canTrap() const;
|
bool canTrap() const;
|
||||||
|
|
||||||
/// ContainsRelocations - Return true if the constant value contains
|
/// getRelocationInfo - This method classifies the entry according to
|
||||||
/// relocations which cannot be resolved at compile time. Note that answer is
|
/// whether or not it may generate a relocation entry. This must be
|
||||||
/// not exclusive: there can be possibility that relocations of other kind are
|
/// conservative, so if it might codegen to a relocatable entry, it should say
|
||||||
/// required as well.
|
/// so. The return values are:
|
||||||
bool ContainsRelocations(unsigned Kind = Reloc::LocalOrGlobal) const;
|
///
|
||||||
|
/// 0: This constant pool entry is guaranteed to never have a relocation
|
||||||
|
/// applied to it (because it holds a simple constant like '4').
|
||||||
|
/// 1: This entry has relocations, but the entries are guaranteed to be
|
||||||
|
/// resolvable by the static linker, so the dynamic linker will never see
|
||||||
|
/// them.
|
||||||
|
/// 2: This entry may have arbitrary relocations.
|
||||||
|
///
|
||||||
|
/// FIXME: This really should not be in VMCore.
|
||||||
|
unsigned getRelocationInfo() const;
|
||||||
|
|
||||||
// Specialize get/setOperand for Constants as their operands are always
|
// Specialize get/setOperand for Constants as their operands are always
|
||||||
// constants as well.
|
// constants as well.
|
||||||
Constant *getOperand(unsigned i) {
|
Constant *getOperand(unsigned i) {
|
||||||
|
@ -547,19 +547,7 @@ const Type *MachineConstantPoolEntry::getType() const {
|
|||||||
unsigned MachineConstantPoolEntry::getRelocationInfo() const {
|
unsigned MachineConstantPoolEntry::getRelocationInfo() const {
|
||||||
if (isMachineConstantPoolEntry())
|
if (isMachineConstantPoolEntry())
|
||||||
return Val.MachineCPVal->getRelocationInfo();
|
return Val.MachineCPVal->getRelocationInfo();
|
||||||
|
return Val.ConstVal->getRelocationInfo();
|
||||||
// FIXME: This API sucks.
|
|
||||||
|
|
||||||
// If no relocations, return 0.
|
|
||||||
if (!Val.ConstVal->ContainsRelocations())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If it contains no global relocations, return 1.
|
|
||||||
if (!Val.ConstVal->ContainsRelocations(Reloc::Global))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// Otherwise, it has general relocations.
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineConstantPool::~MachineConstantPool() {
|
MachineConstantPool::~MachineConstantPool() {
|
||||||
|
@ -54,20 +54,20 @@ ELFTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
|
|||||||
|
|
||||||
// Decide, whether we need data.rel stuff
|
// Decide, whether we need data.rel stuff
|
||||||
const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
|
const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
|
||||||
if (GVar->hasInitializer()) {
|
if (GVar->hasInitializer() && TM.getRelocationModel() != Reloc::Static) {
|
||||||
Constant *C = GVar->getInitializer();
|
Constant *C = GVar->getInitializer();
|
||||||
bool isConstant = GVar->isConstant();
|
bool isConstant = GVar->isConstant();
|
||||||
|
|
||||||
|
|
||||||
// By default - all relocations in PIC mode would force symbol to be
|
// By default - all relocations in PIC mode would force symbol to be
|
||||||
// placed in r/w section.
|
// placed in r/w section.
|
||||||
if (TM.getRelocationModel() != Reloc::Static &&
|
switch (C->getRelocationInfo()) {
|
||||||
C->ContainsRelocations(Reloc::LocalOrGlobal))
|
default: break;
|
||||||
return (C->ContainsRelocations(Reloc::Global) ?
|
case 1:
|
||||||
(isConstant ?
|
return isConstant ? SectionKind::DataRelROLocal :
|
||||||
SectionKind::DataRelRO : SectionKind::DataRel) :
|
SectionKind::DataRelLocal;
|
||||||
(isConstant ?
|
case 2:
|
||||||
SectionKind::DataRelROLocal : SectionKind::DataRelLocal));
|
return isConstant ? SectionKind::DataRelRO : SectionKind::DataRel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Kind;
|
return Kind;
|
||||||
|
@ -202,13 +202,13 @@ TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
|
|||||||
|
|
||||||
if (isSuitableForBSS(GVar)) {
|
if (isSuitableForBSS(GVar)) {
|
||||||
// Variable can be easily put to BSS section.
|
// Variable can be easily put to BSS section.
|
||||||
return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS);
|
return isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS;
|
||||||
} else if (GVar->isConstant() && !isThreadLocal) {
|
} else if (GVar->isConstant() && !isThreadLocal) {
|
||||||
// Now we know, that variable has initializer and it is constant. We need to
|
// 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
|
// check its initializer to decide, which section to output it into. Also
|
||||||
// note, there is no thread-local r/o section.
|
// note, there is no thread-local r/o section.
|
||||||
Constant *C = GVar->getInitializer();
|
Constant *C = GVar->getInitializer();
|
||||||
if (C->ContainsRelocations(Reloc::LocalOrGlobal)) {
|
if (C->getRelocationInfo() != 0) {
|
||||||
// Decide whether it is still possible to put symbol into r/o section.
|
// Decide whether it is still possible to put symbol into r/o section.
|
||||||
if (TM.getRelocationModel() != Reloc::Static)
|
if (TM.getRelocationModel() != Reloc::Static)
|
||||||
return SectionKind::Data;
|
return SectionKind::Data;
|
||||||
|
@ -101,34 +101,35 @@ bool Constant::canTrap() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ContainsRelocations - Return true if the constant value contains relocations
|
|
||||||
/// which cannot be resolved at compile time. Kind argument is used to filter
|
/// getRelocationInfo - This method classifies the entry according to
|
||||||
/// only 'interesting' sorts of relocations.
|
/// whether or not it may generate a relocation entry. This must be
|
||||||
bool Constant::ContainsRelocations(unsigned Kind) const {
|
/// conservative, so if it might codegen to a relocatable entry, it should say
|
||||||
|
/// so. The return values are:
|
||||||
|
///
|
||||||
|
/// 0: This constant pool entry is guaranteed to never have a relocation
|
||||||
|
/// applied to it (because it holds a simple constant like '4').
|
||||||
|
/// 1: This entry has relocations, but the entries are guaranteed to be
|
||||||
|
/// resolvable by the static linker, so the dynamic linker will never see
|
||||||
|
/// them.
|
||||||
|
/// 2: This entry may have arbitrary relocations.
|
||||||
|
///
|
||||||
|
/// FIXME: This really should not be in VMCore.
|
||||||
|
unsigned Constant::getRelocationInfo() const {
|
||||||
if (const GlobalValue* GV = dyn_cast<GlobalValue>(this)) {
|
if (const GlobalValue* GV = dyn_cast<GlobalValue>(this)) {
|
||||||
bool isLocal = GV->hasLocalLinkage();
|
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
|
||||||
if ((Kind & Reloc::Local) && isLocal) {
|
return 1; // Local to this file/library.
|
||||||
// Global has local linkage and 'local' kind of relocations are
|
return 2; // Global reference.
|
||||||
// requested
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Kind & Reloc::Global) && !isLocal) {
|
|
||||||
// Global has non-local linkage and 'global' kind of relocations are
|
|
||||||
// requested
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Result = 0;
|
||||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
||||||
if (getOperand(i)->ContainsRelocations(Kind))
|
Result = std::max(Result, getOperand(i)->getRelocationInfo());
|
||||||
return true;
|
|
||||||
|
return Result;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// getVectorElements - This method, which is only valid on constant of vector
|
/// getVectorElements - This method, which is only valid on constant of vector
|
||||||
/// type, returns the elements of the vector in the specified smallvector.
|
/// type, returns the elements of the vector in the specified smallvector.
|
||||||
/// This handles breaking down a vector undef into undef elements, etc. For
|
/// This handles breaking down a vector undef into undef elements, etc. For
|
||||||
|
Loading…
x
Reference in New Issue
Block a user