aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2021-02-10 09:59:36 -0800
committerLeonard Chan <leonardchan@google.com>2021-02-18 15:39:00 -0800
commitc77659e5494e4aa942bf0bc709b1779931dd30a8 (patch)
tree8d01772e714404683b7737a24d16351567e191ff /llvm/lib/IR/Constants.cpp
parentafdfdc4bcf1e3d9d8596b701da69f2309e7bf697 (diff)
downloadllvm-c77659e5494e4aa942bf0bc709b1779931dd30a8.zip
llvm-c77659e5494e4aa942bf0bc709b1779931dd30a8.tar.gz
llvm-c77659e5494e4aa942bf0bc709b1779931dd30a8.tar.bz2
[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
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r--llvm/lib/IR/Constants.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 6fd205c..ef0e5f6 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -652,12 +652,20 @@ bool Constant::isConstantUsed() const {
return false;
}
+bool Constant::needsDynamicRelocation() const {
+ return getRelocationInfo() == GlobalRelocation;
+}
+
bool Constant::needsRelocation() const {
+ return getRelocationInfo() != NoRelocation;
+}
+
+Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
if (isa<GlobalValue>(this))
- return true; // Global reference.
+ return GlobalRelocation; // Global reference.
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 (CE->getOpcode() == Instruction::Sub) {
@@ -675,7 +683,7 @@ bool Constant::needsRelocation() const {
if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) &&
cast<BlockAddress>(LHSOp0)->getFunction() ==
cast<BlockAddress>(RHSOp0)->getFunction())
- return false;
+ return NoRelocation;
// Relative pointers do not need to be dynamically relocated.
if (auto *RHSGV =
@@ -683,19 +691,20 @@ bool Constant::needsRelocation() const {
auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
- return false;
+ return LocalRelocation;
} else if (isa<DSOLocalEquivalent>(LHS)) {
if (RHSGV->isDSOLocal())
- return false;
+ return LocalRelocation;
}
}
}
}
}
- bool Result = false;
+ PossibleRelocationsTy Result = NoRelocation;
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;
}