summaryrefslogtreecommitdiff
path: root/include/llvm/Analysis/Interval.h
blob: 3974c72871678cea37e5dcbf564f5833e267e8e9 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
//
// This file contains the declaration of the Interval class, which
// represents a set of CFG nodes and is a portion of an interval partition.
// 
// Intervals have some interesting and useful properties, including the
// following:
//    1. The header node of an interval dominates all of the elements of the
//       interval
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_INTERVAL_H
#define LLVM_INTERVAL_H

#include <vector>
#include <iosfwd>

class BasicBlock;

//===----------------------------------------------------------------------===//
//
// Interval Class - An Interval is a set of nodes defined such that every node
// in the interval has all of its predecessors in the interval (except for the
// header)
//
class Interval {
  // HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
  // interval.  Also, any loops in this interval must go through the HeaderNode.
  //
  BasicBlock *HeaderNode;
public:
  typedef std::vector<BasicBlock*>::iterator succ_iterator;
  typedef std::vector<BasicBlock*>::iterator pred_iterator;
  typedef std::vector<BasicBlock*>::iterator node_iterator;

  inline Interval(BasicBlock *Header) : HeaderNode(Header) {
    Nodes.push_back(Header);
  }

  inline Interval(const Interval &I) // copy ctor
    : HeaderNode(I.HeaderNode), Nodes(I.Nodes), Successors(I.Successors) {}

  inline BasicBlock *getHeaderNode() const { return HeaderNode; }

  // Nodes - The basic blocks in this interval.
  //
  std::vector<BasicBlock*> Nodes;

  // Successors - List of BasicBlocks that are reachable directly from nodes in
  // this interval, but are not in the interval themselves.
  // These nodes neccesarily must be header nodes for other intervals.
  //
  std::vector<BasicBlock*> Successors;

  // Predecessors - List of BasicBlocks that have this Interval's header block
  // as one of their successors.
  //
  std::vector<BasicBlock*> Predecessors;

  // contains - Find out if a basic block is in this interval
  inline bool contains(BasicBlock *BB) const {
    for (unsigned i = 0; i < Nodes.size(); ++i)
      if (Nodes[i] == BB) return true;
    return false;
    // I don't want the dependency on <algorithm>
    //return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
  }

  // isSuccessor - find out if a basic block is a successor of this Interval
  inline bool isSuccessor(BasicBlock *BB) const {
    for (unsigned i = 0; i < Successors.size(); ++i)
      if (Successors[i] == BB) return true;
    return false;
    // I don't want the dependency on <algorithm>
    //return find(Successors.begin(), Successors.end(), BB) != Successors.end();
  }

  // Equality operator.  It is only valid to compare two intervals from the same
  // partition, because of this, all we have to check is the header node for 
  // equality.
  //
  inline bool operator==(const Interval &I) const {
    return HeaderNode == I.HeaderNode;
  }

  // isLoop - Find out if there is a back edge in this interval...
  bool isLoop() const;

  // print - Show contents in human readable format...
  void print(std::ostream &O) const;
};

// succ_begin/succ_end - define methods so that Intervals may be used
// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
//
inline Interval::succ_iterator succ_begin(Interval *I) {
  return I->Successors.begin();
}
inline Interval::succ_iterator succ_end(Interval *I)   {
  return I->Successors.end();
}
  
// pred_begin/pred_end - define methods so that Intervals may be used
// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
//
inline Interval::pred_iterator pred_begin(Interval *I) {
  return I->Predecessors.begin();
}
inline Interval::pred_iterator pred_end(Interval *I)   {
  return I->Predecessors.end();
}

#endif