summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/Analyses/DataflowWorklist.h
blob: 11415525a910ea2ca3dc93f1b854a1c0b5820667 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//===- DataflowWorklist.h - worklist for dataflow analysis --------*- C++ --*-//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// DataflowWorklist keeps track of blocks for dataflow analysis. It maintains a
// vector of blocks for priority processing, and falls back upon a reverse
// post-order iterator. It supports both forward (used in UninitializedValues)
// and reverse (used in LiveVariables) analyses.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DATAFLOWWORKLIST_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_DATAFLOWWORKLIST_H

#include "clang/Analysis/Analyses/PostOrderCFGView.h"

namespace clang {

class DataflowWorklistBase {
protected:
  PostOrderCFGView::iterator PO_I, PO_E;
  PostOrderCFGView::BlockOrderCompare comparator;
  SmallVector<const CFGBlock *, 20> worklist;
  llvm::BitVector enqueuedBlocks;

  DataflowWorklistBase(const CFG &cfg, PostOrderCFGView &view)
    : PO_I(view.begin()), PO_E(view.end()),
      comparator(view.getComparator()),
      enqueuedBlocks(cfg.getNumBlockIDs(), true) {
        // Treat the first block as already analyzed.
        if (PO_I != PO_E) {
          assert(*PO_I == &cfg.getEntry());
          enqueuedBlocks[(*PO_I)->getBlockID()] = false;
          ++PO_I;
        }
      }
};

class DataflowWorklist : DataflowWorklistBase {

public:
  DataflowWorklist(const CFG &cfg, AnalysisDeclContext &Ctx)
    : DataflowWorklistBase(cfg, *Ctx.getAnalysis<PostOrderCFGView>()) {}

  void enqueueBlock(const CFGBlock *block);
  void enqueuePredecessors(const CFGBlock *block);
  void enqueueSuccessors(const CFGBlock *block);
  const CFGBlock *dequeue();

  void sortWorklist();
};

} // end clang namespace

#endif