SchrodingerZhu updated this revision to Diff 441906.
SchrodingerZhu added a comment.
typo
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D129009/new/
https://reviews.llvm.org/D129009
Files:
llvm/include/llvm/IR/GlobalIFunc.h
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/IR/Globals.cpp
llvm/lib/Transforms/IPO/FunctionImport.cpp
llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
llvm/test/LTO/Resolution/X86/alias-indirect-function-lto.ll
Index: llvm/test/LTO/Resolution/X86/alias-indirect-function-lto.ll
===================================================================
--- /dev/null
+++ llvm/test/LTO/Resolution/X86/alias-indirect-function-lto.ll
@@ -0,0 +1,31 @@
+; RUN: opt -module-summary -o %t.bc %s
+; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,px -r %t.bc,bar,px -r %t.bc,baz,px -r %t.bc,qux,px -r %t.bc,grault,px -o %t2
+; RUN: llvm-nm %t2.1 | FileCheck %s
+; CHECK: i bar
+; CHECK: i baz
+; CHECK: i foo
+; CHECK: t foo_resolver
+; CHECK: i grault
+; CHECK: i quuz
+; CHECK: i qux
+
+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"
+
+@foo = ifunc i32 (i32), i32 (i32)* ()* @foo_resolver
+
+define internal i32 (i32)* @foo_resolver() {
+entry:
+ ret i32 (i32)* null
+}
+
+@bar = alias i32 (i32), i32 (i32)* @foo
+@baz = weak alias i32 (i32), i32 (i32)* @foo
+@qux = alias i32 (i32), i32 (i32)* @bar
+
+@quux = internal alias i32 (i32)* (), i32 (i32)* ()* @foo_resolver
+@quuz = internal ifunc i32 (i32), i32 (i32)* ()* @quux
+@corge = internal alias i32 (i32), i32 (i32)* @quuz
+@grault = alias i32 (i32), i32 (i32)* @corge
+
+; no crash
Index: llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
+++ llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
@@ -35,6 +35,13 @@
bool FunctionImportGlobalProcessing::shouldPromoteLocalToGlobal(
const GlobalValue *SGV, ValueInfo VI) {
assert(SGV->hasLocalLinkage());
+
+ // ifuncs and ifunc aliasee does not have summary
+ if (isa<GlobalIFunc>(SGV) ||
+ (isa<GlobalAlias>(SGV) &&
+ isa<GlobalIFunc>(cast<GlobalAlias>(SGV)->getAliaseeObject())))
+ return false;
+
// Both the imported references and the original local variable must
// be promoted.
if (!isPerformingImport() && !isModuleExporting())
Index: llvm/lib/Transforms/IPO/FunctionImport.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -1147,6 +1147,14 @@
// Declare a callback for the internalize pass that will ask for every
// candidate GlobalValue if it can be internalized or not.
auto MustPreserveGV = [&](const GlobalValue &GV) -> bool {
+ // It maybe the case that GV is on a chain of an ifunc, its alias and
+ // subsequent aliases. In this case, the summary for the value is not
+ // available.
+ if (isa<GlobalIFunc>(&GV) ||
+ (isa<GlobalAlias>(&GV) &&
+ isa<GlobalIFunc>(dyn_cast<GlobalAlias>(&GV)->getAliaseeObject())))
+ return true;
+
// Lookup the linkage recorded in the summaries during global analysis.
auto GS = DefinedGlobals.find(GV.getGUID());
if (GS == DefinedGlobals.end()) {
@@ -1277,7 +1285,7 @@
}
}
for (GlobalAlias &GA : SrcModule->aliases()) {
- if (!GA.hasName())
+ if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
continue;
auto GUID = GA.getGUID();
auto Import = ImportGUIDs.count(GUID);
Index: llvm/lib/IR/Globals.cpp
===================================================================
--- llvm/lib/IR/Globals.cpp
+++ llvm/lib/IR/Globals.cpp
@@ -316,32 +316,38 @@
return true;
}
+template <typename Operation>
static const GlobalObject *
-findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) {
- if (auto *GO = dyn_cast<GlobalObject>(C))
+findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases,
+ const Operation &Op) {
+ if (auto *GO = dyn_cast<GlobalObject>(C)) {
+ Op(GO);
return GO;
- if (auto *GA = dyn_cast<GlobalAlias>(C))
+ }
+ if (auto *GA = dyn_cast<GlobalAlias>(C)) {
+ Op(GA);
if (Aliases.insert(GA).second)
- return findBaseObject(GA->getOperand(0), Aliases);
+ return findBaseObject(GA->getOperand(0), Aliases, Op);
+ }
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
switch (CE->getOpcode()) {
case Instruction::Add: {
- auto *LHS = findBaseObject(CE->getOperand(0), Aliases);
- auto *RHS = findBaseObject(CE->getOperand(1), Aliases);
+ auto *LHS = findBaseObject(CE->getOperand(0), Aliases, Op);
+ auto *RHS = findBaseObject(CE->getOperand(1), Aliases, Op);
if (LHS && RHS)
return nullptr;
return LHS ? LHS : RHS;
}
case Instruction::Sub: {
- if (findBaseObject(CE->getOperand(1), Aliases))
+ if (findBaseObject(CE->getOperand(1), Aliases, Op))
return nullptr;
- return findBaseObject(CE->getOperand(0), Aliases);
+ return findBaseObject(CE->getOperand(0), Aliases, Op);
}
case Instruction::IntToPtr:
case Instruction::PtrToInt:
case Instruction::BitCast:
case Instruction::GetElementPtr:
- return findBaseObject(CE->getOperand(0), Aliases);
+ return findBaseObject(CE->getOperand(0), Aliases, Op);
default:
break;
}
@@ -351,7 +357,7 @@
const GlobalObject *GlobalValue::getAliaseeObject() const {
DenseSet<const GlobalAlias *> Aliases;
- return findBaseObject(this, Aliases);
+ return findBaseObject(this, Aliases, [](...) {});
}
bool GlobalValue::isAbsoluteSymbolRef() const {
@@ -544,7 +550,7 @@
const GlobalObject *GlobalAlias::getAliaseeObject() const {
DenseSet<const GlobalAlias *> Aliases;
- return findBaseObject(getOperand(0), Aliases);
+ return findBaseObject(getOperand(0), Aliases, [](...) {});
}
//===----------------------------------------------------------------------===//
@@ -577,5 +583,11 @@
const Function *GlobalIFunc::getResolverFunction() const {
DenseSet<const GlobalAlias *> Aliases;
- return dyn_cast<Function>(findBaseObject(getResolver(), Aliases));
+ return dyn_cast<Function>(findBaseObject(getResolver(), Aliases, [](...) {}));
+}
+
+void GlobalIFunc::applyAlongResolverPath(
+ const std::function<void(const GlobalValue *)> &Op) const {
+ DenseSet<const GlobalAlias *> Aliases;
+ findBaseObject(getResolver(), Aliases, Op);
}
Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -4103,8 +4103,9 @@
for (const GlobalAlias &A : M.aliases()) {
auto *Aliasee = A.getAliaseeObject();
- if (!Aliasee->hasName())
- // Nameless function don't have an entry in the summary, skip it.
+ // IFunc function and Nameless function don't have an entry in the
+ // summary, skip it.
+ if (!Aliasee->hasName() || isa<GlobalIFunc>(Aliasee))
continue;
auto AliasId = VE.getValueID(&A);
auto AliaseeId = VE.getValueID(Aliasee);
Index: llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
===================================================================
--- llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -646,15 +646,20 @@
Index.addGlobalValueSummary(V, std::move(GVarSummary));
}
-static void
-computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
- DenseSet<GlobalValue::GUID> &CantBePromoted) {
+static void computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
+ DenseSet<GlobalValue::GUID> &CantBePromoted) {
+ auto *Aliasee = A.getAliaseeObject();
+
+ // Skip summary for indirect function aliases as summary for aliasee will not
+ // be emitted.
+ if (isa<GlobalIFunc>(Aliasee))
+ return;
+
bool NonRenamableLocal = isNonRenamableLocal(A);
GlobalValueSummary::GVFlags Flags(
A.getLinkage(), A.getVisibility(), NonRenamableLocal,
/* Live = */ false, A.isDSOLocal(), A.canBeOmittedFromSymbolTable());
auto AS = std::make_unique<AliasSummary>(Flags);
- auto *Aliasee = A.getAliaseeObject();
auto AliaseeVI = Index.getValueInfo(Aliasee->getGUID());
assert(AliaseeVI && "Alias expects aliasee summary to be available");
assert(AliaseeVI.getSummaryList().size() == 1 &&
@@ -811,6 +816,15 @@
for (const GlobalAlias &A : M.aliases())
computeAliasSummary(Index, A, CantBePromoted);
+ // Iterate through ifuncs, set their resolvers all alive.
+ for (const GlobalIFunc &I : M.ifuncs()) {
+ std::function<void(const GlobalValue *)> Setter =
+ [&Index](const GlobalValue *GV) {
+ Index.getGlobalValueSummary(*GV)->setLive(true);
+ };
+ I.applyAlongResolverPath(Setter);
+ }
+
for (auto *V : LocalsUsed) {
auto *Summary = Index.getGlobalValueSummary(*V);
assert(Summary && "Missing summary for global value");
Index: llvm/include/llvm/IR/GlobalIFunc.h
===================================================================
--- llvm/include/llvm/IR/GlobalIFunc.h
+++ llvm/include/llvm/IR/GlobalIFunc.h
@@ -93,6 +93,14 @@
static bool classof(const Value *V) {
return V->getValueID() == Value::GlobalIFuncVal;
}
+
+ /// Method to apply specific operation to all resolver-related values.
+ /// If resolver target is already a global object, then apply the operation to
+ /// it directly. If target is an expr or an alias, evaluate it to its base
+ /// object and apply the operation for the base object and all aliases along
+ /// the path.
+ void applyAlongResolverPath(
+ const std::function<void(const GlobalValue *)> &Op) const;
};
template <>
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits