Skip to content

Commit c77659e

Browse files
committed
[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
1 parent afdfdc4 commit c77659e

File tree

8 files changed

+46
-15
lines changed

8 files changed

+46
-15
lines changed

llvm/include/llvm/IR/Constant.h

+22-2
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,13 @@ class Constant : public User {
130130
bool isConstantUsed() const;
131131

132132
/// This method classifies the entry according to whether or not it may
133-
/// generate a relocation entry. This must be conservative, so if it might
134-
/// codegen to a relocatable entry, it should say so.
133+
/// generate a relocation entry (either static or dynamic). This must be
134+
/// conservative, so if it might codegen to a relocatable entry, it should say
135+
/// so.
135136
///
136137
/// FIXME: This really should not be in IR.
137138
bool needsRelocation() const;
139+
bool needsDynamicRelocation() const;
138140

139141
/// For aggregates (struct/array/vector) return the constant that corresponds
140142
/// to the specified element if possible, or null if not. This can return null
@@ -214,6 +216,24 @@ class Constant : public User {
214216
/// both must either be scalars or vectors with the same element count. If no
215217
/// changes are made, the constant C is returned.
216218
static Constant *mergeUndefsWith(Constant *C, Constant *Other);
219+
220+
private:
221+
enum PossibleRelocationsTy {
222+
/// This constant requires no relocations. That is, it holds simple
223+
/// constants (like integrals).
224+
NoRelocation = 0,
225+
226+
/// This constant holds static relocations that can be resolved by the
227+
/// static linker.
228+
LocalRelocation = 1,
229+
230+
/// This constant holds dynamic relocations that the dynamic linker will
231+
/// need to resolve.
232+
GlobalRelocation = 2,
233+
};
234+
235+
/// Determine what potential relocations may be needed by this constant.
236+
PossibleRelocationsTy getRelocationInfo() const;
217237
};
218238

219239
} // end namespace llvm

llvm/lib/CodeGen/MachineFunction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ unsigned MachineConstantPoolEntry::getSizeInBytes(const DataLayout &DL) const {
11191119
bool MachineConstantPoolEntry::needsRelocation() const {
11201120
if (isMachineConstantPoolEntry())
11211121
return true;
1122-
return Val.ConstVal->needsRelocation();
1122+
return Val.ConstVal->needsDynamicRelocation();
11231123
}
11241124

11251125
SectionKind

llvm/lib/IR/Constants.cpp

+16-7
Original file line numberDiff line numberDiff line change
@@ -652,12 +652,20 @@ bool Constant::isConstantUsed() const {
652652
return false;
653653
}
654654

655+
bool Constant::needsDynamicRelocation() const {
656+
return getRelocationInfo() == GlobalRelocation;
657+
}
658+
655659
bool Constant::needsRelocation() const {
660+
return getRelocationInfo() != NoRelocation;
661+
}
662+
663+
Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
656664
if (isa<GlobalValue>(this))
657-
return true; // Global reference.
665+
return GlobalRelocation; // Global reference.
658666

659667
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
660-
return BA->getFunction()->needsRelocation();
668+
return BA->getFunction()->getRelocationInfo();
661669

662670
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
663671
if (CE->getOpcode() == Instruction::Sub) {
@@ -675,27 +683,28 @@ bool Constant::needsRelocation() const {
675683
if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) &&
676684
cast<BlockAddress>(LHSOp0)->getFunction() ==
677685
cast<BlockAddress>(RHSOp0)->getFunction())
678-
return false;
686+
return NoRelocation;
679687

680688
// Relative pointers do not need to be dynamically relocated.
681689
if (auto *RHSGV =
682690
dyn_cast<GlobalValue>(RHSOp0->stripInBoundsConstantOffsets())) {
683691
auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
684692
if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
685693
if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
686-
return false;
694+
return LocalRelocation;
687695
} else if (isa<DSOLocalEquivalent>(LHS)) {
688696
if (RHSGV->isDSOLocal())
689-
return false;
697+
return LocalRelocation;
690698
}
691699
}
692700
}
693701
}
694702
}
695703

696-
bool Result = false;
704+
PossibleRelocationsTy Result = NoRelocation;
697705
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
698-
Result |= cast<Constant>(getOperand(i))->needsRelocation();
706+
Result =
707+
std::max(cast<Constant>(getOperand(i))->getRelocationInfo(), Result);
699708

700709
return Result;
701710
}

llvm/lib/Target/ARM/ARMISelLowering.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3601,7 +3601,7 @@ static SDValue promoteToConstantPool(const ARMTargetLowering *TLI,
36013601
// from .data to .text. This is not allowed in position-independent code.
36023602
auto *Init = GVar->getInitializer();
36033603
if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
3604-
Init->needsRelocation())
3604+
Init->needsDynamicRelocation())
36053605
return SDValue();
36063606

36073607
// The constant islands pass can only really deal with alignment requests

llvm/lib/Target/ARM/ARMTargetTransformInfo.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ class ARMTTIImpl : public BasicTTIImplBase<ARMTTIImpl> {
275275
// variables or functions in constant data, so don't convert switches to
276276
// lookup tables if any of the values would need relocation.
277277
if (ST->isROPI() || ST->isRWPI())
278-
return !C->needsRelocation();
278+
return !C->needsDynamicRelocation();
279279

280280
return true;
281281
}

llvm/lib/Target/PowerPC/PPCTargetObjectFile.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ MCSection *PPC64LinuxTargetObjectFile::SelectSectionForGlobal(
4040
if (Kind.isReadOnly()) {
4141
const auto *GVar = dyn_cast<GlobalVariable>(GO);
4242

43-
if (GVar && GVar->isConstant() && GVar->getInitializer()->needsRelocation())
43+
if (GVar && GVar->isConstant() &&
44+
GVar->getInitializer()->needsDynamicRelocation())
4445
Kind = SectionKind::getReadOnlyWithRel();
4546
}
4647

llvm/lib/Target/TargetLoweringObjectFile.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
290290
// consideration when it tries to merge entries in the section.
291291
Reloc::Model ReloModel = TM.getRelocationModel();
292292
if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI ||
293-
ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI)
293+
ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI ||
294+
!C->needsDynamicRelocation())
294295
return SectionKind::getReadOnly();
295296

296297
// Otherwise, the dynamic linker needs to fix it up, put it in the

llvm/test/CodeGen/X86/relptr-rodata.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ target triple = "x86_64-unknown-linux-gnu"
2020
; CHECK: .long hidden-relro2
2121
@relro2 = constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @relro2 to i64)) to i32)
2222

23-
; CHECK: .section .rodata.cst8
23+
; CHECK: .section .rodata.obj
2424
; CHECK-NEXT: .globl obj
2525
; CHECK: obj:
2626
; CHECK: .long 0

0 commit comments

Comments
 (0)