diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -112,10 +112,11 @@ } /// Compute the BlockData for the current function in one iteration. - /// Returns whether the BlockData changes in this iteration. /// Initialize - Whether this is the first iteration, we can optimize /// the initial case a little bit by manual loop switch. - template bool computeBlockData(); + /// Returns whether the BlockData changes in this iteration. + template + bool computeBlockData(const BBRangeTy &BBRange); public: #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -223,12 +224,13 @@ } #endif -template bool SuspendCrossingInfo::computeBlockData() { - const size_t N = Mapping.size(); +template +bool SuspendCrossingInfo::computeBlockData(const BBRangeTy &BBRange) { bool Changed = false; - for (size_t I = 0; I < N; ++I) { - auto &B = Block[I]; + for (auto BB : BBRange) { + auto BBNo = Mapping.blockToIndex(BB); + auto &B = Block[BBNo]; // We don't need to count the predecessors when initialization. if constexpr (!Initialize) @@ -261,7 +263,7 @@ } if (B.Suspend) { - // If block S is a suspend block, it should kill all of the blocks it + // If block B is a suspend block, it should kill all of the blocks it // consumes. B.Kills |= B.Consumes; } else if (B.End) { @@ -273,8 +275,8 @@ } else { // This is reached when B block it not Suspend nor coro.end and it // need to make sure that it is not in the kill set. - B.KillLoop |= B.Kills[I]; - B.Kills.reset(I); + B.KillLoop |= B.Kills[BBNo]; + B.Kills.reset(BBNo); } if constexpr (!Initialize) { @@ -283,9 +285,6 @@ } } - if constexpr (Initialize) - return true; - return Changed; } @@ -325,9 +324,11 @@ markSuspendBlock(Save); } - computeBlockData(); - - while (computeBlockData()) + // It is considered to be faster to use RPO traversal for forward-edges + // dataflow analysis. + ReversePostOrderTraversal RPOT(&F); + computeBlockData(RPOT); + while (computeBlockData(RPOT)) ; LLVM_DEBUG(dump());