diff options
author | Leonard Chan <leonardchan@google.com> | 2021-02-10 09:59:36 -0800 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2021-02-18 15:39:00 -0800 |
commit | c77659e5494e4aa942bf0bc709b1779931dd30a8 (patch) | |
tree | 8d01772e714404683b7737a24d16351567e191ff /llvm/lib/IR/Constants.cpp | |
parent | afdfdc4bcf1e3d9d8596b701da69f2309e7bf697 (diff) | |
download | llvm-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.cpp | 23 |
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; } |