aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
diff options
context:
space:
mode:
authorMircea Trofin <mtrofin@google.com>2023-11-30 11:58:26 -0800
committerGitHub <noreply@github.com>2023-11-30 11:58:26 -0800
commit284da049f5feb62b40f5abc41dda7895e3d81d72 (patch)
treeaca05bcf4ac6e8e656b4b75141c122ee8edc242f /llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
parent0584e6c1669dbfc6252f5b069e2a895389660120 (diff)
downloadllvm-284da049f5feb62b40f5abc41dda7895e3d81d72.zip
llvm-284da049f5feb62b40f5abc41dda7895e3d81d72.tar.gz
llvm-284da049f5feb62b40f5abc41dda7895e3d81d72.tar.bz2
[coro][pgo] Don't promote pgo counters in the suspend basic block (#71263)
If a suspend happens in the resume part (this can happen in the case of chained coroutines), and that's part of a loop, the pre-split CFG has the suspend block as an exit of that loop. PGO Counter Promotion will then try to commit the temporary counter to the global in that "exit" block (it also does that in the other loop exit BBs, which also includes the "destroy" case). This interferes with symmetric transfer. We don't need to commit the counter in the suspend case - it's not a loop exit from the perspective of the behavior of the program. The regular loop exit, together with the "destroy" case, completely cover any updates that may need to happen to the global counter.
Diffstat (limited to 'llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/BasicBlockUtils.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 168998f..ccee970 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -2149,3 +2149,15 @@ bool llvm::hasOnlySimpleTerminator(const Function &F) {
}
return true;
}
+
+bool llvm::isPresplitCoroSuspendExitEdge(const BasicBlock &Src,
+ const BasicBlock &Dest) {
+ assert(Src.getParent() == Dest.getParent());
+ if (!Src.getParent()->isPresplitCoroutine())
+ return false;
+ if (auto *SW = dyn_cast<SwitchInst>(Src.getTerminator()))
+ if (auto *Intr = dyn_cast<IntrinsicInst>(SW->getCondition()))
+ return Intr->getIntrinsicID() == Intrinsic::coro_suspend &&
+ SW->getDefaultDest() == &Dest;
+ return false;
+}