Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:33

0001 //===- RDFGraph.h -----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Target-independent, SSA-based data flow graph for register data flow (RDF)
0010 // for a non-SSA program representation (e.g. post-RA machine code).
0011 //
0012 //
0013 // *** Introduction
0014 //
0015 // The RDF graph is a collection of nodes, each of which denotes some element
0016 // of the program. There are two main types of such elements: code and refe-
0017 // rences. Conceptually, "code" is something that represents the structure
0018 // of the program, e.g. basic block or a statement, while "reference" is an
0019 // instance of accessing a register, e.g. a definition or a use. Nodes are
0020 // connected with each other based on the structure of the program (such as
0021 // blocks, instructions, etc.), and based on the data flow (e.g. reaching
0022 // definitions, reached uses, etc.). The single-reaching-definition principle
0023 // of SSA is generally observed, although, due to the non-SSA representation
0024 // of the program, there are some differences between the graph and a "pure"
0025 // SSA representation.
0026 //
0027 //
0028 // *** Implementation remarks
0029 //
0030 // Since the graph can contain a large number of nodes, memory consumption
0031 // was one of the major design considerations. As a result, there is a single
0032 // base class NodeBase which defines all members used by all possible derived
0033 // classes. The members are arranged in a union, and a derived class cannot
0034 // add any data members of its own. Each derived class only defines the
0035 // functional interface, i.e. member functions. NodeBase must be a POD,
0036 // which implies that all of its members must also be PODs.
0037 // Since nodes need to be connected with other nodes, pointers have been
0038 // replaced with 32-bit identifiers: each node has an id of type NodeId.
0039 // There are mapping functions in the graph that translate between actual
0040 // memory addresses and the corresponding identifiers.
0041 // A node id of 0 is equivalent to nullptr.
0042 //
0043 //
0044 // *** Structure of the graph
0045 //
0046 // A code node is always a collection of other nodes. For example, a code
0047 // node corresponding to a basic block will contain code nodes corresponding
0048 // to instructions. In turn, a code node corresponding to an instruction will
0049 // contain a list of reference nodes that correspond to the definitions and
0050 // uses of registers in that instruction. The members are arranged into a
0051 // circular list, which is yet another consequence of the effort to save
0052 // memory: for each member node it should be possible to obtain its owner,
0053 // and it should be possible to access all other members. There are other
0054 // ways to accomplish that, but the circular list seemed the most natural.
0055 //
0056 // +- CodeNode -+
0057 // |            | <---------------------------------------------------+
0058 // +-+--------+-+                                                     |
0059 //   |FirstM  |LastM                                                  |
0060 //   |        +-------------------------------------+                 |
0061 //   |                                              |                 |
0062 //   V                                              V                 |
0063 //  +----------+ Next +----------+ Next       Next +----------+ Next  |
0064 //  |          |----->|          |-----> ... ----->|          |----->-+
0065 //  +- Member -+      +- Member -+                 +- Member -+
0066 //
0067 // The order of members is such that related reference nodes (see below)
0068 // should be contiguous on the member list.
0069 //
0070 // A reference node is a node that encapsulates an access to a register,
0071 // in other words, data flowing into or out of a register. There are two
0072 // major kinds of reference nodes: defs and uses. A def node will contain
0073 // the id of the first reached use, and the id of the first reached def.
0074 // Each def and use will contain the id of the reaching def, and also the
0075 // id of the next reached def (for def nodes) or use (for use nodes).
0076 // The "next node sharing the same reaching def" is denoted as "sibling".
0077 // In summary:
0078 // - Def node contains: reaching def, sibling, first reached def, and first
0079 // reached use.
0080 // - Use node contains: reaching def and sibling.
0081 //
0082 // +-- DefNode --+
0083 // | R2 = ...    | <---+--------------------+
0084 // ++---------+--+     |                    |
0085 //  |Reached  |Reached |                    |
0086 //  |Def      |Use     |                    |
0087 //  |         |        |Reaching            |Reaching
0088 //  |         V        |Def                 |Def
0089 //  |      +-- UseNode --+ Sib  +-- UseNode --+ Sib       Sib
0090 //  |      | ... = R2    |----->| ... = R2    |----> ... ----> 0
0091 //  |      +-------------+      +-------------+
0092 //  V
0093 // +-- DefNode --+ Sib
0094 // | R2 = ...    |----> ...
0095 // ++---------+--+
0096 //  |         |
0097 //  |         |
0098 // ...       ...
0099 //
0100 // To get a full picture, the circular lists connecting blocks within a
0101 // function, instructions within a block, etc. should be superimposed with
0102 // the def-def, def-use links shown above.
0103 // To illustrate this, consider a small example in a pseudo-assembly:
0104 // foo:
0105 //   add r2, r0, r1   ; r2 = r0+r1
0106 //   addi r0, r2, 1   ; r0 = r2+1
0107 //   ret r0           ; return value in r0
0108 //
0109 // The graph (in a format used by the debugging functions) would look like:
0110 //
0111 //   DFG dump:[
0112 //   f1: Function foo
0113 //   b2: === %bb.0 === preds(0), succs(0):
0114 //   p3: phi [d4<r0>(,d12,u9):]
0115 //   p5: phi [d6<r1>(,,u10):]
0116 //   s7: add [d8<r2>(,,u13):, u9<r0>(d4):, u10<r1>(d6):]
0117 //   s11: addi [d12<r0>(d4,,u15):, u13<r2>(d8):]
0118 //   s14: ret [u15<r0>(d12):]
0119 //   ]
0120 //
0121 // The f1, b2, p3, etc. are node ids. The letter is prepended to indicate the
0122 // kind of the node (i.e. f - function, b - basic block, p - phi, s - state-
0123 // ment, d - def, u - use).
0124 // The format of a def node is:
0125 //   dN<R>(rd,d,u):sib,
0126 // where
0127 //   N   - numeric node id,
0128 //   R   - register being defined
0129 //   rd  - reaching def,
0130 //   d   - reached def,
0131 //   u   - reached use,
0132 //   sib - sibling.
0133 // The format of a use node is:
0134 //   uN<R>[!](rd):sib,
0135 // where
0136 //   N   - numeric node id,
0137 //   R   - register being used,
0138 //   rd  - reaching def,
0139 //   sib - sibling.
0140 // Possible annotations (usually preceding the node id):
0141 //   +   - preserving def,
0142 //   ~   - clobbering def,
0143 //   "   - shadow ref (follows the node id),
0144 //   !   - fixed register (appears after register name).
0145 //
0146 // The circular lists are not explicit in the dump.
0147 //
0148 //
0149 // *** Node attributes
0150 //
0151 // NodeBase has a member "Attrs", which is the primary way of determining
0152 // the node's characteristics. The fields in this member decide whether
0153 // the node is a code node or a reference node (i.e. node's "type"), then
0154 // within each type, the "kind" determines what specifically this node
0155 // represents. The remaining bits, "flags", contain additional information
0156 // that is even more detailed than the "kind".
0157 // CodeNode's kinds are:
0158 // - Phi:   Phi node, members are reference nodes.
0159 // - Stmt:  Statement, members are reference nodes.
0160 // - Block: Basic block, members are instruction nodes (i.e. Phi or Stmt).
0161 // - Func:  The whole function. The members are basic block nodes.
0162 // RefNode's kinds are:
0163 // - Use.
0164 // - Def.
0165 //
0166 // Meaning of flags:
0167 // - Preserving: applies only to defs. A preserving def is one that can
0168 //   preserve some of the original bits among those that are included in
0169 //   the register associated with that def. For example, if R0 is a 32-bit
0170 //   register, but a def can only change the lower 16 bits, then it will
0171 //   be marked as preserving.
0172 // - Shadow: a reference that has duplicates holding additional reaching
0173 //   defs (see more below).
0174 // - Clobbering: applied only to defs, indicates that the value generated
0175 //   by this def is unspecified. A typical example would be volatile registers
0176 //   after function calls.
0177 // - Fixed: the register in this def/use cannot be replaced with any other
0178 //   register. A typical case would be a parameter register to a call, or
0179 //   the register with the return value from a function.
0180 // - Undef: the register in this reference the register is assumed to have
0181 //   no pre-existing value, even if it appears to be reached by some def.
0182 //   This is typically used to prevent keeping registers artificially live
0183 //   in cases when they are defined via predicated instructions. For example:
0184 //     r0 = add-if-true cond, r10, r11                (1)
0185 //     r0 = add-if-false cond, r12, r13, implicit r0  (2)
0186 //     ... = r0                                       (3)
0187 //   Before (1), r0 is not intended to be live, and the use of r0 in (3) is
0188 //   not meant to be reached by any def preceding (1). However, since the
0189 //   defs in (1) and (2) are both preserving, these properties alone would
0190 //   imply that the use in (3) may indeed be reached by some prior def.
0191 //   Adding Undef flag to the def in (1) prevents that. The Undef flag
0192 //   may be applied to both defs and uses.
0193 // - Dead: applies only to defs. The value coming out of a "dead" def is
0194 //   assumed to be unused, even if the def appears to be reaching other defs
0195 //   or uses. The motivation for this flag comes from dead defs on function
0196 //   calls: there is no way to determine if such a def is dead without
0197 //   analyzing the target's ABI. Hence the graph should contain this info,
0198 //   as it is unavailable otherwise. On the other hand, a def without any
0199 //   uses on a typical instruction is not the intended target for this flag.
0200 //
0201 // *** Shadow references
0202 //
0203 // It may happen that a super-register can have two (or more) non-overlapping
0204 // sub-registers. When both of these sub-registers are defined and followed
0205 // by a use of the super-register, the use of the super-register will not
0206 // have a unique reaching def: both defs of the sub-registers need to be
0207 // accounted for. In such cases, a duplicate use of the super-register is
0208 // added and it points to the extra reaching def. Both uses are marked with
0209 // a flag "shadow". Example:
0210 // Assume t0 is a super-register of r0 and r1, r0 and r1 do not overlap:
0211 //   set r0, 1        ; r0 = 1
0212 //   set r1, 1        ; r1 = 1
0213 //   addi t1, t0, 1   ; t1 = t0+1
0214 //
0215 // The DFG:
0216 //   s1: set [d2<r0>(,,u9):]
0217 //   s3: set [d4<r1>(,,u10):]
0218 //   s5: addi [d6<t1>(,,):, u7"<t0>(d2):, u8"<t0>(d4):]
0219 //
0220 // The statement s5 has two use nodes for t0: u7" and u9". The quotation
0221 // mark " indicates that the node is a shadow.
0222 //
0223 
0224 #ifndef LLVM_CODEGEN_RDFGRAPH_H
0225 #define LLVM_CODEGEN_RDFGRAPH_H
0226 
0227 #include "RDFRegisters.h"
0228 #include "llvm/ADT/ArrayRef.h"
0229 #include "llvm/ADT/SmallVector.h"
0230 #include "llvm/MC/LaneBitmask.h"
0231 #include "llvm/Support/Allocator.h"
0232 #include "llvm/Support/MathExtras.h"
0233 #include <cassert>
0234 #include <cstdint>
0235 #include <cstring>
0236 #include <map>
0237 #include <memory>
0238 #include <set>
0239 #include <unordered_map>
0240 #include <utility>
0241 #include <vector>
0242 
0243 // RDF uses uint32_t to refer to registers. This is to ensure that the type
0244 // size remains specific. In other places, registers are often stored using
0245 // unsigned.
0246 static_assert(sizeof(uint32_t) == sizeof(unsigned), "Those should be equal");
0247 
0248 namespace llvm {
0249 
0250 class MachineBasicBlock;
0251 class MachineDominanceFrontier;
0252 class MachineDominatorTree;
0253 class MachineFunction;
0254 class MachineInstr;
0255 class MachineOperand;
0256 class raw_ostream;
0257 class TargetInstrInfo;
0258 class TargetRegisterInfo;
0259 
0260 namespace rdf {
0261 
0262 using NodeId = uint32_t;
0263 
0264 struct DataFlowGraph;
0265 
0266 struct NodeAttrs {
0267   // clang-format off
0268   enum : uint16_t {
0269     None          = 0x0000,   // Nothing
0270 
0271     // Types: 2 bits
0272     TypeMask      = 0x0003,
0273     Code          = 0x0001,   // 01, Container
0274     Ref           = 0x0002,   // 10, Reference
0275 
0276     // Kind: 3 bits
0277     KindMask      = 0x0007 << 2,
0278     Def           = 0x0001 << 2,  // 001
0279     Use           = 0x0002 << 2,  // 010
0280     Phi           = 0x0003 << 2,  // 011
0281     Stmt          = 0x0004 << 2,  // 100
0282     Block         = 0x0005 << 2,  // 101
0283     Func          = 0x0006 << 2,  // 110
0284 
0285     // Flags: 7 bits for now
0286     FlagMask      = 0x007F << 5,
0287     Shadow        = 0x0001 << 5,  // 0000001, Has extra reaching defs.
0288     Clobbering    = 0x0002 << 5,  // 0000010, Produces unspecified values.
0289     PhiRef        = 0x0004 << 5,  // 0000100, Member of PhiNode.
0290     Preserving    = 0x0008 << 5,  // 0001000, Def can keep original bits.
0291     Fixed         = 0x0010 << 5,  // 0010000, Fixed register.
0292     Undef         = 0x0020 << 5,  // 0100000, Has no pre-existing value.
0293     Dead          = 0x0040 << 5,  // 1000000, Does not define a value.
0294   };
0295   // clang-format on
0296 
0297   static uint16_t type(uint16_t T) { //
0298     return T & TypeMask;
0299   }
0300   static uint16_t kind(uint16_t T) { //
0301     return T & KindMask;
0302   }
0303   static uint16_t flags(uint16_t T) { //
0304     return T & FlagMask;
0305   }
0306   static uint16_t set_type(uint16_t A, uint16_t T) {
0307     return (A & ~TypeMask) | T;
0308   }
0309 
0310   static uint16_t set_kind(uint16_t A, uint16_t K) {
0311     return (A & ~KindMask) | K;
0312   }
0313 
0314   static uint16_t set_flags(uint16_t A, uint16_t F) {
0315     return (A & ~FlagMask) | F;
0316   }
0317 
0318   // Test if A contains B.
0319   static bool contains(uint16_t A, uint16_t B) {
0320     if (type(A) != Code)
0321       return false;
0322     uint16_t KB = kind(B);
0323     switch (kind(A)) {
0324     case Func:
0325       return KB == Block;
0326     case Block:
0327       return KB == Phi || KB == Stmt;
0328     case Phi:
0329     case Stmt:
0330       return type(B) == Ref;
0331     }
0332     return false;
0333   }
0334 };
0335 
0336 struct BuildOptions {
0337   enum : unsigned {
0338     None = 0x00,
0339     KeepDeadPhis = 0x01, // Do not remove dead phis during build.
0340     OmitReserved = 0x02, // Do not track reserved registers.
0341   };
0342 };
0343 
0344 template <typename T> struct NodeAddr {
0345   NodeAddr() = default;
0346   NodeAddr(T A, NodeId I) : Addr(A), Id(I) {}
0347 
0348   // Type cast (casting constructor). The reason for having this class
0349   // instead of std::pair.
0350   template <typename S>
0351   NodeAddr(const NodeAddr<S> &NA) : Addr(static_cast<T>(NA.Addr)), Id(NA.Id) {}
0352 
0353   bool operator==(const NodeAddr<T> &NA) const {
0354     assert((Addr == NA.Addr) == (Id == NA.Id));
0355     return Addr == NA.Addr;
0356   }
0357   bool operator!=(const NodeAddr<T> &NA) const { //
0358     return !operator==(NA);
0359   }
0360 
0361   T Addr = nullptr;
0362   NodeId Id = 0;
0363 };
0364 
0365 struct NodeBase;
0366 
0367 struct RefNode;
0368 struct DefNode;
0369 struct UseNode;
0370 struct PhiUseNode;
0371 
0372 struct CodeNode;
0373 struct InstrNode;
0374 struct PhiNode;
0375 struct StmtNode;
0376 struct BlockNode;
0377 struct FuncNode;
0378 
0379 // Use these short names with rdf:: qualification to avoid conflicts with
0380 // preexisting names. Do not use 'using namespace rdf'.
0381 using Node = NodeAddr<NodeBase *>;
0382 
0383 using Ref = NodeAddr<RefNode *>;
0384 using Def = NodeAddr<DefNode *>;
0385 using Use = NodeAddr<UseNode *>; // This may conflict with llvm::Use.
0386 using PhiUse = NodeAddr<PhiUseNode *>;
0387 
0388 using Code = NodeAddr<CodeNode *>;
0389 using Instr = NodeAddr<InstrNode *>;
0390 using Phi = NodeAddr<PhiNode *>;
0391 using Stmt = NodeAddr<StmtNode *>;
0392 using Block = NodeAddr<BlockNode *>;
0393 using Func = NodeAddr<FuncNode *>;
0394 
0395 // Fast memory allocation and translation between node id and node address.
0396 // This is really the same idea as the one underlying the "bump pointer
0397 // allocator", the difference being in the translation. A node id is
0398 // composed of two components: the index of the block in which it was
0399 // allocated, and the index within the block. With the default settings,
0400 // where the number of nodes per block is 4096, the node id (minus 1) is:
0401 //
0402 // bit position:                11             0
0403 // +----------------------------+--------------+
0404 // | Index of the block         |Index in block|
0405 // +----------------------------+--------------+
0406 //
0407 // The actual node id is the above plus 1, to avoid creating a node id of 0.
0408 //
0409 // This method significantly improved the build time, compared to using maps
0410 // (std::unordered_map or DenseMap) to translate between pointers and ids.
0411 struct NodeAllocator {
0412   // Amount of storage for a single node.
0413   enum { NodeMemSize = 32 };
0414 
0415   NodeAllocator(uint32_t NPB = 4096)
0416       : NodesPerBlock(NPB), BitsPerIndex(Log2_32(NPB)),
0417         IndexMask((1 << BitsPerIndex) - 1) {
0418     assert(isPowerOf2_32(NPB));
0419   }
0420 
0421   NodeBase *ptr(NodeId N) const {
0422     uint32_t N1 = N - 1;
0423     uint32_t BlockN = N1 >> BitsPerIndex;
0424     uint32_t Offset = (N1 & IndexMask) * NodeMemSize;
0425     return reinterpret_cast<NodeBase *>(Blocks[BlockN] + Offset);
0426   }
0427 
0428   NodeId id(const NodeBase *P) const;
0429   Node New();
0430   void clear();
0431 
0432 private:
0433   void startNewBlock();
0434   bool needNewBlock();
0435 
0436   uint32_t makeId(uint32_t Block, uint32_t Index) const {
0437     // Add 1 to the id, to avoid the id of 0, which is treated as "null".
0438     return ((Block << BitsPerIndex) | Index) + 1;
0439   }
0440 
0441   const uint32_t NodesPerBlock;
0442   const uint32_t BitsPerIndex;
0443   const uint32_t IndexMask;
0444   char *ActiveEnd = nullptr;
0445   std::vector<char *> Blocks;
0446   using AllocatorTy = BumpPtrAllocatorImpl<MallocAllocator, 65536>;
0447   AllocatorTy MemPool;
0448 };
0449 
0450 using RegisterSet = std::set<RegisterRef>;
0451 
0452 struct TargetOperandInfo {
0453   TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {}
0454   virtual ~TargetOperandInfo() = default;
0455 
0456   virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const;
0457   virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const;
0458   virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const;
0459 
0460   const TargetInstrInfo &TII;
0461 };
0462 
0463 // Packed register reference. Only used for storage.
0464 struct PackedRegisterRef {
0465   RegisterId Reg;
0466   uint32_t MaskId;
0467 };
0468 
0469 struct LaneMaskIndex : private IndexedSet<LaneBitmask> {
0470   LaneMaskIndex() = default;
0471 
0472   LaneBitmask getLaneMaskForIndex(uint32_t K) const {
0473     return K == 0 ? LaneBitmask::getAll() : get(K);
0474   }
0475 
0476   uint32_t getIndexForLaneMask(LaneBitmask LM) {
0477     assert(LM.any());
0478     return LM.all() ? 0 : insert(LM);
0479   }
0480 
0481   uint32_t getIndexForLaneMask(LaneBitmask LM) const {
0482     assert(LM.any());
0483     return LM.all() ? 0 : find(LM);
0484   }
0485 };
0486 
0487 struct NodeBase {
0488 public:
0489   // Make sure this is a POD.
0490   NodeBase() = default;
0491 
0492   uint16_t getType() const { return NodeAttrs::type(Attrs); }
0493   uint16_t getKind() const { return NodeAttrs::kind(Attrs); }
0494   uint16_t getFlags() const { return NodeAttrs::flags(Attrs); }
0495   NodeId getNext() const { return Next; }
0496 
0497   uint16_t getAttrs() const { return Attrs; }
0498   void setAttrs(uint16_t A) { Attrs = A; }
0499   void setFlags(uint16_t F) { setAttrs(NodeAttrs::set_flags(getAttrs(), F)); }
0500 
0501   // Insert node NA after "this" in the circular chain.
0502   void append(Node NA);
0503 
0504   // Initialize all members to 0.
0505   void init() { memset(this, 0, sizeof *this); }
0506 
0507   void setNext(NodeId N) { Next = N; }
0508 
0509 protected:
0510   uint16_t Attrs;
0511   uint16_t Reserved;
0512   NodeId Next; // Id of the next node in the circular chain.
0513   // Definitions of nested types. Using anonymous nested structs would make
0514   // this class definition clearer, but unnamed structs are not a part of
0515   // the standard.
0516   struct Def_struct {
0517     NodeId DD, DU; // Ids of the first reached def and use.
0518   };
0519   struct PhiU_struct {
0520     NodeId PredB; // Id of the predecessor block for a phi use.
0521   };
0522   struct Code_struct {
0523     void *CP;             // Pointer to the actual code.
0524     NodeId FirstM, LastM; // Id of the first member and last.
0525   };
0526   struct Ref_struct {
0527     NodeId RD, Sib; // Ids of the reaching def and the sibling.
0528     union {
0529       Def_struct Def;
0530       PhiU_struct PhiU;
0531     };
0532     union {
0533       MachineOperand *Op;   // Non-phi refs point to a machine operand.
0534       PackedRegisterRef PR; // Phi refs store register info directly.
0535     };
0536   };
0537 
0538   // The actual payload.
0539   union {
0540     Ref_struct RefData;
0541     Code_struct CodeData;
0542   };
0543 };
0544 // The allocator allocates chunks of 32 bytes for each node. The fact that
0545 // each node takes 32 bytes in memory is used for fast translation between
0546 // the node id and the node address.
0547 static_assert(sizeof(NodeBase) <= NodeAllocator::NodeMemSize,
0548               "NodeBase must be at most NodeAllocator::NodeMemSize bytes");
0549 
0550 using NodeList = SmallVector<Node, 4>;
0551 using NodeSet = std::set<NodeId>;
0552 
0553 struct RefNode : public NodeBase {
0554   RefNode() = default;
0555 
0556   RegisterRef getRegRef(const DataFlowGraph &G) const;
0557 
0558   MachineOperand &getOp() {
0559     assert(!(getFlags() & NodeAttrs::PhiRef));
0560     return *RefData.Op;
0561   }
0562 
0563   void setRegRef(RegisterRef RR, DataFlowGraph &G);
0564   void setRegRef(MachineOperand *Op, DataFlowGraph &G);
0565 
0566   NodeId getReachingDef() const { return RefData.RD; }
0567   void setReachingDef(NodeId RD) { RefData.RD = RD; }
0568 
0569   NodeId getSibling() const { return RefData.Sib; }
0570   void setSibling(NodeId Sib) { RefData.Sib = Sib; }
0571 
0572   bool isUse() const {
0573     assert(getType() == NodeAttrs::Ref);
0574     return getKind() == NodeAttrs::Use;
0575   }
0576 
0577   bool isDef() const {
0578     assert(getType() == NodeAttrs::Ref);
0579     return getKind() == NodeAttrs::Def;
0580   }
0581 
0582   template <typename Predicate>
0583   Ref getNextRef(RegisterRef RR, Predicate P, bool NextOnly,
0584                  const DataFlowGraph &G);
0585   Node getOwner(const DataFlowGraph &G);
0586 };
0587 
0588 struct DefNode : public RefNode {
0589   NodeId getReachedDef() const { return RefData.Def.DD; }
0590   void setReachedDef(NodeId D) { RefData.Def.DD = D; }
0591   NodeId getReachedUse() const { return RefData.Def.DU; }
0592   void setReachedUse(NodeId U) { RefData.Def.DU = U; }
0593 
0594   void linkToDef(NodeId Self, Def DA);
0595 };
0596 
0597 struct UseNode : public RefNode {
0598   void linkToDef(NodeId Self, Def DA);
0599 };
0600 
0601 struct PhiUseNode : public UseNode {
0602   NodeId getPredecessor() const {
0603     assert(getFlags() & NodeAttrs::PhiRef);
0604     return RefData.PhiU.PredB;
0605   }
0606   void setPredecessor(NodeId B) {
0607     assert(getFlags() & NodeAttrs::PhiRef);
0608     RefData.PhiU.PredB = B;
0609   }
0610 };
0611 
0612 struct CodeNode : public NodeBase {
0613   template <typename T> T getCode() const { //
0614     return static_cast<T>(CodeData.CP);
0615   }
0616   void setCode(void *C) { CodeData.CP = C; }
0617 
0618   Node getFirstMember(const DataFlowGraph &G) const;
0619   Node getLastMember(const DataFlowGraph &G) const;
0620   void addMember(Node NA, const DataFlowGraph &G);
0621   void addMemberAfter(Node MA, Node NA, const DataFlowGraph &G);
0622   void removeMember(Node NA, const DataFlowGraph &G);
0623 
0624   NodeList members(const DataFlowGraph &G) const;
0625   template <typename Predicate>
0626   NodeList members_if(Predicate P, const DataFlowGraph &G) const;
0627 };
0628 
0629 struct InstrNode : public CodeNode {
0630   Node getOwner(const DataFlowGraph &G);
0631 };
0632 
0633 struct PhiNode : public InstrNode {
0634   MachineInstr *getCode() const { return nullptr; }
0635 };
0636 
0637 struct StmtNode : public InstrNode {
0638   MachineInstr *getCode() const { //
0639     return CodeNode::getCode<MachineInstr *>();
0640   }
0641 };
0642 
0643 struct BlockNode : public CodeNode {
0644   MachineBasicBlock *getCode() const {
0645     return CodeNode::getCode<MachineBasicBlock *>();
0646   }
0647 
0648   void addPhi(Phi PA, const DataFlowGraph &G);
0649 };
0650 
0651 struct FuncNode : public CodeNode {
0652   MachineFunction *getCode() const {
0653     return CodeNode::getCode<MachineFunction *>();
0654   }
0655 
0656   Block findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const;
0657   Block getEntryBlock(const DataFlowGraph &G);
0658 };
0659 
0660 struct DataFlowGraph {
0661   DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
0662                 const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
0663                 const MachineDominanceFrontier &mdf);
0664   DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
0665                 const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
0666                 const MachineDominanceFrontier &mdf,
0667                 const TargetOperandInfo &toi);
0668 
0669   struct Config {
0670     Config() = default;
0671     Config(unsigned Opts) : Options(Opts) {}
0672     Config(ArrayRef<const TargetRegisterClass *> RCs) : Classes(RCs) {}
0673     Config(ArrayRef<MCPhysReg> Track) : TrackRegs(Track.begin(), Track.end()) {}
0674     Config(ArrayRef<RegisterId> Track)
0675         : TrackRegs(Track.begin(), Track.end()) {}
0676 
0677     unsigned Options = BuildOptions::None;
0678     SmallVector<const TargetRegisterClass *> Classes;
0679     std::set<RegisterId> TrackRegs;
0680   };
0681 
0682   NodeBase *ptr(NodeId N) const;
0683   template <typename T> T ptr(NodeId N) const { //
0684     return static_cast<T>(ptr(N));
0685   }
0686 
0687   NodeId id(const NodeBase *P) const;
0688 
0689   template <typename T> NodeAddr<T> addr(NodeId N) const {
0690     return {ptr<T>(N), N};
0691   }
0692 
0693   Func getFunc() const { return TheFunc; }
0694   MachineFunction &getMF() const { return MF; }
0695   const TargetInstrInfo &getTII() const { return TII; }
0696   const TargetRegisterInfo &getTRI() const { return TRI; }
0697   const PhysicalRegisterInfo &getPRI() const { return PRI; }
0698   const MachineDominatorTree &getDT() const { return MDT; }
0699   const MachineDominanceFrontier &getDF() const { return MDF; }
0700   const RegisterAggr &getLiveIns() const { return LiveIns; }
0701 
0702   struct DefStack {
0703     DefStack() = default;
0704 
0705     bool empty() const { return Stack.empty() || top() == bottom(); }
0706 
0707   private:
0708     using value_type = Def;
0709     struct Iterator {
0710       using value_type = DefStack::value_type;
0711 
0712       Iterator &up() {
0713         Pos = DS.nextUp(Pos);
0714         return *this;
0715       }
0716       Iterator &down() {
0717         Pos = DS.nextDown(Pos);
0718         return *this;
0719       }
0720 
0721       value_type operator*() const {
0722         assert(Pos >= 1);
0723         return DS.Stack[Pos - 1];
0724       }
0725       const value_type *operator->() const {
0726         assert(Pos >= 1);
0727         return &DS.Stack[Pos - 1];
0728       }
0729       bool operator==(const Iterator &It) const { return Pos == It.Pos; }
0730       bool operator!=(const Iterator &It) const { return Pos != It.Pos; }
0731 
0732     private:
0733       friend struct DefStack;
0734 
0735       Iterator(const DefStack &S, bool Top);
0736 
0737       // Pos-1 is the index in the StorageType object that corresponds to
0738       // the top of the DefStack.
0739       const DefStack &DS;
0740       unsigned Pos;
0741     };
0742 
0743   public:
0744     using iterator = Iterator;
0745 
0746     iterator top() const { return Iterator(*this, true); }
0747     iterator bottom() const { return Iterator(*this, false); }
0748     unsigned size() const;
0749 
0750     void push(Def DA) { Stack.push_back(DA); }
0751     void pop();
0752     void start_block(NodeId N);
0753     void clear_block(NodeId N);
0754 
0755   private:
0756     friend struct Iterator;
0757 
0758     using StorageType = std::vector<value_type>;
0759 
0760     bool isDelimiter(const StorageType::value_type &P, NodeId N = 0) const {
0761       return (P.Addr == nullptr) && (N == 0 || P.Id == N);
0762     }
0763 
0764     unsigned nextUp(unsigned P) const;
0765     unsigned nextDown(unsigned P) const;
0766 
0767     StorageType Stack;
0768   };
0769 
0770   // Make this std::unordered_map for speed of accessing elements.
0771   // Map: Register (physical or virtual) -> DefStack
0772   using DefStackMap = std::unordered_map<RegisterId, DefStack>;
0773 
0774   void build(const Config &config);
0775   void build() { build(Config()); }
0776 
0777   void pushAllDefs(Instr IA, DefStackMap &DM);
0778   void markBlock(NodeId B, DefStackMap &DefM);
0779   void releaseBlock(NodeId B, DefStackMap &DefM);
0780 
0781   PackedRegisterRef pack(RegisterRef RR) {
0782     return {RR.Reg, LMI.getIndexForLaneMask(RR.Mask)};
0783   }
0784   PackedRegisterRef pack(RegisterRef RR) const {
0785     return {RR.Reg, LMI.getIndexForLaneMask(RR.Mask)};
0786   }
0787   RegisterRef unpack(PackedRegisterRef PR) const {
0788     return RegisterRef(PR.Reg, LMI.getLaneMaskForIndex(PR.MaskId));
0789   }
0790 
0791   RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const;
0792   RegisterRef makeRegRef(const MachineOperand &Op) const;
0793 
0794   Ref getNextRelated(Instr IA, Ref RA) const;
0795   Ref getNextShadow(Instr IA, Ref RA, bool Create);
0796 
0797   NodeList getRelatedRefs(Instr IA, Ref RA) const;
0798 
0799   Block findBlock(MachineBasicBlock *BB) const { return BlockNodes.at(BB); }
0800 
0801   void unlinkUse(Use UA, bool RemoveFromOwner) {
0802     unlinkUseDF(UA);
0803     if (RemoveFromOwner)
0804       removeFromOwner(UA);
0805   }
0806 
0807   void unlinkDef(Def DA, bool RemoveFromOwner) {
0808     unlinkDefDF(DA);
0809     if (RemoveFromOwner)
0810       removeFromOwner(DA);
0811   }
0812 
0813   bool isTracked(RegisterRef RR) const;
0814   bool hasUntrackedRef(Stmt S, bool IgnoreReserved = true) const;
0815 
0816   // Some useful filters.
0817   template <uint16_t Kind> static bool IsRef(const Node BA) {
0818     return BA.Addr->getType() == NodeAttrs::Ref && BA.Addr->getKind() == Kind;
0819   }
0820 
0821   template <uint16_t Kind> static bool IsCode(const Node BA) {
0822     return BA.Addr->getType() == NodeAttrs::Code && BA.Addr->getKind() == Kind;
0823   }
0824 
0825   static bool IsDef(const Node BA) {
0826     return BA.Addr->getType() == NodeAttrs::Ref &&
0827            BA.Addr->getKind() == NodeAttrs::Def;
0828   }
0829 
0830   static bool IsUse(const Node BA) {
0831     return BA.Addr->getType() == NodeAttrs::Ref &&
0832            BA.Addr->getKind() == NodeAttrs::Use;
0833   }
0834 
0835   static bool IsPhi(const Node BA) {
0836     return BA.Addr->getType() == NodeAttrs::Code &&
0837            BA.Addr->getKind() == NodeAttrs::Phi;
0838   }
0839 
0840   static bool IsPreservingDef(const Def DA) {
0841     uint16_t Flags = DA.Addr->getFlags();
0842     return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
0843   }
0844 
0845 private:
0846   void reset();
0847 
0848   RegisterAggr getLandingPadLiveIns() const;
0849 
0850   Node newNode(uint16_t Attrs);
0851   Node cloneNode(const Node B);
0852   Use newUse(Instr Owner, MachineOperand &Op, uint16_t Flags = NodeAttrs::None);
0853   PhiUse newPhiUse(Phi Owner, RegisterRef RR, Block PredB,
0854                    uint16_t Flags = NodeAttrs::PhiRef);
0855   Def newDef(Instr Owner, MachineOperand &Op, uint16_t Flags = NodeAttrs::None);
0856   Def newDef(Instr Owner, RegisterRef RR, uint16_t Flags = NodeAttrs::PhiRef);
0857   Phi newPhi(Block Owner);
0858   Stmt newStmt(Block Owner, MachineInstr *MI);
0859   Block newBlock(Func Owner, MachineBasicBlock *BB);
0860   Func newFunc(MachineFunction *MF);
0861 
0862   template <typename Predicate>
0863   std::pair<Ref, Ref> locateNextRef(Instr IA, Ref RA, Predicate P) const;
0864 
0865   using BlockRefsMap = RegisterAggrMap<NodeId>;
0866 
0867   void buildStmt(Block BA, MachineInstr &In);
0868   void recordDefsForDF(BlockRefsMap &PhiM, Block BA);
0869   void buildPhis(BlockRefsMap &PhiM, Block BA);
0870   void removeUnusedPhis();
0871 
0872   void pushClobbers(Instr IA, DefStackMap &DM);
0873   void pushDefs(Instr IA, DefStackMap &DM);
0874   template <typename T> void linkRefUp(Instr IA, NodeAddr<T> TA, DefStack &DS);
0875   template <typename Predicate>
0876   void linkStmtRefs(DefStackMap &DefM, Stmt SA, Predicate P);
0877   void linkBlockRefs(DefStackMap &DefM, Block BA);
0878 
0879   void unlinkUseDF(Use UA);
0880   void unlinkDefDF(Def DA);
0881 
0882   void removeFromOwner(Ref RA) {
0883     Instr IA = RA.Addr->getOwner(*this);
0884     IA.Addr->removeMember(RA, *this);
0885   }
0886 
0887   // Default TOI object, if not given in the constructor.
0888   std::unique_ptr<TargetOperandInfo> DefaultTOI;
0889 
0890   MachineFunction &MF;
0891   const TargetInstrInfo &TII;
0892   const TargetRegisterInfo &TRI;
0893   const PhysicalRegisterInfo PRI;
0894   const MachineDominatorTree &MDT;
0895   const MachineDominanceFrontier &MDF;
0896   const TargetOperandInfo &TOI;
0897 
0898   RegisterAggr LiveIns;
0899   Func TheFunc;
0900   NodeAllocator Memory;
0901   // Local map:  MachineBasicBlock -> NodeAddr<BlockNode*>
0902   std::map<MachineBasicBlock *, Block> BlockNodes;
0903   // Lane mask map.
0904   LaneMaskIndex LMI;
0905 
0906   Config BuildCfg;
0907   std::set<unsigned> TrackedUnits;
0908   BitVector ReservedRegs;
0909 }; // struct DataFlowGraph
0910 
0911 template <typename Predicate>
0912 Ref RefNode::getNextRef(RegisterRef RR, Predicate P, bool NextOnly,
0913                         const DataFlowGraph &G) {
0914   // Get the "Next" reference in the circular list that references RR and
0915   // satisfies predicate "Pred".
0916   auto NA = G.addr<NodeBase *>(getNext());
0917 
0918   while (NA.Addr != this) {
0919     if (NA.Addr->getType() == NodeAttrs::Ref) {
0920       Ref RA = NA;
0921       if (G.getPRI().equal_to(RA.Addr->getRegRef(G), RR) && P(NA))
0922         return NA;
0923       if (NextOnly)
0924         break;
0925       NA = G.addr<NodeBase *>(NA.Addr->getNext());
0926     } else {
0927       // We've hit the beginning of the chain.
0928       assert(NA.Addr->getType() == NodeAttrs::Code);
0929       // Make sure we stop here with NextOnly. Otherwise we can return the
0930       // wrong ref. Consider the following while creating/linking shadow uses:
0931       //   -> code -> sr1 -> sr2 -> [back to code]
0932       // Say that shadow refs sr1, and sr2 have been linked, but we need to
0933       // create and link another one. Starting from sr2, we'd hit the code
0934       // node and return sr1 if the iteration didn't stop here.
0935       if (NextOnly)
0936         break;
0937       Code CA = NA;
0938       NA = CA.Addr->getFirstMember(G);
0939     }
0940   }
0941   // Return the equivalent of "nullptr" if such a node was not found.
0942   return Ref();
0943 }
0944 
0945 template <typename Predicate>
0946 NodeList CodeNode::members_if(Predicate P, const DataFlowGraph &G) const {
0947   NodeList MM;
0948   auto M = getFirstMember(G);
0949   if (M.Id == 0)
0950     return MM;
0951 
0952   while (M.Addr != this) {
0953     if (P(M))
0954       MM.push_back(M);
0955     M = G.addr<NodeBase *>(M.Addr->getNext());
0956   }
0957   return MM;
0958 }
0959 
0960 template <typename T> struct Print {
0961   Print(const T &x, const DataFlowGraph &g) : Obj(x), G(g) {}
0962 
0963   const T &Obj;
0964   const DataFlowGraph &G;
0965 };
0966 
0967 template <typename T> Print(const T &, const DataFlowGraph &) -> Print<T>;
0968 
0969 template <typename T> struct PrintNode : Print<NodeAddr<T>> {
0970   PrintNode(const NodeAddr<T> &x, const DataFlowGraph &g)
0971       : Print<NodeAddr<T>>(x, g) {}
0972 };
0973 
0974 raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterRef> &P);
0975 raw_ostream &operator<<(raw_ostream &OS, const Print<NodeId> &P);
0976 raw_ostream &operator<<(raw_ostream &OS, const Print<Def> &P);
0977 raw_ostream &operator<<(raw_ostream &OS, const Print<Use> &P);
0978 raw_ostream &operator<<(raw_ostream &OS, const Print<PhiUse> &P);
0979 raw_ostream &operator<<(raw_ostream &OS, const Print<Ref> &P);
0980 raw_ostream &operator<<(raw_ostream &OS, const Print<NodeList> &P);
0981 raw_ostream &operator<<(raw_ostream &OS, const Print<NodeSet> &P);
0982 raw_ostream &operator<<(raw_ostream &OS, const Print<Phi> &P);
0983 raw_ostream &operator<<(raw_ostream &OS, const Print<Stmt> &P);
0984 raw_ostream &operator<<(raw_ostream &OS, const Print<Instr> &P);
0985 raw_ostream &operator<<(raw_ostream &OS, const Print<Block> &P);
0986 raw_ostream &operator<<(raw_ostream &OS, const Print<Func> &P);
0987 raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterSet> &P);
0988 raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterAggr> &P);
0989 raw_ostream &operator<<(raw_ostream &OS,
0990                         const Print<DataFlowGraph::DefStack> &P);
0991 
0992 } // end namespace rdf
0993 } // end namespace llvm
0994 
0995 #endif // LLVM_CODEGEN_RDFGRAPH_H