Skip to content

Commit d5e59e9

Browse files
gezalorenikic
authored andcommitted
[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
1 parent efbb4d0 commit d5e59e9

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5722,11 +5722,6 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
57225722
SmallSet<const BasicBlock *, 4> Visited;
57235723

57245724
YieldsPoison.insert(V);
5725-
auto Propagate = [&](const User *User) {
5726-
if (propagatesPoison(cast<Operator>(User)))
5727-
YieldsPoison.insert(User);
5728-
};
5729-
for_each(V->users(), Propagate);
57305725
Visited.insert(BB);
57315726

57325727
while (true) {
@@ -5740,9 +5735,16 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
57405735
if (!isGuaranteedToTransferExecutionToSuccessor(&I))
57415736
return false;
57425737

5743-
// Mark poison that propagates from I through uses of I.
5744-
if (YieldsPoison.count(&I))
5745-
for_each(I.users(), Propagate);
5738+
// If this instruction propagates poison, mark it as poison if any of
5739+
// its operands are poison
5740+
if (propagatesPoison(cast<Operator>(&I))) {
5741+
for (const Value *Op : I.operands()) {
5742+
if (YieldsPoison.count(Op)) {
5743+
YieldsPoison.insert(&I);
5744+
break;
5745+
}
5746+
}
5747+
}
57465748
}
57475749

57485750
BB = BB->getSingleSuccessor();

0 commit comments

Comments
 (0)