[flang-commits] [flang] [flang] Delete a trailing CYCLE that is the last statement of its DO (PR #223399)
Kareem Ergawy via flang-commits
flang-commits at lists.llvm.org
Tue Sep 15 03:03:30 PDT 2026
================
@@ -677,6 +678,58 @@ class PFTBuilder {
evaluationListStack.pop_back();
}
+ /// Delete a CycleStmt that is the last statement of the body of its own
+ /// DoConstruct, where it is a no-op. The pre-branch-analysis code:
+ ///
+ /// <<DoConstruct>>
+ /// 1 NonLabelDoStmt: do n = 1, nb
+ /// 2 Statement: ...
+ /// 3 CycleStmt: cycle
+ /// 4 EndDoStmt
+ /// <<End DoConstruct>>
+ ///
+ /// becomes:
+ ///
+ /// <<DoConstruct>>
+ /// 1 NonLabelDoStmt: do n = 1, nb
+ /// 2 Statement: ...
+ /// 4 EndDoStmt
+ /// <<End DoConstruct>>
+ ///
+ /// Branching to the EndDoStmt and falling through to it are the same thing,
+ /// so the CycleStmt has no effect. Deleting it matters because branch
+ /// analysis otherwise marks the DoConstruct unstructured, which costs the
+ /// structured form of the loop -- and with it the induction variable
+ /// semantics that later passes rely on.
+ void rewriteTrailingCycle() {
+ auto &evaluationList = *evaluationListStack.back();
+ if (evaluationList.size() < 3)
+ return;
+ const auto *doStmt =
+ evaluationList.begin()->getIf<parser::NonLabelDoStmt>();
+ if (!doStmt)
+ return;
+ lower::pft::EvaluationList::iterator endDoStmtIt =
+ std::prev(evaluationList.end());
+ if (!endDoStmtIt->isA<parser::EndDoStmt>())
+ return;
+ lower::pft::EvaluationList::iterator cycleStmtIt = std::prev(endDoStmtIt);
+ const auto *cycleStmt = cycleStmtIt->getIf<parser::CycleStmt>();
+ if (!cycleStmt || cycleStmtIt->label)
+ return;
+ std::string cycleName = getConstructName(*cycleStmt);
+ if (!cycleName.empty() && cycleName != getConstructName(*doStmt))
+ return; // cycle for an outer construct
+ // Relink the lexical predecessor of the CycleStmt to the EndDoStmt. That
+ // predecessor is the last statement reachable from the preceding
+ // evaluation, so descend through nested evaluation lists to find it.
+ lower::pft::Evaluation *predecessor = &*std::prev(cycleStmtIt);
+ while (predecessor->evaluationList && !predecessor->evaluationList->empty())
+ predecessor = &predecessor->evaluationList->back();
+ predecessor->lexicalSuccessor = cycleStmtIt->lexicalSuccessor;
----------------
ergawy wrote:
Done in 8756ee115ca429c2d5dc209d1615f2daf30ea723.
https://github.com/llvm/llvm-project/pull/223399
More information about the flang-commits
mailing list