[PATCH] D98841: [lld:elf] Weaken the requirement for a computed binding to be STB_LOCAL
Nathan Lanza via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 17 20:35:05 PDT 2021
lanza created this revision.
Herald added subscribers: steven_wu, hiraditya, arichardson, Prazek, emaste.
Herald added a reviewer: MaskRay.
lanza requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Given the following scenario:
// Cat.cpp
struct Animal { virtual void makeNoise() const = 0; };
struct Cat : Animal { void makeNoise() const override; };
extern "C" int puts(char const *);
void Cat::makeNoise() const { puts("Meow"); }
void doThingWithCat(Animal *a) { static_cast<Cat *>(a)->makeNoise(); }
// CatUser.cpp
struct Animal { virtual void makeNoise() const = 0; };
struct Cat : Animal { void makeNoise() const override; };
void doThingWithCat(Animal *a);
void useDoThingWithCat() {
Cat *d = new Cat;
doThingWithCat(d);
}
// cat.ver
{
global: _Z17useDoThingWithCatv;
local: *;
};
$ clang++ Cat.cpp CatUser.cpp -fpic -flto=thin -fwhole-program-vtables
-shared -O3 -fuse-ld=lld -Wl,--lto-whole-program-visibility
-Wl,--version-script,cat.ver
We cannot devirtualize `Cat::makeNoise`. The issue is complex:
Due to `-fsplit-lto-unit` and usage of type metadata, we place the Cat
vtable declaration into module 0 and the Cat vtable definition with type
metadata into module 1, causing duplicate entries (Undefined followed by
Defined) in the `lto::InputFile::symbols()` output.
In `BitcodeFile::parse`, after processing the `Undefined` then the
`Defined`, the final state is `Defined`.
In `BitcodeCompiler::add`, for the first symbol, `computeBinding`
returns `STB_LOCAL`, then we reset it to `Undefined` because it is
prevailing (`versionId` is `preserved`). For the second symbol, because
the state is now `Undefined`, `computeBinding` returns `STB_GLOBAL`,
causing `ExportDynamic` to be true and suppressing devirtualization.
In D77280 <https://reviews.llvm.org/D77280>, the `computeBinding` change used a stricter `isDefined()`
condition to make weak``Lazy` symbol work.
This patch relaxes the condition to weaker `!isLazy()` to keep it
working while making the devirtualization work as well.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D98841
Files:
lld/ELF/Symbols.cpp
lld/test/ELF/lto/devirt_split_unit_localize.ll
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D98841.331451.patch
Type: text/x-patch
Size: 6337 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210318/76d2a54c/attachment-0001.bin>
More information about the llvm-commits
mailing list