ymandel created this revision.
ymandel added reviewers: xazax.hun, gribozavr.
Herald added a subscriber: martong.
Herald added a reviewer: NoQ.
Herald added a project: All.
ymandel requested review of this revision.
Herald added a project: clang.

This patch replaces use of the reverse-post order (RPO) based worklist with one
based on a weak topological order (WTO). The WTO gives better guarantees on
maximum number of times we'll visit each node in the CFG. The new test case
fails (because of too many iterations) with RPO but passes with WTO.

Ideally, we could iterate using WTO directly without a worklist, but this isn't
yet possible because our widening is limited to booleans. Once we have full
widening at loop heads, we can simplify further to guide the iteration directly
from the WTO's structure.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153078

Files:
  clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
  clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2673,6 +2673,49 @@
       });
 }
 
+TEST(TransferTest, SequencedWhilesNoTimeout) {
+  std::string Code = R"(
+    void target() {
+      bool b = true;
+      while (b) {
+        b = false;
+      }
+      b = true;
+      while (b) {
+        b = false;
+      }
+      b = true;
+      while (b) {
+        b = false;
+      }
+      b = true;
+      while (b) {
+        b = false;
+      }
+      b = true;
+      while (b) {
+        b = false;
+      }
+      b = true;
+      while (b) {
+        b = false;
+      }
+      b = true;
+      while (b) {
+        b = false;
+      }
+      (void)0;
+      /*[[p]]*/
+    }
+  )";
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        EXPECT_EQ(Results.size(), 1u);
+      });
+}
+
 TEST(TransferTest, AggregateInitialization) {
   std::string BracesCode = R"(
     struct A {
Index: clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp
@@ -123,17 +123,17 @@
 transfer()
 recordState(Elements=2, Branches=0, Joins=0)
 
-enterBlock(3)
-transferBranch(0)
+enterBlock(2)
+transferBranch(1)
 recordState(Elements=2, Branches=1, Joins=0)
-enterElement(q)
+enterElement(p)
 transfer()
 recordState(Elements=3, Branches=1, Joins=0)
 
-enterBlock(2)
-transferBranch(1)
+enterBlock(3)
+transferBranch(0)
 recordState(Elements=2, Branches=1, Joins=0)
-enterElement(p)
+enterElement(q)
 transfer()
 recordState(Elements=3, Branches=1, Joins=0)
 
Index: clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -395,8 +395,15 @@
     std::function<void(const CFGElement &,
                        const TypeErasedDataflowAnalysisState &)>
         PostVisitCFG) {
-  PostOrderCFGView POV(&CFCtx.getCFG());
-  ForwardDataflowWorklist Worklist(CFCtx.getCFG(), &POV);
+  std::optional<WeakTopologicalOrdering> WTO = getIntervalWTO(CFCtx.getCFG());
+  if (!WTO)
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "input CFG not reducible");
+  WTOCompare Cmp(*WTO);
+  WTODataflowWorklist Worklist(CFCtx.getCFG(), Cmp);
+  // FIXME: provide fallback?
+  // PostOrderCFGView POV(&CFCtx.getCFG());
+  // ForwardDataflowWorklist Worklist(CFCtx.getCFG(), &POV);
 
   std::vector<std::optional<TypeErasedDataflowAnalysisState>> BlockStates(
       CFCtx.getCFG().size(), std::nullopt);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to