[llvm] 1a6e1ee - Resolve {GlobalValue,GloalIndirectSymol}::getBaseObject confusion
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 23 09:23:40 PDT 2021
Author: Fangrui Song
Date: 2021-09-23T09:23:35-07:00
New Revision: 1a6e1ee42a6af255d45e3fd2fe87021dd31f79bb
URL: https://github.com/llvm/llvm-project/commit/1a6e1ee42a6af255d45e3fd2fe87021dd31f79bb
DIFF: https://github.com/llvm/llvm-project/commit/1a6e1ee42a6af255d45e3fd2fe87021dd31f79bb.diff
LOG: Resolve {GlobalValue,GloalIndirectSymol}::getBaseObject confusion
While both GlobalAlias and GlobalIFunc are GlobalIndirectSymbol, their
`getIndirectSymbol()` usage is quite different (GlobalIFunc's resolver
is an entity different from GlobalIFunc itself).
As discussed on https://lists.llvm.org/pipermail/llvm-dev/2020-September/144904.html
("[IR] Modelling of GlobalIFunc"), the name `getBaseObject` is confusing when
used with GlobalIFunc.
To resolve the confusion:
* Move GloalIndirectSymol::getBaseObject to GlobalAlias:: (GlobalIFunc should use `getResolver` instead)
* Change GlobalValue::getBaseObject not to inspect GlobalIFunc. Note: the function has 7 references.
* Add GlobalIFunc::getResolverFunction to peel off potential ConstantExpr indirection
(`strlen` in `test/LTO/Resolution/X86/ifunc.ll`)
Note: GlobalIFunc::getResolver (like GlobalAlias::getAliasee which does not peel
off ConstantExpr indirection) is kept to be used by ValueEnumerator.
Reviewed By: ibookstein
Differential Revision: https://reviews.llvm.org/D109792
Added:
Modified:
llvm/include/llvm/IR/GlobalAlias.h
llvm/include/llvm/IR/GlobalIFunc.h
llvm/lib/IR/Globals.cpp
llvm/lib/Object/IRSymtab.cpp
llvm/lib/Object/ModuleSymbolTable.cpp
llvm/lib/Transforms/Utils/SplitModule.cpp
llvm/test/LTO/Resolution/X86/ifunc.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/GlobalAlias.h b/llvm/include/llvm/IR/GlobalAlias.h
index f2d9b9676ec96..f2c56f6b68b79 100644
--- a/llvm/include/llvm/IR/GlobalAlias.h
+++ b/llvm/include/llvm/IR/GlobalAlias.h
@@ -77,6 +77,12 @@ class GlobalAlias : public GlobalIndirectSymbol,
return getIndirectSymbol();
}
+ const GlobalObject *getBaseObject() const;
+ GlobalObject *getBaseObject() {
+ return const_cast<GlobalObject *>(
+ static_cast<const GlobalAlias *>(this)->getBaseObject());
+ }
+
static bool isValidLinkage(LinkageTypes L) {
return isExternalLinkage(L) || isLocalLinkage(L) ||
isWeakLinkage(L) || isLinkOnceLinkage(L);
diff --git a/llvm/include/llvm/IR/GlobalIFunc.h b/llvm/include/llvm/IR/GlobalIFunc.h
index ddd29c8a4a191..39316937ac4cc 100644
--- a/llvm/include/llvm/IR/GlobalIFunc.h
+++ b/llvm/include/llvm/IR/GlobalIFunc.h
@@ -57,11 +57,15 @@ class GlobalIFunc final : public GlobalIndirectSymbol,
void setResolver(Constant *Resolver) {
setIndirectSymbol(Resolver);
}
- const Constant *getResolver() const {
- return getIndirectSymbol();
- }
- Constant *getResolver() {
- return getIndirectSymbol();
+ const Constant *getResolver() const { return getIndirectSymbol(); }
+ Constant *getResolver() { return getIndirectSymbol(); }
+
+ // Return the resolver function after peeling off potential ConstantExpr
+ // indirection.
+ const Function *getResolverFunction() const;
+ Function *getResolverFunction() {
+ return const_cast<Function *>(
+ static_cast<const GlobalIFunc *>(this)->getResolverFunction());
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index b1c6dcc6672de..a8dc0e2503964 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -283,7 +283,7 @@ bool GlobalObject::canIncreaseAlignment() const {
const GlobalObject *GlobalValue::getBaseObject() const {
if (auto *GO = dyn_cast<GlobalObject>(this))
return GO;
- if (auto *GA = dyn_cast<GlobalIndirectSymbol>(this))
+ if (auto *GA = dyn_cast<GlobalAlias>(this))
return GA->getBaseObject();
return nullptr;
}
@@ -464,11 +464,6 @@ findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) {
return nullptr;
}
-const GlobalObject *GlobalIndirectSymbol::getBaseObject() const {
- DenseSet<const GlobalAlias *> Aliases;
- return findBaseObject(getOperand(0), Aliases);
-}
-
//===----------------------------------------------------------------------===//
// GlobalAlias Implementation
//===----------------------------------------------------------------------===//
@@ -524,6 +519,11 @@ void GlobalAlias::setAliasee(Constant *Aliasee) {
setIndirectSymbol(Aliasee);
}
+const GlobalObject *GlobalAlias::getBaseObject() const {
+ DenseSet<const GlobalAlias *> Aliases;
+ return findBaseObject(getOperand(0), Aliases);
+}
+
//===----------------------------------------------------------------------===//
// GlobalIFunc Implementation
//===----------------------------------------------------------------------===//
@@ -550,3 +550,8 @@ void GlobalIFunc::removeFromParent() {
void GlobalIFunc::eraseFromParent() {
getParent()->getIFuncList().erase(getIterator());
}
+
+const Function *GlobalIFunc::getResolverFunction() const {
+ DenseSet<const GlobalAlias *> Aliases;
+ return cast<Function>(findBaseObject(getIndirectSymbol(), Aliases));
+}
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index 746b008671573..9208f9018f6e7 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -284,9 +284,13 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
}
const GlobalObject *Base = GV->getBaseObject();
- if (!Base)
- return make_error<StringError>("Unable to determine comdat of alias!",
- inconvertibleErrorCode());
+ if (!Base) {
+ if (isa<GlobalIFunc>(GV))
+ Base = cast<GlobalIFunc>(GV)->getResolverFunction();
+ if (!Base)
+ return make_error<StringError>("Unable to determine comdat of alias!",
+ inconvertibleErrorCode());
+ }
if (const Comdat *C = Base->getComdat()) {
Expected<int> ComdatIndexOrErr = getComdatIndex(C, GV->getParent());
if (!ComdatIndexOrErr)
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 9a79de77af16d..5ae81c9505677 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -204,7 +204,7 @@ uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
if (GVar->isConstant())
Res |= BasicSymbolRef::SF_Const;
}
- if (dyn_cast_or_null<Function>(GV->getBaseObject()))
+ if (isa_and_nonnull<Function>(GV->getBaseObject()) || isa<GlobalIFunc>(GV))
Res |= BasicSymbolRef::SF_Executable;
if (isa<GlobalAlias>(GV))
Res |= BasicSymbolRef::SF_Indirect;
diff --git a/llvm/lib/Transforms/Utils/SplitModule.cpp b/llvm/lib/Transforms/Utils/SplitModule.cpp
index 32f2f4e233b2b..2fd3eed53b5e1 100644
--- a/llvm/lib/Transforms/Utils/SplitModule.cpp
+++ b/llvm/lib/Transforms/Utils/SplitModule.cpp
@@ -125,9 +125,11 @@ static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap,
// For aliases we should not separate them from their aliasees regardless
// of linkage.
- if (auto *GIS = dyn_cast<GlobalIndirectSymbol>(&GV)) {
+ if (auto *GIS = dyn_cast<GlobalAlias>(&GV)) {
if (const GlobalObject *Base = GIS->getBaseObject())
GVtoClusterMap.unionSets(&GV, Base);
+ } else if (auto *GIS = dyn_cast<GlobalIFunc>(&GV)) {
+ GVtoClusterMap.unionSets(&GV, GIS->getResolverFunction());
}
if (const Function *F = dyn_cast<Function>(&GV)) {
@@ -225,9 +227,12 @@ static void externalize(GlobalValue *GV) {
// Returns whether GV should be in partition (0-based) I of N.
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {
- if (auto *GIS = dyn_cast<GlobalIndirectSymbol>(GV))
+ if (auto *GIS = dyn_cast<GlobalAlias>(GV)) {
if (const GlobalObject *Base = GIS->getBaseObject())
GV = Base;
+ } else if (auto *GIS = dyn_cast<GlobalIFunc>(GV)) {
+ GV = GIS->getResolverFunction();
+ }
StringRef Name;
if (const Comdat *C = GV->getComdat())
diff --git a/llvm/test/LTO/Resolution/X86/ifunc.ll b/llvm/test/LTO/Resolution/X86/ifunc.ll
index 7192ea2d5f771..afe7c8cd1e7e7 100644
--- a/llvm/test/LTO/Resolution/X86/ifunc.ll
+++ b/llvm/test/LTO/Resolution/X86/ifunc.ll
@@ -1,15 +1,23 @@
; RUN: opt -module-summary -o %t.bc %s
-; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,pl -o %t2
+; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,pl -r %t.bc,strlen,pl -o %t2
; RUN: llvm-nm %t2.1 | FileCheck %s
; CHECK: i foo
-; CHECK: t foo_ifunc
+; CHECK: t foo_resolver
+; CHECK: i strlen
+; CHECK: t strlen_resolver
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
- at foo = ifunc i32 (i32), i64 ()* @foo_ifunc
+ at foo = ifunc i32 (i32), i64 ()* @foo_resolver
+ at strlen = ifunc i64 (i8*), bitcast (i64 (i8*)* ()* @strlen_resolver to i64 (i8*)*)
-define internal i64 @foo_ifunc() {
+define internal i64 @foo_resolver() {
entry:
ret i64 0
}
+
+define internal i64 (i8*)* @strlen_resolver() {
+entry:
+ ret i64 (i8*)* null
+}
More information about the llvm-commits
mailing list