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