[all-commits] [llvm/llvm-project] 2f6516: [lld:elf] Weaken the requirement for a computed bi...
Nathan Lanza via All-commits
all-commits at lists.llvm.org
Mon May 24 20:33:26 PDT 2021
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 2f6516605615e99221181ec2a1947f9ad55aa9d3
https://github.com/llvm/llvm-project/commit/2f6516605615e99221181ec2a1947f9ad55aa9d3
Author: Nathan Lanza <nathan at lanza.io>
Date: 2021-05-24 (Mon, 24 May 2021)
Changed paths:
M lld/ELF/Symbols.cpp
A lld/test/ELF/lto/devirt_split_unit_localize.ll
Log Message:
-----------
[lld:elf] Weaken the requirement for a computed binding to be STB_LOCAL
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, 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.
Differential Revision: https://reviews.llvm.org/D98686
More information about the All-commits
mailing list