1*9880d681SAndroid Build Coastguard Worker //===--- RDFGraph.h -------------------------------------------------------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // Target-independent, SSA-based data flow graph for register data flow (RDF) 11*9880d681SAndroid Build Coastguard Worker // for a non-SSA program representation (e.g. post-RA machine code). 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker // 14*9880d681SAndroid Build Coastguard Worker // *** Introduction 15*9880d681SAndroid Build Coastguard Worker // 16*9880d681SAndroid Build Coastguard Worker // The RDF graph is a collection of nodes, each of which denotes some element 17*9880d681SAndroid Build Coastguard Worker // of the program. There are two main types of such elements: code and refe- 18*9880d681SAndroid Build Coastguard Worker // rences. Conceptually, "code" is something that represents the structure 19*9880d681SAndroid Build Coastguard Worker // of the program, e.g. basic block or a statement, while "reference" is an 20*9880d681SAndroid Build Coastguard Worker // instance of accessing a register, e.g. a definition or a use. Nodes are 21*9880d681SAndroid Build Coastguard Worker // connected with each other based on the structure of the program (such as 22*9880d681SAndroid Build Coastguard Worker // blocks, instructions, etc.), and based on the data flow (e.g. reaching 23*9880d681SAndroid Build Coastguard Worker // definitions, reached uses, etc.). The single-reaching-definition principle 24*9880d681SAndroid Build Coastguard Worker // of SSA is generally observed, although, due to the non-SSA representation 25*9880d681SAndroid Build Coastguard Worker // of the program, there are some differences between the graph and a "pure" 26*9880d681SAndroid Build Coastguard Worker // SSA representation. 27*9880d681SAndroid Build Coastguard Worker // 28*9880d681SAndroid Build Coastguard Worker // 29*9880d681SAndroid Build Coastguard Worker // *** Implementation remarks 30*9880d681SAndroid Build Coastguard Worker // 31*9880d681SAndroid Build Coastguard Worker // Since the graph can contain a large number of nodes, memory consumption 32*9880d681SAndroid Build Coastguard Worker // was one of the major design considerations. As a result, there is a single 33*9880d681SAndroid Build Coastguard Worker // base class NodeBase which defines all members used by all possible derived 34*9880d681SAndroid Build Coastguard Worker // classes. The members are arranged in a union, and a derived class cannot 35*9880d681SAndroid Build Coastguard Worker // add any data members of its own. Each derived class only defines the 36*9880d681SAndroid Build Coastguard Worker // functional interface, i.e. member functions. NodeBase must be a POD, 37*9880d681SAndroid Build Coastguard Worker // which implies that all of its members must also be PODs. 38*9880d681SAndroid Build Coastguard Worker // Since nodes need to be connected with other nodes, pointers have been 39*9880d681SAndroid Build Coastguard Worker // replaced with 32-bit identifiers: each node has an id of type NodeId. 40*9880d681SAndroid Build Coastguard Worker // There are mapping functions in the graph that translate between actual 41*9880d681SAndroid Build Coastguard Worker // memory addresses and the corresponding identifiers. 42*9880d681SAndroid Build Coastguard Worker // A node id of 0 is equivalent to nullptr. 43*9880d681SAndroid Build Coastguard Worker // 44*9880d681SAndroid Build Coastguard Worker // 45*9880d681SAndroid Build Coastguard Worker // *** Structure of the graph 46*9880d681SAndroid Build Coastguard Worker // 47*9880d681SAndroid Build Coastguard Worker // A code node is always a collection of other nodes. For example, a code 48*9880d681SAndroid Build Coastguard Worker // node corresponding to a basic block will contain code nodes corresponding 49*9880d681SAndroid Build Coastguard Worker // to instructions. In turn, a code node corresponding to an instruction will 50*9880d681SAndroid Build Coastguard Worker // contain a list of reference nodes that correspond to the definitions and 51*9880d681SAndroid Build Coastguard Worker // uses of registers in that instruction. The members are arranged into a 52*9880d681SAndroid Build Coastguard Worker // circular list, which is yet another consequence of the effort to save 53*9880d681SAndroid Build Coastguard Worker // memory: for each member node it should be possible to obtain its owner, 54*9880d681SAndroid Build Coastguard Worker // and it should be possible to access all other members. There are other 55*9880d681SAndroid Build Coastguard Worker // ways to accomplish that, but the circular list seemed the most natural. 56*9880d681SAndroid Build Coastguard Worker // 57*9880d681SAndroid Build Coastguard Worker // +- CodeNode -+ 58*9880d681SAndroid Build Coastguard Worker // | | <---------------------------------------------------+ 59*9880d681SAndroid Build Coastguard Worker // +-+--------+-+ | 60*9880d681SAndroid Build Coastguard Worker // |FirstM |LastM | 61*9880d681SAndroid Build Coastguard Worker // | +-------------------------------------+ | 62*9880d681SAndroid Build Coastguard Worker // | | | 63*9880d681SAndroid Build Coastguard Worker // V V | 64*9880d681SAndroid Build Coastguard Worker // +----------+ Next +----------+ Next Next +----------+ Next | 65*9880d681SAndroid Build Coastguard Worker // | |----->| |-----> ... ----->| |----->-+ 66*9880d681SAndroid Build Coastguard Worker // +- Member -+ +- Member -+ +- Member -+ 67*9880d681SAndroid Build Coastguard Worker // 68*9880d681SAndroid Build Coastguard Worker // The order of members is such that related reference nodes (see below) 69*9880d681SAndroid Build Coastguard Worker // should be contiguous on the member list. 70*9880d681SAndroid Build Coastguard Worker // 71*9880d681SAndroid Build Coastguard Worker // A reference node is a node that encapsulates an access to a register, 72*9880d681SAndroid Build Coastguard Worker // in other words, data flowing into or out of a register. There are two 73*9880d681SAndroid Build Coastguard Worker // major kinds of reference nodes: defs and uses. A def node will contain 74*9880d681SAndroid Build Coastguard Worker // the id of the first reached use, and the id of the first reached def. 75*9880d681SAndroid Build Coastguard Worker // Each def and use will contain the id of the reaching def, and also the 76*9880d681SAndroid Build Coastguard Worker // id of the next reached def (for def nodes) or use (for use nodes). 77*9880d681SAndroid Build Coastguard Worker // The "next node sharing the same reaching def" is denoted as "sibling". 78*9880d681SAndroid Build Coastguard Worker // In summary: 79*9880d681SAndroid Build Coastguard Worker // - Def node contains: reaching def, sibling, first reached def, and first 80*9880d681SAndroid Build Coastguard Worker // reached use. 81*9880d681SAndroid Build Coastguard Worker // - Use node contains: reaching def and sibling. 82*9880d681SAndroid Build Coastguard Worker // 83*9880d681SAndroid Build Coastguard Worker // +-- DefNode --+ 84*9880d681SAndroid Build Coastguard Worker // | R2 = ... | <---+--------------------+ 85*9880d681SAndroid Build Coastguard Worker // ++---------+--+ | | 86*9880d681SAndroid Build Coastguard Worker // |Reached |Reached | | 87*9880d681SAndroid Build Coastguard Worker // |Def |Use | | 88*9880d681SAndroid Build Coastguard Worker // | | |Reaching |Reaching 89*9880d681SAndroid Build Coastguard Worker // | V |Def |Def 90*9880d681SAndroid Build Coastguard Worker // | +-- UseNode --+ Sib +-- UseNode --+ Sib Sib 91*9880d681SAndroid Build Coastguard Worker // | | ... = R2 |----->| ... = R2 |----> ... ----> 0 92*9880d681SAndroid Build Coastguard Worker // | +-------------+ +-------------+ 93*9880d681SAndroid Build Coastguard Worker // V 94*9880d681SAndroid Build Coastguard Worker // +-- DefNode --+ Sib 95*9880d681SAndroid Build Coastguard Worker // | R2 = ... |----> ... 96*9880d681SAndroid Build Coastguard Worker // ++---------+--+ 97*9880d681SAndroid Build Coastguard Worker // | | 98*9880d681SAndroid Build Coastguard Worker // | | 99*9880d681SAndroid Build Coastguard Worker // ... ... 100*9880d681SAndroid Build Coastguard Worker // 101*9880d681SAndroid Build Coastguard Worker // To get a full picture, the circular lists connecting blocks within a 102*9880d681SAndroid Build Coastguard Worker // function, instructions within a block, etc. should be superimposed with 103*9880d681SAndroid Build Coastguard Worker // the def-def, def-use links shown above. 104*9880d681SAndroid Build Coastguard Worker // To illustrate this, consider a small example in a pseudo-assembly: 105*9880d681SAndroid Build Coastguard Worker // foo: 106*9880d681SAndroid Build Coastguard Worker // add r2, r0, r1 ; r2 = r0+r1 107*9880d681SAndroid Build Coastguard Worker // addi r0, r2, 1 ; r0 = r2+1 108*9880d681SAndroid Build Coastguard Worker // ret r0 ; return value in r0 109*9880d681SAndroid Build Coastguard Worker // 110*9880d681SAndroid Build Coastguard Worker // The graph (in a format used by the debugging functions) would look like: 111*9880d681SAndroid Build Coastguard Worker // 112*9880d681SAndroid Build Coastguard Worker // DFG dump:[ 113*9880d681SAndroid Build Coastguard Worker // f1: Function foo 114*9880d681SAndroid Build Coastguard Worker // b2: === BB#0 === preds(0), succs(0): 115*9880d681SAndroid Build Coastguard Worker // p3: phi [d4<r0>(,d12,u9):] 116*9880d681SAndroid Build Coastguard Worker // p5: phi [d6<r1>(,,u10):] 117*9880d681SAndroid Build Coastguard Worker // s7: add [d8<r2>(,,u13):, u9<r0>(d4):, u10<r1>(d6):] 118*9880d681SAndroid Build Coastguard Worker // s11: addi [d12<r0>(d4,,u15):, u13<r2>(d8):] 119*9880d681SAndroid Build Coastguard Worker // s14: ret [u15<r0>(d12):] 120*9880d681SAndroid Build Coastguard Worker // ] 121*9880d681SAndroid Build Coastguard Worker // 122*9880d681SAndroid Build Coastguard Worker // The f1, b2, p3, etc. are node ids. The letter is prepended to indicate the 123*9880d681SAndroid Build Coastguard Worker // kind of the node (i.e. f - function, b - basic block, p - phi, s - state- 124*9880d681SAndroid Build Coastguard Worker // ment, d - def, u - use). 125*9880d681SAndroid Build Coastguard Worker // The format of a def node is: 126*9880d681SAndroid Build Coastguard Worker // dN<R>(rd,d,u):sib, 127*9880d681SAndroid Build Coastguard Worker // where 128*9880d681SAndroid Build Coastguard Worker // N - numeric node id, 129*9880d681SAndroid Build Coastguard Worker // R - register being defined 130*9880d681SAndroid Build Coastguard Worker // rd - reaching def, 131*9880d681SAndroid Build Coastguard Worker // d - reached def, 132*9880d681SAndroid Build Coastguard Worker // u - reached use, 133*9880d681SAndroid Build Coastguard Worker // sib - sibling. 134*9880d681SAndroid Build Coastguard Worker // The format of a use node is: 135*9880d681SAndroid Build Coastguard Worker // uN<R>[!](rd):sib, 136*9880d681SAndroid Build Coastguard Worker // where 137*9880d681SAndroid Build Coastguard Worker // N - numeric node id, 138*9880d681SAndroid Build Coastguard Worker // R - register being used, 139*9880d681SAndroid Build Coastguard Worker // rd - reaching def, 140*9880d681SAndroid Build Coastguard Worker // sib - sibling. 141*9880d681SAndroid Build Coastguard Worker // Possible annotations (usually preceding the node id): 142*9880d681SAndroid Build Coastguard Worker // + - preserving def, 143*9880d681SAndroid Build Coastguard Worker // ~ - clobbering def, 144*9880d681SAndroid Build Coastguard Worker // " - shadow ref (follows the node id), 145*9880d681SAndroid Build Coastguard Worker // ! - fixed register (appears after register name). 146*9880d681SAndroid Build Coastguard Worker // 147*9880d681SAndroid Build Coastguard Worker // The circular lists are not explicit in the dump. 148*9880d681SAndroid Build Coastguard Worker // 149*9880d681SAndroid Build Coastguard Worker // 150*9880d681SAndroid Build Coastguard Worker // *** Node attributes 151*9880d681SAndroid Build Coastguard Worker // 152*9880d681SAndroid Build Coastguard Worker // NodeBase has a member "Attrs", which is the primary way of determining 153*9880d681SAndroid Build Coastguard Worker // the node's characteristics. The fields in this member decide whether 154*9880d681SAndroid Build Coastguard Worker // the node is a code node or a reference node (i.e. node's "type"), then 155*9880d681SAndroid Build Coastguard Worker // within each type, the "kind" determines what specifically this node 156*9880d681SAndroid Build Coastguard Worker // represents. The remaining bits, "flags", contain additional information 157*9880d681SAndroid Build Coastguard Worker // that is even more detailed than the "kind". 158*9880d681SAndroid Build Coastguard Worker // CodeNode's kinds are: 159*9880d681SAndroid Build Coastguard Worker // - Phi: Phi node, members are reference nodes. 160*9880d681SAndroid Build Coastguard Worker // - Stmt: Statement, members are reference nodes. 161*9880d681SAndroid Build Coastguard Worker // - Block: Basic block, members are instruction nodes (i.e. Phi or Stmt). 162*9880d681SAndroid Build Coastguard Worker // - Func: The whole function. The members are basic block nodes. 163*9880d681SAndroid Build Coastguard Worker // RefNode's kinds are: 164*9880d681SAndroid Build Coastguard Worker // - Use. 165*9880d681SAndroid Build Coastguard Worker // - Def. 166*9880d681SAndroid Build Coastguard Worker // 167*9880d681SAndroid Build Coastguard Worker // Meaning of flags: 168*9880d681SAndroid Build Coastguard Worker // - Preserving: applies only to defs. A preserving def is one that can 169*9880d681SAndroid Build Coastguard Worker // preserve some of the original bits among those that are included in 170*9880d681SAndroid Build Coastguard Worker // the register associated with that def. For example, if R0 is a 32-bit 171*9880d681SAndroid Build Coastguard Worker // register, but a def can only change the lower 16 bits, then it will 172*9880d681SAndroid Build Coastguard Worker // be marked as preserving. 173*9880d681SAndroid Build Coastguard Worker // - Shadow: a reference that has duplicates holding additional reaching 174*9880d681SAndroid Build Coastguard Worker // defs (see more below). 175*9880d681SAndroid Build Coastguard Worker // - Clobbering: applied only to defs, indicates that the value generated 176*9880d681SAndroid Build Coastguard Worker // by this def is unspecified. A typical example would be volatile registers 177*9880d681SAndroid Build Coastguard Worker // after function calls. 178*9880d681SAndroid Build Coastguard Worker // 179*9880d681SAndroid Build Coastguard Worker // 180*9880d681SAndroid Build Coastguard Worker // *** Shadow references 181*9880d681SAndroid Build Coastguard Worker // 182*9880d681SAndroid Build Coastguard Worker // It may happen that a super-register can have two (or more) non-overlapping 183*9880d681SAndroid Build Coastguard Worker // sub-registers. When both of these sub-registers are defined and followed 184*9880d681SAndroid Build Coastguard Worker // by a use of the super-register, the use of the super-register will not 185*9880d681SAndroid Build Coastguard Worker // have a unique reaching def: both defs of the sub-registers need to be 186*9880d681SAndroid Build Coastguard Worker // accounted for. In such cases, a duplicate use of the super-register is 187*9880d681SAndroid Build Coastguard Worker // added and it points to the extra reaching def. Both uses are marked with 188*9880d681SAndroid Build Coastguard Worker // a flag "shadow". Example: 189*9880d681SAndroid Build Coastguard Worker // Assume t0 is a super-register of r0 and r1, r0 and r1 do not overlap: 190*9880d681SAndroid Build Coastguard Worker // set r0, 1 ; r0 = 1 191*9880d681SAndroid Build Coastguard Worker // set r1, 1 ; r1 = 1 192*9880d681SAndroid Build Coastguard Worker // addi t1, t0, 1 ; t1 = t0+1 193*9880d681SAndroid Build Coastguard Worker // 194*9880d681SAndroid Build Coastguard Worker // The DFG: 195*9880d681SAndroid Build Coastguard Worker // s1: set [d2<r0>(,,u9):] 196*9880d681SAndroid Build Coastguard Worker // s3: set [d4<r1>(,,u10):] 197*9880d681SAndroid Build Coastguard Worker // s5: addi [d6<t1>(,,):, u7"<t0>(d2):, u8"<t0>(d4):] 198*9880d681SAndroid Build Coastguard Worker // 199*9880d681SAndroid Build Coastguard Worker // The statement s5 has two use nodes for t0: u7" and u9". The quotation 200*9880d681SAndroid Build Coastguard Worker // mark " indicates that the node is a shadow. 201*9880d681SAndroid Build Coastguard Worker // 202*9880d681SAndroid Build Coastguard Worker #ifndef RDF_GRAPH_H 203*9880d681SAndroid Build Coastguard Worker #define RDF_GRAPH_H 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Allocator.h" 206*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h" 207*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 208*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Timer.h" 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker #include <functional> 211*9880d681SAndroid Build Coastguard Worker #include <map> 212*9880d681SAndroid Build Coastguard Worker #include <set> 213*9880d681SAndroid Build Coastguard Worker #include <vector> 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker namespace llvm { 216*9880d681SAndroid Build Coastguard Worker class MachineBasicBlock; 217*9880d681SAndroid Build Coastguard Worker class MachineFunction; 218*9880d681SAndroid Build Coastguard Worker class MachineInstr; 219*9880d681SAndroid Build Coastguard Worker class MachineOperand; 220*9880d681SAndroid Build Coastguard Worker class MachineDominanceFrontier; 221*9880d681SAndroid Build Coastguard Worker class MachineDominatorTree; 222*9880d681SAndroid Build Coastguard Worker class TargetInstrInfo; 223*9880d681SAndroid Build Coastguard Worker class TargetRegisterInfo; 224*9880d681SAndroid Build Coastguard Worker 225*9880d681SAndroid Build Coastguard Worker namespace rdf { 226*9880d681SAndroid Build Coastguard Worker typedef uint32_t NodeId; 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker struct NodeAttrs { 229*9880d681SAndroid Build Coastguard Worker enum : uint16_t { 230*9880d681SAndroid Build Coastguard Worker None = 0x0000, // Nothing 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Worker // Types: 2 bits 233*9880d681SAndroid Build Coastguard Worker TypeMask = 0x0003, 234*9880d681SAndroid Build Coastguard Worker Code = 0x0001, // 01, Container 235*9880d681SAndroid Build Coastguard Worker Ref = 0x0002, // 10, Reference 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Worker // Kind: 3 bits 238*9880d681SAndroid Build Coastguard Worker KindMask = 0x0007 << 2, 239*9880d681SAndroid Build Coastguard Worker Def = 0x0001 << 2, // 001 240*9880d681SAndroid Build Coastguard Worker Use = 0x0002 << 2, // 010 241*9880d681SAndroid Build Coastguard Worker Phi = 0x0003 << 2, // 011 242*9880d681SAndroid Build Coastguard Worker Stmt = 0x0004 << 2, // 100 243*9880d681SAndroid Build Coastguard Worker Block = 0x0005 << 2, // 101 244*9880d681SAndroid Build Coastguard Worker Func = 0x0006 << 2, // 110 245*9880d681SAndroid Build Coastguard Worker 246*9880d681SAndroid Build Coastguard Worker // Flags: 5 bits for now 247*9880d681SAndroid Build Coastguard Worker FlagMask = 0x001F << 5, 248*9880d681SAndroid Build Coastguard Worker Shadow = 0x0001 << 5, // 00001, Has extra reaching defs. 249*9880d681SAndroid Build Coastguard Worker Clobbering = 0x0002 << 5, // 00010, Produces unspecified values. 250*9880d681SAndroid Build Coastguard Worker PhiRef = 0x0004 << 5, // 00100, Member of PhiNode. 251*9880d681SAndroid Build Coastguard Worker Preserving = 0x0008 << 5, // 01000, Def can keep original bits. 252*9880d681SAndroid Build Coastguard Worker Fixed = 0x0010 << 5, // 10000, Fixed register. 253*9880d681SAndroid Build Coastguard Worker }; 254*9880d681SAndroid Build Coastguard Worker typeNodeAttrs255*9880d681SAndroid Build Coastguard Worker static uint16_t type(uint16_t T) { return T & TypeMask; } kindNodeAttrs256*9880d681SAndroid Build Coastguard Worker static uint16_t kind(uint16_t T) { return T & KindMask; } flagsNodeAttrs257*9880d681SAndroid Build Coastguard Worker static uint16_t flags(uint16_t T) { return T & FlagMask; } 258*9880d681SAndroid Build Coastguard Worker set_typeNodeAttrs259*9880d681SAndroid Build Coastguard Worker static uint16_t set_type(uint16_t A, uint16_t T) { 260*9880d681SAndroid Build Coastguard Worker return (A & ~TypeMask) | T; 261*9880d681SAndroid Build Coastguard Worker } set_kindNodeAttrs262*9880d681SAndroid Build Coastguard Worker static uint16_t set_kind(uint16_t A, uint16_t K) { 263*9880d681SAndroid Build Coastguard Worker return (A & ~KindMask) | K; 264*9880d681SAndroid Build Coastguard Worker } set_flagsNodeAttrs265*9880d681SAndroid Build Coastguard Worker static uint16_t set_flags(uint16_t A, uint16_t F) { 266*9880d681SAndroid Build Coastguard Worker return (A & ~FlagMask) | F; 267*9880d681SAndroid Build Coastguard Worker } 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Worker // Test if A contains B. containsNodeAttrs270*9880d681SAndroid Build Coastguard Worker static bool contains(uint16_t A, uint16_t B) { 271*9880d681SAndroid Build Coastguard Worker if (type(A) != Code) 272*9880d681SAndroid Build Coastguard Worker return false; 273*9880d681SAndroid Build Coastguard Worker uint16_t KB = kind(B); 274*9880d681SAndroid Build Coastguard Worker switch (kind(A)) { 275*9880d681SAndroid Build Coastguard Worker case Func: 276*9880d681SAndroid Build Coastguard Worker return KB == Block; 277*9880d681SAndroid Build Coastguard Worker case Block: 278*9880d681SAndroid Build Coastguard Worker return KB == Phi || KB == Stmt; 279*9880d681SAndroid Build Coastguard Worker case Phi: 280*9880d681SAndroid Build Coastguard Worker case Stmt: 281*9880d681SAndroid Build Coastguard Worker return type(B) == Ref; 282*9880d681SAndroid Build Coastguard Worker } 283*9880d681SAndroid Build Coastguard Worker return false; 284*9880d681SAndroid Build Coastguard Worker } 285*9880d681SAndroid Build Coastguard Worker }; 286*9880d681SAndroid Build Coastguard Worker 287*9880d681SAndroid Build Coastguard Worker struct BuildOptions { 288*9880d681SAndroid Build Coastguard Worker enum : unsigned { 289*9880d681SAndroid Build Coastguard Worker None = 0x00, 290*9880d681SAndroid Build Coastguard Worker KeepDeadPhis = 0x01, // Do not remove dead phis during build. 291*9880d681SAndroid Build Coastguard Worker }; 292*9880d681SAndroid Build Coastguard Worker }; 293*9880d681SAndroid Build Coastguard Worker 294*9880d681SAndroid Build Coastguard Worker template <typename T> struct NodeAddr { NodeAddrNodeAddr295*9880d681SAndroid Build Coastguard Worker NodeAddr() : Addr(nullptr), Id(0) {} NodeAddrNodeAddr296*9880d681SAndroid Build Coastguard Worker NodeAddr(T A, NodeId I) : Addr(A), Id(I) {} 297*9880d681SAndroid Build Coastguard Worker NodeAddr(const NodeAddr&) = default; 298*9880d681SAndroid Build Coastguard Worker NodeAddr &operator= (const NodeAddr&) = default; 299*9880d681SAndroid Build Coastguard Worker 300*9880d681SAndroid Build Coastguard Worker bool operator== (const NodeAddr<T> &NA) const { 301*9880d681SAndroid Build Coastguard Worker assert((Addr == NA.Addr) == (Id == NA.Id)); 302*9880d681SAndroid Build Coastguard Worker return Addr == NA.Addr; 303*9880d681SAndroid Build Coastguard Worker } 304*9880d681SAndroid Build Coastguard Worker bool operator!= (const NodeAddr<T> &NA) const { 305*9880d681SAndroid Build Coastguard Worker return !operator==(NA); 306*9880d681SAndroid Build Coastguard Worker } 307*9880d681SAndroid Build Coastguard Worker // Type cast (casting constructor). The reason for having this class 308*9880d681SAndroid Build Coastguard Worker // instead of std::pair. NodeAddrNodeAddr309*9880d681SAndroid Build Coastguard Worker template <typename S> NodeAddr(const NodeAddr<S> &NA) 310*9880d681SAndroid Build Coastguard Worker : Addr(static_cast<T>(NA.Addr)), Id(NA.Id) {} 311*9880d681SAndroid Build Coastguard Worker 312*9880d681SAndroid Build Coastguard Worker T Addr; 313*9880d681SAndroid Build Coastguard Worker NodeId Id; 314*9880d681SAndroid Build Coastguard Worker }; 315*9880d681SAndroid Build Coastguard Worker 316*9880d681SAndroid Build Coastguard Worker struct NodeBase; 317*9880d681SAndroid Build Coastguard Worker 318*9880d681SAndroid Build Coastguard Worker // Fast memory allocation and translation between node id and node address. 319*9880d681SAndroid Build Coastguard Worker // This is really the same idea as the one underlying the "bump pointer 320*9880d681SAndroid Build Coastguard Worker // allocator", the difference being in the translation. A node id is 321*9880d681SAndroid Build Coastguard Worker // composed of two components: the index of the block in which it was 322*9880d681SAndroid Build Coastguard Worker // allocated, and the index within the block. With the default settings, 323*9880d681SAndroid Build Coastguard Worker // where the number of nodes per block is 4096, the node id (minus 1) is: 324*9880d681SAndroid Build Coastguard Worker // 325*9880d681SAndroid Build Coastguard Worker // bit position: 11 0 326*9880d681SAndroid Build Coastguard Worker // +----------------------------+--------------+ 327*9880d681SAndroid Build Coastguard Worker // | Index of the block |Index in block| 328*9880d681SAndroid Build Coastguard Worker // +----------------------------+--------------+ 329*9880d681SAndroid Build Coastguard Worker // 330*9880d681SAndroid Build Coastguard Worker // The actual node id is the above plus 1, to avoid creating a node id of 0. 331*9880d681SAndroid Build Coastguard Worker // 332*9880d681SAndroid Build Coastguard Worker // This method significantly improved the build time, compared to using maps 333*9880d681SAndroid Build Coastguard Worker // (std::unordered_map or DenseMap) to translate between pointers and ids. 334*9880d681SAndroid Build Coastguard Worker struct NodeAllocator { 335*9880d681SAndroid Build Coastguard Worker // Amount of storage for a single node. 336*9880d681SAndroid Build Coastguard Worker enum { NodeMemSize = 32 }; 337*9880d681SAndroid Build Coastguard Worker NodeAllocator(uint32_t NPB = 4096) NodesPerBlockNodeAllocator338*9880d681SAndroid Build Coastguard Worker : NodesPerBlock(NPB), BitsPerIndex(Log2_32(NPB)), 339*9880d681SAndroid Build Coastguard Worker IndexMask((1 << BitsPerIndex)-1), ActiveEnd(nullptr) { 340*9880d681SAndroid Build Coastguard Worker assert(isPowerOf2_32(NPB)); 341*9880d681SAndroid Build Coastguard Worker } ptrNodeAllocator342*9880d681SAndroid Build Coastguard Worker NodeBase *ptr(NodeId N) const { 343*9880d681SAndroid Build Coastguard Worker uint32_t N1 = N-1; 344*9880d681SAndroid Build Coastguard Worker uint32_t BlockN = N1 >> BitsPerIndex; 345*9880d681SAndroid Build Coastguard Worker uint32_t Offset = (N1 & IndexMask) * NodeMemSize; 346*9880d681SAndroid Build Coastguard Worker return reinterpret_cast<NodeBase*>(Blocks[BlockN]+Offset); 347*9880d681SAndroid Build Coastguard Worker } 348*9880d681SAndroid Build Coastguard Worker NodeId id(const NodeBase *P) const; 349*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> New(); 350*9880d681SAndroid Build Coastguard Worker void clear(); 351*9880d681SAndroid Build Coastguard Worker 352*9880d681SAndroid Build Coastguard Worker private: 353*9880d681SAndroid Build Coastguard Worker void startNewBlock(); 354*9880d681SAndroid Build Coastguard Worker bool needNewBlock(); makeIdNodeAllocator355*9880d681SAndroid Build Coastguard Worker uint32_t makeId(uint32_t Block, uint32_t Index) const { 356*9880d681SAndroid Build Coastguard Worker // Add 1 to the id, to avoid the id of 0, which is treated as "null". 357*9880d681SAndroid Build Coastguard Worker return ((Block << BitsPerIndex) | Index) + 1; 358*9880d681SAndroid Build Coastguard Worker } 359*9880d681SAndroid Build Coastguard Worker 360*9880d681SAndroid Build Coastguard Worker const uint32_t NodesPerBlock; 361*9880d681SAndroid Build Coastguard Worker const uint32_t BitsPerIndex; 362*9880d681SAndroid Build Coastguard Worker const uint32_t IndexMask; 363*9880d681SAndroid Build Coastguard Worker char *ActiveEnd; 364*9880d681SAndroid Build Coastguard Worker std::vector<char*> Blocks; 365*9880d681SAndroid Build Coastguard Worker typedef BumpPtrAllocatorImpl<MallocAllocator, 65536> AllocatorTy; 366*9880d681SAndroid Build Coastguard Worker AllocatorTy MemPool; 367*9880d681SAndroid Build Coastguard Worker }; 368*9880d681SAndroid Build Coastguard Worker 369*9880d681SAndroid Build Coastguard Worker struct RegisterRef { 370*9880d681SAndroid Build Coastguard Worker unsigned Reg, Sub; 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard Worker // No non-trivial constructors, since this will be a member of a union. 373*9880d681SAndroid Build Coastguard Worker RegisterRef() = default; 374*9880d681SAndroid Build Coastguard Worker RegisterRef(const RegisterRef &RR) = default; 375*9880d681SAndroid Build Coastguard Worker RegisterRef &operator= (const RegisterRef &RR) = default; 376*9880d681SAndroid Build Coastguard Worker bool operator== (const RegisterRef &RR) const { 377*9880d681SAndroid Build Coastguard Worker return Reg == RR.Reg && Sub == RR.Sub; 378*9880d681SAndroid Build Coastguard Worker } 379*9880d681SAndroid Build Coastguard Worker bool operator!= (const RegisterRef &RR) const { 380*9880d681SAndroid Build Coastguard Worker return !operator==(RR); 381*9880d681SAndroid Build Coastguard Worker } 382*9880d681SAndroid Build Coastguard Worker bool operator< (const RegisterRef &RR) const { 383*9880d681SAndroid Build Coastguard Worker return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub); 384*9880d681SAndroid Build Coastguard Worker } 385*9880d681SAndroid Build Coastguard Worker }; 386*9880d681SAndroid Build Coastguard Worker typedef std::set<RegisterRef> RegisterSet; 387*9880d681SAndroid Build Coastguard Worker 388*9880d681SAndroid Build Coastguard Worker struct RegisterAliasInfo { RegisterAliasInfoRegisterAliasInfo389*9880d681SAndroid Build Coastguard Worker RegisterAliasInfo(const TargetRegisterInfo &tri) : TRI(tri) {} ~RegisterAliasInfoRegisterAliasInfo390*9880d681SAndroid Build Coastguard Worker virtual ~RegisterAliasInfo() {} 391*9880d681SAndroid Build Coastguard Worker 392*9880d681SAndroid Build Coastguard Worker virtual std::vector<RegisterRef> getAliasSet(RegisterRef RR) const; 393*9880d681SAndroid Build Coastguard Worker virtual bool alias(RegisterRef RA, RegisterRef RB) const; 394*9880d681SAndroid Build Coastguard Worker virtual bool covers(RegisterRef RA, RegisterRef RB) const; 395*9880d681SAndroid Build Coastguard Worker virtual bool covers(const RegisterSet &RRs, RegisterRef RR) const; 396*9880d681SAndroid Build Coastguard Worker 397*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI; 398*9880d681SAndroid Build Coastguard Worker }; 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Worker struct TargetOperandInfo { TargetOperandInfoTargetOperandInfo401*9880d681SAndroid Build Coastguard Worker TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {} ~TargetOperandInfoTargetOperandInfo402*9880d681SAndroid Build Coastguard Worker virtual ~TargetOperandInfo() {} 403*9880d681SAndroid Build Coastguard Worker virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const; 404*9880d681SAndroid Build Coastguard Worker virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const; 405*9880d681SAndroid Build Coastguard Worker virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const; 406*9880d681SAndroid Build Coastguard Worker 407*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII; 408*9880d681SAndroid Build Coastguard Worker }; 409*9880d681SAndroid Build Coastguard Worker 410*9880d681SAndroid Build Coastguard Worker 411*9880d681SAndroid Build Coastguard Worker struct DataFlowGraph; 412*9880d681SAndroid Build Coastguard Worker 413*9880d681SAndroid Build Coastguard Worker struct NodeBase { 414*9880d681SAndroid Build Coastguard Worker public: 415*9880d681SAndroid Build Coastguard Worker // Make sure this is a POD. 416*9880d681SAndroid Build Coastguard Worker NodeBase() = default; getTypeNodeBase417*9880d681SAndroid Build Coastguard Worker uint16_t getType() const { return NodeAttrs::type(Attrs); } getKindNodeBase418*9880d681SAndroid Build Coastguard Worker uint16_t getKind() const { return NodeAttrs::kind(Attrs); } getFlagsNodeBase419*9880d681SAndroid Build Coastguard Worker uint16_t getFlags() const { return NodeAttrs::flags(Attrs); } getNextNodeBase420*9880d681SAndroid Build Coastguard Worker NodeId getNext() const { return Next; } 421*9880d681SAndroid Build Coastguard Worker getAttrsNodeBase422*9880d681SAndroid Build Coastguard Worker uint16_t getAttrs() const { return Attrs; } setAttrsNodeBase423*9880d681SAndroid Build Coastguard Worker void setAttrs(uint16_t A) { Attrs = A; } setFlagsNodeBase424*9880d681SAndroid Build Coastguard Worker void setFlags(uint16_t F) { setAttrs(NodeAttrs::set_flags(getAttrs(), F)); } 425*9880d681SAndroid Build Coastguard Worker 426*9880d681SAndroid Build Coastguard Worker // Insert node NA after "this" in the circular chain. 427*9880d681SAndroid Build Coastguard Worker void append(NodeAddr<NodeBase*> NA); 428*9880d681SAndroid Build Coastguard Worker // Initialize all members to 0. initNodeBase429*9880d681SAndroid Build Coastguard Worker void init() { memset(this, 0, sizeof *this); } setNextNodeBase430*9880d681SAndroid Build Coastguard Worker void setNext(NodeId N) { Next = N; } 431*9880d681SAndroid Build Coastguard Worker 432*9880d681SAndroid Build Coastguard Worker protected: 433*9880d681SAndroid Build Coastguard Worker uint16_t Attrs; 434*9880d681SAndroid Build Coastguard Worker uint16_t Reserved; 435*9880d681SAndroid Build Coastguard Worker NodeId Next; // Id of the next node in the circular chain. 436*9880d681SAndroid Build Coastguard Worker // Definitions of nested types. Using anonymous nested structs would make 437*9880d681SAndroid Build Coastguard Worker // this class definition clearer, but unnamed structs are not a part of 438*9880d681SAndroid Build Coastguard Worker // the standard. 439*9880d681SAndroid Build Coastguard Worker struct Def_struct { 440*9880d681SAndroid Build Coastguard Worker NodeId DD, DU; // Ids of the first reached def and use. 441*9880d681SAndroid Build Coastguard Worker }; 442*9880d681SAndroid Build Coastguard Worker struct PhiU_struct { 443*9880d681SAndroid Build Coastguard Worker NodeId PredB; // Id of the predecessor block for a phi use. 444*9880d681SAndroid Build Coastguard Worker }; 445*9880d681SAndroid Build Coastguard Worker struct Code_struct { 446*9880d681SAndroid Build Coastguard Worker void *CP; // Pointer to the actual code. 447*9880d681SAndroid Build Coastguard Worker NodeId FirstM, LastM; // Id of the first member and last. 448*9880d681SAndroid Build Coastguard Worker }; 449*9880d681SAndroid Build Coastguard Worker struct Ref_struct { 450*9880d681SAndroid Build Coastguard Worker NodeId RD, Sib; // Ids of the reaching def and the sibling. 451*9880d681SAndroid Build Coastguard Worker union { 452*9880d681SAndroid Build Coastguard Worker Def_struct Def; 453*9880d681SAndroid Build Coastguard Worker PhiU_struct PhiU; 454*9880d681SAndroid Build Coastguard Worker }; 455*9880d681SAndroid Build Coastguard Worker union { 456*9880d681SAndroid Build Coastguard Worker MachineOperand *Op; // Non-phi refs point to a machine operand. 457*9880d681SAndroid Build Coastguard Worker RegisterRef RR; // Phi refs store register info directly. 458*9880d681SAndroid Build Coastguard Worker }; 459*9880d681SAndroid Build Coastguard Worker }; 460*9880d681SAndroid Build Coastguard Worker 461*9880d681SAndroid Build Coastguard Worker // The actual payload. 462*9880d681SAndroid Build Coastguard Worker union { 463*9880d681SAndroid Build Coastguard Worker Ref_struct Ref; 464*9880d681SAndroid Build Coastguard Worker Code_struct Code; 465*9880d681SAndroid Build Coastguard Worker }; 466*9880d681SAndroid Build Coastguard Worker }; 467*9880d681SAndroid Build Coastguard Worker // The allocator allocates chunks of 32 bytes for each node. The fact that 468*9880d681SAndroid Build Coastguard Worker // each node takes 32 bytes in memory is used for fast translation between 469*9880d681SAndroid Build Coastguard Worker // the node id and the node address. 470*9880d681SAndroid Build Coastguard Worker static_assert(sizeof(NodeBase) <= NodeAllocator::NodeMemSize, 471*9880d681SAndroid Build Coastguard Worker "NodeBase must be at most NodeAllocator::NodeMemSize bytes"); 472*9880d681SAndroid Build Coastguard Worker 473*9880d681SAndroid Build Coastguard Worker typedef std::vector<NodeAddr<NodeBase*>> NodeList; 474*9880d681SAndroid Build Coastguard Worker typedef std::set<NodeId> NodeSet; 475*9880d681SAndroid Build Coastguard Worker 476*9880d681SAndroid Build Coastguard Worker struct RefNode : public NodeBase { 477*9880d681SAndroid Build Coastguard Worker RefNode() = default; 478*9880d681SAndroid Build Coastguard Worker RegisterRef getRegRef() const; getOpRefNode479*9880d681SAndroid Build Coastguard Worker MachineOperand &getOp() { 480*9880d681SAndroid Build Coastguard Worker assert(!(getFlags() & NodeAttrs::PhiRef)); 481*9880d681SAndroid Build Coastguard Worker return *Ref.Op; 482*9880d681SAndroid Build Coastguard Worker } 483*9880d681SAndroid Build Coastguard Worker void setRegRef(RegisterRef RR); 484*9880d681SAndroid Build Coastguard Worker void setRegRef(MachineOperand *Op); getReachingDefRefNode485*9880d681SAndroid Build Coastguard Worker NodeId getReachingDef() const { 486*9880d681SAndroid Build Coastguard Worker return Ref.RD; 487*9880d681SAndroid Build Coastguard Worker } setReachingDefRefNode488*9880d681SAndroid Build Coastguard Worker void setReachingDef(NodeId RD) { 489*9880d681SAndroid Build Coastguard Worker Ref.RD = RD; 490*9880d681SAndroid Build Coastguard Worker } getSiblingRefNode491*9880d681SAndroid Build Coastguard Worker NodeId getSibling() const { 492*9880d681SAndroid Build Coastguard Worker return Ref.Sib; 493*9880d681SAndroid Build Coastguard Worker } setSiblingRefNode494*9880d681SAndroid Build Coastguard Worker void setSibling(NodeId Sib) { 495*9880d681SAndroid Build Coastguard Worker Ref.Sib = Sib; 496*9880d681SAndroid Build Coastguard Worker } isUseRefNode497*9880d681SAndroid Build Coastguard Worker bool isUse() const { 498*9880d681SAndroid Build Coastguard Worker assert(getType() == NodeAttrs::Ref); 499*9880d681SAndroid Build Coastguard Worker return getKind() == NodeAttrs::Use; 500*9880d681SAndroid Build Coastguard Worker } isDefRefNode501*9880d681SAndroid Build Coastguard Worker bool isDef() const { 502*9880d681SAndroid Build Coastguard Worker assert(getType() == NodeAttrs::Ref); 503*9880d681SAndroid Build Coastguard Worker return getKind() == NodeAttrs::Def; 504*9880d681SAndroid Build Coastguard Worker } 505*9880d681SAndroid Build Coastguard Worker 506*9880d681SAndroid Build Coastguard Worker template <typename Predicate> 507*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> getNextRef(RegisterRef RR, Predicate P, bool NextOnly, 508*9880d681SAndroid Build Coastguard Worker const DataFlowGraph &G); 509*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> getOwner(const DataFlowGraph &G); 510*9880d681SAndroid Build Coastguard Worker }; 511*9880d681SAndroid Build Coastguard Worker 512*9880d681SAndroid Build Coastguard Worker struct DefNode : public RefNode { getReachedDefDefNode513*9880d681SAndroid Build Coastguard Worker NodeId getReachedDef() const { 514*9880d681SAndroid Build Coastguard Worker return Ref.Def.DD; 515*9880d681SAndroid Build Coastguard Worker } setReachedDefDefNode516*9880d681SAndroid Build Coastguard Worker void setReachedDef(NodeId D) { 517*9880d681SAndroid Build Coastguard Worker Ref.Def.DD = D; 518*9880d681SAndroid Build Coastguard Worker } getReachedUseDefNode519*9880d681SAndroid Build Coastguard Worker NodeId getReachedUse() const { 520*9880d681SAndroid Build Coastguard Worker return Ref.Def.DU; 521*9880d681SAndroid Build Coastguard Worker } setReachedUseDefNode522*9880d681SAndroid Build Coastguard Worker void setReachedUse(NodeId U) { 523*9880d681SAndroid Build Coastguard Worker Ref.Def.DU = U; 524*9880d681SAndroid Build Coastguard Worker } 525*9880d681SAndroid Build Coastguard Worker 526*9880d681SAndroid Build Coastguard Worker void linkToDef(NodeId Self, NodeAddr<DefNode*> DA); 527*9880d681SAndroid Build Coastguard Worker }; 528*9880d681SAndroid Build Coastguard Worker 529*9880d681SAndroid Build Coastguard Worker struct UseNode : public RefNode { 530*9880d681SAndroid Build Coastguard Worker void linkToDef(NodeId Self, NodeAddr<DefNode*> DA); 531*9880d681SAndroid Build Coastguard Worker }; 532*9880d681SAndroid Build Coastguard Worker 533*9880d681SAndroid Build Coastguard Worker struct PhiUseNode : public UseNode { getPredecessorPhiUseNode534*9880d681SAndroid Build Coastguard Worker NodeId getPredecessor() const { 535*9880d681SAndroid Build Coastguard Worker assert(getFlags() & NodeAttrs::PhiRef); 536*9880d681SAndroid Build Coastguard Worker return Ref.PhiU.PredB; 537*9880d681SAndroid Build Coastguard Worker } setPredecessorPhiUseNode538*9880d681SAndroid Build Coastguard Worker void setPredecessor(NodeId B) { 539*9880d681SAndroid Build Coastguard Worker assert(getFlags() & NodeAttrs::PhiRef); 540*9880d681SAndroid Build Coastguard Worker Ref.PhiU.PredB = B; 541*9880d681SAndroid Build Coastguard Worker } 542*9880d681SAndroid Build Coastguard Worker }; 543*9880d681SAndroid Build Coastguard Worker 544*9880d681SAndroid Build Coastguard Worker struct CodeNode : public NodeBase { getCodeCodeNode545*9880d681SAndroid Build Coastguard Worker template <typename T> T getCode() const { 546*9880d681SAndroid Build Coastguard Worker return static_cast<T>(Code.CP); 547*9880d681SAndroid Build Coastguard Worker } setCodeCodeNode548*9880d681SAndroid Build Coastguard Worker void setCode(void *C) { 549*9880d681SAndroid Build Coastguard Worker Code.CP = C; 550*9880d681SAndroid Build Coastguard Worker } 551*9880d681SAndroid Build Coastguard Worker 552*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> getFirstMember(const DataFlowGraph &G) const; 553*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> getLastMember(const DataFlowGraph &G) const; 554*9880d681SAndroid Build Coastguard Worker void addMember(NodeAddr<NodeBase*> NA, const DataFlowGraph &G); 555*9880d681SAndroid Build Coastguard Worker void addMemberAfter(NodeAddr<NodeBase*> MA, NodeAddr<NodeBase*> NA, 556*9880d681SAndroid Build Coastguard Worker const DataFlowGraph &G); 557*9880d681SAndroid Build Coastguard Worker void removeMember(NodeAddr<NodeBase*> NA, const DataFlowGraph &G); 558*9880d681SAndroid Build Coastguard Worker 559*9880d681SAndroid Build Coastguard Worker NodeList members(const DataFlowGraph &G) const; 560*9880d681SAndroid Build Coastguard Worker template <typename Predicate> 561*9880d681SAndroid Build Coastguard Worker NodeList members_if(Predicate P, const DataFlowGraph &G) const; 562*9880d681SAndroid Build Coastguard Worker }; 563*9880d681SAndroid Build Coastguard Worker 564*9880d681SAndroid Build Coastguard Worker struct InstrNode : public CodeNode { 565*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> getOwner(const DataFlowGraph &G); 566*9880d681SAndroid Build Coastguard Worker }; 567*9880d681SAndroid Build Coastguard Worker 568*9880d681SAndroid Build Coastguard Worker struct PhiNode : public InstrNode { getCodePhiNode569*9880d681SAndroid Build Coastguard Worker MachineInstr *getCode() const { 570*9880d681SAndroid Build Coastguard Worker return nullptr; 571*9880d681SAndroid Build Coastguard Worker } 572*9880d681SAndroid Build Coastguard Worker }; 573*9880d681SAndroid Build Coastguard Worker 574*9880d681SAndroid Build Coastguard Worker struct StmtNode : public InstrNode { getCodeStmtNode575*9880d681SAndroid Build Coastguard Worker MachineInstr *getCode() const { 576*9880d681SAndroid Build Coastguard Worker return CodeNode::getCode<MachineInstr*>(); 577*9880d681SAndroid Build Coastguard Worker } 578*9880d681SAndroid Build Coastguard Worker }; 579*9880d681SAndroid Build Coastguard Worker 580*9880d681SAndroid Build Coastguard Worker struct BlockNode : public CodeNode { getCodeBlockNode581*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *getCode() const { 582*9880d681SAndroid Build Coastguard Worker return CodeNode::getCode<MachineBasicBlock*>(); 583*9880d681SAndroid Build Coastguard Worker } 584*9880d681SAndroid Build Coastguard Worker void addPhi(NodeAddr<PhiNode*> PA, const DataFlowGraph &G); 585*9880d681SAndroid Build Coastguard Worker }; 586*9880d681SAndroid Build Coastguard Worker 587*9880d681SAndroid Build Coastguard Worker struct FuncNode : public CodeNode { getCodeFuncNode588*9880d681SAndroid Build Coastguard Worker MachineFunction *getCode() const { 589*9880d681SAndroid Build Coastguard Worker return CodeNode::getCode<MachineFunction*>(); 590*9880d681SAndroid Build Coastguard Worker } 591*9880d681SAndroid Build Coastguard Worker NodeAddr<BlockNode*> findBlock(const MachineBasicBlock *BB, 592*9880d681SAndroid Build Coastguard Worker const DataFlowGraph &G) const; 593*9880d681SAndroid Build Coastguard Worker NodeAddr<BlockNode*> getEntryBlock(const DataFlowGraph &G); 594*9880d681SAndroid Build Coastguard Worker }; 595*9880d681SAndroid Build Coastguard Worker 596*9880d681SAndroid Build Coastguard Worker struct DataFlowGraph { 597*9880d681SAndroid Build Coastguard Worker DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii, 598*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &tri, const MachineDominatorTree &mdt, 599*9880d681SAndroid Build Coastguard Worker const MachineDominanceFrontier &mdf, const RegisterAliasInfo &rai, 600*9880d681SAndroid Build Coastguard Worker const TargetOperandInfo &toi); 601*9880d681SAndroid Build Coastguard Worker 602*9880d681SAndroid Build Coastguard Worker NodeBase *ptr(NodeId N) const; ptrDataFlowGraph603*9880d681SAndroid Build Coastguard Worker template <typename T> T ptr(NodeId N) const { 604*9880d681SAndroid Build Coastguard Worker return static_cast<T>(ptr(N)); 605*9880d681SAndroid Build Coastguard Worker } 606*9880d681SAndroid Build Coastguard Worker NodeId id(const NodeBase *P) const; 607*9880d681SAndroid Build Coastguard Worker addrDataFlowGraph608*9880d681SAndroid Build Coastguard Worker template <typename T> NodeAddr<T> addr(NodeId N) const { 609*9880d681SAndroid Build Coastguard Worker return { ptr<T>(N), N }; 610*9880d681SAndroid Build Coastguard Worker } 611*9880d681SAndroid Build Coastguard Worker getFuncDataFlowGraph612*9880d681SAndroid Build Coastguard Worker NodeAddr<FuncNode*> getFunc() const { 613*9880d681SAndroid Build Coastguard Worker return Func; 614*9880d681SAndroid Build Coastguard Worker } getMFDataFlowGraph615*9880d681SAndroid Build Coastguard Worker MachineFunction &getMF() const { 616*9880d681SAndroid Build Coastguard Worker return MF; 617*9880d681SAndroid Build Coastguard Worker } getTIIDataFlowGraph618*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &getTII() const { 619*9880d681SAndroid Build Coastguard Worker return TII; 620*9880d681SAndroid Build Coastguard Worker } getTRIDataFlowGraph621*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &getTRI() const { 622*9880d681SAndroid Build Coastguard Worker return TRI; 623*9880d681SAndroid Build Coastguard Worker } getDTDataFlowGraph624*9880d681SAndroid Build Coastguard Worker const MachineDominatorTree &getDT() const { 625*9880d681SAndroid Build Coastguard Worker return MDT; 626*9880d681SAndroid Build Coastguard Worker } getDFDataFlowGraph627*9880d681SAndroid Build Coastguard Worker const MachineDominanceFrontier &getDF() const { 628*9880d681SAndroid Build Coastguard Worker return MDF; 629*9880d681SAndroid Build Coastguard Worker } getRAIDataFlowGraph630*9880d681SAndroid Build Coastguard Worker const RegisterAliasInfo &getRAI() const { 631*9880d681SAndroid Build Coastguard Worker return RAI; 632*9880d681SAndroid Build Coastguard Worker } 633*9880d681SAndroid Build Coastguard Worker 634*9880d681SAndroid Build Coastguard Worker struct DefStack { 635*9880d681SAndroid Build Coastguard Worker DefStack() = default; emptyDataFlowGraph::DefStack636*9880d681SAndroid Build Coastguard Worker bool empty() const { return Stack.empty() || top() == bottom(); } 637*9880d681SAndroid Build Coastguard Worker private: 638*9880d681SAndroid Build Coastguard Worker typedef NodeAddr<DefNode*> value_type; 639*9880d681SAndroid Build Coastguard Worker struct Iterator { 640*9880d681SAndroid Build Coastguard Worker typedef DefStack::value_type value_type; upDataFlowGraph::DefStack::Iterator641*9880d681SAndroid Build Coastguard Worker Iterator &up() { Pos = DS.nextUp(Pos); return *this; } downDataFlowGraph::DefStack::Iterator642*9880d681SAndroid Build Coastguard Worker Iterator &down() { Pos = DS.nextDown(Pos); return *this; } 643*9880d681SAndroid Build Coastguard Worker value_type operator*() const { 644*9880d681SAndroid Build Coastguard Worker assert(Pos >= 1); 645*9880d681SAndroid Build Coastguard Worker return DS.Stack[Pos-1]; 646*9880d681SAndroid Build Coastguard Worker } 647*9880d681SAndroid Build Coastguard Worker const value_type *operator->() const { 648*9880d681SAndroid Build Coastguard Worker assert(Pos >= 1); 649*9880d681SAndroid Build Coastguard Worker return &DS.Stack[Pos-1]; 650*9880d681SAndroid Build Coastguard Worker } 651*9880d681SAndroid Build Coastguard Worker bool operator==(const Iterator &It) const { return Pos == It.Pos; } 652*9880d681SAndroid Build Coastguard Worker bool operator!=(const Iterator &It) const { return Pos != It.Pos; } 653*9880d681SAndroid Build Coastguard Worker private: 654*9880d681SAndroid Build Coastguard Worker Iterator(const DefStack &S, bool Top); 655*9880d681SAndroid Build Coastguard Worker // Pos-1 is the index in the StorageType object that corresponds to 656*9880d681SAndroid Build Coastguard Worker // the top of the DefStack. 657*9880d681SAndroid Build Coastguard Worker const DefStack &DS; 658*9880d681SAndroid Build Coastguard Worker unsigned Pos; 659*9880d681SAndroid Build Coastguard Worker friend struct DefStack; 660*9880d681SAndroid Build Coastguard Worker }; 661*9880d681SAndroid Build Coastguard Worker public: 662*9880d681SAndroid Build Coastguard Worker typedef Iterator iterator; topDataFlowGraph::DefStack663*9880d681SAndroid Build Coastguard Worker iterator top() const { return Iterator(*this, true); } bottomDataFlowGraph::DefStack664*9880d681SAndroid Build Coastguard Worker iterator bottom() const { return Iterator(*this, false); } 665*9880d681SAndroid Build Coastguard Worker unsigned size() const; 666*9880d681SAndroid Build Coastguard Worker pushDataFlowGraph::DefStack667*9880d681SAndroid Build Coastguard Worker void push(NodeAddr<DefNode*> DA) { Stack.push_back(DA); } 668*9880d681SAndroid Build Coastguard Worker void pop(); 669*9880d681SAndroid Build Coastguard Worker void start_block(NodeId N); 670*9880d681SAndroid Build Coastguard Worker void clear_block(NodeId N); 671*9880d681SAndroid Build Coastguard Worker private: 672*9880d681SAndroid Build Coastguard Worker friend struct Iterator; 673*9880d681SAndroid Build Coastguard Worker typedef std::vector<value_type> StorageType; 674*9880d681SAndroid Build Coastguard Worker bool isDelimiter(const StorageType::value_type &P, NodeId N = 0) const { 675*9880d681SAndroid Build Coastguard Worker return (P.Addr == nullptr) && (N == 0 || P.Id == N); 676*9880d681SAndroid Build Coastguard Worker } 677*9880d681SAndroid Build Coastguard Worker unsigned nextUp(unsigned P) const; 678*9880d681SAndroid Build Coastguard Worker unsigned nextDown(unsigned P) const; 679*9880d681SAndroid Build Coastguard Worker StorageType Stack; 680*9880d681SAndroid Build Coastguard Worker }; 681*9880d681SAndroid Build Coastguard Worker 682*9880d681SAndroid Build Coastguard Worker typedef std::map<RegisterRef,DefStack> DefStackMap; 683*9880d681SAndroid Build Coastguard Worker 684*9880d681SAndroid Build Coastguard Worker void build(unsigned Options = BuildOptions::None); 685*9880d681SAndroid Build Coastguard Worker void pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM); 686*9880d681SAndroid Build Coastguard Worker void markBlock(NodeId B, DefStackMap &DefM); 687*9880d681SAndroid Build Coastguard Worker void releaseBlock(NodeId B, DefStackMap &DefM); 688*9880d681SAndroid Build Coastguard Worker 689*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> getNextRelated(NodeAddr<InstrNode*> IA, 690*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA) const; 691*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> getNextImp(NodeAddr<InstrNode*> IA, 692*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA, bool Create); 693*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> getNextImp(NodeAddr<InstrNode*> IA, 694*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA) const; 695*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> getNextShadow(NodeAddr<InstrNode*> IA, 696*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA, bool Create); 697*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> getNextShadow(NodeAddr<InstrNode*> IA, 698*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA) const; 699*9880d681SAndroid Build Coastguard Worker 700*9880d681SAndroid Build Coastguard Worker NodeList getRelatedRefs(NodeAddr<InstrNode*> IA, 701*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA) const; 702*9880d681SAndroid Build Coastguard Worker unlinkUseDataFlowGraph703*9880d681SAndroid Build Coastguard Worker void unlinkUse(NodeAddr<UseNode*> UA, bool RemoveFromOwner) { 704*9880d681SAndroid Build Coastguard Worker unlinkUseDF(UA); 705*9880d681SAndroid Build Coastguard Worker if (RemoveFromOwner) 706*9880d681SAndroid Build Coastguard Worker removeFromOwner(UA); 707*9880d681SAndroid Build Coastguard Worker } unlinkDefDataFlowGraph708*9880d681SAndroid Build Coastguard Worker void unlinkDef(NodeAddr<DefNode*> DA, bool RemoveFromOwner) { 709*9880d681SAndroid Build Coastguard Worker unlinkDefDF(DA); 710*9880d681SAndroid Build Coastguard Worker if (RemoveFromOwner) 711*9880d681SAndroid Build Coastguard Worker removeFromOwner(DA); 712*9880d681SAndroid Build Coastguard Worker } 713*9880d681SAndroid Build Coastguard Worker 714*9880d681SAndroid Build Coastguard Worker // Some useful filters. 715*9880d681SAndroid Build Coastguard Worker template <uint16_t Kind> IsRefDataFlowGraph716*9880d681SAndroid Build Coastguard Worker static bool IsRef(const NodeAddr<NodeBase*> BA) { 717*9880d681SAndroid Build Coastguard Worker return BA.Addr->getType() == NodeAttrs::Ref && 718*9880d681SAndroid Build Coastguard Worker BA.Addr->getKind() == Kind; 719*9880d681SAndroid Build Coastguard Worker } 720*9880d681SAndroid Build Coastguard Worker template <uint16_t Kind> IsCodeDataFlowGraph721*9880d681SAndroid Build Coastguard Worker static bool IsCode(const NodeAddr<NodeBase*> BA) { 722*9880d681SAndroid Build Coastguard Worker return BA.Addr->getType() == NodeAttrs::Code && 723*9880d681SAndroid Build Coastguard Worker BA.Addr->getKind() == Kind; 724*9880d681SAndroid Build Coastguard Worker } IsDefDataFlowGraph725*9880d681SAndroid Build Coastguard Worker static bool IsDef(const NodeAddr<NodeBase*> BA) { 726*9880d681SAndroid Build Coastguard Worker return BA.Addr->getType() == NodeAttrs::Ref && 727*9880d681SAndroid Build Coastguard Worker BA.Addr->getKind() == NodeAttrs::Def; 728*9880d681SAndroid Build Coastguard Worker } IsUseDataFlowGraph729*9880d681SAndroid Build Coastguard Worker static bool IsUse(const NodeAddr<NodeBase*> BA) { 730*9880d681SAndroid Build Coastguard Worker return BA.Addr->getType() == NodeAttrs::Ref && 731*9880d681SAndroid Build Coastguard Worker BA.Addr->getKind() == NodeAttrs::Use; 732*9880d681SAndroid Build Coastguard Worker } IsPhiDataFlowGraph733*9880d681SAndroid Build Coastguard Worker static bool IsPhi(const NodeAddr<NodeBase*> BA) { 734*9880d681SAndroid Build Coastguard Worker return BA.Addr->getType() == NodeAttrs::Code && 735*9880d681SAndroid Build Coastguard Worker BA.Addr->getKind() == NodeAttrs::Phi; 736*9880d681SAndroid Build Coastguard Worker } 737*9880d681SAndroid Build Coastguard Worker 738*9880d681SAndroid Build Coastguard Worker private: 739*9880d681SAndroid Build Coastguard Worker void reset(); 740*9880d681SAndroid Build Coastguard Worker 741*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> newNode(uint16_t Attrs); 742*9880d681SAndroid Build Coastguard Worker NodeAddr<NodeBase*> cloneNode(const NodeAddr<NodeBase*> B); 743*9880d681SAndroid Build Coastguard Worker NodeAddr<UseNode*> newUse(NodeAddr<InstrNode*> Owner, 744*9880d681SAndroid Build Coastguard Worker MachineOperand &Op, uint16_t Flags = NodeAttrs::None); 745*9880d681SAndroid Build Coastguard Worker NodeAddr<PhiUseNode*> newPhiUse(NodeAddr<PhiNode*> Owner, 746*9880d681SAndroid Build Coastguard Worker RegisterRef RR, NodeAddr<BlockNode*> PredB, 747*9880d681SAndroid Build Coastguard Worker uint16_t Flags = NodeAttrs::PhiRef); 748*9880d681SAndroid Build Coastguard Worker NodeAddr<DefNode*> newDef(NodeAddr<InstrNode*> Owner, 749*9880d681SAndroid Build Coastguard Worker MachineOperand &Op, uint16_t Flags = NodeAttrs::None); 750*9880d681SAndroid Build Coastguard Worker NodeAddr<DefNode*> newDef(NodeAddr<InstrNode*> Owner, 751*9880d681SAndroid Build Coastguard Worker RegisterRef RR, uint16_t Flags = NodeAttrs::PhiRef); 752*9880d681SAndroid Build Coastguard Worker NodeAddr<PhiNode*> newPhi(NodeAddr<BlockNode*> Owner); 753*9880d681SAndroid Build Coastguard Worker NodeAddr<StmtNode*> newStmt(NodeAddr<BlockNode*> Owner, 754*9880d681SAndroid Build Coastguard Worker MachineInstr *MI); 755*9880d681SAndroid Build Coastguard Worker NodeAddr<BlockNode*> newBlock(NodeAddr<FuncNode*> Owner, 756*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB); 757*9880d681SAndroid Build Coastguard Worker NodeAddr<FuncNode*> newFunc(MachineFunction *MF); 758*9880d681SAndroid Build Coastguard Worker 759*9880d681SAndroid Build Coastguard Worker template <typename Predicate> 760*9880d681SAndroid Build Coastguard Worker std::pair<NodeAddr<RefNode*>,NodeAddr<RefNode*>> 761*9880d681SAndroid Build Coastguard Worker locateNextRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA, 762*9880d681SAndroid Build Coastguard Worker Predicate P) const; 763*9880d681SAndroid Build Coastguard Worker 764*9880d681SAndroid Build Coastguard Worker typedef std::map<NodeId,RegisterSet> BlockRefsMap; 765*9880d681SAndroid Build Coastguard Worker 766*9880d681SAndroid Build Coastguard Worker void buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In); 767*9880d681SAndroid Build Coastguard Worker void buildBlockRefs(NodeAddr<BlockNode*> BA, BlockRefsMap &RefM); 768*9880d681SAndroid Build Coastguard Worker void recordDefsForDF(BlockRefsMap &PhiM, BlockRefsMap &RefM, 769*9880d681SAndroid Build Coastguard Worker NodeAddr<BlockNode*> BA); 770*9880d681SAndroid Build Coastguard Worker void buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM, 771*9880d681SAndroid Build Coastguard Worker NodeAddr<BlockNode*> BA); 772*9880d681SAndroid Build Coastguard Worker void removeUnusedPhis(); 773*9880d681SAndroid Build Coastguard Worker 774*9880d681SAndroid Build Coastguard Worker template <typename T> void linkRefUp(NodeAddr<InstrNode*> IA, 775*9880d681SAndroid Build Coastguard Worker NodeAddr<T> TA, DefStack &DS); 776*9880d681SAndroid Build Coastguard Worker void linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA); 777*9880d681SAndroid Build Coastguard Worker void linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA); 778*9880d681SAndroid Build Coastguard Worker 779*9880d681SAndroid Build Coastguard Worker void unlinkUseDF(NodeAddr<UseNode*> UA); 780*9880d681SAndroid Build Coastguard Worker void unlinkDefDF(NodeAddr<DefNode*> DA); removeFromOwnerDataFlowGraph781*9880d681SAndroid Build Coastguard Worker void removeFromOwner(NodeAddr<RefNode*> RA) { 782*9880d681SAndroid Build Coastguard Worker NodeAddr<InstrNode*> IA = RA.Addr->getOwner(*this); 783*9880d681SAndroid Build Coastguard Worker IA.Addr->removeMember(RA, *this); 784*9880d681SAndroid Build Coastguard Worker } 785*9880d681SAndroid Build Coastguard Worker 786*9880d681SAndroid Build Coastguard Worker TimerGroup TimeG; 787*9880d681SAndroid Build Coastguard Worker NodeAddr<FuncNode*> Func; 788*9880d681SAndroid Build Coastguard Worker NodeAllocator Memory; 789*9880d681SAndroid Build Coastguard Worker 790*9880d681SAndroid Build Coastguard Worker MachineFunction &MF; 791*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII; 792*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI; 793*9880d681SAndroid Build Coastguard Worker const MachineDominatorTree &MDT; 794*9880d681SAndroid Build Coastguard Worker const MachineDominanceFrontier &MDF; 795*9880d681SAndroid Build Coastguard Worker const RegisterAliasInfo &RAI; 796*9880d681SAndroid Build Coastguard Worker const TargetOperandInfo &TOI; 797*9880d681SAndroid Build Coastguard Worker }; // struct DataFlowGraph 798*9880d681SAndroid Build Coastguard Worker 799*9880d681SAndroid Build Coastguard Worker template <typename Predicate> getNextRef(RegisterRef RR,Predicate P,bool NextOnly,const DataFlowGraph & G)800*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RefNode::getNextRef(RegisterRef RR, Predicate P, 801*9880d681SAndroid Build Coastguard Worker bool NextOnly, const DataFlowGraph &G) { 802*9880d681SAndroid Build Coastguard Worker // Get the "Next" reference in the circular list that references RR and 803*9880d681SAndroid Build Coastguard Worker // satisfies predicate "Pred". 804*9880d681SAndroid Build Coastguard Worker auto NA = G.addr<NodeBase*>(getNext()); 805*9880d681SAndroid Build Coastguard Worker 806*9880d681SAndroid Build Coastguard Worker while (NA.Addr != this) { 807*9880d681SAndroid Build Coastguard Worker if (NA.Addr->getType() == NodeAttrs::Ref) { 808*9880d681SAndroid Build Coastguard Worker NodeAddr<RefNode*> RA = NA; 809*9880d681SAndroid Build Coastguard Worker if (RA.Addr->getRegRef() == RR && P(NA)) 810*9880d681SAndroid Build Coastguard Worker return NA; 811*9880d681SAndroid Build Coastguard Worker if (NextOnly) 812*9880d681SAndroid Build Coastguard Worker break; 813*9880d681SAndroid Build Coastguard Worker NA = G.addr<NodeBase*>(NA.Addr->getNext()); 814*9880d681SAndroid Build Coastguard Worker } else { 815*9880d681SAndroid Build Coastguard Worker // We've hit the beginning of the chain. 816*9880d681SAndroid Build Coastguard Worker assert(NA.Addr->getType() == NodeAttrs::Code); 817*9880d681SAndroid Build Coastguard Worker NodeAddr<CodeNode*> CA = NA; 818*9880d681SAndroid Build Coastguard Worker NA = CA.Addr->getFirstMember(G); 819*9880d681SAndroid Build Coastguard Worker } 820*9880d681SAndroid Build Coastguard Worker } 821*9880d681SAndroid Build Coastguard Worker // Return the equivalent of "nullptr" if such a node was not found. 822*9880d681SAndroid Build Coastguard Worker return NodeAddr<RefNode*>(); 823*9880d681SAndroid Build Coastguard Worker } 824*9880d681SAndroid Build Coastguard Worker 825*9880d681SAndroid Build Coastguard Worker template <typename Predicate> members_if(Predicate P,const DataFlowGraph & G)826*9880d681SAndroid Build Coastguard Worker NodeList CodeNode::members_if(Predicate P, const DataFlowGraph &G) const { 827*9880d681SAndroid Build Coastguard Worker NodeList MM; 828*9880d681SAndroid Build Coastguard Worker auto M = getFirstMember(G); 829*9880d681SAndroid Build Coastguard Worker if (M.Id == 0) 830*9880d681SAndroid Build Coastguard Worker return MM; 831*9880d681SAndroid Build Coastguard Worker 832*9880d681SAndroid Build Coastguard Worker while (M.Addr != this) { 833*9880d681SAndroid Build Coastguard Worker if (P(M)) 834*9880d681SAndroid Build Coastguard Worker MM.push_back(M); 835*9880d681SAndroid Build Coastguard Worker M = G.addr<NodeBase*>(M.Addr->getNext()); 836*9880d681SAndroid Build Coastguard Worker } 837*9880d681SAndroid Build Coastguard Worker return MM; 838*9880d681SAndroid Build Coastguard Worker } 839*9880d681SAndroid Build Coastguard Worker 840*9880d681SAndroid Build Coastguard Worker 841*9880d681SAndroid Build Coastguard Worker template <typename T> struct Print; 842*9880d681SAndroid Build Coastguard Worker template <typename T> 843*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, const Print<T> &P); 844*9880d681SAndroid Build Coastguard Worker 845*9880d681SAndroid Build Coastguard Worker template <typename T> 846*9880d681SAndroid Build Coastguard Worker struct Print { PrintPrint847*9880d681SAndroid Build Coastguard Worker Print(const T &x, const DataFlowGraph &g) : Obj(x), G(g) {} 848*9880d681SAndroid Build Coastguard Worker const T &Obj; 849*9880d681SAndroid Build Coastguard Worker const DataFlowGraph &G; 850*9880d681SAndroid Build Coastguard Worker }; 851*9880d681SAndroid Build Coastguard Worker 852*9880d681SAndroid Build Coastguard Worker template <typename T> 853*9880d681SAndroid Build Coastguard Worker struct PrintNode : Print<NodeAddr<T>> { PrintNodePrintNode854*9880d681SAndroid Build Coastguard Worker PrintNode(const NodeAddr<T> &x, const DataFlowGraph &g) 855*9880d681SAndroid Build Coastguard Worker : Print<NodeAddr<T>>(x, g) {} 856*9880d681SAndroid Build Coastguard Worker }; 857*9880d681SAndroid Build Coastguard Worker } // namespace rdf 858*9880d681SAndroid Build Coastguard Worker } // namespace llvm 859*9880d681SAndroid Build Coastguard Worker 860*9880d681SAndroid Build Coastguard Worker #endif // RDF_GRAPH_H 861