aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeza Lore <gezalore@gmail.com>2022-10-31 10:20:11 +0100
committerNikita Popov <npopov@redhat.com>2022-10-31 10:20:11 +0100
commitd5e59e99f4046a421983f76f5b4c44b646a4af9b (patch)
tree89c87f9e33db572c17826e205c131cbfa12d7007
parentefbb4d0245b50dd8ad80a99ea7f676576fd538f7 (diff)
downloadllvm-d5e59e99f4046a421983f76f5b4c44b646a4af9b.zip
llvm-d5e59e99f4046a421983f76f5b4c44b646a4af9b.tar.gz
llvm-d5e59e99f4046a421983f76f5b4c44b646a4af9b.tar.bz2
[ValueTracking] Improve performance of programUndefinedIfUndefOrPoison (NFC)
programUndefinedIfUndefOrPoison used to eagerly propagate the fact that a value is poison to the users of the value. The problem is that if the value has a lot of uses (orders of magnitude more than the scanning limit we use in this function), then we spend the bulk of our time in eagerly propagating the poison property, which we will mostly never use later anyway due to the scanning limit. I have a test case (of ~50k lines of machine generated C++), where this results in ~60% of 35s compilation time being spent doing just this eager propagation. This patch changes programUndefinedIfUndefOrPoison to only propagate to instructions actually visited, looking back to see if their operands are poison. This should be equivalent and no functional change is intended, but we regain virtually all of the 60% compilation time spent in this function in my test case (i.e.: a 2.5x total compilation speedup). Differential Revision: https://reviews.llvm.org/D137027
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp18
1 files changed, 10 insertions, 8 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 7605f66..b137cd2 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5722,11 +5722,6 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
SmallSet<const BasicBlock *, 4> Visited;
YieldsPoison.insert(V);
- auto Propagate = [&](const User *User) {
- if (propagatesPoison(cast<Operator>(User)))
- YieldsPoison.insert(User);
- };
- for_each(V->users(), Propagate);
Visited.insert(BB);
while (true) {
@@ -5740,9 +5735,16 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
if (!isGuaranteedToTransferExecutionToSuccessor(&I))
return false;
- // Mark poison that propagates from I through uses of I.
- if (YieldsPoison.count(&I))
- for_each(I.users(), Propagate);
+ // If this instruction propagates poison, mark it as poison if any of
+ // its operands are poison
+ if (propagatesPoison(cast<Operator>(&I))) {
+ for (const Value *Op : I.operands()) {
+ if (YieldsPoison.count(Op)) {
+ YieldsPoison.insert(&I);
+ break;
+ }
+ }
+ }
}
BB = BB->getSingleSuccessor();