1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file contains the declaration of the Interval class, which
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// represents a set of CFG nodes and is a portion of an interval partition.
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Intervals have some interesting and useful properties, including the
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// following:
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//    1. The header node of an interval dominates all of the elements of the
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//       interval
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_ANALYSIS_INTERVAL_H
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_ANALYSIS_INTERVAL_H
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/GraphTraits.h"
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <vector>
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass BasicBlock;
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass raw_ostream;
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Interval Class - An Interval is a set of nodes defined such that every node
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// in the interval has all of its predecessors in the interval (except for the
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// header)
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Interval {
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// interval.  Also, any loops in this interval must go through the HeaderNode.
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BasicBlock *HeaderNode;
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using succ_iterator = std::vector<BasicBlock*>::iterator;
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using pred_iterator = std::vector<BasicBlock*>::iterator;
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using node_iterator = std::vector<BasicBlock*>::iterator;
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline Interval(BasicBlock *Header) : HeaderNode(Header) {
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Nodes.push_back(Header);
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline BasicBlock *getHeaderNode() const { return HeaderNode; }
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Nodes - The basic blocks in this interval.
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<BasicBlock*> Nodes;
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Successors - List of BasicBlocks that are reachable directly from nodes in
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// this interval, but are not in the interval themselves.
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// These nodes necessarily must be header nodes for other intervals.
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<BasicBlock*> Successors;
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Predecessors - List of BasicBlocks that have this Interval's header block
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// as one of their successors.
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<BasicBlock*> Predecessors;
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// contains - Find out if a basic block is in this interval
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline bool contains(BasicBlock *BB) const {
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    for (BasicBlock *Node : Nodes)
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (Node == BB)
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // I don't want the dependency on <algorithm>
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// isSuccessor - find out if a basic block is a successor of this Interval
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline bool isSuccessor(BasicBlock *BB) const {
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    for (BasicBlock *Successor : Successors)
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (Successor == BB)
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // I don't want the dependency on <algorithm>
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //return find(Successors.begin(), Successors.end(), BB) != Successors.end();
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Equality operator.  It is only valid to compare two intervals from the
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// same partition, because of this, all we have to check is the header node
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// for equality.
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline bool operator==(const Interval &I) const {
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return HeaderNode == I.HeaderNode;
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// isLoop - Find out if there is a back edge in this interval...
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isLoop() const;
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// print - Show contents in human readable format...
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void print(raw_ostream &O) const;
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// succ_begin/succ_end - define methods so that Intervals may be used
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline Interval::succ_iterator succ_begin(Interval *I) {
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return I->Successors.begin();
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline Interval::succ_iterator succ_end(Interval *I)   {
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return I->Successors.end();
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// pred_begin/pred_end - define methods so that Intervals may be used
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline Interval::pred_iterator pred_begin(Interval *I) {
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return I->Predecessors.begin();
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline Interval::pred_iterator pred_end(Interval *I)   {
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return I->Predecessors.end();
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <> struct GraphTraits<Interval*> {
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using NodeRef = Interval *;
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using ChildIteratorType = Interval::succ_iterator;
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static NodeRef getEntryNode(Interval *I) { return I; }
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); }
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static ChildIteratorType child_end(NodeRef N) { return succ_end(N); }
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <> struct GraphTraits<Inverse<Interval*>> {
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using NodeRef = Interval *;
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using ChildIteratorType = Interval::pred_iterator;
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static NodeRef getEntryNode(Inverse<Interval *> G) { return G.Graph; }
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_ANALYSIS_INTERVAL_H
143