[llvm] 757e044 - [Inliner] Don't removeDeadConstantUsers() when checking if a function is dead
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 13 14:37:59 PST 2022
Author: Arthur Eubanks
Date: 2022-01-13T14:29:45-08:00
New Revision: 757e044dce51d01391e3fa2dbff2cd8e16f964cb
URL: https://github.com/llvm/llvm-project/commit/757e044dce51d01391e3fa2dbff2cd8e16f964cb
DIFF: https://github.com/llvm/llvm-project/commit/757e044dce51d01391e3fa2dbff2cd8e16f964cb.diff
LOG: [Inliner] Don't removeDeadConstantUsers() when checking if a function is dead
If a function has many uses, this can take a good chunk of compile times.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D117236
Added:
Modified:
llvm/include/llvm/IR/Constant.h
llvm/lib/Analysis/LazyCallGraph.cpp
llvm/lib/IR/Constants.cpp
llvm/lib/Transforms/IPO/Inliner.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h
index c8999b71f3d16..a97372ebbad28 100644
--- a/llvm/include/llvm/IR/Constant.h
+++ b/llvm/include/llvm/IR/Constant.h
@@ -204,6 +204,12 @@ class Constant : public User {
/// Constant::removeDeadConstantUsers, but doesn't remove dead constants.
bool hasOneLiveUse() const;
+ /// Return true if the constant has no live uses.
+ ///
+ /// This returns the same result as calling Value::use_empty after
+ /// Constant::removeDeadConstantUsers, but doesn't remove dead constants.
+ bool hasZeroLiveUses() const;
+
const Constant *stripPointerCasts() const {
return cast<Constant>(Value::stripPointerCasts());
}
@@ -244,6 +250,8 @@ class Constant : public User {
/// Determine what potential relocations may be needed by this constant.
PossibleRelocationsTy getRelocationInfo() const;
+
+ bool hasNLiveUses(unsigned N) const;
};
} // end namespace llvm
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index ecac2d204f259..e8e9593d70305 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -1503,7 +1503,7 @@ void LazyCallGraph::removeEdge(Node &SourceN, Node &TargetN) {
void LazyCallGraph::removeDeadFunction(Function &F) {
// FIXME: This is unnecessarily restrictive. We should be able to remove
// functions which recursively call themselves.
- assert(F.use_empty() &&
+ assert(F.hasZeroLiveUses() &&
"This routine should only be called on trivially dead functions!");
// We shouldn't remove library functions as they are never really dead while
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index e753fc7a38710..8fb17f6163ea1 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -779,18 +779,22 @@ void Constant::removeDeadConstantUsers() const {
}
}
-bool Constant::hasOneLiveUse() const {
+bool Constant::hasOneLiveUse() const { return hasNLiveUses(1); }
+
+bool Constant::hasZeroLiveUses() const { return hasNLiveUses(0); }
+
+bool Constant::hasNLiveUses(unsigned N) const {
unsigned NumUses = 0;
- for (const Use &use : uses()) {
- const Constant *User = dyn_cast<Constant>(use.getUser());
+ for (const Use &U : uses()) {
+ const Constant *User = dyn_cast<Constant>(U.getUser());
if (!User || !constantIsDead(User, /* RemoveDeadUsers= */ false)) {
++NumUses;
- if (NumUses > 1)
+ if (NumUses > N)
return false;
}
}
- return NumUses == 1;
+ return NumUses == N;
}
Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) {
diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp
index c5527c76e8882..fa264fdba0392 100644
--- a/llvm/lib/Transforms/IPO/Inliner.cpp
+++ b/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -940,24 +940,20 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// which may reduce the number of callers of other functions to one,
// changing inline cost thresholds.
bool CalleeWasDeleted = false;
- if (Callee.hasLocalLinkage()) {
- // To check this we also need to nuke any dead constant uses (perhaps
- // made dead by this operation on other functions).
- Callee.removeDeadConstantUsers();
- if (Callee.use_empty() && !CG.isLibFunction(Callee)) {
- Calls->erase_if([&](const std::pair<CallBase *, int> &Call) {
- return Call.first->getCaller() == &Callee;
- });
- // Clear the body and queue the function itself for deletion when we
- // finish inlining and call graph updates.
- // Note that after this point, it is an error to do anything other
- // than use the callee's address or delete it.
- Callee.dropAllReferences();
- assert(!is_contained(DeadFunctions, &Callee) &&
- "Cannot put cause a function to become dead twice!");
- DeadFunctions.push_back(&Callee);
- CalleeWasDeleted = true;
- }
+ if (Callee.hasLocalLinkage() && Callee.hasZeroLiveUses() &&
+ !CG.isLibFunction(Callee)) {
+ Calls->erase_if([&](const std::pair<CallBase *, int> &Call) {
+ return Call.first->getCaller() == &Callee;
+ });
+ // Clear the body and queue the function itself for deletion when we
+ // finish inlining and call graph updates.
+ // Note that after this point, it is an error to do anything other
+ // than use the callee's address or delete it.
+ Callee.dropAllReferences();
+ assert(!is_contained(DeadFunctions, &Callee) &&
+ "Cannot put cause a function to become dead twice!");
+ DeadFunctions.push_back(&Callee);
+ CalleeWasDeleted = true;
}
if (CalleeWasDeleted)
Advice->recordInliningWithCalleeDeleted();
More information about the llvm-commits
mailing list