r344313 - [analyzer] Experiment with an iteration order only based on location, and not using the stack frame

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 11 15:59:59 PDT 2018


Author: george.karpenkov
Date: Thu Oct 11 15:59:59 2018
New Revision: 344313

URL: http://llvm.org/viewvc/llvm-project?rev=344313&view=rev
Log:
[analyzer] Experiment with an iteration order only based on location, and not using the stack frame

Differential Revision: https://reviews.llvm.org/D53058

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
    cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/WorkList.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=344313&r1=344312&r2=344313&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Thu Oct 11 15:59:59 2018
@@ -186,6 +186,7 @@ public:
     BFS,
     UnexploredFirst,
     UnexploredFirstQueue,
+    UnexploredFirstLocationQueue,
     BFSBlockDFSContents,
     NotSet
   };

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h?rev=344313&r1=344312&r2=344313&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h Thu Oct 11 15:59:59 2018
@@ -85,6 +85,7 @@ public:
   static std::unique_ptr<WorkList> makeBFSBlockDFSContents();
   static std::unique_ptr<WorkList> makeUnexploredFirst();
   static std::unique_ptr<WorkList> makeUnexploredFirstPriorityQueue();
+  static std::unique_ptr<WorkList> makeUnexploredFirstPriorityLocationQueue();
 };
 
 } // end ento namespace

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=344313&r1=344312&r2=344313&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Thu Oct 11 15:59:59 2018
@@ -77,6 +77,8 @@ AnalyzerOptions::getExplorationStrategy(
                   ExplorationStrategyKind::UnexploredFirst)
             .Case("unexplored_first_queue",
                   ExplorationStrategyKind::UnexploredFirstQueue)
+            .Case("unexplored_first_location_queue",
+                  ExplorationStrategyKind::UnexploredFirstLocationQueue)
             .Case("bfs_block_dfs_contents",
                   ExplorationStrategyKind::BFSBlockDFSContents)
             .Default(ExplorationStrategyKind::NotSet);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=344313&r1=344312&r2=344313&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Thu Oct 11 15:59:59 2018
@@ -53,7 +53,8 @@ STATISTIC(NumPathsExplored,
 // Core analysis engine.
 //===----------------------------------------------------------------------===//
 
-static std::unique_ptr<WorkList> generateWorkList(AnalyzerOptions &Opts) {
+static std::unique_ptr<WorkList> generateWorkList(AnalyzerOptions &Opts,
+                                                  SubEngine &subengine) {
   switch (Opts.getExplorationStrategy()) {
     case AnalyzerOptions::ExplorationStrategyKind::DFS:
       return WorkList::makeDFS();
@@ -65,6 +66,8 @@ static std::unique_ptr<WorkList> generat
       return WorkList::makeUnexploredFirst();
     case AnalyzerOptions::ExplorationStrategyKind::UnexploredFirstQueue:
       return WorkList::makeUnexploredFirstPriorityQueue();
+    case AnalyzerOptions::ExplorationStrategyKind::UnexploredFirstLocationQueue:
+      return WorkList::makeUnexploredFirstPriorityLocationQueue();
     default:
       llvm_unreachable("Unexpected case");
   }
@@ -72,7 +75,7 @@ static std::unique_ptr<WorkList> generat
 
 CoreEngine::CoreEngine(SubEngine &subengine, FunctionSummariesTy *FS,
                        AnalyzerOptions &Opts)
-    : SubEng(subengine), WList(generateWorkList(Opts)),
+    : SubEng(subengine), WList(generateWorkList(Opts, subengine)),
       BCounterFactory(G.getAllocator()), FunctionSummaries(FS) {}
 
 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/WorkList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/WorkList.cpp?rev=344313&r1=344312&r2=344313&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/WorkList.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/WorkList.cpp Thu Oct 11 15:59:59 2018
@@ -252,3 +252,63 @@ public:
 std::unique_ptr<WorkList> WorkList::makeUnexploredFirstPriorityQueue() {
   return llvm::make_unique<UnexploredFirstPriorityQueue>();
 }
+
+namespace {
+class UnexploredFirstPriorityLocationQueue : public WorkList {
+  using LocIdentifier = int;
+
+  // How many times each location was visited.
+  // Is signed because we negate it later in order to have a reversed
+  // comparison.
+  using VisitedTimesMap = llvm::DenseMap<LocIdentifier, int>;
+
+  // Compare by number of times the location was visited first (negated
+  // to prefer less often visited locations), then by insertion time (prefer
+  // expanding nodes inserted sooner first).
+  using QueuePriority = std::pair<int, unsigned long>;
+  using QueueItem = std::pair<WorkListUnit, QueuePriority>;
+
+  struct ExplorationComparator {
+    bool operator() (const QueueItem &LHS, const QueueItem &RHS) {
+      return LHS.second < RHS.second;
+    }
+  };
+
+  // Number of inserted nodes, used to emulate DFS ordering in the priority
+  // queue when insertions are equal.
+  unsigned long Counter = 0;
+
+  // Number of times a current location was reached.
+  VisitedTimesMap NumReached;
+
+  // The top item is the largest one.
+  llvm::PriorityQueue<QueueItem, std::vector<QueueItem>, ExplorationComparator>
+      queue;
+
+public:
+  bool hasWork() const override {
+    return !queue.empty();
+  }
+
+  void enqueue(const WorkListUnit &U) override {
+    const ExplodedNode *N = U.getNode();
+    unsigned NumVisited = 0;
+    if (auto BE = N->getLocation().getAs<BlockEntrance>())
+      NumVisited = NumReached[BE->getBlock()->getBlockID()]++;
+
+    queue.push(std::make_pair(U, std::make_pair(-NumVisited, ++Counter)));
+  }
+
+  WorkListUnit dequeue() override {
+    QueueItem U = queue.top();
+    queue.pop();
+    return U.first;
+  }
+
+};
+
+}
+
+std::unique_ptr<WorkList> WorkList::makeUnexploredFirstPriorityLocationQueue() {
+  return llvm::make_unique<UnexploredFirstPriorityLocationQueue>();
+}




More information about the cfe-commits mailing list