xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RDFGraph.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10946e70aSDimitry Andric //===- RDFGraph.cpp -------------------------------------------------------===//
20946e70aSDimitry Andric //
30946e70aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40946e70aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50946e70aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60946e70aSDimitry Andric //
70946e70aSDimitry Andric //===----------------------------------------------------------------------===//
80946e70aSDimitry Andric //
90946e70aSDimitry Andric // Target-independent, SSA-based data flow graph for register data flow (RDF).
100946e70aSDimitry Andric //
110946e70aSDimitry Andric #include "llvm/ADT/BitVector.h"
120946e70aSDimitry Andric #include "llvm/ADT/STLExtras.h"
130946e70aSDimitry Andric #include "llvm/ADT/SetVector.h"
140946e70aSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
150946e70aSDimitry Andric #include "llvm/CodeGen/MachineDominanceFrontier.h"
160946e70aSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
170946e70aSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
180946e70aSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
190946e70aSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
200946e70aSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
2106c3fb27SDimitry Andric #include "llvm/CodeGen/RDFGraph.h"
220946e70aSDimitry Andric #include "llvm/CodeGen/RDFRegisters.h"
230946e70aSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
240946e70aSDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
250946e70aSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
260946e70aSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
270946e70aSDimitry Andric #include "llvm/IR/Function.h"
280946e70aSDimitry Andric #include "llvm/MC/LaneBitmask.h"
290946e70aSDimitry Andric #include "llvm/MC/MCInstrDesc.h"
300946e70aSDimitry Andric #include "llvm/Support/ErrorHandling.h"
310946e70aSDimitry Andric #include "llvm/Support/raw_ostream.h"
320946e70aSDimitry Andric #include <algorithm>
330946e70aSDimitry Andric #include <cassert>
340946e70aSDimitry Andric #include <cstdint>
350946e70aSDimitry Andric #include <cstring>
360946e70aSDimitry Andric #include <iterator>
370946e70aSDimitry Andric #include <set>
380946e70aSDimitry Andric #include <utility>
390946e70aSDimitry Andric #include <vector>
400946e70aSDimitry Andric 
410946e70aSDimitry Andric // Printing functions. Have them here first, so that the rest of the code
420946e70aSDimitry Andric // can use them.
4306c3fb27SDimitry Andric namespace llvm::rdf {
440946e70aSDimitry Andric 
450946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterRef> &P) {
4606c3fb27SDimitry Andric   P.G.getPRI().print(OS, P.Obj);
470946e70aSDimitry Andric   return OS;
480946e70aSDimitry Andric }
490946e70aSDimitry Andric 
500946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<NodeId> &P) {
5106c3fb27SDimitry Andric   if (P.Obj == 0)
5206c3fb27SDimitry Andric     return OS << "null";
530946e70aSDimitry Andric   auto NA = P.G.addr<NodeBase *>(P.Obj);
540946e70aSDimitry Andric   uint16_t Attrs = NA.Addr->getAttrs();
550946e70aSDimitry Andric   uint16_t Kind = NodeAttrs::kind(Attrs);
560946e70aSDimitry Andric   uint16_t Flags = NodeAttrs::flags(Attrs);
570946e70aSDimitry Andric   switch (NodeAttrs::type(Attrs)) {
580946e70aSDimitry Andric   case NodeAttrs::Code:
590946e70aSDimitry Andric     switch (Kind) {
6006c3fb27SDimitry Andric     case NodeAttrs::Func:
6106c3fb27SDimitry Andric       OS << 'f';
6206c3fb27SDimitry Andric       break;
6306c3fb27SDimitry Andric     case NodeAttrs::Block:
6406c3fb27SDimitry Andric       OS << 'b';
6506c3fb27SDimitry Andric       break;
6606c3fb27SDimitry Andric     case NodeAttrs::Stmt:
6706c3fb27SDimitry Andric       OS << 's';
6806c3fb27SDimitry Andric       break;
6906c3fb27SDimitry Andric     case NodeAttrs::Phi:
7006c3fb27SDimitry Andric       OS << 'p';
7106c3fb27SDimitry Andric       break;
7206c3fb27SDimitry Andric     default:
7306c3fb27SDimitry Andric       OS << "c?";
7406c3fb27SDimitry Andric       break;
750946e70aSDimitry Andric     }
760946e70aSDimitry Andric     break;
770946e70aSDimitry Andric   case NodeAttrs::Ref:
780946e70aSDimitry Andric     if (Flags & NodeAttrs::Undef)
790946e70aSDimitry Andric       OS << '/';
800946e70aSDimitry Andric     if (Flags & NodeAttrs::Dead)
810946e70aSDimitry Andric       OS << '\\';
820946e70aSDimitry Andric     if (Flags & NodeAttrs::Preserving)
830946e70aSDimitry Andric       OS << '+';
840946e70aSDimitry Andric     if (Flags & NodeAttrs::Clobbering)
850946e70aSDimitry Andric       OS << '~';
860946e70aSDimitry Andric     switch (Kind) {
8706c3fb27SDimitry Andric     case NodeAttrs::Use:
8806c3fb27SDimitry Andric       OS << 'u';
8906c3fb27SDimitry Andric       break;
9006c3fb27SDimitry Andric     case NodeAttrs::Def:
9106c3fb27SDimitry Andric       OS << 'd';
9206c3fb27SDimitry Andric       break;
9306c3fb27SDimitry Andric     case NodeAttrs::Block:
9406c3fb27SDimitry Andric       OS << 'b';
9506c3fb27SDimitry Andric       break;
9606c3fb27SDimitry Andric     default:
9706c3fb27SDimitry Andric       OS << "r?";
9806c3fb27SDimitry Andric       break;
990946e70aSDimitry Andric     }
1000946e70aSDimitry Andric     break;
1010946e70aSDimitry Andric   default:
1020946e70aSDimitry Andric     OS << '?';
1030946e70aSDimitry Andric     break;
1040946e70aSDimitry Andric   }
1050946e70aSDimitry Andric   OS << P.Obj;
1060946e70aSDimitry Andric   if (Flags & NodeAttrs::Shadow)
1070946e70aSDimitry Andric     OS << '"';
1080946e70aSDimitry Andric   return OS;
1090946e70aSDimitry Andric }
1100946e70aSDimitry Andric 
11106c3fb27SDimitry Andric static void printRefHeader(raw_ostream &OS, const Ref RA,
1120946e70aSDimitry Andric                            const DataFlowGraph &G) {
11306c3fb27SDimitry Andric   OS << Print(RA.Id, G) << '<' << Print(RA.Addr->getRegRef(G), G) << '>';
1140946e70aSDimitry Andric   if (RA.Addr->getFlags() & NodeAttrs::Fixed)
1150946e70aSDimitry Andric     OS << '!';
1160946e70aSDimitry Andric }
1170946e70aSDimitry Andric 
11806c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Def> &P) {
1190946e70aSDimitry Andric   printRefHeader(OS, P.Obj, P.G);
1200946e70aSDimitry Andric   OS << '(';
1210946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachingDef())
122bdd1243dSDimitry Andric     OS << Print(N, P.G);
1230946e70aSDimitry Andric   OS << ',';
1240946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachedDef())
125bdd1243dSDimitry Andric     OS << Print(N, P.G);
1260946e70aSDimitry Andric   OS << ',';
1270946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachedUse())
128bdd1243dSDimitry Andric     OS << Print(N, P.G);
1290946e70aSDimitry Andric   OS << "):";
1300946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getSibling())
131bdd1243dSDimitry Andric     OS << Print(N, P.G);
1320946e70aSDimitry Andric   return OS;
1330946e70aSDimitry Andric }
1340946e70aSDimitry Andric 
13506c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Use> &P) {
1360946e70aSDimitry Andric   printRefHeader(OS, P.Obj, P.G);
1370946e70aSDimitry Andric   OS << '(';
1380946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachingDef())
139bdd1243dSDimitry Andric     OS << Print(N, P.G);
1400946e70aSDimitry Andric   OS << "):";
1410946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getSibling())
142bdd1243dSDimitry Andric     OS << Print(N, P.G);
1430946e70aSDimitry Andric   return OS;
1440946e70aSDimitry Andric }
1450946e70aSDimitry Andric 
14606c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<PhiUse> &P) {
1470946e70aSDimitry Andric   printRefHeader(OS, P.Obj, P.G);
1480946e70aSDimitry Andric   OS << '(';
1490946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachingDef())
150bdd1243dSDimitry Andric     OS << Print(N, P.G);
1510946e70aSDimitry Andric   OS << ',';
1520946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getPredecessor())
153bdd1243dSDimitry Andric     OS << Print(N, P.G);
1540946e70aSDimitry Andric   OS << "):";
1550946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getSibling())
156bdd1243dSDimitry Andric     OS << Print(N, P.G);
1570946e70aSDimitry Andric   return OS;
1580946e70aSDimitry Andric }
1590946e70aSDimitry Andric 
16006c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Ref> &P) {
1610946e70aSDimitry Andric   switch (P.Obj.Addr->getKind()) {
1620946e70aSDimitry Andric   case NodeAttrs::Def:
1630946e70aSDimitry Andric     OS << PrintNode<DefNode *>(P.Obj, P.G);
1640946e70aSDimitry Andric     break;
1650946e70aSDimitry Andric   case NodeAttrs::Use:
1660946e70aSDimitry Andric     if (P.Obj.Addr->getFlags() & NodeAttrs::PhiRef)
1670946e70aSDimitry Andric       OS << PrintNode<PhiUseNode *>(P.Obj, P.G);
1680946e70aSDimitry Andric     else
1690946e70aSDimitry Andric       OS << PrintNode<UseNode *>(P.Obj, P.G);
1700946e70aSDimitry Andric     break;
1710946e70aSDimitry Andric   }
1720946e70aSDimitry Andric   return OS;
1730946e70aSDimitry Andric }
1740946e70aSDimitry Andric 
1750946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<NodeList> &P) {
1760946e70aSDimitry Andric   unsigned N = P.Obj.size();
1770946e70aSDimitry Andric   for (auto I : P.Obj) {
178bdd1243dSDimitry Andric     OS << Print(I.Id, P.G);
1790946e70aSDimitry Andric     if (--N)
1800946e70aSDimitry Andric       OS << ' ';
1810946e70aSDimitry Andric   }
1820946e70aSDimitry Andric   return OS;
1830946e70aSDimitry Andric }
1840946e70aSDimitry Andric 
1850946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<NodeSet> &P) {
1860946e70aSDimitry Andric   unsigned N = P.Obj.size();
1870946e70aSDimitry Andric   for (auto I : P.Obj) {
188bdd1243dSDimitry Andric     OS << Print(I, P.G);
1890946e70aSDimitry Andric     if (--N)
1900946e70aSDimitry Andric       OS << ' ';
1910946e70aSDimitry Andric   }
1920946e70aSDimitry Andric   return OS;
1930946e70aSDimitry Andric }
1940946e70aSDimitry Andric 
1950946e70aSDimitry Andric namespace {
1960946e70aSDimitry Andric 
19706c3fb27SDimitry Andric template <typename T> struct PrintListV {
1980946e70aSDimitry Andric   PrintListV(const NodeList &L, const DataFlowGraph &G) : List(L), G(G) {}
1990946e70aSDimitry Andric 
2000946e70aSDimitry Andric   using Type = T;
2010946e70aSDimitry Andric   const NodeList &List;
2020946e70aSDimitry Andric   const DataFlowGraph &G;
2030946e70aSDimitry Andric };
2040946e70aSDimitry Andric 
2050946e70aSDimitry Andric template <typename T>
2060946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const PrintListV<T> &P) {
2070946e70aSDimitry Andric   unsigned N = P.List.size();
2080946e70aSDimitry Andric   for (NodeAddr<T> A : P.List) {
2090946e70aSDimitry Andric     OS << PrintNode<T>(A, P.G);
2100946e70aSDimitry Andric     if (--N)
2110946e70aSDimitry Andric       OS << ", ";
2120946e70aSDimitry Andric   }
2130946e70aSDimitry Andric   return OS;
2140946e70aSDimitry Andric }
2150946e70aSDimitry Andric 
2160946e70aSDimitry Andric } // end anonymous namespace
2170946e70aSDimitry Andric 
21806c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Phi> &P) {
219bdd1243dSDimitry Andric   OS << Print(P.Obj.Id, P.G) << ": phi ["
2200946e70aSDimitry Andric      << PrintListV<RefNode *>(P.Obj.Addr->members(P.G), P.G) << ']';
2210946e70aSDimitry Andric   return OS;
2220946e70aSDimitry Andric }
2230946e70aSDimitry Andric 
22406c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Stmt> &P) {
2250946e70aSDimitry Andric   const MachineInstr &MI = *P.Obj.Addr->getCode();
2260946e70aSDimitry Andric   unsigned Opc = MI.getOpcode();
227bdd1243dSDimitry Andric   OS << Print(P.Obj.Id, P.G) << ": " << P.G.getTII().getName(Opc);
2280946e70aSDimitry Andric   // Print the target for calls and branches (for readability).
2290946e70aSDimitry Andric   if (MI.isCall() || MI.isBranch()) {
2300946e70aSDimitry Andric     MachineInstr::const_mop_iterator T =
23106c3fb27SDimitry Andric         llvm::find_if(MI.operands(), [](const MachineOperand &Op) -> bool {
2320946e70aSDimitry Andric           return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
2330946e70aSDimitry Andric         });
2340946e70aSDimitry Andric     if (T != MI.operands_end()) {
2350946e70aSDimitry Andric       OS << ' ';
2360946e70aSDimitry Andric       if (T->isMBB())
2370946e70aSDimitry Andric         OS << printMBBReference(*T->getMBB());
2380946e70aSDimitry Andric       else if (T->isGlobal())
2390946e70aSDimitry Andric         OS << T->getGlobal()->getName();
2400946e70aSDimitry Andric       else if (T->isSymbol())
2410946e70aSDimitry Andric         OS << T->getSymbolName();
2420946e70aSDimitry Andric     }
2430946e70aSDimitry Andric   }
2440946e70aSDimitry Andric   OS << " [" << PrintListV<RefNode *>(P.Obj.Addr->members(P.G), P.G) << ']';
2450946e70aSDimitry Andric   return OS;
2460946e70aSDimitry Andric }
2470946e70aSDimitry Andric 
24806c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Instr> &P) {
2490946e70aSDimitry Andric   switch (P.Obj.Addr->getKind()) {
2500946e70aSDimitry Andric   case NodeAttrs::Phi:
2510946e70aSDimitry Andric     OS << PrintNode<PhiNode *>(P.Obj, P.G);
2520946e70aSDimitry Andric     break;
2530946e70aSDimitry Andric   case NodeAttrs::Stmt:
2540946e70aSDimitry Andric     OS << PrintNode<StmtNode *>(P.Obj, P.G);
2550946e70aSDimitry Andric     break;
2560946e70aSDimitry Andric   default:
257bdd1243dSDimitry Andric     OS << "instr? " << Print(P.Obj.Id, P.G);
2580946e70aSDimitry Andric     break;
2590946e70aSDimitry Andric   }
2600946e70aSDimitry Andric   return OS;
2610946e70aSDimitry Andric }
2620946e70aSDimitry Andric 
26306c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Block> &P) {
2640946e70aSDimitry Andric   MachineBasicBlock *BB = P.Obj.Addr->getCode();
2650946e70aSDimitry Andric   unsigned NP = BB->pred_size();
2660946e70aSDimitry Andric   std::vector<int> Ns;
267*0fca6ea1SDimitry Andric   auto PrintBBs = [&OS](const std::vector<int> &Ns) -> void {
2680946e70aSDimitry Andric     unsigned N = Ns.size();
2690946e70aSDimitry Andric     for (int I : Ns) {
2700946e70aSDimitry Andric       OS << "%bb." << I;
2710946e70aSDimitry Andric       if (--N)
2720946e70aSDimitry Andric         OS << ", ";
2730946e70aSDimitry Andric     }
2740946e70aSDimitry Andric   };
2750946e70aSDimitry Andric 
276bdd1243dSDimitry Andric   OS << Print(P.Obj.Id, P.G) << ": --- " << printMBBReference(*BB)
2770946e70aSDimitry Andric      << " --- preds(" << NP << "): ";
2780946e70aSDimitry Andric   for (MachineBasicBlock *B : BB->predecessors())
2790946e70aSDimitry Andric     Ns.push_back(B->getNumber());
2800946e70aSDimitry Andric   PrintBBs(Ns);
2810946e70aSDimitry Andric 
2820946e70aSDimitry Andric   unsigned NS = BB->succ_size();
2830946e70aSDimitry Andric   OS << "  succs(" << NS << "): ";
2840946e70aSDimitry Andric   Ns.clear();
2850946e70aSDimitry Andric   for (MachineBasicBlock *B : BB->successors())
2860946e70aSDimitry Andric     Ns.push_back(B->getNumber());
2870946e70aSDimitry Andric   PrintBBs(Ns);
2880946e70aSDimitry Andric   OS << '\n';
2890946e70aSDimitry Andric 
2900946e70aSDimitry Andric   for (auto I : P.Obj.Addr->members(P.G))
2910946e70aSDimitry Andric     OS << PrintNode<InstrNode *>(I, P.G) << '\n';
2920946e70aSDimitry Andric   return OS;
2930946e70aSDimitry Andric }
2940946e70aSDimitry Andric 
29506c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Func> &P) {
29606c3fb27SDimitry Andric   OS << "DFG dump:[\n"
29706c3fb27SDimitry Andric      << Print(P.Obj.Id, P.G)
29806c3fb27SDimitry Andric      << ": Function: " << P.Obj.Addr->getCode()->getName() << '\n';
2990946e70aSDimitry Andric   for (auto I : P.Obj.Addr->members(P.G))
3000946e70aSDimitry Andric     OS << PrintNode<BlockNode *>(I, P.G) << '\n';
3010946e70aSDimitry Andric   OS << "]\n";
3020946e70aSDimitry Andric   return OS;
3030946e70aSDimitry Andric }
3040946e70aSDimitry Andric 
3050946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterSet> &P) {
3060946e70aSDimitry Andric   OS << '{';
3070946e70aSDimitry Andric   for (auto I : P.Obj)
308bdd1243dSDimitry Andric     OS << ' ' << Print(I, P.G);
3090946e70aSDimitry Andric   OS << " }";
3100946e70aSDimitry Andric   return OS;
3110946e70aSDimitry Andric }
3120946e70aSDimitry Andric 
3130946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterAggr> &P) {
31406c3fb27SDimitry Andric   OS << P.Obj;
3150946e70aSDimitry Andric   return OS;
3160946e70aSDimitry Andric }
3170946e70aSDimitry Andric 
3180946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS,
3190946e70aSDimitry Andric                         const Print<DataFlowGraph::DefStack> &P) {
3200946e70aSDimitry Andric   for (auto I = P.Obj.top(), E = P.Obj.bottom(); I != E;) {
32106c3fb27SDimitry Andric     OS << Print(I->Id, P.G) << '<' << Print(I->Addr->getRegRef(P.G), P.G)
32206c3fb27SDimitry Andric        << '>';
3230946e70aSDimitry Andric     I.down();
3240946e70aSDimitry Andric     if (I != E)
3250946e70aSDimitry Andric       OS << ' ';
3260946e70aSDimitry Andric   }
3270946e70aSDimitry Andric   return OS;
3280946e70aSDimitry Andric }
3290946e70aSDimitry Andric 
3300946e70aSDimitry Andric // Node allocation functions.
3310946e70aSDimitry Andric //
3320946e70aSDimitry Andric // Node allocator is like a slab memory allocator: it allocates blocks of
3330946e70aSDimitry Andric // memory in sizes that are multiples of the size of a node. Each block has
3340946e70aSDimitry Andric // the same size. Nodes are allocated from the currently active block, and
3350946e70aSDimitry Andric // when it becomes full, a new one is created.
3360946e70aSDimitry Andric // There is a mapping scheme between node id and its location in a block,
3370946e70aSDimitry Andric // and within that block is described in the header file.
3380946e70aSDimitry Andric //
3390946e70aSDimitry Andric void NodeAllocator::startNewBlock() {
3400946e70aSDimitry Andric   void *T = MemPool.Allocate(NodesPerBlock * NodeMemSize, NodeMemSize);
3410946e70aSDimitry Andric   char *P = static_cast<char *>(T);
3420946e70aSDimitry Andric   Blocks.push_back(P);
3430946e70aSDimitry Andric   // Check if the block index is still within the allowed range, i.e. less
3440946e70aSDimitry Andric   // than 2^N, where N is the number of bits in NodeId for the block index.
3450946e70aSDimitry Andric   // BitsPerIndex is the number of bits per node index.
3460946e70aSDimitry Andric   assert((Blocks.size() < ((size_t)1 << (8 * sizeof(NodeId) - BitsPerIndex))) &&
3470946e70aSDimitry Andric          "Out of bits for block index");
3480946e70aSDimitry Andric   ActiveEnd = P;
3490946e70aSDimitry Andric }
3500946e70aSDimitry Andric 
3510946e70aSDimitry Andric bool NodeAllocator::needNewBlock() {
3520946e70aSDimitry Andric   if (Blocks.empty())
3530946e70aSDimitry Andric     return true;
3540946e70aSDimitry Andric 
3550946e70aSDimitry Andric   char *ActiveBegin = Blocks.back();
3560946e70aSDimitry Andric   uint32_t Index = (ActiveEnd - ActiveBegin) / NodeMemSize;
3570946e70aSDimitry Andric   return Index >= NodesPerBlock;
3580946e70aSDimitry Andric }
3590946e70aSDimitry Andric 
36006c3fb27SDimitry Andric Node NodeAllocator::New() {
3610946e70aSDimitry Andric   if (needNewBlock())
3620946e70aSDimitry Andric     startNewBlock();
3630946e70aSDimitry Andric 
3640946e70aSDimitry Andric   uint32_t ActiveB = Blocks.size() - 1;
3650946e70aSDimitry Andric   uint32_t Index = (ActiveEnd - Blocks[ActiveB]) / NodeMemSize;
36606c3fb27SDimitry Andric   Node NA = {reinterpret_cast<NodeBase *>(ActiveEnd), makeId(ActiveB, Index)};
3670946e70aSDimitry Andric   ActiveEnd += NodeMemSize;
3680946e70aSDimitry Andric   return NA;
3690946e70aSDimitry Andric }
3700946e70aSDimitry Andric 
3710946e70aSDimitry Andric NodeId NodeAllocator::id(const NodeBase *P) const {
3720946e70aSDimitry Andric   uintptr_t A = reinterpret_cast<uintptr_t>(P);
3730946e70aSDimitry Andric   for (unsigned i = 0, n = Blocks.size(); i != n; ++i) {
3740946e70aSDimitry Andric     uintptr_t B = reinterpret_cast<uintptr_t>(Blocks[i]);
3750946e70aSDimitry Andric     if (A < B || A >= B + NodesPerBlock * NodeMemSize)
3760946e70aSDimitry Andric       continue;
3770946e70aSDimitry Andric     uint32_t Idx = (A - B) / NodeMemSize;
3780946e70aSDimitry Andric     return makeId(i, Idx);
3790946e70aSDimitry Andric   }
3800946e70aSDimitry Andric   llvm_unreachable("Invalid node address");
3810946e70aSDimitry Andric }
3820946e70aSDimitry Andric 
3830946e70aSDimitry Andric void NodeAllocator::clear() {
3840946e70aSDimitry Andric   MemPool.Reset();
3850946e70aSDimitry Andric   Blocks.clear();
3860946e70aSDimitry Andric   ActiveEnd = nullptr;
3870946e70aSDimitry Andric }
3880946e70aSDimitry Andric 
3890946e70aSDimitry Andric // Insert node NA after "this" in the circular chain.
39006c3fb27SDimitry Andric void NodeBase::append(Node NA) {
3910946e70aSDimitry Andric   NodeId Nx = Next;
3920946e70aSDimitry Andric   // If NA is already "next", do nothing.
3930946e70aSDimitry Andric   if (Next != NA.Id) {
3940946e70aSDimitry Andric     Next = NA.Id;
3950946e70aSDimitry Andric     NA.Addr->Next = Nx;
3960946e70aSDimitry Andric   }
3970946e70aSDimitry Andric }
3980946e70aSDimitry Andric 
3990946e70aSDimitry Andric // Fundamental node manipulator functions.
4000946e70aSDimitry Andric 
4010946e70aSDimitry Andric // Obtain the register reference from a reference node.
4020946e70aSDimitry Andric RegisterRef RefNode::getRegRef(const DataFlowGraph &G) const {
4030946e70aSDimitry Andric   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
4040946e70aSDimitry Andric   if (NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef)
40506c3fb27SDimitry Andric     return G.unpack(RefData.PR);
40606c3fb27SDimitry Andric   assert(RefData.Op != nullptr);
40706c3fb27SDimitry Andric   return G.makeRegRef(*RefData.Op);
4080946e70aSDimitry Andric }
4090946e70aSDimitry Andric 
4100946e70aSDimitry Andric // Set the register reference in the reference node directly (for references
4110946e70aSDimitry Andric // in phi nodes).
4120946e70aSDimitry Andric void RefNode::setRegRef(RegisterRef RR, DataFlowGraph &G) {
4130946e70aSDimitry Andric   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
4140946e70aSDimitry Andric   assert(NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef);
41506c3fb27SDimitry Andric   RefData.PR = G.pack(RR);
4160946e70aSDimitry Andric }
4170946e70aSDimitry Andric 
4180946e70aSDimitry Andric // Set the register reference in the reference node based on a machine
4190946e70aSDimitry Andric // operand (for references in statement nodes).
4200946e70aSDimitry Andric void RefNode::setRegRef(MachineOperand *Op, DataFlowGraph &G) {
4210946e70aSDimitry Andric   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
4220946e70aSDimitry Andric   assert(!(NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef));
4230946e70aSDimitry Andric   (void)G;
42406c3fb27SDimitry Andric   RefData.Op = Op;
4250946e70aSDimitry Andric }
4260946e70aSDimitry Andric 
4270946e70aSDimitry Andric // Get the owner of a given reference node.
42806c3fb27SDimitry Andric Node RefNode::getOwner(const DataFlowGraph &G) {
42906c3fb27SDimitry Andric   Node NA = G.addr<NodeBase *>(getNext());
4300946e70aSDimitry Andric 
4310946e70aSDimitry Andric   while (NA.Addr != this) {
4320946e70aSDimitry Andric     if (NA.Addr->getType() == NodeAttrs::Code)
4330946e70aSDimitry Andric       return NA;
4340946e70aSDimitry Andric     NA = G.addr<NodeBase *>(NA.Addr->getNext());
4350946e70aSDimitry Andric   }
4360946e70aSDimitry Andric   llvm_unreachable("No owner in circular list");
4370946e70aSDimitry Andric }
4380946e70aSDimitry Andric 
4390946e70aSDimitry Andric // Connect the def node to the reaching def node.
44006c3fb27SDimitry Andric void DefNode::linkToDef(NodeId Self, Def DA) {
44106c3fb27SDimitry Andric   RefData.RD = DA.Id;
44206c3fb27SDimitry Andric   RefData.Sib = DA.Addr->getReachedDef();
4430946e70aSDimitry Andric   DA.Addr->setReachedDef(Self);
4440946e70aSDimitry Andric }
4450946e70aSDimitry Andric 
4460946e70aSDimitry Andric // Connect the use node to the reaching def node.
44706c3fb27SDimitry Andric void UseNode::linkToDef(NodeId Self, Def DA) {
44806c3fb27SDimitry Andric   RefData.RD = DA.Id;
44906c3fb27SDimitry Andric   RefData.Sib = DA.Addr->getReachedUse();
4500946e70aSDimitry Andric   DA.Addr->setReachedUse(Self);
4510946e70aSDimitry Andric }
4520946e70aSDimitry Andric 
4530946e70aSDimitry Andric // Get the first member of the code node.
45406c3fb27SDimitry Andric Node CodeNode::getFirstMember(const DataFlowGraph &G) const {
45506c3fb27SDimitry Andric   if (CodeData.FirstM == 0)
45606c3fb27SDimitry Andric     return Node();
45706c3fb27SDimitry Andric   return G.addr<NodeBase *>(CodeData.FirstM);
4580946e70aSDimitry Andric }
4590946e70aSDimitry Andric 
4600946e70aSDimitry Andric // Get the last member of the code node.
46106c3fb27SDimitry Andric Node CodeNode::getLastMember(const DataFlowGraph &G) const {
46206c3fb27SDimitry Andric   if (CodeData.LastM == 0)
46306c3fb27SDimitry Andric     return Node();
46406c3fb27SDimitry Andric   return G.addr<NodeBase *>(CodeData.LastM);
4650946e70aSDimitry Andric }
4660946e70aSDimitry Andric 
4670946e70aSDimitry Andric // Add node NA at the end of the member list of the given code node.
46806c3fb27SDimitry Andric void CodeNode::addMember(Node NA, const DataFlowGraph &G) {
46906c3fb27SDimitry Andric   Node ML = getLastMember(G);
4700946e70aSDimitry Andric   if (ML.Id != 0) {
4710946e70aSDimitry Andric     ML.Addr->append(NA);
4720946e70aSDimitry Andric   } else {
47306c3fb27SDimitry Andric     CodeData.FirstM = NA.Id;
4740946e70aSDimitry Andric     NodeId Self = G.id(this);
4750946e70aSDimitry Andric     NA.Addr->setNext(Self);
4760946e70aSDimitry Andric   }
47706c3fb27SDimitry Andric   CodeData.LastM = NA.Id;
4780946e70aSDimitry Andric }
4790946e70aSDimitry Andric 
4800946e70aSDimitry Andric // Add node NA after member node MA in the given code node.
48106c3fb27SDimitry Andric void CodeNode::addMemberAfter(Node MA, Node NA, const DataFlowGraph &G) {
4820946e70aSDimitry Andric   MA.Addr->append(NA);
48306c3fb27SDimitry Andric   if (CodeData.LastM == MA.Id)
48406c3fb27SDimitry Andric     CodeData.LastM = NA.Id;
4850946e70aSDimitry Andric }
4860946e70aSDimitry Andric 
4870946e70aSDimitry Andric // Remove member node NA from the given code node.
48806c3fb27SDimitry Andric void CodeNode::removeMember(Node NA, const DataFlowGraph &G) {
48906c3fb27SDimitry Andric   Node MA = getFirstMember(G);
4900946e70aSDimitry Andric   assert(MA.Id != 0);
4910946e70aSDimitry Andric 
4920946e70aSDimitry Andric   // Special handling if the member to remove is the first member.
4930946e70aSDimitry Andric   if (MA.Id == NA.Id) {
49406c3fb27SDimitry Andric     if (CodeData.LastM == MA.Id) {
4950946e70aSDimitry Andric       // If it is the only member, set both first and last to 0.
49606c3fb27SDimitry Andric       CodeData.FirstM = CodeData.LastM = 0;
4970946e70aSDimitry Andric     } else {
4980946e70aSDimitry Andric       // Otherwise, advance the first member.
49906c3fb27SDimitry Andric       CodeData.FirstM = MA.Addr->getNext();
5000946e70aSDimitry Andric     }
5010946e70aSDimitry Andric     return;
5020946e70aSDimitry Andric   }
5030946e70aSDimitry Andric 
5040946e70aSDimitry Andric   while (MA.Addr != this) {
5050946e70aSDimitry Andric     NodeId MX = MA.Addr->getNext();
5060946e70aSDimitry Andric     if (MX == NA.Id) {
5070946e70aSDimitry Andric       MA.Addr->setNext(NA.Addr->getNext());
5080946e70aSDimitry Andric       // If the member to remove happens to be the last one, update the
5090946e70aSDimitry Andric       // LastM indicator.
51006c3fb27SDimitry Andric       if (CodeData.LastM == NA.Id)
51106c3fb27SDimitry Andric         CodeData.LastM = MA.Id;
5120946e70aSDimitry Andric       return;
5130946e70aSDimitry Andric     }
5140946e70aSDimitry Andric     MA = G.addr<NodeBase *>(MX);
5150946e70aSDimitry Andric   }
5160946e70aSDimitry Andric   llvm_unreachable("No such member");
5170946e70aSDimitry Andric }
5180946e70aSDimitry Andric 
5190946e70aSDimitry Andric // Return the list of all members of the code node.
5200946e70aSDimitry Andric NodeList CodeNode::members(const DataFlowGraph &G) const {
52106c3fb27SDimitry Andric   static auto True = [](Node) -> bool { return true; };
5220946e70aSDimitry Andric   return members_if(True, G);
5230946e70aSDimitry Andric }
5240946e70aSDimitry Andric 
5250946e70aSDimitry Andric // Return the owner of the given instr node.
52606c3fb27SDimitry Andric Node InstrNode::getOwner(const DataFlowGraph &G) {
52706c3fb27SDimitry Andric   Node NA = G.addr<NodeBase *>(getNext());
5280946e70aSDimitry Andric 
5290946e70aSDimitry Andric   while (NA.Addr != this) {
5300946e70aSDimitry Andric     assert(NA.Addr->getType() == NodeAttrs::Code);
5310946e70aSDimitry Andric     if (NA.Addr->getKind() == NodeAttrs::Block)
5320946e70aSDimitry Andric       return NA;
5330946e70aSDimitry Andric     NA = G.addr<NodeBase *>(NA.Addr->getNext());
5340946e70aSDimitry Andric   }
5350946e70aSDimitry Andric   llvm_unreachable("No owner in circular list");
5360946e70aSDimitry Andric }
5370946e70aSDimitry Andric 
5380946e70aSDimitry Andric // Add the phi node PA to the given block node.
53906c3fb27SDimitry Andric void BlockNode::addPhi(Phi PA, const DataFlowGraph &G) {
54006c3fb27SDimitry Andric   Node M = getFirstMember(G);
5410946e70aSDimitry Andric   if (M.Id == 0) {
5420946e70aSDimitry Andric     addMember(PA, G);
5430946e70aSDimitry Andric     return;
5440946e70aSDimitry Andric   }
5450946e70aSDimitry Andric 
5460946e70aSDimitry Andric   assert(M.Addr->getType() == NodeAttrs::Code);
5470946e70aSDimitry Andric   if (M.Addr->getKind() == NodeAttrs::Stmt) {
5480946e70aSDimitry Andric     // If the first member of the block is a statement, insert the phi as
5490946e70aSDimitry Andric     // the first member.
55006c3fb27SDimitry Andric     CodeData.FirstM = PA.Id;
5510946e70aSDimitry Andric     PA.Addr->setNext(M.Id);
5520946e70aSDimitry Andric   } else {
5530946e70aSDimitry Andric     // If the first member is a phi, find the last phi, and append PA to it.
5540946e70aSDimitry Andric     assert(M.Addr->getKind() == NodeAttrs::Phi);
55506c3fb27SDimitry Andric     Node MN = M;
5560946e70aSDimitry Andric     do {
5570946e70aSDimitry Andric       M = MN;
5580946e70aSDimitry Andric       MN = G.addr<NodeBase *>(M.Addr->getNext());
5590946e70aSDimitry Andric       assert(MN.Addr->getType() == NodeAttrs::Code);
5600946e70aSDimitry Andric     } while (MN.Addr->getKind() == NodeAttrs::Phi);
5610946e70aSDimitry Andric 
5620946e70aSDimitry Andric     // M is the last phi.
5630946e70aSDimitry Andric     addMemberAfter(M, PA, G);
5640946e70aSDimitry Andric   }
5650946e70aSDimitry Andric }
5660946e70aSDimitry Andric 
5670946e70aSDimitry Andric // Find the block node corresponding to the machine basic block BB in the
5680946e70aSDimitry Andric // given func node.
56906c3fb27SDimitry Andric Block FuncNode::findBlock(const MachineBasicBlock *BB,
5700946e70aSDimitry Andric                           const DataFlowGraph &G) const {
57106c3fb27SDimitry Andric   auto EqBB = [BB](Node NA) -> bool { return Block(NA).Addr->getCode() == BB; };
5720946e70aSDimitry Andric   NodeList Ms = members_if(EqBB, G);
5730946e70aSDimitry Andric   if (!Ms.empty())
5740946e70aSDimitry Andric     return Ms[0];
57506c3fb27SDimitry Andric   return Block();
5760946e70aSDimitry Andric }
5770946e70aSDimitry Andric 
5780946e70aSDimitry Andric // Get the block node for the entry block in the given function.
57906c3fb27SDimitry Andric Block FuncNode::getEntryBlock(const DataFlowGraph &G) {
5800946e70aSDimitry Andric   MachineBasicBlock *EntryB = &getCode()->front();
5810946e70aSDimitry Andric   return findBlock(EntryB, G);
5820946e70aSDimitry Andric }
5830946e70aSDimitry Andric 
5840946e70aSDimitry Andric // Target operand information.
5850946e70aSDimitry Andric //
5860946e70aSDimitry Andric 
5870946e70aSDimitry Andric // For a given instruction, check if there are any bits of RR that can remain
5880946e70aSDimitry Andric // unchanged across this def.
58906c3fb27SDimitry Andric bool TargetOperandInfo::isPreserving(const MachineInstr &In,
59006c3fb27SDimitry Andric                                      unsigned OpNum) const {
5910946e70aSDimitry Andric   return TII.isPredicated(In);
5920946e70aSDimitry Andric }
5930946e70aSDimitry Andric 
5940946e70aSDimitry Andric // Check if the definition of RR produces an unspecified value.
59506c3fb27SDimitry Andric bool TargetOperandInfo::isClobbering(const MachineInstr &In,
59606c3fb27SDimitry Andric                                      unsigned OpNum) const {
5970946e70aSDimitry Andric   const MachineOperand &Op = In.getOperand(OpNum);
5980946e70aSDimitry Andric   if (Op.isRegMask())
5990946e70aSDimitry Andric     return true;
6000946e70aSDimitry Andric   assert(Op.isReg());
6010946e70aSDimitry Andric   if (In.isCall())
6020946e70aSDimitry Andric     if (Op.isDef() && Op.isDead())
6030946e70aSDimitry Andric       return true;
6040946e70aSDimitry Andric   return false;
6050946e70aSDimitry Andric }
6060946e70aSDimitry Andric 
6070946e70aSDimitry Andric // Check if the given instruction specifically requires
60806c3fb27SDimitry Andric bool TargetOperandInfo::isFixedReg(const MachineInstr &In,
60906c3fb27SDimitry Andric                                    unsigned OpNum) const {
6100946e70aSDimitry Andric   if (In.isCall() || In.isReturn() || In.isInlineAsm())
6110946e70aSDimitry Andric     return true;
6120946e70aSDimitry Andric   // Check for a tail call.
6130946e70aSDimitry Andric   if (In.isBranch())
6140946e70aSDimitry Andric     for (const MachineOperand &O : In.operands())
6150946e70aSDimitry Andric       if (O.isGlobal() || O.isSymbol())
6160946e70aSDimitry Andric         return true;
6170946e70aSDimitry Andric 
6180946e70aSDimitry Andric   const MCInstrDesc &D = In.getDesc();
619bdd1243dSDimitry Andric   if (D.implicit_defs().empty() && D.implicit_uses().empty())
6200946e70aSDimitry Andric     return false;
6210946e70aSDimitry Andric   const MachineOperand &Op = In.getOperand(OpNum);
6220946e70aSDimitry Andric   // If there is a sub-register, treat the operand as non-fixed. Currently,
6230946e70aSDimitry Andric   // fixed registers are those that are listed in the descriptor as implicit
6240946e70aSDimitry Andric   // uses or defs, and those lists do not allow sub-registers.
6250946e70aSDimitry Andric   if (Op.getSubReg() != 0)
6260946e70aSDimitry Andric     return false;
6270946e70aSDimitry Andric   Register Reg = Op.getReg();
628bdd1243dSDimitry Andric   ArrayRef<MCPhysReg> ImpOps =
629bdd1243dSDimitry Andric       Op.isDef() ? D.implicit_defs() : D.implicit_uses();
630bdd1243dSDimitry Andric   return is_contained(ImpOps, Reg);
6310946e70aSDimitry Andric }
6320946e70aSDimitry Andric 
6330946e70aSDimitry Andric //
6340946e70aSDimitry Andric // The data flow graph construction.
6350946e70aSDimitry Andric //
6360946e70aSDimitry Andric 
6370946e70aSDimitry Andric DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
63806c3fb27SDimitry Andric                              const TargetRegisterInfo &tri,
63906c3fb27SDimitry Andric                              const MachineDominatorTree &mdt,
640bdd1243dSDimitry Andric                              const MachineDominanceFrontier &mdf)
641bdd1243dSDimitry Andric     : DefaultTOI(std::make_unique<TargetOperandInfo>(tii)), MF(mf), TII(tii),
642bdd1243dSDimitry Andric       TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(*DefaultTOI),
64306c3fb27SDimitry Andric       LiveIns(PRI) {}
644bdd1243dSDimitry Andric 
645bdd1243dSDimitry Andric DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
64606c3fb27SDimitry Andric                              const TargetRegisterInfo &tri,
64706c3fb27SDimitry Andric                              const MachineDominatorTree &mdt,
64806c3fb27SDimitry Andric                              const MachineDominanceFrontier &mdf,
64906c3fb27SDimitry Andric                              const TargetOperandInfo &toi)
6500946e70aSDimitry Andric     : MF(mf), TII(tii), TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
65106c3fb27SDimitry Andric       LiveIns(PRI) {}
6520946e70aSDimitry Andric 
6530946e70aSDimitry Andric // The implementation of the definition stack.
6540946e70aSDimitry Andric // Each register reference has its own definition stack. In particular,
6550946e70aSDimitry Andric // for a register references "Reg" and "Reg:subreg" will each have their
6560946e70aSDimitry Andric // own definition stacks.
6570946e70aSDimitry Andric 
6580946e70aSDimitry Andric // Construct a stack iterator.
6590946e70aSDimitry Andric DataFlowGraph::DefStack::Iterator::Iterator(const DataFlowGraph::DefStack &S,
66006c3fb27SDimitry Andric                                             bool Top)
66106c3fb27SDimitry Andric     : DS(S) {
6620946e70aSDimitry Andric   if (!Top) {
6630946e70aSDimitry Andric     // Initialize to bottom.
6640946e70aSDimitry Andric     Pos = 0;
6650946e70aSDimitry Andric     return;
6660946e70aSDimitry Andric   }
6670946e70aSDimitry Andric   // Initialize to the top, i.e. top-most non-delimiter (or 0, if empty).
6680946e70aSDimitry Andric   Pos = DS.Stack.size();
6690946e70aSDimitry Andric   while (Pos > 0 && DS.isDelimiter(DS.Stack[Pos - 1]))
6700946e70aSDimitry Andric     Pos--;
6710946e70aSDimitry Andric }
6720946e70aSDimitry Andric 
6730946e70aSDimitry Andric // Return the size of the stack, including block delimiters.
6740946e70aSDimitry Andric unsigned DataFlowGraph::DefStack::size() const {
6750946e70aSDimitry Andric   unsigned S = 0;
6760946e70aSDimitry Andric   for (auto I = top(), E = bottom(); I != E; I.down())
6770946e70aSDimitry Andric     S++;
6780946e70aSDimitry Andric   return S;
6790946e70aSDimitry Andric }
6800946e70aSDimitry Andric 
6810946e70aSDimitry Andric // Remove the top entry from the stack. Remove all intervening delimiters
6820946e70aSDimitry Andric // so that after this, the stack is either empty, or the top of the stack
6830946e70aSDimitry Andric // is a non-delimiter.
6840946e70aSDimitry Andric void DataFlowGraph::DefStack::pop() {
6850946e70aSDimitry Andric   assert(!empty());
6860946e70aSDimitry Andric   unsigned P = nextDown(Stack.size());
6870946e70aSDimitry Andric   Stack.resize(P);
6880946e70aSDimitry Andric }
6890946e70aSDimitry Andric 
6900946e70aSDimitry Andric // Push a delimiter for block node N on the stack.
6910946e70aSDimitry Andric void DataFlowGraph::DefStack::start_block(NodeId N) {
6920946e70aSDimitry Andric   assert(N != 0);
69306c3fb27SDimitry Andric   Stack.push_back(Def(nullptr, N));
6940946e70aSDimitry Andric }
6950946e70aSDimitry Andric 
6960946e70aSDimitry Andric // Remove all nodes from the top of the stack, until the delimited for
6970946e70aSDimitry Andric // block node N is encountered. Remove the delimiter as well. In effect,
6980946e70aSDimitry Andric // this will remove from the stack all definitions from block N.
6990946e70aSDimitry Andric void DataFlowGraph::DefStack::clear_block(NodeId N) {
7000946e70aSDimitry Andric   assert(N != 0);
7010946e70aSDimitry Andric   unsigned P = Stack.size();
7020946e70aSDimitry Andric   while (P > 0) {
7030946e70aSDimitry Andric     bool Found = isDelimiter(Stack[P - 1], N);
7040946e70aSDimitry Andric     P--;
7050946e70aSDimitry Andric     if (Found)
7060946e70aSDimitry Andric       break;
7070946e70aSDimitry Andric   }
7080946e70aSDimitry Andric   // This will also remove the delimiter, if found.
7090946e70aSDimitry Andric   Stack.resize(P);
7100946e70aSDimitry Andric }
7110946e70aSDimitry Andric 
7120946e70aSDimitry Andric // Move the stack iterator up by one.
7130946e70aSDimitry Andric unsigned DataFlowGraph::DefStack::nextUp(unsigned P) const {
7140946e70aSDimitry Andric   // Get the next valid position after P (skipping all delimiters).
7150946e70aSDimitry Andric   // The input position P does not have to point to a non-delimiter.
7160946e70aSDimitry Andric   unsigned SS = Stack.size();
7170946e70aSDimitry Andric   bool IsDelim;
7180946e70aSDimitry Andric   assert(P < SS);
7190946e70aSDimitry Andric   do {
7200946e70aSDimitry Andric     P++;
7210946e70aSDimitry Andric     IsDelim = isDelimiter(Stack[P - 1]);
7220946e70aSDimitry Andric   } while (P < SS && IsDelim);
7230946e70aSDimitry Andric   assert(!IsDelim);
7240946e70aSDimitry Andric   return P;
7250946e70aSDimitry Andric }
7260946e70aSDimitry Andric 
7270946e70aSDimitry Andric // Move the stack iterator down by one.
7280946e70aSDimitry Andric unsigned DataFlowGraph::DefStack::nextDown(unsigned P) const {
7290946e70aSDimitry Andric   // Get the preceding valid position before P (skipping all delimiters).
7300946e70aSDimitry Andric   // The input position P does not have to point to a non-delimiter.
7310946e70aSDimitry Andric   assert(P > 0 && P <= Stack.size());
7320946e70aSDimitry Andric   bool IsDelim = isDelimiter(Stack[P - 1]);
7330946e70aSDimitry Andric   do {
7340946e70aSDimitry Andric     if (--P == 0)
7350946e70aSDimitry Andric       break;
7360946e70aSDimitry Andric     IsDelim = isDelimiter(Stack[P - 1]);
7370946e70aSDimitry Andric   } while (P > 0 && IsDelim);
7380946e70aSDimitry Andric   assert(!IsDelim);
7390946e70aSDimitry Andric   return P;
7400946e70aSDimitry Andric }
7410946e70aSDimitry Andric 
7420946e70aSDimitry Andric // Register information.
7430946e70aSDimitry Andric 
74406c3fb27SDimitry Andric RegisterAggr DataFlowGraph::getLandingPadLiveIns() const {
74506c3fb27SDimitry Andric   RegisterAggr LR(getPRI());
7460946e70aSDimitry Andric   const Function &F = MF.getFunction();
74706c3fb27SDimitry Andric   const Constant *PF = F.hasPersonalityFn() ? F.getPersonalityFn() : nullptr;
7480946e70aSDimitry Andric   const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
7490946e70aSDimitry Andric   if (RegisterId R = TLI.getExceptionPointerRegister(PF))
7500946e70aSDimitry Andric     LR.insert(RegisterRef(R));
7510946e70aSDimitry Andric   if (!isFuncletEHPersonality(classifyEHPersonality(PF))) {
7520946e70aSDimitry Andric     if (RegisterId R = TLI.getExceptionSelectorRegister(PF))
7530946e70aSDimitry Andric       LR.insert(RegisterRef(R));
7540946e70aSDimitry Andric   }
7550946e70aSDimitry Andric   return LR;
7560946e70aSDimitry Andric }
7570946e70aSDimitry Andric 
7580946e70aSDimitry Andric // Node management functions.
7590946e70aSDimitry Andric 
7600946e70aSDimitry Andric // Get the pointer to the node with the id N.
7610946e70aSDimitry Andric NodeBase *DataFlowGraph::ptr(NodeId N) const {
7620946e70aSDimitry Andric   if (N == 0)
7630946e70aSDimitry Andric     return nullptr;
7640946e70aSDimitry Andric   return Memory.ptr(N);
7650946e70aSDimitry Andric }
7660946e70aSDimitry Andric 
7670946e70aSDimitry Andric // Get the id of the node at the address P.
7680946e70aSDimitry Andric NodeId DataFlowGraph::id(const NodeBase *P) const {
7690946e70aSDimitry Andric   if (P == nullptr)
7700946e70aSDimitry Andric     return 0;
7710946e70aSDimitry Andric   return Memory.id(P);
7720946e70aSDimitry Andric }
7730946e70aSDimitry Andric 
7740946e70aSDimitry Andric // Allocate a new node and set the attributes to Attrs.
77506c3fb27SDimitry Andric Node DataFlowGraph::newNode(uint16_t Attrs) {
77606c3fb27SDimitry Andric   Node P = Memory.New();
7770946e70aSDimitry Andric   P.Addr->init();
7780946e70aSDimitry Andric   P.Addr->setAttrs(Attrs);
7790946e70aSDimitry Andric   return P;
7800946e70aSDimitry Andric }
7810946e70aSDimitry Andric 
7820946e70aSDimitry Andric // Make a copy of the given node B, except for the data-flow links, which
7830946e70aSDimitry Andric // are set to 0.
78406c3fb27SDimitry Andric Node DataFlowGraph::cloneNode(const Node B) {
78506c3fb27SDimitry Andric   Node NA = newNode(0);
7860946e70aSDimitry Andric   memcpy(NA.Addr, B.Addr, sizeof(NodeBase));
7870946e70aSDimitry Andric   // Ref nodes need to have the data-flow links reset.
7880946e70aSDimitry Andric   if (NA.Addr->getType() == NodeAttrs::Ref) {
78906c3fb27SDimitry Andric     Ref RA = NA;
7900946e70aSDimitry Andric     RA.Addr->setReachingDef(0);
7910946e70aSDimitry Andric     RA.Addr->setSibling(0);
7920946e70aSDimitry Andric     if (NA.Addr->getKind() == NodeAttrs::Def) {
79306c3fb27SDimitry Andric       Def DA = NA;
7940946e70aSDimitry Andric       DA.Addr->setReachedDef(0);
7950946e70aSDimitry Andric       DA.Addr->setReachedUse(0);
7960946e70aSDimitry Andric     }
7970946e70aSDimitry Andric   }
7980946e70aSDimitry Andric   return NA;
7990946e70aSDimitry Andric }
8000946e70aSDimitry Andric 
8010946e70aSDimitry Andric // Allocation routines for specific node types/kinds.
8020946e70aSDimitry Andric 
80306c3fb27SDimitry Andric Use DataFlowGraph::newUse(Instr Owner, MachineOperand &Op, uint16_t Flags) {
80406c3fb27SDimitry Andric   Use UA = newNode(NodeAttrs::Ref | NodeAttrs::Use | Flags);
8050946e70aSDimitry Andric   UA.Addr->setRegRef(&Op, *this);
8060946e70aSDimitry Andric   return UA;
8070946e70aSDimitry Andric }
8080946e70aSDimitry Andric 
80906c3fb27SDimitry Andric PhiUse DataFlowGraph::newPhiUse(Phi Owner, RegisterRef RR, Block PredB,
81006c3fb27SDimitry Andric                                 uint16_t Flags) {
81106c3fb27SDimitry Andric   PhiUse PUA = newNode(NodeAttrs::Ref | NodeAttrs::Use | Flags);
8120946e70aSDimitry Andric   assert(Flags & NodeAttrs::PhiRef);
8130946e70aSDimitry Andric   PUA.Addr->setRegRef(RR, *this);
8140946e70aSDimitry Andric   PUA.Addr->setPredecessor(PredB.Id);
8150946e70aSDimitry Andric   return PUA;
8160946e70aSDimitry Andric }
8170946e70aSDimitry Andric 
81806c3fb27SDimitry Andric Def DataFlowGraph::newDef(Instr Owner, MachineOperand &Op, uint16_t Flags) {
81906c3fb27SDimitry Andric   Def DA = newNode(NodeAttrs::Ref | NodeAttrs::Def | Flags);
8200946e70aSDimitry Andric   DA.Addr->setRegRef(&Op, *this);
8210946e70aSDimitry Andric   return DA;
8220946e70aSDimitry Andric }
8230946e70aSDimitry Andric 
82406c3fb27SDimitry Andric Def DataFlowGraph::newDef(Instr Owner, RegisterRef RR, uint16_t Flags) {
82506c3fb27SDimitry Andric   Def DA = newNode(NodeAttrs::Ref | NodeAttrs::Def | Flags);
8260946e70aSDimitry Andric   assert(Flags & NodeAttrs::PhiRef);
8270946e70aSDimitry Andric   DA.Addr->setRegRef(RR, *this);
8280946e70aSDimitry Andric   return DA;
8290946e70aSDimitry Andric }
8300946e70aSDimitry Andric 
83106c3fb27SDimitry Andric Phi DataFlowGraph::newPhi(Block Owner) {
83206c3fb27SDimitry Andric   Phi PA = newNode(NodeAttrs::Code | NodeAttrs::Phi);
8330946e70aSDimitry Andric   Owner.Addr->addPhi(PA, *this);
8340946e70aSDimitry Andric   return PA;
8350946e70aSDimitry Andric }
8360946e70aSDimitry Andric 
83706c3fb27SDimitry Andric Stmt DataFlowGraph::newStmt(Block Owner, MachineInstr *MI) {
83806c3fb27SDimitry Andric   Stmt SA = newNode(NodeAttrs::Code | NodeAttrs::Stmt);
8390946e70aSDimitry Andric   SA.Addr->setCode(MI);
8400946e70aSDimitry Andric   Owner.Addr->addMember(SA, *this);
8410946e70aSDimitry Andric   return SA;
8420946e70aSDimitry Andric }
8430946e70aSDimitry Andric 
84406c3fb27SDimitry Andric Block DataFlowGraph::newBlock(Func Owner, MachineBasicBlock *BB) {
84506c3fb27SDimitry Andric   Block BA = newNode(NodeAttrs::Code | NodeAttrs::Block);
8460946e70aSDimitry Andric   BA.Addr->setCode(BB);
8470946e70aSDimitry Andric   Owner.Addr->addMember(BA, *this);
8480946e70aSDimitry Andric   return BA;
8490946e70aSDimitry Andric }
8500946e70aSDimitry Andric 
85106c3fb27SDimitry Andric Func DataFlowGraph::newFunc(MachineFunction *MF) {
85206c3fb27SDimitry Andric   Func FA = newNode(NodeAttrs::Code | NodeAttrs::Func);
8530946e70aSDimitry Andric   FA.Addr->setCode(MF);
8540946e70aSDimitry Andric   return FA;
8550946e70aSDimitry Andric }
8560946e70aSDimitry Andric 
8570946e70aSDimitry Andric // Build the data flow graph.
85806c3fb27SDimitry Andric void DataFlowGraph::build(const Config &config) {
8590946e70aSDimitry Andric   reset();
86006c3fb27SDimitry Andric   BuildCfg = config;
86106c3fb27SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
86206c3fb27SDimitry Andric   ReservedRegs = MRI.getReservedRegs();
86306c3fb27SDimitry Andric   bool SkipReserved = BuildCfg.Options & BuildOptions::OmitReserved;
86406c3fb27SDimitry Andric 
86506c3fb27SDimitry Andric   auto Insert = [](auto &Set, auto &&Range) {
86606c3fb27SDimitry Andric     Set.insert(Range.begin(), Range.end());
86706c3fb27SDimitry Andric   };
86806c3fb27SDimitry Andric 
86906c3fb27SDimitry Andric   if (BuildCfg.TrackRegs.empty()) {
87006c3fb27SDimitry Andric     std::set<RegisterId> BaseSet;
87106c3fb27SDimitry Andric     if (BuildCfg.Classes.empty()) {
87206c3fb27SDimitry Andric       // Insert every register.
873*0fca6ea1SDimitry Andric       for (unsigned R = 1, E = getPRI().getTRI().getNumRegs(); R != E; ++R)
87406c3fb27SDimitry Andric         BaseSet.insert(R);
87506c3fb27SDimitry Andric     } else {
87606c3fb27SDimitry Andric       for (const TargetRegisterClass *RC : BuildCfg.Classes) {
87706c3fb27SDimitry Andric         for (MCPhysReg R : *RC)
87806c3fb27SDimitry Andric           BaseSet.insert(R);
87906c3fb27SDimitry Andric       }
88006c3fb27SDimitry Andric     }
88106c3fb27SDimitry Andric     for (RegisterId R : BaseSet) {
88206c3fb27SDimitry Andric       if (SkipReserved && ReservedRegs[R])
88306c3fb27SDimitry Andric         continue;
88406c3fb27SDimitry Andric       Insert(TrackedUnits, getPRI().getUnits(RegisterRef(R)));
88506c3fb27SDimitry Andric     }
88606c3fb27SDimitry Andric   } else {
88706c3fb27SDimitry Andric     // Track set in Config overrides everything.
88806c3fb27SDimitry Andric     for (unsigned R : BuildCfg.TrackRegs) {
88906c3fb27SDimitry Andric       if (SkipReserved && ReservedRegs[R])
89006c3fb27SDimitry Andric         continue;
89106c3fb27SDimitry Andric       Insert(TrackedUnits, getPRI().getUnits(RegisterRef(R)));
89206c3fb27SDimitry Andric     }
89306c3fb27SDimitry Andric   }
89406c3fb27SDimitry Andric 
89506c3fb27SDimitry Andric   TheFunc = newFunc(&MF);
8960946e70aSDimitry Andric 
8970946e70aSDimitry Andric   if (MF.empty())
8980946e70aSDimitry Andric     return;
8990946e70aSDimitry Andric 
9000946e70aSDimitry Andric   for (MachineBasicBlock &B : MF) {
90106c3fb27SDimitry Andric     Block BA = newBlock(TheFunc, &B);
9020946e70aSDimitry Andric     BlockNodes.insert(std::make_pair(&B, BA));
9030946e70aSDimitry Andric     for (MachineInstr &I : B) {
9040946e70aSDimitry Andric       if (I.isDebugInstr())
9050946e70aSDimitry Andric         continue;
9060946e70aSDimitry Andric       buildStmt(BA, I);
9070946e70aSDimitry Andric     }
9080946e70aSDimitry Andric   }
9090946e70aSDimitry Andric 
91006c3fb27SDimitry Andric   Block EA = TheFunc.Addr->getEntryBlock(*this);
91106c3fb27SDimitry Andric   NodeList Blocks = TheFunc.Addr->members(*this);
9120946e70aSDimitry Andric 
9130946e70aSDimitry Andric   // Collect function live-ins and entry block live-ins.
9140946e70aSDimitry Andric   MachineBasicBlock &EntryB = *EA.Addr->getCode();
9150946e70aSDimitry Andric   assert(EntryB.pred_empty() && "Function entry block has predecessors");
9160946e70aSDimitry Andric   for (std::pair<unsigned, unsigned> P : MRI.liveins())
9170946e70aSDimitry Andric     LiveIns.insert(RegisterRef(P.first));
9180946e70aSDimitry Andric   if (MRI.tracksLiveness()) {
9190946e70aSDimitry Andric     for (auto I : EntryB.liveins())
9200946e70aSDimitry Andric       LiveIns.insert(RegisterRef(I.PhysReg, I.LaneMask));
9210946e70aSDimitry Andric   }
9220946e70aSDimitry Andric 
9230946e70aSDimitry Andric   // Add function-entry phi nodes for the live-in registers.
92406c3fb27SDimitry Andric   for (RegisterRef RR : LiveIns.refs()) {
92506c3fb27SDimitry Andric     if (RR.isReg() && !isTracked(RR)) // isReg is likely guaranteed
92606c3fb27SDimitry Andric       continue;
92706c3fb27SDimitry Andric     Phi PA = newPhi(EA);
9280946e70aSDimitry Andric     uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
92906c3fb27SDimitry Andric     Def DA = newDef(PA, RR, PhiFlags);
9300946e70aSDimitry Andric     PA.Addr->addMember(DA, *this);
9310946e70aSDimitry Andric   }
9320946e70aSDimitry Andric 
9330946e70aSDimitry Andric   // Add phis for landing pads.
9340946e70aSDimitry Andric   // Landing pads, unlike usual backs blocks, are not entered through
9350946e70aSDimitry Andric   // branches in the program, or fall-throughs from other blocks. They
9360946e70aSDimitry Andric   // are entered from the exception handling runtime and target's ABI
9370946e70aSDimitry Andric   // may define certain registers as defined on entry to such a block.
93806c3fb27SDimitry Andric   RegisterAggr EHRegs = getLandingPadLiveIns();
9390946e70aSDimitry Andric   if (!EHRegs.empty()) {
94006c3fb27SDimitry Andric     for (Block BA : Blocks) {
9410946e70aSDimitry Andric       const MachineBasicBlock &B = *BA.Addr->getCode();
9420946e70aSDimitry Andric       if (!B.isEHPad())
9430946e70aSDimitry Andric         continue;
9440946e70aSDimitry Andric 
9450946e70aSDimitry Andric       // Prepare a list of NodeIds of the block's predecessors.
9460946e70aSDimitry Andric       NodeList Preds;
9470946e70aSDimitry Andric       for (MachineBasicBlock *PB : B.predecessors())
9480946e70aSDimitry Andric         Preds.push_back(findBlock(PB));
9490946e70aSDimitry Andric 
9500946e70aSDimitry Andric       // Build phi nodes for each live-in.
95106c3fb27SDimitry Andric       for (RegisterRef RR : EHRegs.refs()) {
95206c3fb27SDimitry Andric         if (RR.isReg() && !isTracked(RR))
95306c3fb27SDimitry Andric           continue;
95406c3fb27SDimitry Andric         Phi PA = newPhi(BA);
9550946e70aSDimitry Andric         uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
9560946e70aSDimitry Andric         // Add def:
95706c3fb27SDimitry Andric         Def DA = newDef(PA, RR, PhiFlags);
9580946e70aSDimitry Andric         PA.Addr->addMember(DA, *this);
9590946e70aSDimitry Andric         // Add uses (no reaching defs for phi uses):
96006c3fb27SDimitry Andric         for (Block PBA : Preds) {
96106c3fb27SDimitry Andric           PhiUse PUA = newPhiUse(PA, RR, PBA);
9620946e70aSDimitry Andric           PA.Addr->addMember(PUA, *this);
9630946e70aSDimitry Andric         }
9640946e70aSDimitry Andric       }
9650946e70aSDimitry Andric     }
9660946e70aSDimitry Andric   }
9670946e70aSDimitry Andric 
9680946e70aSDimitry Andric   // Build a map "PhiM" which will contain, for each block, the set
9690946e70aSDimitry Andric   // of references that will require phi definitions in that block.
97006c3fb27SDimitry Andric   BlockRefsMap PhiM(getPRI());
97106c3fb27SDimitry Andric   for (Block BA : Blocks)
9720946e70aSDimitry Andric     recordDefsForDF(PhiM, BA);
97306c3fb27SDimitry Andric   for (Block BA : Blocks)
97406c3fb27SDimitry Andric     buildPhis(PhiM, BA);
9750946e70aSDimitry Andric 
9760946e70aSDimitry Andric   // Link all the refs. This will recursively traverse the dominator tree.
9770946e70aSDimitry Andric   DefStackMap DM;
9780946e70aSDimitry Andric   linkBlockRefs(DM, EA);
9790946e70aSDimitry Andric 
9800946e70aSDimitry Andric   // Finally, remove all unused phi nodes.
98106c3fb27SDimitry Andric   if (!(BuildCfg.Options & BuildOptions::KeepDeadPhis))
9820946e70aSDimitry Andric     removeUnusedPhis();
9830946e70aSDimitry Andric }
9840946e70aSDimitry Andric 
9850946e70aSDimitry Andric RegisterRef DataFlowGraph::makeRegRef(unsigned Reg, unsigned Sub) const {
98606c3fb27SDimitry Andric   assert(RegisterRef::isRegId(Reg) || RegisterRef::isMaskId(Reg));
9870946e70aSDimitry Andric   assert(Reg != 0);
9880946e70aSDimitry Andric   if (Sub != 0)
9890946e70aSDimitry Andric     Reg = TRI.getSubReg(Reg, Sub);
9900946e70aSDimitry Andric   return RegisterRef(Reg);
9910946e70aSDimitry Andric }
9920946e70aSDimitry Andric 
9930946e70aSDimitry Andric RegisterRef DataFlowGraph::makeRegRef(const MachineOperand &Op) const {
9940946e70aSDimitry Andric   assert(Op.isReg() || Op.isRegMask());
9950946e70aSDimitry Andric   if (Op.isReg())
9960946e70aSDimitry Andric     return makeRegRef(Op.getReg(), Op.getSubReg());
99706c3fb27SDimitry Andric   return RegisterRef(getPRI().getRegMaskId(Op.getRegMask()),
99806c3fb27SDimitry Andric                      LaneBitmask::getAll());
9990946e70aSDimitry Andric }
10000946e70aSDimitry Andric 
10010946e70aSDimitry Andric // For each stack in the map DefM, push the delimiter for block B on it.
10020946e70aSDimitry Andric void DataFlowGraph::markBlock(NodeId B, DefStackMap &DefM) {
10030946e70aSDimitry Andric   // Push block delimiters.
1004fe6060f1SDimitry Andric   for (auto &P : DefM)
1005fe6060f1SDimitry Andric     P.second.start_block(B);
10060946e70aSDimitry Andric }
10070946e70aSDimitry Andric 
10080946e70aSDimitry Andric // Remove all definitions coming from block B from each stack in DefM.
10090946e70aSDimitry Andric void DataFlowGraph::releaseBlock(NodeId B, DefStackMap &DefM) {
10100946e70aSDimitry Andric   // Pop all defs from this block from the definition stack. Defs that were
10110946e70aSDimitry Andric   // added to the map during the traversal of instructions will not have a
10120946e70aSDimitry Andric   // delimiter, but for those, the whole stack will be emptied.
1013fe6060f1SDimitry Andric   for (auto &P : DefM)
1014fe6060f1SDimitry Andric     P.second.clear_block(B);
10150946e70aSDimitry Andric 
10160946e70aSDimitry Andric   // Finally, remove empty stacks from the map.
10170946e70aSDimitry Andric   for (auto I = DefM.begin(), E = DefM.end(), NextI = I; I != E; I = NextI) {
10180946e70aSDimitry Andric     NextI = std::next(I);
10190946e70aSDimitry Andric     // This preserves the validity of iterators other than I.
10200946e70aSDimitry Andric     if (I->second.empty())
10210946e70aSDimitry Andric       DefM.erase(I);
10220946e70aSDimitry Andric   }
10230946e70aSDimitry Andric }
10240946e70aSDimitry Andric 
10250946e70aSDimitry Andric // Push all definitions from the instruction node IA to an appropriate
10260946e70aSDimitry Andric // stack in DefM.
102706c3fb27SDimitry Andric void DataFlowGraph::pushAllDefs(Instr IA, DefStackMap &DefM) {
10280946e70aSDimitry Andric   pushClobbers(IA, DefM);
10290946e70aSDimitry Andric   pushDefs(IA, DefM);
10300946e70aSDimitry Andric }
10310946e70aSDimitry Andric 
10320946e70aSDimitry Andric // Push all definitions from the instruction node IA to an appropriate
10330946e70aSDimitry Andric // stack in DefM.
103406c3fb27SDimitry Andric void DataFlowGraph::pushClobbers(Instr IA, DefStackMap &DefM) {
10350946e70aSDimitry Andric   NodeSet Visited;
10360946e70aSDimitry Andric   std::set<RegisterId> Defined;
10370946e70aSDimitry Andric 
10380946e70aSDimitry Andric   // The important objectives of this function are:
10390946e70aSDimitry Andric   // - to be able to handle instructions both while the graph is being
10400946e70aSDimitry Andric   //   constructed, and after the graph has been constructed, and
10410946e70aSDimitry Andric   // - maintain proper ordering of definitions on the stack for each
10420946e70aSDimitry Andric   //   register reference:
10430946e70aSDimitry Andric   //   - if there are two or more related defs in IA (i.e. coming from
10440946e70aSDimitry Andric   //     the same machine operand), then only push one def on the stack,
10450946e70aSDimitry Andric   //   - if there are multiple unrelated defs of non-overlapping
10460946e70aSDimitry Andric   //     subregisters of S, then the stack for S will have both (in an
10470946e70aSDimitry Andric   //     unspecified order), but the order does not matter from the data-
10480946e70aSDimitry Andric   //     -flow perspective.
10490946e70aSDimitry Andric 
105006c3fb27SDimitry Andric   for (Def DA : IA.Addr->members_if(IsDef, *this)) {
10510946e70aSDimitry Andric     if (Visited.count(DA.Id))
10520946e70aSDimitry Andric       continue;
10530946e70aSDimitry Andric     if (!(DA.Addr->getFlags() & NodeAttrs::Clobbering))
10540946e70aSDimitry Andric       continue;
10550946e70aSDimitry Andric 
10560946e70aSDimitry Andric     NodeList Rel = getRelatedRefs(IA, DA);
105706c3fb27SDimitry Andric     Def PDA = Rel.front();
10580946e70aSDimitry Andric     RegisterRef RR = PDA.Addr->getRegRef(*this);
10590946e70aSDimitry Andric 
10600946e70aSDimitry Andric     // Push the definition on the stack for the register and all aliases.
10610946e70aSDimitry Andric     // The def stack traversal in linkNodeUp will check the exact aliasing.
10620946e70aSDimitry Andric     DefM[RR.Reg].push(DA);
10630946e70aSDimitry Andric     Defined.insert(RR.Reg);
106406c3fb27SDimitry Andric     for (RegisterId A : getPRI().getAliasSet(RR.Reg)) {
106506c3fb27SDimitry Andric       if (RegisterRef::isRegId(A) && !isTracked(RegisterRef(A)))
106606c3fb27SDimitry Andric         continue;
10670946e70aSDimitry Andric       // Check that we don't push the same def twice.
10680946e70aSDimitry Andric       assert(A != RR.Reg);
10690946e70aSDimitry Andric       if (!Defined.count(A))
10700946e70aSDimitry Andric         DefM[A].push(DA);
10710946e70aSDimitry Andric     }
10720946e70aSDimitry Andric     // Mark all the related defs as visited.
107306c3fb27SDimitry Andric     for (Node T : Rel)
10740946e70aSDimitry Andric       Visited.insert(T.Id);
10750946e70aSDimitry Andric   }
10760946e70aSDimitry Andric }
10770946e70aSDimitry Andric 
10780946e70aSDimitry Andric // Push all definitions from the instruction node IA to an appropriate
10790946e70aSDimitry Andric // stack in DefM.
108006c3fb27SDimitry Andric void DataFlowGraph::pushDefs(Instr IA, DefStackMap &DefM) {
10810946e70aSDimitry Andric   NodeSet Visited;
10820946e70aSDimitry Andric #ifndef NDEBUG
10830946e70aSDimitry Andric   std::set<RegisterId> Defined;
10840946e70aSDimitry Andric #endif
10850946e70aSDimitry Andric 
10860946e70aSDimitry Andric   // The important objectives of this function are:
10870946e70aSDimitry Andric   // - to be able to handle instructions both while the graph is being
10880946e70aSDimitry Andric   //   constructed, and after the graph has been constructed, and
10890946e70aSDimitry Andric   // - maintain proper ordering of definitions on the stack for each
10900946e70aSDimitry Andric   //   register reference:
10910946e70aSDimitry Andric   //   - if there are two or more related defs in IA (i.e. coming from
10920946e70aSDimitry Andric   //     the same machine operand), then only push one def on the stack,
10930946e70aSDimitry Andric   //   - if there are multiple unrelated defs of non-overlapping
10940946e70aSDimitry Andric   //     subregisters of S, then the stack for S will have both (in an
10950946e70aSDimitry Andric   //     unspecified order), but the order does not matter from the data-
10960946e70aSDimitry Andric   //     -flow perspective.
10970946e70aSDimitry Andric 
109806c3fb27SDimitry Andric   for (Def DA : IA.Addr->members_if(IsDef, *this)) {
10990946e70aSDimitry Andric     if (Visited.count(DA.Id))
11000946e70aSDimitry Andric       continue;
11010946e70aSDimitry Andric     if (DA.Addr->getFlags() & NodeAttrs::Clobbering)
11020946e70aSDimitry Andric       continue;
11030946e70aSDimitry Andric 
11040946e70aSDimitry Andric     NodeList Rel = getRelatedRefs(IA, DA);
110506c3fb27SDimitry Andric     Def PDA = Rel.front();
11060946e70aSDimitry Andric     RegisterRef RR = PDA.Addr->getRegRef(*this);
11070946e70aSDimitry Andric #ifndef NDEBUG
11080946e70aSDimitry Andric     // Assert if the register is defined in two or more unrelated defs.
11090946e70aSDimitry Andric     // This could happen if there are two or more def operands defining it.
11100946e70aSDimitry Andric     if (!Defined.insert(RR.Reg).second) {
111106c3fb27SDimitry Andric       MachineInstr *MI = Stmt(IA).Addr->getCode();
111206c3fb27SDimitry Andric       dbgs() << "Multiple definitions of register: " << Print(RR, *this)
111306c3fb27SDimitry Andric              << " in\n  " << *MI << "in " << printMBBReference(*MI->getParent())
111406c3fb27SDimitry Andric              << '\n';
11150946e70aSDimitry Andric       llvm_unreachable(nullptr);
11160946e70aSDimitry Andric     }
11170946e70aSDimitry Andric #endif
11180946e70aSDimitry Andric     // Push the definition on the stack for the register and all aliases.
11190946e70aSDimitry Andric     // The def stack traversal in linkNodeUp will check the exact aliasing.
11200946e70aSDimitry Andric     DefM[RR.Reg].push(DA);
112106c3fb27SDimitry Andric     for (RegisterId A : getPRI().getAliasSet(RR.Reg)) {
112206c3fb27SDimitry Andric       if (RegisterRef::isRegId(A) && !isTracked(RegisterRef(A)))
112306c3fb27SDimitry Andric         continue;
11240946e70aSDimitry Andric       // Check that we don't push the same def twice.
11250946e70aSDimitry Andric       assert(A != RR.Reg);
11260946e70aSDimitry Andric       DefM[A].push(DA);
11270946e70aSDimitry Andric     }
11280946e70aSDimitry Andric     // Mark all the related defs as visited.
112906c3fb27SDimitry Andric     for (Node T : Rel)
11300946e70aSDimitry Andric       Visited.insert(T.Id);
11310946e70aSDimitry Andric   }
11320946e70aSDimitry Andric }
11330946e70aSDimitry Andric 
11340946e70aSDimitry Andric // Return the list of all reference nodes related to RA, including RA itself.
11350946e70aSDimitry Andric // See "getNextRelated" for the meaning of a "related reference".
113606c3fb27SDimitry Andric NodeList DataFlowGraph::getRelatedRefs(Instr IA, Ref RA) const {
11370946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
11380946e70aSDimitry Andric 
11390946e70aSDimitry Andric   NodeList Refs;
11400946e70aSDimitry Andric   NodeId Start = RA.Id;
11410946e70aSDimitry Andric   do {
11420946e70aSDimitry Andric     Refs.push_back(RA);
11430946e70aSDimitry Andric     RA = getNextRelated(IA, RA);
11440946e70aSDimitry Andric   } while (RA.Id != 0 && RA.Id != Start);
11450946e70aSDimitry Andric   return Refs;
11460946e70aSDimitry Andric }
11470946e70aSDimitry Andric 
11480946e70aSDimitry Andric // Clear all information in the graph.
11490946e70aSDimitry Andric void DataFlowGraph::reset() {
11500946e70aSDimitry Andric   Memory.clear();
11510946e70aSDimitry Andric   BlockNodes.clear();
115206c3fb27SDimitry Andric   TrackedUnits.clear();
115306c3fb27SDimitry Andric   ReservedRegs.clear();
115406c3fb27SDimitry Andric   TheFunc = Func();
11550946e70aSDimitry Andric }
11560946e70aSDimitry Andric 
11570946e70aSDimitry Andric // Return the next reference node in the instruction node IA that is related
11580946e70aSDimitry Andric // to RA. Conceptually, two reference nodes are related if they refer to the
11590946e70aSDimitry Andric // same instance of a register access, but differ in flags or other minor
11600946e70aSDimitry Andric // characteristics. Specific examples of related nodes are shadow reference
11610946e70aSDimitry Andric // nodes.
11620946e70aSDimitry Andric // Return the equivalent of nullptr if there are no more related references.
116306c3fb27SDimitry Andric Ref DataFlowGraph::getNextRelated(Instr IA, Ref RA) const {
11640946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
11650946e70aSDimitry Andric 
116606c3fb27SDimitry Andric   auto IsRelated = [this, RA](Ref TA) -> bool {
11670946e70aSDimitry Andric     if (TA.Addr->getKind() != RA.Addr->getKind())
11680946e70aSDimitry Andric       return false;
116906c3fb27SDimitry Andric     if (!getPRI().equal_to(TA.Addr->getRegRef(*this),
117006c3fb27SDimitry Andric                            RA.Addr->getRegRef(*this))) {
11710946e70aSDimitry Andric       return false;
117206c3fb27SDimitry Andric     }
11730946e70aSDimitry Andric     return true;
11740946e70aSDimitry Andric   };
117506c3fb27SDimitry Andric 
117606c3fb27SDimitry Andric   RegisterRef RR = RA.Addr->getRegRef(*this);
117706c3fb27SDimitry Andric   if (IA.Addr->getKind() == NodeAttrs::Stmt) {
117806c3fb27SDimitry Andric     auto Cond = [&IsRelated, RA](Ref TA) -> bool {
117906c3fb27SDimitry Andric       return IsRelated(TA) && &RA.Addr->getOp() == &TA.Addr->getOp();
11800946e70aSDimitry Andric     };
118106c3fb27SDimitry Andric     return RA.Addr->getNextRef(RR, Cond, true, *this);
118206c3fb27SDimitry Andric   }
118306c3fb27SDimitry Andric 
118406c3fb27SDimitry Andric   assert(IA.Addr->getKind() == NodeAttrs::Phi);
118506c3fb27SDimitry Andric   auto Cond = [&IsRelated, RA](Ref TA) -> bool {
118606c3fb27SDimitry Andric     if (!IsRelated(TA))
11870946e70aSDimitry Andric       return false;
11880946e70aSDimitry Andric     if (TA.Addr->getKind() != NodeAttrs::Use)
11890946e70aSDimitry Andric       return true;
11900946e70aSDimitry Andric     // For phi uses, compare predecessor blocks.
119106c3fb27SDimitry Andric     return PhiUse(TA).Addr->getPredecessor() ==
119206c3fb27SDimitry Andric            PhiUse(RA).Addr->getPredecessor();
11930946e70aSDimitry Andric   };
119406c3fb27SDimitry Andric   return RA.Addr->getNextRef(RR, Cond, true, *this);
11950946e70aSDimitry Andric }
11960946e70aSDimitry Andric 
11970946e70aSDimitry Andric // Find the next node related to RA in IA that satisfies condition P.
11980946e70aSDimitry Andric // If such a node was found, return a pair where the second element is the
11990946e70aSDimitry Andric // located node. If such a node does not exist, return a pair where the
12000946e70aSDimitry Andric // first element is the element after which such a node should be inserted,
12010946e70aSDimitry Andric // and the second element is a null-address.
12020946e70aSDimitry Andric template <typename Predicate>
120306c3fb27SDimitry Andric std::pair<Ref, Ref> DataFlowGraph::locateNextRef(Instr IA, Ref RA,
12040946e70aSDimitry Andric                                                  Predicate P) const {
12050946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
12060946e70aSDimitry Andric 
120706c3fb27SDimitry Andric   Ref NA;
12080946e70aSDimitry Andric   NodeId Start = RA.Id;
12090946e70aSDimitry Andric   while (true) {
12100946e70aSDimitry Andric     NA = getNextRelated(IA, RA);
12110946e70aSDimitry Andric     if (NA.Id == 0 || NA.Id == Start)
12120946e70aSDimitry Andric       break;
12130946e70aSDimitry Andric     if (P(NA))
12140946e70aSDimitry Andric       break;
12150946e70aSDimitry Andric     RA = NA;
12160946e70aSDimitry Andric   }
12170946e70aSDimitry Andric 
12180946e70aSDimitry Andric   if (NA.Id != 0 && NA.Id != Start)
12190946e70aSDimitry Andric     return std::make_pair(RA, NA);
122006c3fb27SDimitry Andric   return std::make_pair(RA, Ref());
12210946e70aSDimitry Andric }
12220946e70aSDimitry Andric 
12230946e70aSDimitry Andric // Get the next shadow node in IA corresponding to RA, and optionally create
12240946e70aSDimitry Andric // such a node if it does not exist.
122506c3fb27SDimitry Andric Ref DataFlowGraph::getNextShadow(Instr IA, Ref RA, bool Create) {
12260946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
12270946e70aSDimitry Andric 
12280946e70aSDimitry Andric   uint16_t Flags = RA.Addr->getFlags() | NodeAttrs::Shadow;
122906c3fb27SDimitry Andric   auto IsShadow = [Flags](Ref TA) -> bool {
12300946e70aSDimitry Andric     return TA.Addr->getFlags() == Flags;
12310946e70aSDimitry Andric   };
12320946e70aSDimitry Andric   auto Loc = locateNextRef(IA, RA, IsShadow);
12330946e70aSDimitry Andric   if (Loc.second.Id != 0 || !Create)
12340946e70aSDimitry Andric     return Loc.second;
12350946e70aSDimitry Andric 
12360946e70aSDimitry Andric   // Create a copy of RA and mark is as shadow.
123706c3fb27SDimitry Andric   Ref NA = cloneNode(RA);
12380946e70aSDimitry Andric   NA.Addr->setFlags(Flags | NodeAttrs::Shadow);
12390946e70aSDimitry Andric   IA.Addr->addMemberAfter(Loc.first, NA, *this);
12400946e70aSDimitry Andric   return NA;
12410946e70aSDimitry Andric }
12420946e70aSDimitry Andric 
12430946e70aSDimitry Andric // Create a new statement node in the block node BA that corresponds to
12440946e70aSDimitry Andric // the machine instruction MI.
124506c3fb27SDimitry Andric void DataFlowGraph::buildStmt(Block BA, MachineInstr &In) {
124606c3fb27SDimitry Andric   Stmt SA = newStmt(BA, &In);
12470946e70aSDimitry Andric 
12480946e70aSDimitry Andric   auto isCall = [](const MachineInstr &In) -> bool {
12490946e70aSDimitry Andric     if (In.isCall())
12500946e70aSDimitry Andric       return true;
12510946e70aSDimitry Andric     // Is tail call?
12520946e70aSDimitry Andric     if (In.isBranch()) {
12530946e70aSDimitry Andric       for (const MachineOperand &Op : In.operands())
12540946e70aSDimitry Andric         if (Op.isGlobal() || Op.isSymbol())
12550946e70aSDimitry Andric           return true;
12560946e70aSDimitry Andric       // Assume indirect branches are calls. This is for the purpose of
12570946e70aSDimitry Andric       // keeping implicit operands, and so it won't hurt on intra-function
12580946e70aSDimitry Andric       // indirect branches.
12590946e70aSDimitry Andric       if (In.isIndirectBranch())
12600946e70aSDimitry Andric         return true;
12610946e70aSDimitry Andric     }
12620946e70aSDimitry Andric     return false;
12630946e70aSDimitry Andric   };
12640946e70aSDimitry Andric 
12650946e70aSDimitry Andric   auto isDefUndef = [this](const MachineInstr &In, RegisterRef DR) -> bool {
12660946e70aSDimitry Andric     // This instruction defines DR. Check if there is a use operand that
12670946e70aSDimitry Andric     // would make DR live on entry to the instruction.
126806c3fb27SDimitry Andric     for (const MachineOperand &Op : In.all_uses()) {
126906c3fb27SDimitry Andric       if (Op.getReg() == 0 || Op.isUndef())
12700946e70aSDimitry Andric         continue;
12710946e70aSDimitry Andric       RegisterRef UR = makeRegRef(Op);
127206c3fb27SDimitry Andric       if (getPRI().alias(DR, UR))
12730946e70aSDimitry Andric         return false;
12740946e70aSDimitry Andric     }
12750946e70aSDimitry Andric     return true;
12760946e70aSDimitry Andric   };
12770946e70aSDimitry Andric 
12780946e70aSDimitry Andric   bool IsCall = isCall(In);
12790946e70aSDimitry Andric   unsigned NumOps = In.getNumOperands();
12800946e70aSDimitry Andric 
12810946e70aSDimitry Andric   // Avoid duplicate implicit defs. This will not detect cases of implicit
12820946e70aSDimitry Andric   // defs that define registers that overlap, but it is not clear how to
12830946e70aSDimitry Andric   // interpret that in the absence of explicit defs. Overlapping explicit
12840946e70aSDimitry Andric   // defs are likely illegal already.
12850946e70aSDimitry Andric   BitVector DoneDefs(TRI.getNumRegs());
12860946e70aSDimitry Andric   // Process explicit defs first.
12870946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
12880946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
12890946e70aSDimitry Andric     if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
12900946e70aSDimitry Andric       continue;
12910946e70aSDimitry Andric     Register R = Op.getReg();
129206c3fb27SDimitry Andric     if (!R || !R.isPhysical() || !isTracked(RegisterRef(R)))
12930946e70aSDimitry Andric       continue;
12940946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::None;
12950946e70aSDimitry Andric     if (TOI.isPreserving(In, OpN)) {
12960946e70aSDimitry Andric       Flags |= NodeAttrs::Preserving;
12970946e70aSDimitry Andric       // If the def is preserving, check if it is also undefined.
12980946e70aSDimitry Andric       if (isDefUndef(In, makeRegRef(Op)))
12990946e70aSDimitry Andric         Flags |= NodeAttrs::Undef;
13000946e70aSDimitry Andric     }
13010946e70aSDimitry Andric     if (TOI.isClobbering(In, OpN))
13020946e70aSDimitry Andric       Flags |= NodeAttrs::Clobbering;
13030946e70aSDimitry Andric     if (TOI.isFixedReg(In, OpN))
13040946e70aSDimitry Andric       Flags |= NodeAttrs::Fixed;
13050946e70aSDimitry Andric     if (IsCall && Op.isDead())
13060946e70aSDimitry Andric       Flags |= NodeAttrs::Dead;
130706c3fb27SDimitry Andric     Def DA = newDef(SA, Op, Flags);
13080946e70aSDimitry Andric     SA.Addr->addMember(DA, *this);
13090946e70aSDimitry Andric     assert(!DoneDefs.test(R));
13100946e70aSDimitry Andric     DoneDefs.set(R);
13110946e70aSDimitry Andric   }
13120946e70aSDimitry Andric 
13130946e70aSDimitry Andric   // Process reg-masks (as clobbers).
13140946e70aSDimitry Andric   BitVector DoneClobbers(TRI.getNumRegs());
13150946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
13160946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
13170946e70aSDimitry Andric     if (!Op.isRegMask())
13180946e70aSDimitry Andric       continue;
131906c3fb27SDimitry Andric     uint16_t Flags = NodeAttrs::Clobbering | NodeAttrs::Fixed | NodeAttrs::Dead;
132006c3fb27SDimitry Andric     Def DA = newDef(SA, Op, Flags);
13210946e70aSDimitry Andric     SA.Addr->addMember(DA, *this);
13220946e70aSDimitry Andric     // Record all clobbered registers in DoneDefs.
13230946e70aSDimitry Andric     const uint32_t *RM = Op.getRegMask();
132406c3fb27SDimitry Andric     for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
132506c3fb27SDimitry Andric       if (!isTracked(RegisterRef(i)))
132606c3fb27SDimitry Andric         continue;
13270946e70aSDimitry Andric       if (!(RM[i / 32] & (1u << (i % 32))))
13280946e70aSDimitry Andric         DoneClobbers.set(i);
13290946e70aSDimitry Andric     }
133006c3fb27SDimitry Andric   }
13310946e70aSDimitry Andric 
13320946e70aSDimitry Andric   // Process implicit defs, skipping those that have already been added
13330946e70aSDimitry Andric   // as explicit.
13340946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
13350946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
13360946e70aSDimitry Andric     if (!Op.isReg() || !Op.isDef() || !Op.isImplicit())
13370946e70aSDimitry Andric       continue;
13380946e70aSDimitry Andric     Register R = Op.getReg();
133906c3fb27SDimitry Andric     if (!R || !R.isPhysical() || !isTracked(RegisterRef(R)) || DoneDefs.test(R))
13400946e70aSDimitry Andric       continue;
13410946e70aSDimitry Andric     RegisterRef RR = makeRegRef(Op);
13420946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::None;
13430946e70aSDimitry Andric     if (TOI.isPreserving(In, OpN)) {
13440946e70aSDimitry Andric       Flags |= NodeAttrs::Preserving;
13450946e70aSDimitry Andric       // If the def is preserving, check if it is also undefined.
13460946e70aSDimitry Andric       if (isDefUndef(In, RR))
13470946e70aSDimitry Andric         Flags |= NodeAttrs::Undef;
13480946e70aSDimitry Andric     }
13490946e70aSDimitry Andric     if (TOI.isClobbering(In, OpN))
13500946e70aSDimitry Andric       Flags |= NodeAttrs::Clobbering;
13510946e70aSDimitry Andric     if (TOI.isFixedReg(In, OpN))
13520946e70aSDimitry Andric       Flags |= NodeAttrs::Fixed;
13530946e70aSDimitry Andric     if (IsCall && Op.isDead()) {
13540946e70aSDimitry Andric       if (DoneClobbers.test(R))
13550946e70aSDimitry Andric         continue;
13560946e70aSDimitry Andric       Flags |= NodeAttrs::Dead;
13570946e70aSDimitry Andric     }
135806c3fb27SDimitry Andric     Def DA = newDef(SA, Op, Flags);
13590946e70aSDimitry Andric     SA.Addr->addMember(DA, *this);
13600946e70aSDimitry Andric     DoneDefs.set(R);
13610946e70aSDimitry Andric   }
13620946e70aSDimitry Andric 
13630946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
13640946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
13650946e70aSDimitry Andric     if (!Op.isReg() || !Op.isUse())
13660946e70aSDimitry Andric       continue;
13670946e70aSDimitry Andric     Register R = Op.getReg();
136806c3fb27SDimitry Andric     if (!R || !R.isPhysical() || !isTracked(RegisterRef(R)))
13690946e70aSDimitry Andric       continue;
13700946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::None;
13710946e70aSDimitry Andric     if (Op.isUndef())
13720946e70aSDimitry Andric       Flags |= NodeAttrs::Undef;
13730946e70aSDimitry Andric     if (TOI.isFixedReg(In, OpN))
13740946e70aSDimitry Andric       Flags |= NodeAttrs::Fixed;
137506c3fb27SDimitry Andric     Use UA = newUse(SA, Op, Flags);
13760946e70aSDimitry Andric     SA.Addr->addMember(UA, *this);
13770946e70aSDimitry Andric   }
13780946e70aSDimitry Andric }
13790946e70aSDimitry Andric 
13800946e70aSDimitry Andric // Scan all defs in the block node BA and record in PhiM the locations of
13810946e70aSDimitry Andric // phi nodes corresponding to these defs.
138206c3fb27SDimitry Andric void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM, Block BA) {
13830946e70aSDimitry Andric   // Check all defs from block BA and record them in each block in BA's
13840946e70aSDimitry Andric   // iterated dominance frontier. This information will later be used to
13850946e70aSDimitry Andric   // create phi nodes.
13860946e70aSDimitry Andric   MachineBasicBlock *BB = BA.Addr->getCode();
13870946e70aSDimitry Andric   assert(BB);
13880946e70aSDimitry Andric   auto DFLoc = MDF.find(BB);
13890946e70aSDimitry Andric   if (DFLoc == MDF.end() || DFLoc->second.empty())
13900946e70aSDimitry Andric     return;
13910946e70aSDimitry Andric 
13920946e70aSDimitry Andric   // Traverse all instructions in the block and collect the set of all
13930946e70aSDimitry Andric   // defined references. For each reference there will be a phi created
13940946e70aSDimitry Andric   // in the block's iterated dominance frontier.
13950946e70aSDimitry Andric   // This is done to make sure that each defined reference gets only one
13960946e70aSDimitry Andric   // phi node, even if it is defined multiple times.
139706c3fb27SDimitry Andric   RegisterAggr Defs(getPRI());
139806c3fb27SDimitry Andric   for (Instr IA : BA.Addr->members(*this)) {
139906c3fb27SDimitry Andric     for (Ref RA : IA.Addr->members_if(IsDef, *this)) {
140006c3fb27SDimitry Andric       RegisterRef RR = RA.Addr->getRegRef(*this);
140106c3fb27SDimitry Andric       if (RR.isReg() && isTracked(RR))
140206c3fb27SDimitry Andric         Defs.insert(RR);
140306c3fb27SDimitry Andric     }
140406c3fb27SDimitry Andric   }
14050946e70aSDimitry Andric 
14060946e70aSDimitry Andric   // Calculate the iterated dominance frontier of BB.
14070946e70aSDimitry Andric   const MachineDominanceFrontier::DomSetType &DF = DFLoc->second;
14080946e70aSDimitry Andric   SetVector<MachineBasicBlock *> IDF(DF.begin(), DF.end());
14090946e70aSDimitry Andric   for (unsigned i = 0; i < IDF.size(); ++i) {
14100946e70aSDimitry Andric     auto F = MDF.find(IDF[i]);
14110946e70aSDimitry Andric     if (F != MDF.end())
14120946e70aSDimitry Andric       IDF.insert(F->second.begin(), F->second.end());
14130946e70aSDimitry Andric   }
14140946e70aSDimitry Andric 
14150946e70aSDimitry Andric   // Finally, add the set of defs to each block in the iterated dominance
14160946e70aSDimitry Andric   // frontier.
1417fcaf7f86SDimitry Andric   for (auto *DB : IDF) {
141806c3fb27SDimitry Andric     Block DBA = findBlock(DB);
141906c3fb27SDimitry Andric     PhiM[DBA.Id].insert(Defs);
14200946e70aSDimitry Andric   }
14210946e70aSDimitry Andric }
14220946e70aSDimitry Andric 
14230946e70aSDimitry Andric // Given the locations of phi nodes in the map PhiM, create the phi nodes
14240946e70aSDimitry Andric // that are located in the block node BA.
142506c3fb27SDimitry Andric void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, Block BA) {
14260946e70aSDimitry Andric   // Check if this blocks has any DF defs, i.e. if there are any defs
14270946e70aSDimitry Andric   // that this block is in the iterated dominance frontier of.
14280946e70aSDimitry Andric   auto HasDF = PhiM.find(BA.Id);
14290946e70aSDimitry Andric   if (HasDF == PhiM.end() || HasDF->second.empty())
14300946e70aSDimitry Andric     return;
14310946e70aSDimitry Andric 
14320946e70aSDimitry Andric   // Prepare a list of NodeIds of the block's predecessors.
14330946e70aSDimitry Andric   NodeList Preds;
14340946e70aSDimitry Andric   const MachineBasicBlock *MBB = BA.Addr->getCode();
14350946e70aSDimitry Andric   for (MachineBasicBlock *PB : MBB->predecessors())
14360946e70aSDimitry Andric     Preds.push_back(findBlock(PB));
14370946e70aSDimitry Andric 
143806c3fb27SDimitry Andric   const RegisterAggr &Defs = PhiM[BA.Id];
14390946e70aSDimitry Andric   uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
14400946e70aSDimitry Andric 
144106c3fb27SDimitry Andric   for (RegisterRef RR : Defs.refs()) {
144206c3fb27SDimitry Andric     Phi PA = newPhi(BA);
144306c3fb27SDimitry Andric     PA.Addr->addMember(newDef(PA, RR, PhiFlags), *this);
144406c3fb27SDimitry Andric 
144506c3fb27SDimitry Andric     // Add phi uses.
144606c3fb27SDimitry Andric     for (Block PBA : Preds) {
144706c3fb27SDimitry Andric       PA.Addr->addMember(newPhiUse(PA, RR, PBA), *this);
144806c3fb27SDimitry Andric     }
14490946e70aSDimitry Andric   }
14500946e70aSDimitry Andric }
14510946e70aSDimitry Andric 
14520946e70aSDimitry Andric // Remove any unneeded phi nodes that were created during the build process.
14530946e70aSDimitry Andric void DataFlowGraph::removeUnusedPhis() {
14540946e70aSDimitry Andric   // This will remove unused phis, i.e. phis where each def does not reach
14550946e70aSDimitry Andric   // any uses or other defs. This will not detect or remove circular phi
14560946e70aSDimitry Andric   // chains that are otherwise dead. Unused/dead phis are created during
14570946e70aSDimitry Andric   // the build process and this function is intended to remove these cases
14580946e70aSDimitry Andric   // that are easily determinable to be unnecessary.
14590946e70aSDimitry Andric 
14600946e70aSDimitry Andric   SetVector<NodeId> PhiQ;
146106c3fb27SDimitry Andric   for (Block BA : TheFunc.Addr->members(*this)) {
14620946e70aSDimitry Andric     for (auto P : BA.Addr->members_if(IsPhi, *this))
14630946e70aSDimitry Andric       PhiQ.insert(P.Id);
14640946e70aSDimitry Andric   }
14650946e70aSDimitry Andric 
14660946e70aSDimitry Andric   static auto HasUsedDef = [](NodeList &Ms) -> bool {
146706c3fb27SDimitry Andric     for (Node M : Ms) {
14680946e70aSDimitry Andric       if (M.Addr->getKind() != NodeAttrs::Def)
14690946e70aSDimitry Andric         continue;
147006c3fb27SDimitry Andric       Def DA = M;
14710946e70aSDimitry Andric       if (DA.Addr->getReachedDef() != 0 || DA.Addr->getReachedUse() != 0)
14720946e70aSDimitry Andric         return true;
14730946e70aSDimitry Andric     }
14740946e70aSDimitry Andric     return false;
14750946e70aSDimitry Andric   };
14760946e70aSDimitry Andric 
14770946e70aSDimitry Andric   // Any phi, if it is removed, may affect other phis (make them dead).
14780946e70aSDimitry Andric   // For each removed phi, collect the potentially affected phis and add
14790946e70aSDimitry Andric   // them back to the queue.
14800946e70aSDimitry Andric   while (!PhiQ.empty()) {
14810946e70aSDimitry Andric     auto PA = addr<PhiNode *>(PhiQ[0]);
14820946e70aSDimitry Andric     PhiQ.remove(PA.Id);
14830946e70aSDimitry Andric     NodeList Refs = PA.Addr->members(*this);
14840946e70aSDimitry Andric     if (HasUsedDef(Refs))
14850946e70aSDimitry Andric       continue;
148606c3fb27SDimitry Andric     for (Ref RA : Refs) {
14870946e70aSDimitry Andric       if (NodeId RD = RA.Addr->getReachingDef()) {
14880946e70aSDimitry Andric         auto RDA = addr<DefNode *>(RD);
148906c3fb27SDimitry Andric         Instr OA = RDA.Addr->getOwner(*this);
14900946e70aSDimitry Andric         if (IsPhi(OA))
14910946e70aSDimitry Andric           PhiQ.insert(OA.Id);
14920946e70aSDimitry Andric       }
14930946e70aSDimitry Andric       if (RA.Addr->isDef())
14940946e70aSDimitry Andric         unlinkDef(RA, true);
14950946e70aSDimitry Andric       else
14960946e70aSDimitry Andric         unlinkUse(RA, true);
14970946e70aSDimitry Andric     }
149806c3fb27SDimitry Andric     Block BA = PA.Addr->getOwner(*this);
14990946e70aSDimitry Andric     BA.Addr->removeMember(PA, *this);
15000946e70aSDimitry Andric   }
15010946e70aSDimitry Andric }
15020946e70aSDimitry Andric 
15030946e70aSDimitry Andric // For a given reference node TA in an instruction node IA, connect the
15040946e70aSDimitry Andric // reaching def of TA to the appropriate def node. Create any shadow nodes
15050946e70aSDimitry Andric // as appropriate.
15060946e70aSDimitry Andric template <typename T>
150706c3fb27SDimitry Andric void DataFlowGraph::linkRefUp(Instr IA, NodeAddr<T> TA, DefStack &DS) {
15080946e70aSDimitry Andric   if (DS.empty())
15090946e70aSDimitry Andric     return;
15100946e70aSDimitry Andric   RegisterRef RR = TA.Addr->getRegRef(*this);
15110946e70aSDimitry Andric   NodeAddr<T> TAP;
15120946e70aSDimitry Andric 
15130946e70aSDimitry Andric   // References from the def stack that have been examined so far.
151406c3fb27SDimitry Andric   RegisterAggr Defs(getPRI());
15150946e70aSDimitry Andric 
15160946e70aSDimitry Andric   for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
15170946e70aSDimitry Andric     RegisterRef QR = I->Addr->getRegRef(*this);
15180946e70aSDimitry Andric 
15190946e70aSDimitry Andric     // Skip all defs that are aliased to any of the defs that we have already
15200946e70aSDimitry Andric     // seen. If this completes a cover of RR, stop the stack traversal.
15210946e70aSDimitry Andric     bool Alias = Defs.hasAliasOf(QR);
15220946e70aSDimitry Andric     bool Cover = Defs.insert(QR).hasCoverOf(RR);
15230946e70aSDimitry Andric     if (Alias) {
15240946e70aSDimitry Andric       if (Cover)
15250946e70aSDimitry Andric         break;
15260946e70aSDimitry Andric       continue;
15270946e70aSDimitry Andric     }
15280946e70aSDimitry Andric 
15290946e70aSDimitry Andric     // The reaching def.
153006c3fb27SDimitry Andric     Def RDA = *I;
15310946e70aSDimitry Andric 
15320946e70aSDimitry Andric     // Pick the reached node.
15330946e70aSDimitry Andric     if (TAP.Id == 0) {
15340946e70aSDimitry Andric       TAP = TA;
15350946e70aSDimitry Andric     } else {
15360946e70aSDimitry Andric       // Mark the existing ref as "shadow" and create a new shadow.
15370946e70aSDimitry Andric       TAP.Addr->setFlags(TAP.Addr->getFlags() | NodeAttrs::Shadow);
15380946e70aSDimitry Andric       TAP = getNextShadow(IA, TAP, true);
15390946e70aSDimitry Andric     }
15400946e70aSDimitry Andric 
15410946e70aSDimitry Andric     // Create the link.
15420946e70aSDimitry Andric     TAP.Addr->linkToDef(TAP.Id, RDA);
15430946e70aSDimitry Andric 
15440946e70aSDimitry Andric     if (Cover)
15450946e70aSDimitry Andric       break;
15460946e70aSDimitry Andric   }
15470946e70aSDimitry Andric }
15480946e70aSDimitry Andric 
15490946e70aSDimitry Andric // Create data-flow links for all reference nodes in the statement node SA.
15500946e70aSDimitry Andric template <typename Predicate>
155106c3fb27SDimitry Andric void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, Stmt SA, Predicate P) {
15520946e70aSDimitry Andric #ifndef NDEBUG
155306c3fb27SDimitry Andric   RegisterSet Defs(getPRI());
15540946e70aSDimitry Andric #endif
15550946e70aSDimitry Andric 
15560946e70aSDimitry Andric   // Link all nodes (upwards in the data-flow) with their reaching defs.
155706c3fb27SDimitry Andric   for (Ref RA : SA.Addr->members_if(P, *this)) {
15580946e70aSDimitry Andric     uint16_t Kind = RA.Addr->getKind();
15590946e70aSDimitry Andric     assert(Kind == NodeAttrs::Def || Kind == NodeAttrs::Use);
15600946e70aSDimitry Andric     RegisterRef RR = RA.Addr->getRegRef(*this);
15610946e70aSDimitry Andric #ifndef NDEBUG
15620946e70aSDimitry Andric     // Do not expect multiple defs of the same reference.
15630946e70aSDimitry Andric     assert(Kind != NodeAttrs::Def || !Defs.count(RR));
15640946e70aSDimitry Andric     Defs.insert(RR);
15650946e70aSDimitry Andric #endif
15660946e70aSDimitry Andric 
15670946e70aSDimitry Andric     auto F = DefM.find(RR.Reg);
15680946e70aSDimitry Andric     if (F == DefM.end())
15690946e70aSDimitry Andric       continue;
15700946e70aSDimitry Andric     DefStack &DS = F->second;
15710946e70aSDimitry Andric     if (Kind == NodeAttrs::Use)
15720946e70aSDimitry Andric       linkRefUp<UseNode *>(SA, RA, DS);
15730946e70aSDimitry Andric     else if (Kind == NodeAttrs::Def)
15740946e70aSDimitry Andric       linkRefUp<DefNode *>(SA, RA, DS);
15750946e70aSDimitry Andric     else
15760946e70aSDimitry Andric       llvm_unreachable("Unexpected node in instruction");
15770946e70aSDimitry Andric   }
15780946e70aSDimitry Andric }
15790946e70aSDimitry Andric 
15800946e70aSDimitry Andric // Create data-flow links for all instructions in the block node BA. This
15810946e70aSDimitry Andric // will include updating any phi nodes in BA.
158206c3fb27SDimitry Andric void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, Block BA) {
15830946e70aSDimitry Andric   // Push block delimiters.
15840946e70aSDimitry Andric   markBlock(BA.Id, DefM);
15850946e70aSDimitry Andric 
158606c3fb27SDimitry Andric   auto IsClobber = [](Ref RA) -> bool {
15870946e70aSDimitry Andric     return IsDef(RA) && (RA.Addr->getFlags() & NodeAttrs::Clobbering);
15880946e70aSDimitry Andric   };
158906c3fb27SDimitry Andric   auto IsNoClobber = [](Ref RA) -> bool {
15900946e70aSDimitry Andric     return IsDef(RA) && !(RA.Addr->getFlags() & NodeAttrs::Clobbering);
15910946e70aSDimitry Andric   };
15920946e70aSDimitry Andric 
15930946e70aSDimitry Andric   assert(BA.Addr && "block node address is needed to create a data-flow link");
15940946e70aSDimitry Andric   // For each non-phi instruction in the block, link all the defs and uses
15950946e70aSDimitry Andric   // to their reaching defs. For any member of the block (including phis),
15960946e70aSDimitry Andric   // push the defs on the corresponding stacks.
159706c3fb27SDimitry Andric   for (Instr IA : BA.Addr->members(*this)) {
15980946e70aSDimitry Andric     // Ignore phi nodes here. They will be linked part by part from the
15990946e70aSDimitry Andric     // predecessors.
16000946e70aSDimitry Andric     if (IA.Addr->getKind() == NodeAttrs::Stmt) {
16010946e70aSDimitry Andric       linkStmtRefs(DefM, IA, IsUse);
16020946e70aSDimitry Andric       linkStmtRefs(DefM, IA, IsClobber);
16030946e70aSDimitry Andric     }
16040946e70aSDimitry Andric 
16050946e70aSDimitry Andric     // Push the definitions on the stack.
16060946e70aSDimitry Andric     pushClobbers(IA, DefM);
16070946e70aSDimitry Andric 
16080946e70aSDimitry Andric     if (IA.Addr->getKind() == NodeAttrs::Stmt)
16090946e70aSDimitry Andric       linkStmtRefs(DefM, IA, IsNoClobber);
16100946e70aSDimitry Andric 
16110946e70aSDimitry Andric     pushDefs(IA, DefM);
16120946e70aSDimitry Andric   }
16130946e70aSDimitry Andric 
16140946e70aSDimitry Andric   // Recursively process all children in the dominator tree.
16150946e70aSDimitry Andric   MachineDomTreeNode *N = MDT.getNode(BA.Addr->getCode());
1616fcaf7f86SDimitry Andric   for (auto *I : *N) {
16170946e70aSDimitry Andric     MachineBasicBlock *SB = I->getBlock();
161806c3fb27SDimitry Andric     Block SBA = findBlock(SB);
16190946e70aSDimitry Andric     linkBlockRefs(DefM, SBA);
16200946e70aSDimitry Andric   }
16210946e70aSDimitry Andric 
16220946e70aSDimitry Andric   // Link the phi uses from the successor blocks.
162306c3fb27SDimitry Andric   auto IsUseForBA = [BA](Node NA) -> bool {
16240946e70aSDimitry Andric     if (NA.Addr->getKind() != NodeAttrs::Use)
16250946e70aSDimitry Andric       return false;
16260946e70aSDimitry Andric     assert(NA.Addr->getFlags() & NodeAttrs::PhiRef);
162706c3fb27SDimitry Andric     return PhiUse(NA).Addr->getPredecessor() == BA.Id;
16280946e70aSDimitry Andric   };
16290946e70aSDimitry Andric 
163006c3fb27SDimitry Andric   RegisterAggr EHLiveIns = getLandingPadLiveIns();
16310946e70aSDimitry Andric   MachineBasicBlock *MBB = BA.Addr->getCode();
16320946e70aSDimitry Andric 
16330946e70aSDimitry Andric   for (MachineBasicBlock *SB : MBB->successors()) {
16340946e70aSDimitry Andric     bool IsEHPad = SB->isEHPad();
163506c3fb27SDimitry Andric     Block SBA = findBlock(SB);
163606c3fb27SDimitry Andric     for (Instr IA : SBA.Addr->members_if(IsPhi, *this)) {
16370946e70aSDimitry Andric       // Do not link phi uses for landing pad live-ins.
16380946e70aSDimitry Andric       if (IsEHPad) {
16390946e70aSDimitry Andric         // Find what register this phi is for.
164006c3fb27SDimitry Andric         Ref RA = IA.Addr->getFirstMember(*this);
16410946e70aSDimitry Andric         assert(RA.Id != 0);
164206c3fb27SDimitry Andric         if (EHLiveIns.hasCoverOf(RA.Addr->getRegRef(*this)))
16430946e70aSDimitry Andric           continue;
16440946e70aSDimitry Andric       }
16450946e70aSDimitry Andric       // Go over each phi use associated with MBB, and link it.
16460946e70aSDimitry Andric       for (auto U : IA.Addr->members_if(IsUseForBA, *this)) {
164706c3fb27SDimitry Andric         PhiUse PUA = U;
16480946e70aSDimitry Andric         RegisterRef RR = PUA.Addr->getRegRef(*this);
16490946e70aSDimitry Andric         linkRefUp<UseNode *>(IA, PUA, DefM[RR.Reg]);
16500946e70aSDimitry Andric       }
16510946e70aSDimitry Andric     }
16520946e70aSDimitry Andric   }
16530946e70aSDimitry Andric 
16540946e70aSDimitry Andric   // Pop all defs from this block from the definition stacks.
16550946e70aSDimitry Andric   releaseBlock(BA.Id, DefM);
16560946e70aSDimitry Andric }
16570946e70aSDimitry Andric 
16580946e70aSDimitry Andric // Remove the use node UA from any data-flow and structural links.
165906c3fb27SDimitry Andric void DataFlowGraph::unlinkUseDF(Use UA) {
16600946e70aSDimitry Andric   NodeId RD = UA.Addr->getReachingDef();
16610946e70aSDimitry Andric   NodeId Sib = UA.Addr->getSibling();
16620946e70aSDimitry Andric 
16630946e70aSDimitry Andric   if (RD == 0) {
16640946e70aSDimitry Andric     assert(Sib == 0);
16650946e70aSDimitry Andric     return;
16660946e70aSDimitry Andric   }
16670946e70aSDimitry Andric 
16680946e70aSDimitry Andric   auto RDA = addr<DefNode *>(RD);
16690946e70aSDimitry Andric   auto TA = addr<UseNode *>(RDA.Addr->getReachedUse());
16700946e70aSDimitry Andric   if (TA.Id == UA.Id) {
16710946e70aSDimitry Andric     RDA.Addr->setReachedUse(Sib);
16720946e70aSDimitry Andric     return;
16730946e70aSDimitry Andric   }
16740946e70aSDimitry Andric 
16750946e70aSDimitry Andric   while (TA.Id != 0) {
16760946e70aSDimitry Andric     NodeId S = TA.Addr->getSibling();
16770946e70aSDimitry Andric     if (S == UA.Id) {
16780946e70aSDimitry Andric       TA.Addr->setSibling(UA.Addr->getSibling());
16790946e70aSDimitry Andric       return;
16800946e70aSDimitry Andric     }
16810946e70aSDimitry Andric     TA = addr<UseNode *>(S);
16820946e70aSDimitry Andric   }
16830946e70aSDimitry Andric }
16840946e70aSDimitry Andric 
16850946e70aSDimitry Andric // Remove the def node DA from any data-flow and structural links.
168606c3fb27SDimitry Andric void DataFlowGraph::unlinkDefDF(Def DA) {
16870946e70aSDimitry Andric   //
16880946e70aSDimitry Andric   //         RD
16890946e70aSDimitry Andric   //         | reached
16900946e70aSDimitry Andric   //         | def
16910946e70aSDimitry Andric   //         :
16920946e70aSDimitry Andric   //         .
16930946e70aSDimitry Andric   //        +----+
16940946e70aSDimitry Andric   // ... -- | DA | -- ... -- 0  : sibling chain of DA
16950946e70aSDimitry Andric   //        +----+
16960946e70aSDimitry Andric   //         |  | reached
16970946e70aSDimitry Andric   //         |  : def
16980946e70aSDimitry Andric   //         |  .
16990946e70aSDimitry Andric   //         | ...  : Siblings (defs)
17000946e70aSDimitry Andric   //         |
17010946e70aSDimitry Andric   //         : reached
17020946e70aSDimitry Andric   //         . use
17030946e70aSDimitry Andric   //        ... : sibling chain of reached uses
17040946e70aSDimitry Andric 
17050946e70aSDimitry Andric   NodeId RD = DA.Addr->getReachingDef();
17060946e70aSDimitry Andric 
17070946e70aSDimitry Andric   // Visit all siblings of the reached def and reset their reaching defs.
17080946e70aSDimitry Andric   // Also, defs reached by DA are now "promoted" to being reached by RD,
17090946e70aSDimitry Andric   // so all of them will need to be spliced into the sibling chain where
17100946e70aSDimitry Andric   // DA belongs.
17110946e70aSDimitry Andric   auto getAllNodes = [this](NodeId N) -> NodeList {
17120946e70aSDimitry Andric     NodeList Res;
17130946e70aSDimitry Andric     while (N) {
17140946e70aSDimitry Andric       auto RA = addr<RefNode *>(N);
17150946e70aSDimitry Andric       // Keep the nodes in the exact sibling order.
17160946e70aSDimitry Andric       Res.push_back(RA);
17170946e70aSDimitry Andric       N = RA.Addr->getSibling();
17180946e70aSDimitry Andric     }
17190946e70aSDimitry Andric     return Res;
17200946e70aSDimitry Andric   };
17210946e70aSDimitry Andric   NodeList ReachedDefs = getAllNodes(DA.Addr->getReachedDef());
17220946e70aSDimitry Andric   NodeList ReachedUses = getAllNodes(DA.Addr->getReachedUse());
17230946e70aSDimitry Andric 
17240946e70aSDimitry Andric   if (RD == 0) {
172506c3fb27SDimitry Andric     for (Ref I : ReachedDefs)
17260946e70aSDimitry Andric       I.Addr->setSibling(0);
172706c3fb27SDimitry Andric     for (Ref I : ReachedUses)
17280946e70aSDimitry Andric       I.Addr->setSibling(0);
17290946e70aSDimitry Andric   }
173006c3fb27SDimitry Andric   for (Def I : ReachedDefs)
17310946e70aSDimitry Andric     I.Addr->setReachingDef(RD);
173206c3fb27SDimitry Andric   for (Use I : ReachedUses)
17330946e70aSDimitry Andric     I.Addr->setReachingDef(RD);
17340946e70aSDimitry Andric 
17350946e70aSDimitry Andric   NodeId Sib = DA.Addr->getSibling();
17360946e70aSDimitry Andric   if (RD == 0) {
17370946e70aSDimitry Andric     assert(Sib == 0);
17380946e70aSDimitry Andric     return;
17390946e70aSDimitry Andric   }
17400946e70aSDimitry Andric 
17410946e70aSDimitry Andric   // Update the reaching def node and remove DA from the sibling list.
17420946e70aSDimitry Andric   auto RDA = addr<DefNode *>(RD);
17430946e70aSDimitry Andric   auto TA = addr<DefNode *>(RDA.Addr->getReachedDef());
17440946e70aSDimitry Andric   if (TA.Id == DA.Id) {
17450946e70aSDimitry Andric     // If DA is the first reached def, just update the RD's reached def
17460946e70aSDimitry Andric     // to the DA's sibling.
17470946e70aSDimitry Andric     RDA.Addr->setReachedDef(Sib);
17480946e70aSDimitry Andric   } else {
17490946e70aSDimitry Andric     // Otherwise, traverse the sibling list of the reached defs and remove
17500946e70aSDimitry Andric     // DA from it.
17510946e70aSDimitry Andric     while (TA.Id != 0) {
17520946e70aSDimitry Andric       NodeId S = TA.Addr->getSibling();
17530946e70aSDimitry Andric       if (S == DA.Id) {
17540946e70aSDimitry Andric         TA.Addr->setSibling(Sib);
17550946e70aSDimitry Andric         break;
17560946e70aSDimitry Andric       }
17570946e70aSDimitry Andric       TA = addr<DefNode *>(S);
17580946e70aSDimitry Andric     }
17590946e70aSDimitry Andric   }
17600946e70aSDimitry Andric 
17610946e70aSDimitry Andric   // Splice the DA's reached defs into the RDA's reached def chain.
17620946e70aSDimitry Andric   if (!ReachedDefs.empty()) {
176306c3fb27SDimitry Andric     auto Last = Def(ReachedDefs.back());
17640946e70aSDimitry Andric     Last.Addr->setSibling(RDA.Addr->getReachedDef());
17650946e70aSDimitry Andric     RDA.Addr->setReachedDef(ReachedDefs.front().Id);
17660946e70aSDimitry Andric   }
17670946e70aSDimitry Andric   // Splice the DA's reached uses into the RDA's reached use chain.
17680946e70aSDimitry Andric   if (!ReachedUses.empty()) {
176906c3fb27SDimitry Andric     auto Last = Use(ReachedUses.back());
17700946e70aSDimitry Andric     Last.Addr->setSibling(RDA.Addr->getReachedUse());
17710946e70aSDimitry Andric     RDA.Addr->setReachedUse(ReachedUses.front().Id);
17720946e70aSDimitry Andric   }
17730946e70aSDimitry Andric }
177406c3fb27SDimitry Andric 
177506c3fb27SDimitry Andric bool DataFlowGraph::isTracked(RegisterRef RR) const {
177606c3fb27SDimitry Andric   return !disjoint(getPRI().getUnits(RR), TrackedUnits);
177706c3fb27SDimitry Andric }
177806c3fb27SDimitry Andric 
177906c3fb27SDimitry Andric bool DataFlowGraph::hasUntrackedRef(Stmt S, bool IgnoreReserved) const {
178006c3fb27SDimitry Andric   SmallVector<MachineOperand *> Ops;
178106c3fb27SDimitry Andric 
178206c3fb27SDimitry Andric   for (Ref R : S.Addr->members(*this)) {
178306c3fb27SDimitry Andric     Ops.push_back(&R.Addr->getOp());
178406c3fb27SDimitry Andric     RegisterRef RR = R.Addr->getRegRef(*this);
178506c3fb27SDimitry Andric     if (IgnoreReserved && RR.isReg() && ReservedRegs[RR.idx()])
178606c3fb27SDimitry Andric       continue;
178706c3fb27SDimitry Andric     if (!isTracked(RR))
178806c3fb27SDimitry Andric       return true;
178906c3fb27SDimitry Andric   }
179006c3fb27SDimitry Andric   for (const MachineOperand &Op : S.Addr->getCode()->operands()) {
179106c3fb27SDimitry Andric     if (!Op.isReg() && !Op.isRegMask())
179206c3fb27SDimitry Andric       continue;
17937a6dacacSDimitry Andric     if (!llvm::is_contained(Ops, &Op))
179406c3fb27SDimitry Andric       return true;
179506c3fb27SDimitry Andric   }
179606c3fb27SDimitry Andric   return false;
179706c3fb27SDimitry Andric }
179806c3fb27SDimitry Andric 
179906c3fb27SDimitry Andric } // end namespace llvm::rdf
1800