diff options
| author | Itay Bookstein <ibookstein@gmail.com> | 2021-10-20 10:29:47 -0700 |
|---|---|---|
| committer | Fangrui Song <i@maskray.me> | 2021-10-20 10:29:47 -0700 |
| commit | 08ed216000b6503a4a4be52f18394d008d5fb8f4 (patch) | |
| tree | ca6e548769b20dc1d85b84be27a7e1be101042da /clang/lib/CodeGen/CodeGenModule.cpp | |
| parent | 7562f3df89066ab92a816dc23005c45fd642bdf9 (diff) | |
[IR] Refactor GlobalIFunc to inherit from GlobalObject, Remove GlobalIndirectSymbol
As discussed in:
* https://reviews.llvm.org/D94166
* https://lists.llvm.org/pipermail/llvm-dev/2020-September/145031.html
The GlobalIndirectSymbol class lost most of its meaning in
https://reviews.llvm.org/D109792, which disambiguated getBaseObject
(now getAliaseeObject) between GlobalIFunc and everything else.
In addition, as long as GlobalIFunc is not a GlobalObject and
getAliaseeObject returns GlobalObjects, a GlobalAlias whose aliasee
is a GlobalIFunc cannot currently be modeled properly. Creating
aliases for GlobalIFuncs does happen in the wild (e.g. glibc). In addition,
calling getAliaseeObject on a GlobalIFunc will currently return nullptr,
which is undesirable because it should return the object itself for
non-aliases.
This patch refactors the GlobalIFunc class to inherit directly from
GlobalObject, and removes GlobalIndirectSymbol (while inlining the
relevant parts into GlobalAlias and GlobalIFunc). This allows for
calling getAliaseeObject() on a GlobalIFunc to return the GlobalIFunc
itself, making getAliaseeObject() more consistent and enabling
alias-to-ifunc to be properly modeled in the IR.
I exercised some judgement in the API clients of GlobalIndirectSymbol:
some were 'monomorphized' for GlobalAlias and GlobalIFunc, and
some remained shared (with the type adapted to become GlobalValue).
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D108872
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 57454a59563a..e53a8a36974a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -317,21 +317,21 @@ void CodeGenModule::applyGlobalValReplacements() { // This is only used in aliases that we created and we know they have a // linear structure. -static const llvm::GlobalObject *getAliasedGlobal( - const llvm::GlobalIndirectSymbol &GIS) { - llvm::SmallPtrSet<const llvm::GlobalIndirectSymbol*, 4> Visited; - const llvm::Constant *C = &GIS; +static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { + llvm::SmallPtrSet<const llvm::GlobalValue *, 4> Visited; for (;;) { - C = C->stripPointerCasts(); - if (auto *GO = dyn_cast<llvm::GlobalObject>(C)) - return GO; - // stripPointerCasts will not walk over weak aliases. - auto *GIS2 = dyn_cast<llvm::GlobalIndirectSymbol>(C); - if (!GIS2) + if (!GV || !Visited.insert(GV).second) return nullptr; - if (!Visited.insert(GIS2).second) - return nullptr; - C = GIS2->getIndirectSymbol(); + + const llvm::Constant *C; + if (auto *GA = dyn_cast<llvm::GlobalAlias>(GV)) + C = GA->getAliasee(); + else if (auto *GI = dyn_cast<llvm::GlobalIFunc>(GV)) + C = GI->getResolver(); + else + return GV; + + GV = dyn_cast<llvm::GlobalValue>(C->stripPointerCasts()); } } @@ -350,9 +350,8 @@ void CodeGenModule::checkAliases() { else llvm_unreachable("Not an alias or ifunc?"); StringRef MangledName = getMangledName(GD); - llvm::GlobalValue *Entry = GetGlobalValue(MangledName); - auto *Alias = cast<llvm::GlobalIndirectSymbol>(Entry); - const llvm::GlobalValue *GV = getAliasedGlobal(*Alias); + llvm::GlobalValue *Alias = GetGlobalValue(MangledName); + const llvm::GlobalValue *GV = getAliasedGlobal(Alias); if (!GV) { Error = true; Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc; @@ -369,7 +368,10 @@ void CodeGenModule::checkAliases() { Diags.Report(Location, diag::err_ifunc_resolver_return); } - llvm::Constant *Aliasee = Alias->getIndirectSymbol(); + llvm::Constant *Aliasee = + IsIFunc ? cast<llvm::GlobalIFunc>(Alias)->getResolver() + : cast<llvm::GlobalAlias>(Alias)->getAliasee(); + llvm::GlobalValue *AliaseeGV; if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee)) AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0)); @@ -388,13 +390,17 @@ void CodeGenModule::checkAliases() { // compatibility with gcc we implement it by just pointing the alias // to its aliasee's aliasee. We also warn, since the user is probably // expecting the link to be weak. - if (auto GA = dyn_cast<llvm::GlobalIndirectSymbol>(AliaseeGV)) { + if (auto *GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) { if (GA->isInterposable()) { Diags.Report(Location, diag::warn_alias_to_weak_alias) << GV->getName() << GA->getName() << IsIFunc; Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( - GA->getIndirectSymbol(), Alias->getType()); - Alias->setIndirectSymbol(Aliasee); + GA->getAliasee(), Alias->getType()); + + if (IsIFunc) + cast<llvm::GlobalIFunc>(Alias)->setResolver(Aliasee); + else + cast<llvm::GlobalAlias>(Alias)->setAliasee(Aliasee); } } } @@ -403,8 +409,7 @@ void CodeGenModule::checkAliases() { for (const GlobalDecl &GD : Aliases) { StringRef MangledName = getMangledName(GD); - llvm::GlobalValue *Entry = GetGlobalValue(MangledName); - auto *Alias = cast<llvm::GlobalIndirectSymbol>(Entry); + llvm::GlobalValue *Alias = GetGlobalValue(MangledName); Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType())); Alias->eraseFromParent(); } |
