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 StackFrameContext *>;
 
  142  llvm::DenseSet<LocIdentifier> Reachable;
 
  145  bool hasWork()
 const override {
 
  146    return !(StackUnexplored.empty() && StackOthers.empty());
 
  156      StackUnexplored.push_back(
U);
 
  158      LocIdentifier LocId = std::make_pair(
 
  159          BE->getBlock()->getBlockID(),
 
  161      auto InsertInfo = Reachable.insert(LocId);
 
  163      if (InsertInfo.second) {
 
  164        StackUnexplored.push_back(
U);
 
  166        StackOthers.push_back(U);
 
  169    MaxReachableSize.updateMax(Reachable.size());
 
  170    MaxQueueSize.updateMax(StackUnexplored.size() + StackOthers.size());
 
  173  WorkListUnit dequeue()
 override {
 
  174    if (!StackUnexplored.empty()) {
 
  175      WorkListUnit &U = StackUnexplored.back();
 
  176      StackUnexplored.pop_back();
 
  179      WorkListUnit &U = StackOthers.back();
 
  180      StackOthers.pop_back();
 
  189  return std::make_unique<UnexploredFirstStack>();
 
 
  193class UnexploredFirstPriorityQueue : 
public WorkList {
 
  195  using LocIdentifier = std::pair<BlockID, const StackFrameContext *>;
 
  200  using VisitedTimesMap = llvm::DenseMap<LocIdentifier, int>;
 
  205  using QueuePriority = std::pair<int, unsigned long>;
 
  206  using QueueItem = std::pair<WorkListUnit, QueuePriority>;
 
  210  unsigned long Counter = 0;
 
  213  VisitedTimesMap NumReached;
 
  216  llvm::PriorityQueue<QueueItem, std::vector<QueueItem>, llvm::less_second>
 
  220  bool hasWork()
 const override {
 
  221    return !queue.empty();
 
  226    unsigned NumVisited = 0;
 
  228      LocIdentifier LocId = std::make_pair(
 
  229          BE->getBlock()->getBlockID(),
 
  231      NumVisited = NumReached[LocId]++;
 
  234    queue.push(std::make_pair(
U, std::make_pair(-NumVisited, ++Counter)));
 
  237  WorkListUnit dequeue()
 override {
 
  238    QueueItem U = queue.top();
 
  246  return std::make_unique<UnexploredFirstPriorityQueue>();
 
 
  250class UnexploredFirstPriorityLocationQueue : 
public WorkList {
 
  251  using LocIdentifier = 
const CFGBlock *;
 
  256  using VisitedTimesMap = llvm::DenseMap<LocIdentifier, int>;
 
  261  using QueuePriority = std::pair<int, unsigned long>;
 
  262  using QueueItem = std::pair<WorkListUnit, QueuePriority>;
 
  266  unsigned long Counter = 0;
 
  269  VisitedTimesMap NumReached;
 
  272  llvm::PriorityQueue<QueueItem, std::vector<QueueItem>, llvm::less_second>
 
  276  bool hasWork()
 const override {
 
  277    return !queue.
empty();
 
  282    unsigned NumVisited = 0;
 
  284      NumVisited = NumReached[BE->getBlock()]++;
 
  286    queue.push(std::make_pair(
U, std::make_pair(-NumVisited, ++Counter)));
 
  290    QueueItem 
U = queue.top();
 
  300  return std::make_unique<UnexploredFirstPriorityLocationQueue>();
 
 
#define STAT_MAX(VARNAME, DESC)
Represents a single basic block in a source-level CFG.
const StackFrameContext * getStackFrame() const
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 LocationContext * getLocationContext() 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.