forked from OSchip/llvm-project
[llvm][IR] Do not place constants with static relocations in a mergeable section
This patch provides two major changes: 1. Add getRelocationInfo to check if a constant will have static, dynamic, or no relocations. (Also rename the original needsRelocation to needsDynamicRelocation.) 2. Only allow a constant with no relocations (static or dynamic) to be placed in a mergeable section. This will allow unused symbols that contain static relocations and happen to fit in mergeable constant sections (.rodata.cstN) to instead be placed in unique-named sections if -fdata-sections is used and subsequently garbage collected by --gc-sections. See https://lists.llvm.org/pipermail/llvm-dev/2021-February/148281.html. Differential Revision: https://reviews.llvm.org/D95960
This commit is contained in:
parent
afdfdc4bcf
commit
c77659e549
|
@ -130,11 +130,13 @@ public:
|
||||||
bool isConstantUsed() const;
|
bool isConstantUsed() const;
|
||||||
|
|
||||||
/// This method classifies the entry according to whether or not it may
|
/// This method classifies the entry according to whether or not it may
|
||||||
/// generate a relocation entry. This must be conservative, so if it might
|
/// generate a relocation entry (either static or dynamic). This must be
|
||||||
/// codegen to a relocatable entry, it should say so.
|
/// conservative, so if it might codegen to a relocatable entry, it should say
|
||||||
|
/// so.
|
||||||
///
|
///
|
||||||
/// FIXME: This really should not be in IR.
|
/// FIXME: This really should not be in IR.
|
||||||
bool needsRelocation() const;
|
bool needsRelocation() const;
|
||||||
|
bool needsDynamicRelocation() const;
|
||||||
|
|
||||||
/// For aggregates (struct/array/vector) return the constant that corresponds
|
/// For aggregates (struct/array/vector) return the constant that corresponds
|
||||||
/// to the specified element if possible, or null if not. This can return null
|
/// to the specified element if possible, or null if not. This can return null
|
||||||
|
@ -214,6 +216,24 @@ public:
|
||||||
/// both must either be scalars or vectors with the same element count. If no
|
/// both must either be scalars or vectors with the same element count. If no
|
||||||
/// changes are made, the constant C is returned.
|
/// changes are made, the constant C is returned.
|
||||||
static Constant *mergeUndefsWith(Constant *C, Constant *Other);
|
static Constant *mergeUndefsWith(Constant *C, Constant *Other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum PossibleRelocationsTy {
|
||||||
|
/// This constant requires no relocations. That is, it holds simple
|
||||||
|
/// constants (like integrals).
|
||||||
|
NoRelocation = 0,
|
||||||
|
|
||||||
|
/// This constant holds static relocations that can be resolved by the
|
||||||
|
/// static linker.
|
||||||
|
LocalRelocation = 1,
|
||||||
|
|
||||||
|
/// This constant holds dynamic relocations that the dynamic linker will
|
||||||
|
/// need to resolve.
|
||||||
|
GlobalRelocation = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Determine what potential relocations may be needed by this constant.
|
||||||
|
PossibleRelocationsTy getRelocationInfo() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
|
@ -1119,7 +1119,7 @@ unsigned MachineConstantPoolEntry::getSizeInBytes(const DataLayout &DL) const {
|
||||||
bool MachineConstantPoolEntry::needsRelocation() const {
|
bool MachineConstantPoolEntry::needsRelocation() const {
|
||||||
if (isMachineConstantPoolEntry())
|
if (isMachineConstantPoolEntry())
|
||||||
return true;
|
return true;
|
||||||
return Val.ConstVal->needsRelocation();
|
return Val.ConstVal->needsDynamicRelocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionKind
|
SectionKind
|
||||||
|
|
|
@ -652,12 +652,20 @@ bool Constant::isConstantUsed() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Constant::needsDynamicRelocation() const {
|
||||||
|
return getRelocationInfo() == GlobalRelocation;
|
||||||
|
}
|
||||||
|
|
||||||
bool Constant::needsRelocation() const {
|
bool Constant::needsRelocation() const {
|
||||||
|
return getRelocationInfo() != NoRelocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
|
||||||
if (isa<GlobalValue>(this))
|
if (isa<GlobalValue>(this))
|
||||||
return true; // Global reference.
|
return GlobalRelocation; // Global reference.
|
||||||
|
|
||||||
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
|
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
|
||||||
return BA->getFunction()->needsRelocation();
|
return BA->getFunction()->getRelocationInfo();
|
||||||
|
|
||||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
|
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
|
||||||
if (CE->getOpcode() == Instruction::Sub) {
|
if (CE->getOpcode() == Instruction::Sub) {
|
||||||
|
@ -675,7 +683,7 @@ bool Constant::needsRelocation() const {
|
||||||
if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) &&
|
if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) &&
|
||||||
cast<BlockAddress>(LHSOp0)->getFunction() ==
|
cast<BlockAddress>(LHSOp0)->getFunction() ==
|
||||||
cast<BlockAddress>(RHSOp0)->getFunction())
|
cast<BlockAddress>(RHSOp0)->getFunction())
|
||||||
return false;
|
return NoRelocation;
|
||||||
|
|
||||||
// Relative pointers do not need to be dynamically relocated.
|
// Relative pointers do not need to be dynamically relocated.
|
||||||
if (auto *RHSGV =
|
if (auto *RHSGV =
|
||||||
|
@ -683,19 +691,20 @@ bool Constant::needsRelocation() const {
|
||||||
auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
|
auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
|
||||||
if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
|
if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
|
||||||
if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
|
if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
|
||||||
return false;
|
return LocalRelocation;
|
||||||
} else if (isa<DSOLocalEquivalent>(LHS)) {
|
} else if (isa<DSOLocalEquivalent>(LHS)) {
|
||||||
if (RHSGV->isDSOLocal())
|
if (RHSGV->isDSOLocal())
|
||||||
return false;
|
return LocalRelocation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Result = false;
|
PossibleRelocationsTy Result = NoRelocation;
|
||||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
||||||
Result |= cast<Constant>(getOperand(i))->needsRelocation();
|
Result =
|
||||||
|
std::max(cast<Constant>(getOperand(i))->getRelocationInfo(), Result);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3601,7 +3601,7 @@ static SDValue promoteToConstantPool(const ARMTargetLowering *TLI,
|
||||||
// from .data to .text. This is not allowed in position-independent code.
|
// from .data to .text. This is not allowed in position-independent code.
|
||||||
auto *Init = GVar->getInitializer();
|
auto *Init = GVar->getInitializer();
|
||||||
if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
|
if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
|
||||||
Init->needsRelocation())
|
Init->needsDynamicRelocation())
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
// The constant islands pass can only really deal with alignment requests
|
// The constant islands pass can only really deal with alignment requests
|
||||||
|
|
|
@ -275,7 +275,7 @@ public:
|
||||||
// variables or functions in constant data, so don't convert switches to
|
// variables or functions in constant data, so don't convert switches to
|
||||||
// lookup tables if any of the values would need relocation.
|
// lookup tables if any of the values would need relocation.
|
||||||
if (ST->isROPI() || ST->isRWPI())
|
if (ST->isROPI() || ST->isRWPI())
|
||||||
return !C->needsRelocation();
|
return !C->needsDynamicRelocation();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ MCSection *PPC64LinuxTargetObjectFile::SelectSectionForGlobal(
|
||||||
if (Kind.isReadOnly()) {
|
if (Kind.isReadOnly()) {
|
||||||
const auto *GVar = dyn_cast<GlobalVariable>(GO);
|
const auto *GVar = dyn_cast<GlobalVariable>(GO);
|
||||||
|
|
||||||
if (GVar && GVar->isConstant() && GVar->getInitializer()->needsRelocation())
|
if (GVar && GVar->isConstant() &&
|
||||||
|
GVar->getInitializer()->needsDynamicRelocation())
|
||||||
Kind = SectionKind::getReadOnlyWithRel();
|
Kind = SectionKind::getReadOnlyWithRel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -290,7 +290,8 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
|
||||||
// consideration when it tries to merge entries in the section.
|
// consideration when it tries to merge entries in the section.
|
||||||
Reloc::Model ReloModel = TM.getRelocationModel();
|
Reloc::Model ReloModel = TM.getRelocationModel();
|
||||||
if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI ||
|
if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI ||
|
||||||
ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI)
|
ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI ||
|
||||||
|
!C->needsDynamicRelocation())
|
||||||
return SectionKind::getReadOnly();
|
return SectionKind::getReadOnly();
|
||||||
|
|
||||||
// Otherwise, the dynamic linker needs to fix it up, put it in the
|
// Otherwise, the dynamic linker needs to fix it up, put it in the
|
||||||
|
|
|
@ -20,7 +20,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
; CHECK: .long hidden-relro2
|
; CHECK: .long hidden-relro2
|
||||||
@relro2 = constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @relro2 to i64)) to i32)
|
@relro2 = constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @relro2 to i64)) to i32)
|
||||||
|
|
||||||
; CHECK: .section .rodata.cst8
|
; CHECK: .section .rodata.obj
|
||||||
; CHECK-NEXT: .globl obj
|
; CHECK-NEXT: .globl obj
|
||||||
; CHECK: obj:
|
; CHECK: obj:
|
||||||
; CHECK: .long 0
|
; CHECK: .long 0
|
||||||
|
|
Loading…
Reference in New Issue