15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/DenseSet.h"
17#include "llvm/ADT/PriorityQueue.h"
18#include "llvm/ADT/STLExtras.h"
25#define DEBUG_TYPE "WorkList"
27STAT_MAX(MaxQueueSize,
"Maximum size of the worklist");
28STAT_MAX(MaxReachableSize,
"Maximum size of auxiliary worklist set");
40 bool hasWork()
const override {
41 return !Stack.empty();
44 void enqueue(
const WorkListUnit& U)
override {
48 WorkListUnit dequeue()
override {
49 assert(!Stack.empty());
50 const WorkListUnit& U = Stack.back();
57 std::deque<WorkListUnit> Queue;
60 bool hasWork()
const override {
61 return !Queue.empty();
64 void enqueue(
const WorkListUnit& U)
override {
68 WorkListUnit dequeue()
override {
69 WorkListUnit U = Queue.front();
82 return std::make_unique<DFS>();
86 return std::make_unique<BFS>();
92 std::deque<WorkListUnit> Queue;
96 bool hasWork()
const override {
97 return !Queue.empty() || !Stack.empty();
109 if (!Stack.empty()) {
115 assert(!Queue.empty());
118 WorkListUnit U = Queue.front();
127 return std::make_unique<BFSBlockDFSContents>();
132class UnexploredFirstStack :
public WorkList {
140 using LocIdentifier = std::pair<BlockID, const StackFrame *>;
142 llvm::DenseSet<LocIdentifier> Reachable;
145 bool hasWork()
const override {
146 return !(StackUnexplored.empty() && StackOthers.empty());
156 StackUnexplored.push_back(
U);
158 LocIdentifier LocId =
159 std::make_pair(BE->getBlock()->getBlockID(), N->
getStackFrame());
160 auto InsertInfo = Reachable.insert(LocId);
162 if (InsertInfo.second) {
163 StackUnexplored.push_back(
U);
165 StackOthers.push_back(U);
168 MaxReachableSize.updateMax(Reachable.size());
169 MaxQueueSize.updateMax(StackUnexplored.size() + StackOthers.size());
172 WorkListUnit dequeue()
override {
173 if (!StackUnexplored.empty()) {
174 WorkListUnit &U = StackUnexplored.back();
175 StackUnexplored.pop_back();
178 WorkListUnit &U = StackOthers.back();
179 StackOthers.pop_back();
188 return std::make_unique<UnexploredFirstStack>();
192class UnexploredFirstPriorityQueue :
public WorkList {
194 using LocIdentifier = std::pair<BlockID, const StackFrame *>;
199 using VisitedTimesMap = llvm::DenseMap<LocIdentifier, int>;
204 using QueuePriority = std::pair<int, unsigned long>;
205 using QueueItem = std::pair<WorkListUnit, QueuePriority>;
209 unsigned long Counter = 0;
212 VisitedTimesMap NumReached;
215 llvm::PriorityQueue<QueueItem, std::vector<QueueItem>, llvm::less_second>
219 bool hasWork()
const override {
220 return !queue.empty();
225 unsigned NumVisited = 0;
227 LocIdentifier LocId =
228 std::make_pair(BE->getBlock()->getBlockID(), N->
getStackFrame());
229 NumVisited = NumReached[LocId]++;
232 queue.push(std::make_pair(
U, std::make_pair(-NumVisited, ++Counter)));
235 WorkListUnit dequeue()
override {
236 QueueItem U = queue.top();
244 return std::make_unique<UnexploredFirstPriorityQueue>();
248class UnexploredFirstPriorityLocationQueue :
public WorkList {
249 using LocIdentifier =
const CFGBlock *;
254 using VisitedTimesMap = llvm::DenseMap<LocIdentifier, int>;
259 using QueuePriority = std::pair<int, unsigned long>;
260 using QueueItem = std::pair<WorkListUnit, QueuePriority>;
264 unsigned long Counter = 0;
267 VisitedTimesMap NumReached;
270 llvm::PriorityQueue<QueueItem, std::vector<QueueItem>, llvm::less_second>
274 bool hasWork()
const override {
275 return !queue.
empty();
280 unsigned NumVisited = 0;
282 NumVisited = NumReached[BE->getBlock()]++;
284 queue.push(std::make_pair(
U, std::make_pair(-NumVisited, ++Counter)));
288 QueueItem
U = queue.top();
298 return std::make_unique<UnexploredFirstPriorityLocationQueue>();
#define STAT_MAX(VARNAME, DESC)
Represents a single basic block in a source-level CFG.
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
const StackFrame * getStackFrame() const
static std::unique_ptr< WorkList > makeUnexploredFirstPriorityLocationQueue()
static std::unique_ptr< WorkList > makeUnexploredFirstPriorityQueue()
static std::unique_ptr< WorkList > makeBFSBlockDFSContents()
static std::unique_ptr< WorkList > makeBFS()
static std::unique_ptr< WorkList > makeDFS()
static std::unique_ptr< WorkList > makeUnexploredFirst()
The JSON file list parser is used to communicate input to InstallAPI.