From 08ed216000b6503a4a4be52f18394d008d5fb8f4 Mon Sep 17 00:00:00 2001 From: Itay Bookstein Date: Wed, 20 Oct 2021 10:29:47 -0700 Subject: [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 --- clang/lib/CodeGen/CodeGenModule.cpp | 49 ++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') 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 Visited; - const llvm::Constant *C = &GIS; +static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { + llvm::SmallPtrSet Visited; for (;;) { - C = C->stripPointerCasts(); - if (auto *GO = dyn_cast(C)) - return GO; - // stripPointerCasts will not walk over weak aliases. - auto *GIS2 = dyn_cast(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(GV)) + C = GA->getAliasee(); + else if (auto *GI = dyn_cast(GV)) + C = GI->getResolver(); + else + return GV; + + GV = dyn_cast(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(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(Alias)->getResolver() + : cast(Alias)->getAliasee(); + llvm::GlobalValue *AliaseeGV; if (auto CE = dyn_cast(Aliasee)) AliaseeGV = cast(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(AliaseeGV)) { + if (auto *GA = dyn_cast(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(Alias)->setResolver(Aliasee); + else + cast(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(Entry); + llvm::GlobalValue *Alias = GetGlobalValue(MangledName); Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType())); Alias->eraseFromParent(); } -- cgit v1.2.3