xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RDFGraph.cpp (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
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 //
1181ad6265SDimitry Andric #include "llvm/CodeGen/RDFGraph.h"
120946e70aSDimitry Andric #include "llvm/ADT/BitVector.h"
130946e70aSDimitry Andric #include "llvm/ADT/STLExtras.h"
140946e70aSDimitry Andric #include "llvm/ADT/SetVector.h"
150946e70aSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
160946e70aSDimitry Andric #include "llvm/CodeGen/MachineDominanceFrontier.h"
170946e70aSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
180946e70aSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
190946e70aSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
200946e70aSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
210946e70aSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.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 using namespace llvm;
420946e70aSDimitry Andric using namespace rdf;
430946e70aSDimitry Andric 
440946e70aSDimitry Andric // Printing functions. Have them here first, so that the rest of the code
450946e70aSDimitry Andric // can use them.
460946e70aSDimitry Andric namespace llvm {
470946e70aSDimitry Andric namespace rdf {
480946e70aSDimitry Andric 
490946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P) {
500946e70aSDimitry Andric   if (!P.Mask.all())
510946e70aSDimitry Andric     OS << ':' << PrintLaneMask(P.Mask);
520946e70aSDimitry Andric   return OS;
530946e70aSDimitry Andric }
540946e70aSDimitry Andric 
550946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterRef> &P) {
560946e70aSDimitry Andric   auto &TRI = P.G.getTRI();
570946e70aSDimitry Andric   if (P.Obj.Reg > 0 && P.Obj.Reg < TRI.getNumRegs())
580946e70aSDimitry Andric     OS << TRI.getName(P.Obj.Reg);
590946e70aSDimitry Andric   else
600946e70aSDimitry Andric     OS << '#' << P.Obj.Reg;
610946e70aSDimitry Andric   OS << PrintLaneMaskOpt(P.Obj.Mask);
620946e70aSDimitry Andric   return OS;
630946e70aSDimitry Andric }
640946e70aSDimitry Andric 
650946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeId> &P) {
660946e70aSDimitry Andric   auto NA = P.G.addr<NodeBase*>(P.Obj);
670946e70aSDimitry Andric   uint16_t Attrs = NA.Addr->getAttrs();
680946e70aSDimitry Andric   uint16_t Kind = NodeAttrs::kind(Attrs);
690946e70aSDimitry Andric   uint16_t Flags = NodeAttrs::flags(Attrs);
700946e70aSDimitry Andric   switch (NodeAttrs::type(Attrs)) {
710946e70aSDimitry Andric     case NodeAttrs::Code:
720946e70aSDimitry Andric       switch (Kind) {
730946e70aSDimitry Andric         case NodeAttrs::Func:   OS << 'f'; break;
740946e70aSDimitry Andric         case NodeAttrs::Block:  OS << 'b'; break;
750946e70aSDimitry Andric         case NodeAttrs::Stmt:   OS << 's'; break;
760946e70aSDimitry Andric         case NodeAttrs::Phi:    OS << 'p'; break;
770946e70aSDimitry Andric         default:                OS << "c?"; break;
780946e70aSDimitry Andric       }
790946e70aSDimitry Andric       break;
800946e70aSDimitry Andric     case NodeAttrs::Ref:
810946e70aSDimitry Andric       if (Flags & NodeAttrs::Undef)
820946e70aSDimitry Andric         OS << '/';
830946e70aSDimitry Andric       if (Flags & NodeAttrs::Dead)
840946e70aSDimitry Andric         OS << '\\';
850946e70aSDimitry Andric       if (Flags & NodeAttrs::Preserving)
860946e70aSDimitry Andric         OS << '+';
870946e70aSDimitry Andric       if (Flags & NodeAttrs::Clobbering)
880946e70aSDimitry Andric         OS << '~';
890946e70aSDimitry Andric       switch (Kind) {
900946e70aSDimitry Andric         case NodeAttrs::Use:    OS << 'u'; break;
910946e70aSDimitry Andric         case NodeAttrs::Def:    OS << 'd'; break;
920946e70aSDimitry Andric         case NodeAttrs::Block:  OS << 'b'; break;
930946e70aSDimitry Andric         default:                OS << "r?"; break;
940946e70aSDimitry Andric       }
950946e70aSDimitry Andric       break;
960946e70aSDimitry Andric     default:
970946e70aSDimitry Andric       OS << '?';
980946e70aSDimitry Andric       break;
990946e70aSDimitry Andric   }
1000946e70aSDimitry Andric   OS << P.Obj;
1010946e70aSDimitry Andric   if (Flags & NodeAttrs::Shadow)
1020946e70aSDimitry Andric     OS << '"';
1030946e70aSDimitry Andric   return OS;
1040946e70aSDimitry Andric }
1050946e70aSDimitry Andric 
1060946e70aSDimitry Andric static void printRefHeader(raw_ostream &OS, const NodeAddr<RefNode*> RA,
1070946e70aSDimitry Andric                 const DataFlowGraph &G) {
1080946e70aSDimitry Andric   OS << Print<NodeId>(RA.Id, G) << '<'
1090946e70aSDimitry Andric      << Print<RegisterRef>(RA.Addr->getRegRef(G), G) << '>';
1100946e70aSDimitry Andric   if (RA.Addr->getFlags() & NodeAttrs::Fixed)
1110946e70aSDimitry Andric     OS << '!';
1120946e70aSDimitry Andric }
1130946e70aSDimitry Andric 
1140946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<DefNode*>> &P) {
1150946e70aSDimitry Andric   printRefHeader(OS, P.Obj, P.G);
1160946e70aSDimitry Andric   OS << '(';
1170946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachingDef())
1180946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1190946e70aSDimitry Andric   OS << ',';
1200946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachedDef())
1210946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1220946e70aSDimitry Andric   OS << ',';
1230946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachedUse())
1240946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1250946e70aSDimitry Andric   OS << "):";
1260946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getSibling())
1270946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1280946e70aSDimitry Andric   return OS;
1290946e70aSDimitry Andric }
1300946e70aSDimitry Andric 
1310946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<UseNode*>> &P) {
1320946e70aSDimitry Andric   printRefHeader(OS, P.Obj, P.G);
1330946e70aSDimitry Andric   OS << '(';
1340946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachingDef())
1350946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1360946e70aSDimitry Andric   OS << "):";
1370946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getSibling())
1380946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1390946e70aSDimitry Andric   return OS;
1400946e70aSDimitry Andric }
1410946e70aSDimitry Andric 
1420946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS,
1430946e70aSDimitry Andric       const Print<NodeAddr<PhiUseNode*>> &P) {
1440946e70aSDimitry Andric   printRefHeader(OS, P.Obj, P.G);
1450946e70aSDimitry Andric   OS << '(';
1460946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getReachingDef())
1470946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1480946e70aSDimitry Andric   OS << ',';
1490946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getPredecessor())
1500946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1510946e70aSDimitry Andric   OS << "):";
1520946e70aSDimitry Andric   if (NodeId N = P.Obj.Addr->getSibling())
1530946e70aSDimitry Andric     OS << Print<NodeId>(N, P.G);
1540946e70aSDimitry Andric   return OS;
1550946e70aSDimitry Andric }
1560946e70aSDimitry Andric 
1570946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<RefNode*>> &P) {
1580946e70aSDimitry Andric   switch (P.Obj.Addr->getKind()) {
1590946e70aSDimitry Andric     case NodeAttrs::Def:
1600946e70aSDimitry Andric       OS << PrintNode<DefNode*>(P.Obj, P.G);
1610946e70aSDimitry Andric       break;
1620946e70aSDimitry Andric     case NodeAttrs::Use:
1630946e70aSDimitry Andric       if (P.Obj.Addr->getFlags() & NodeAttrs::PhiRef)
1640946e70aSDimitry Andric         OS << PrintNode<PhiUseNode*>(P.Obj, P.G);
1650946e70aSDimitry Andric       else
1660946e70aSDimitry Andric         OS << PrintNode<UseNode*>(P.Obj, P.G);
1670946e70aSDimitry Andric       break;
1680946e70aSDimitry Andric   }
1690946e70aSDimitry Andric   return OS;
1700946e70aSDimitry Andric }
1710946e70aSDimitry Andric 
1720946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeList> &P) {
1730946e70aSDimitry Andric   unsigned N = P.Obj.size();
1740946e70aSDimitry Andric   for (auto I : P.Obj) {
1750946e70aSDimitry Andric     OS << Print<NodeId>(I.Id, P.G);
1760946e70aSDimitry Andric     if (--N)
1770946e70aSDimitry Andric       OS << ' ';
1780946e70aSDimitry Andric   }
1790946e70aSDimitry Andric   return OS;
1800946e70aSDimitry Andric }
1810946e70aSDimitry Andric 
1820946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeSet> &P) {
1830946e70aSDimitry Andric   unsigned N = P.Obj.size();
1840946e70aSDimitry Andric   for (auto I : P.Obj) {
1850946e70aSDimitry Andric     OS << Print<NodeId>(I, P.G);
1860946e70aSDimitry Andric     if (--N)
1870946e70aSDimitry Andric       OS << ' ';
1880946e70aSDimitry Andric   }
1890946e70aSDimitry Andric   return OS;
1900946e70aSDimitry Andric }
1910946e70aSDimitry Andric 
1920946e70aSDimitry Andric namespace {
1930946e70aSDimitry Andric 
1940946e70aSDimitry Andric   template <typename T>
1950946e70aSDimitry Andric   struct PrintListV {
1960946e70aSDimitry Andric     PrintListV(const NodeList &L, const DataFlowGraph &G) : List(L), G(G) {}
1970946e70aSDimitry Andric 
1980946e70aSDimitry Andric     using Type = T;
1990946e70aSDimitry Andric     const NodeList &List;
2000946e70aSDimitry Andric     const DataFlowGraph &G;
2010946e70aSDimitry Andric   };
2020946e70aSDimitry Andric 
2030946e70aSDimitry Andric   template <typename T>
2040946e70aSDimitry Andric   raw_ostream &operator<< (raw_ostream &OS, const PrintListV<T> &P) {
2050946e70aSDimitry Andric     unsigned N = P.List.size();
2060946e70aSDimitry Andric     for (NodeAddr<T> A : P.List) {
2070946e70aSDimitry Andric       OS << PrintNode<T>(A, P.G);
2080946e70aSDimitry Andric       if (--N)
2090946e70aSDimitry Andric         OS << ", ";
2100946e70aSDimitry Andric     }
2110946e70aSDimitry Andric     return OS;
2120946e70aSDimitry Andric   }
2130946e70aSDimitry Andric 
2140946e70aSDimitry Andric } // end anonymous namespace
2150946e70aSDimitry Andric 
2160946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<PhiNode*>> &P) {
2170946e70aSDimitry Andric   OS << Print<NodeId>(P.Obj.Id, P.G) << ": phi ["
2180946e70aSDimitry Andric      << PrintListV<RefNode*>(P.Obj.Addr->members(P.G), P.G) << ']';
2190946e70aSDimitry Andric   return OS;
2200946e70aSDimitry Andric }
2210946e70aSDimitry Andric 
2220946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<StmtNode *>> &P) {
2230946e70aSDimitry Andric   const MachineInstr &MI = *P.Obj.Addr->getCode();
2240946e70aSDimitry Andric   unsigned Opc = MI.getOpcode();
2250946e70aSDimitry Andric   OS << Print<NodeId>(P.Obj.Id, P.G) << ": " << P.G.getTII().getName(Opc);
2260946e70aSDimitry Andric   // Print the target for calls and branches (for readability).
2270946e70aSDimitry Andric   if (MI.isCall() || MI.isBranch()) {
2280946e70aSDimitry Andric     MachineInstr::const_mop_iterator T =
2290946e70aSDimitry Andric           llvm::find_if(MI.operands(),
2300946e70aSDimitry Andric                         [] (const MachineOperand &Op) -> bool {
2310946e70aSDimitry Andric                           return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
2320946e70aSDimitry Andric                         });
2330946e70aSDimitry Andric     if (T != MI.operands_end()) {
2340946e70aSDimitry Andric       OS << ' ';
2350946e70aSDimitry Andric       if (T->isMBB())
2360946e70aSDimitry Andric         OS << printMBBReference(*T->getMBB());
2370946e70aSDimitry Andric       else if (T->isGlobal())
2380946e70aSDimitry Andric         OS << T->getGlobal()->getName();
2390946e70aSDimitry Andric       else if (T->isSymbol())
2400946e70aSDimitry Andric         OS << T->getSymbolName();
2410946e70aSDimitry Andric     }
2420946e70aSDimitry Andric   }
2430946e70aSDimitry Andric   OS << " [" << PrintListV<RefNode*>(P.Obj.Addr->members(P.G), P.G) << ']';
2440946e70aSDimitry Andric   return OS;
2450946e70aSDimitry Andric }
2460946e70aSDimitry Andric 
2470946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS,
2480946e70aSDimitry Andric       const Print<NodeAddr<InstrNode*>> &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:
2570946e70aSDimitry Andric       OS << "instr? " << Print<NodeId>(P.Obj.Id, P.G);
2580946e70aSDimitry Andric       break;
2590946e70aSDimitry Andric   }
2600946e70aSDimitry Andric   return OS;
2610946e70aSDimitry Andric }
2620946e70aSDimitry Andric 
2630946e70aSDimitry Andric raw_ostream &operator<< (raw_ostream &OS,
2640946e70aSDimitry Andric       const Print<NodeAddr<BlockNode*>> &P) {
2650946e70aSDimitry Andric   MachineBasicBlock *BB = P.Obj.Addr->getCode();
2660946e70aSDimitry Andric   unsigned NP = BB->pred_size();
2670946e70aSDimitry Andric   std::vector<int> Ns;
2680946e70aSDimitry Andric   auto PrintBBs = [&OS] (std::vector<int> Ns) -> void {
2690946e70aSDimitry Andric     unsigned N = Ns.size();
2700946e70aSDimitry Andric     for (int I : Ns) {
2710946e70aSDimitry Andric       OS << "%bb." << I;
2720946e70aSDimitry Andric       if (--N)
2730946e70aSDimitry Andric         OS << ", ";
2740946e70aSDimitry Andric     }
2750946e70aSDimitry Andric   };
2760946e70aSDimitry Andric 
2770946e70aSDimitry Andric   OS << Print<NodeId>(P.Obj.Id, P.G) << ": --- " << printMBBReference(*BB)
2780946e70aSDimitry Andric      << " --- preds(" << NP << "): ";
2790946e70aSDimitry Andric   for (MachineBasicBlock *B : BB->predecessors())
2800946e70aSDimitry Andric     Ns.push_back(B->getNumber());
2810946e70aSDimitry Andric   PrintBBs(Ns);
2820946e70aSDimitry Andric 
2830946e70aSDimitry Andric   unsigned NS = BB->succ_size();
2840946e70aSDimitry Andric   OS << "  succs(" << NS << "): ";
2850946e70aSDimitry Andric   Ns.clear();
2860946e70aSDimitry Andric   for (MachineBasicBlock *B : BB->successors())
2870946e70aSDimitry Andric     Ns.push_back(B->getNumber());
2880946e70aSDimitry Andric   PrintBBs(Ns);
2890946e70aSDimitry Andric   OS << '\n';
2900946e70aSDimitry Andric 
2910946e70aSDimitry Andric   for (auto I : P.Obj.Addr->members(P.G))
2920946e70aSDimitry Andric     OS << PrintNode<InstrNode*>(I, P.G) << '\n';
2930946e70aSDimitry Andric   return OS;
2940946e70aSDimitry Andric }
2950946e70aSDimitry Andric 
2960946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<FuncNode *>> &P) {
2970946e70aSDimitry Andric   OS << "DFG dump:[\n" << Print<NodeId>(P.Obj.Id, P.G) << ": Function: "
2980946e70aSDimitry Andric      << 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)
3080946e70aSDimitry Andric     OS << ' ' << Print<RegisterRef>(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) {
3140946e70aSDimitry Andric   P.Obj.print(OS);
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; ) {
3210946e70aSDimitry Andric     OS << Print<NodeId>(I->Id, P.G)
3220946e70aSDimitry Andric        << '<' << Print<RegisterRef>(I->Addr->getRegRef(P.G), P.G) << '>';
3230946e70aSDimitry Andric     I.down();
3240946e70aSDimitry Andric     if (I != E)
3250946e70aSDimitry Andric       OS << ' ';
3260946e70aSDimitry Andric   }
3270946e70aSDimitry Andric   return OS;
3280946e70aSDimitry Andric }
3290946e70aSDimitry Andric 
3300946e70aSDimitry Andric } // end namespace rdf
3310946e70aSDimitry Andric } // end namespace llvm
3320946e70aSDimitry Andric 
3330946e70aSDimitry Andric // Node allocation functions.
3340946e70aSDimitry Andric //
3350946e70aSDimitry Andric // Node allocator is like a slab memory allocator: it allocates blocks of
3360946e70aSDimitry Andric // memory in sizes that are multiples of the size of a node. Each block has
3370946e70aSDimitry Andric // the same size. Nodes are allocated from the currently active block, and
3380946e70aSDimitry Andric // when it becomes full, a new one is created.
3390946e70aSDimitry Andric // There is a mapping scheme between node id and its location in a block,
3400946e70aSDimitry Andric // and within that block is described in the header file.
3410946e70aSDimitry Andric //
3420946e70aSDimitry Andric void NodeAllocator::startNewBlock() {
3430946e70aSDimitry Andric   void *T = MemPool.Allocate(NodesPerBlock*NodeMemSize, NodeMemSize);
3440946e70aSDimitry Andric   char *P = static_cast<char*>(T);
3450946e70aSDimitry Andric   Blocks.push_back(P);
3460946e70aSDimitry Andric   // Check if the block index is still within the allowed range, i.e. less
3470946e70aSDimitry Andric   // than 2^N, where N is the number of bits in NodeId for the block index.
3480946e70aSDimitry Andric   // BitsPerIndex is the number of bits per node index.
3490946e70aSDimitry Andric   assert((Blocks.size() < ((size_t)1 << (8*sizeof(NodeId)-BitsPerIndex))) &&
3500946e70aSDimitry Andric          "Out of bits for block index");
3510946e70aSDimitry Andric   ActiveEnd = P;
3520946e70aSDimitry Andric }
3530946e70aSDimitry Andric 
3540946e70aSDimitry Andric bool NodeAllocator::needNewBlock() {
3550946e70aSDimitry Andric   if (Blocks.empty())
3560946e70aSDimitry Andric     return true;
3570946e70aSDimitry Andric 
3580946e70aSDimitry Andric   char *ActiveBegin = Blocks.back();
3590946e70aSDimitry Andric   uint32_t Index = (ActiveEnd-ActiveBegin)/NodeMemSize;
3600946e70aSDimitry Andric   return Index >= NodesPerBlock;
3610946e70aSDimitry Andric }
3620946e70aSDimitry Andric 
3630946e70aSDimitry Andric NodeAddr<NodeBase*> NodeAllocator::New() {
3640946e70aSDimitry Andric   if (needNewBlock())
3650946e70aSDimitry Andric     startNewBlock();
3660946e70aSDimitry Andric 
3670946e70aSDimitry Andric   uint32_t ActiveB = Blocks.size()-1;
3680946e70aSDimitry Andric   uint32_t Index = (ActiveEnd - Blocks[ActiveB])/NodeMemSize;
3690946e70aSDimitry Andric   NodeAddr<NodeBase*> NA = { reinterpret_cast<NodeBase*>(ActiveEnd),
3700946e70aSDimitry Andric                              makeId(ActiveB, Index) };
3710946e70aSDimitry Andric   ActiveEnd += NodeMemSize;
3720946e70aSDimitry Andric   return NA;
3730946e70aSDimitry Andric }
3740946e70aSDimitry Andric 
3750946e70aSDimitry Andric NodeId NodeAllocator::id(const NodeBase *P) const {
3760946e70aSDimitry Andric   uintptr_t A = reinterpret_cast<uintptr_t>(P);
3770946e70aSDimitry Andric   for (unsigned i = 0, n = Blocks.size(); i != n; ++i) {
3780946e70aSDimitry Andric     uintptr_t B = reinterpret_cast<uintptr_t>(Blocks[i]);
3790946e70aSDimitry Andric     if (A < B || A >= B + NodesPerBlock*NodeMemSize)
3800946e70aSDimitry Andric       continue;
3810946e70aSDimitry Andric     uint32_t Idx = (A-B)/NodeMemSize;
3820946e70aSDimitry Andric     return makeId(i, Idx);
3830946e70aSDimitry Andric   }
3840946e70aSDimitry Andric   llvm_unreachable("Invalid node address");
3850946e70aSDimitry Andric }
3860946e70aSDimitry Andric 
3870946e70aSDimitry Andric void NodeAllocator::clear() {
3880946e70aSDimitry Andric   MemPool.Reset();
3890946e70aSDimitry Andric   Blocks.clear();
3900946e70aSDimitry Andric   ActiveEnd = nullptr;
3910946e70aSDimitry Andric }
3920946e70aSDimitry Andric 
3930946e70aSDimitry Andric // Insert node NA after "this" in the circular chain.
3940946e70aSDimitry Andric void NodeBase::append(NodeAddr<NodeBase*> NA) {
3950946e70aSDimitry Andric   NodeId Nx = Next;
3960946e70aSDimitry Andric   // If NA is already "next", do nothing.
3970946e70aSDimitry Andric   if (Next != NA.Id) {
3980946e70aSDimitry Andric     Next = NA.Id;
3990946e70aSDimitry Andric     NA.Addr->Next = Nx;
4000946e70aSDimitry Andric   }
4010946e70aSDimitry Andric }
4020946e70aSDimitry Andric 
4030946e70aSDimitry Andric // Fundamental node manipulator functions.
4040946e70aSDimitry Andric 
4050946e70aSDimitry Andric // Obtain the register reference from a reference node.
4060946e70aSDimitry Andric RegisterRef RefNode::getRegRef(const DataFlowGraph &G) const {
4070946e70aSDimitry Andric   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
4080946e70aSDimitry Andric   if (NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef)
4090946e70aSDimitry Andric     return G.unpack(Ref.PR);
4100946e70aSDimitry Andric   assert(Ref.Op != nullptr);
4110946e70aSDimitry Andric   return G.makeRegRef(*Ref.Op);
4120946e70aSDimitry Andric }
4130946e70aSDimitry Andric 
4140946e70aSDimitry Andric // Set the register reference in the reference node directly (for references
4150946e70aSDimitry Andric // in phi nodes).
4160946e70aSDimitry Andric void RefNode::setRegRef(RegisterRef RR, DataFlowGraph &G) {
4170946e70aSDimitry Andric   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
4180946e70aSDimitry Andric   assert(NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef);
4190946e70aSDimitry Andric   Ref.PR = G.pack(RR);
4200946e70aSDimitry Andric }
4210946e70aSDimitry Andric 
4220946e70aSDimitry Andric // Set the register reference in the reference node based on a machine
4230946e70aSDimitry Andric // operand (for references in statement nodes).
4240946e70aSDimitry Andric void RefNode::setRegRef(MachineOperand *Op, DataFlowGraph &G) {
4250946e70aSDimitry Andric   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
4260946e70aSDimitry Andric   assert(!(NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef));
4270946e70aSDimitry Andric   (void)G;
4280946e70aSDimitry Andric   Ref.Op = Op;
4290946e70aSDimitry Andric }
4300946e70aSDimitry Andric 
4310946e70aSDimitry Andric // Get the owner of a given reference node.
4320946e70aSDimitry Andric NodeAddr<NodeBase*> RefNode::getOwner(const DataFlowGraph &G) {
4330946e70aSDimitry Andric   NodeAddr<NodeBase*> NA = G.addr<NodeBase*>(getNext());
4340946e70aSDimitry Andric 
4350946e70aSDimitry Andric   while (NA.Addr != this) {
4360946e70aSDimitry Andric     if (NA.Addr->getType() == NodeAttrs::Code)
4370946e70aSDimitry Andric       return NA;
4380946e70aSDimitry Andric     NA = G.addr<NodeBase*>(NA.Addr->getNext());
4390946e70aSDimitry Andric   }
4400946e70aSDimitry Andric   llvm_unreachable("No owner in circular list");
4410946e70aSDimitry Andric }
4420946e70aSDimitry Andric 
4430946e70aSDimitry Andric // Connect the def node to the reaching def node.
4440946e70aSDimitry Andric void DefNode::linkToDef(NodeId Self, NodeAddr<DefNode*> DA) {
4450946e70aSDimitry Andric   Ref.RD = DA.Id;
4460946e70aSDimitry Andric   Ref.Sib = DA.Addr->getReachedDef();
4470946e70aSDimitry Andric   DA.Addr->setReachedDef(Self);
4480946e70aSDimitry Andric }
4490946e70aSDimitry Andric 
4500946e70aSDimitry Andric // Connect the use node to the reaching def node.
4510946e70aSDimitry Andric void UseNode::linkToDef(NodeId Self, NodeAddr<DefNode*> DA) {
4520946e70aSDimitry Andric   Ref.RD = DA.Id;
4530946e70aSDimitry Andric   Ref.Sib = DA.Addr->getReachedUse();
4540946e70aSDimitry Andric   DA.Addr->setReachedUse(Self);
4550946e70aSDimitry Andric }
4560946e70aSDimitry Andric 
4570946e70aSDimitry Andric // Get the first member of the code node.
4580946e70aSDimitry Andric NodeAddr<NodeBase*> CodeNode::getFirstMember(const DataFlowGraph &G) const {
4590946e70aSDimitry Andric   if (Code.FirstM == 0)
4600946e70aSDimitry Andric     return NodeAddr<NodeBase*>();
4610946e70aSDimitry Andric   return G.addr<NodeBase*>(Code.FirstM);
4620946e70aSDimitry Andric }
4630946e70aSDimitry Andric 
4640946e70aSDimitry Andric // Get the last member of the code node.
4650946e70aSDimitry Andric NodeAddr<NodeBase*> CodeNode::getLastMember(const DataFlowGraph &G) const {
4660946e70aSDimitry Andric   if (Code.LastM == 0)
4670946e70aSDimitry Andric     return NodeAddr<NodeBase*>();
4680946e70aSDimitry Andric   return G.addr<NodeBase*>(Code.LastM);
4690946e70aSDimitry Andric }
4700946e70aSDimitry Andric 
4710946e70aSDimitry Andric // Add node NA at the end of the member list of the given code node.
4720946e70aSDimitry Andric void CodeNode::addMember(NodeAddr<NodeBase*> NA, const DataFlowGraph &G) {
4730946e70aSDimitry Andric   NodeAddr<NodeBase*> ML = getLastMember(G);
4740946e70aSDimitry Andric   if (ML.Id != 0) {
4750946e70aSDimitry Andric     ML.Addr->append(NA);
4760946e70aSDimitry Andric   } else {
4770946e70aSDimitry Andric     Code.FirstM = NA.Id;
4780946e70aSDimitry Andric     NodeId Self = G.id(this);
4790946e70aSDimitry Andric     NA.Addr->setNext(Self);
4800946e70aSDimitry Andric   }
4810946e70aSDimitry Andric   Code.LastM = NA.Id;
4820946e70aSDimitry Andric }
4830946e70aSDimitry Andric 
4840946e70aSDimitry Andric // Add node NA after member node MA in the given code node.
4850946e70aSDimitry Andric void CodeNode::addMemberAfter(NodeAddr<NodeBase*> MA, NodeAddr<NodeBase*> NA,
4860946e70aSDimitry Andric       const DataFlowGraph &G) {
4870946e70aSDimitry Andric   MA.Addr->append(NA);
4880946e70aSDimitry Andric   if (Code.LastM == MA.Id)
4890946e70aSDimitry Andric     Code.LastM = NA.Id;
4900946e70aSDimitry Andric }
4910946e70aSDimitry Andric 
4920946e70aSDimitry Andric // Remove member node NA from the given code node.
4930946e70aSDimitry Andric void CodeNode::removeMember(NodeAddr<NodeBase*> NA, const DataFlowGraph &G) {
4940946e70aSDimitry Andric   NodeAddr<NodeBase*> MA = getFirstMember(G);
4950946e70aSDimitry Andric   assert(MA.Id != 0);
4960946e70aSDimitry Andric 
4970946e70aSDimitry Andric   // Special handling if the member to remove is the first member.
4980946e70aSDimitry Andric   if (MA.Id == NA.Id) {
4990946e70aSDimitry Andric     if (Code.LastM == MA.Id) {
5000946e70aSDimitry Andric       // If it is the only member, set both first and last to 0.
5010946e70aSDimitry Andric       Code.FirstM = Code.LastM = 0;
5020946e70aSDimitry Andric     } else {
5030946e70aSDimitry Andric       // Otherwise, advance the first member.
5040946e70aSDimitry Andric       Code.FirstM = MA.Addr->getNext();
5050946e70aSDimitry Andric     }
5060946e70aSDimitry Andric     return;
5070946e70aSDimitry Andric   }
5080946e70aSDimitry Andric 
5090946e70aSDimitry Andric   while (MA.Addr != this) {
5100946e70aSDimitry Andric     NodeId MX = MA.Addr->getNext();
5110946e70aSDimitry Andric     if (MX == NA.Id) {
5120946e70aSDimitry Andric       MA.Addr->setNext(NA.Addr->getNext());
5130946e70aSDimitry Andric       // If the member to remove happens to be the last one, update the
5140946e70aSDimitry Andric       // LastM indicator.
5150946e70aSDimitry Andric       if (Code.LastM == NA.Id)
5160946e70aSDimitry Andric         Code.LastM = MA.Id;
5170946e70aSDimitry Andric       return;
5180946e70aSDimitry Andric     }
5190946e70aSDimitry Andric     MA = G.addr<NodeBase*>(MX);
5200946e70aSDimitry Andric   }
5210946e70aSDimitry Andric   llvm_unreachable("No such member");
5220946e70aSDimitry Andric }
5230946e70aSDimitry Andric 
5240946e70aSDimitry Andric // Return the list of all members of the code node.
5250946e70aSDimitry Andric NodeList CodeNode::members(const DataFlowGraph &G) const {
5260946e70aSDimitry Andric   static auto True = [] (NodeAddr<NodeBase*>) -> bool { return true; };
5270946e70aSDimitry Andric   return members_if(True, G);
5280946e70aSDimitry Andric }
5290946e70aSDimitry Andric 
5300946e70aSDimitry Andric // Return the owner of the given instr node.
5310946e70aSDimitry Andric NodeAddr<NodeBase*> InstrNode::getOwner(const DataFlowGraph &G) {
5320946e70aSDimitry Andric   NodeAddr<NodeBase*> NA = G.addr<NodeBase*>(getNext());
5330946e70aSDimitry Andric 
5340946e70aSDimitry Andric   while (NA.Addr != this) {
5350946e70aSDimitry Andric     assert(NA.Addr->getType() == NodeAttrs::Code);
5360946e70aSDimitry Andric     if (NA.Addr->getKind() == NodeAttrs::Block)
5370946e70aSDimitry Andric       return NA;
5380946e70aSDimitry Andric     NA = G.addr<NodeBase*>(NA.Addr->getNext());
5390946e70aSDimitry Andric   }
5400946e70aSDimitry Andric   llvm_unreachable("No owner in circular list");
5410946e70aSDimitry Andric }
5420946e70aSDimitry Andric 
5430946e70aSDimitry Andric // Add the phi node PA to the given block node.
5440946e70aSDimitry Andric void BlockNode::addPhi(NodeAddr<PhiNode*> PA, const DataFlowGraph &G) {
5450946e70aSDimitry Andric   NodeAddr<NodeBase*> M = getFirstMember(G);
5460946e70aSDimitry Andric   if (M.Id == 0) {
5470946e70aSDimitry Andric     addMember(PA, G);
5480946e70aSDimitry Andric     return;
5490946e70aSDimitry Andric   }
5500946e70aSDimitry Andric 
5510946e70aSDimitry Andric   assert(M.Addr->getType() == NodeAttrs::Code);
5520946e70aSDimitry Andric   if (M.Addr->getKind() == NodeAttrs::Stmt) {
5530946e70aSDimitry Andric     // If the first member of the block is a statement, insert the phi as
5540946e70aSDimitry Andric     // the first member.
5550946e70aSDimitry Andric     Code.FirstM = PA.Id;
5560946e70aSDimitry Andric     PA.Addr->setNext(M.Id);
5570946e70aSDimitry Andric   } else {
5580946e70aSDimitry Andric     // If the first member is a phi, find the last phi, and append PA to it.
5590946e70aSDimitry Andric     assert(M.Addr->getKind() == NodeAttrs::Phi);
5600946e70aSDimitry Andric     NodeAddr<NodeBase*> MN = M;
5610946e70aSDimitry Andric     do {
5620946e70aSDimitry Andric       M = MN;
5630946e70aSDimitry Andric       MN = G.addr<NodeBase*>(M.Addr->getNext());
5640946e70aSDimitry Andric       assert(MN.Addr->getType() == NodeAttrs::Code);
5650946e70aSDimitry Andric     } while (MN.Addr->getKind() == NodeAttrs::Phi);
5660946e70aSDimitry Andric 
5670946e70aSDimitry Andric     // M is the last phi.
5680946e70aSDimitry Andric     addMemberAfter(M, PA, G);
5690946e70aSDimitry Andric   }
5700946e70aSDimitry Andric }
5710946e70aSDimitry Andric 
5720946e70aSDimitry Andric // Find the block node corresponding to the machine basic block BB in the
5730946e70aSDimitry Andric // given func node.
5740946e70aSDimitry Andric NodeAddr<BlockNode*> FuncNode::findBlock(const MachineBasicBlock *BB,
5750946e70aSDimitry Andric       const DataFlowGraph &G) const {
5760946e70aSDimitry Andric   auto EqBB = [BB] (NodeAddr<NodeBase*> NA) -> bool {
5770946e70aSDimitry Andric     return NodeAddr<BlockNode*>(NA).Addr->getCode() == BB;
5780946e70aSDimitry Andric   };
5790946e70aSDimitry Andric   NodeList Ms = members_if(EqBB, G);
5800946e70aSDimitry Andric   if (!Ms.empty())
5810946e70aSDimitry Andric     return Ms[0];
5820946e70aSDimitry Andric   return NodeAddr<BlockNode*>();
5830946e70aSDimitry Andric }
5840946e70aSDimitry Andric 
5850946e70aSDimitry Andric // Get the block node for the entry block in the given function.
5860946e70aSDimitry Andric NodeAddr<BlockNode*> FuncNode::getEntryBlock(const DataFlowGraph &G) {
5870946e70aSDimitry Andric   MachineBasicBlock *EntryB = &getCode()->front();
5880946e70aSDimitry Andric   return findBlock(EntryB, G);
5890946e70aSDimitry Andric }
5900946e70aSDimitry Andric 
5910946e70aSDimitry Andric // Target operand information.
5920946e70aSDimitry Andric //
5930946e70aSDimitry Andric 
5940946e70aSDimitry Andric // For a given instruction, check if there are any bits of RR that can remain
5950946e70aSDimitry Andric // unchanged across this def.
5960946e70aSDimitry Andric bool TargetOperandInfo::isPreserving(const MachineInstr &In, unsigned OpNum)
5970946e70aSDimitry Andric       const {
5980946e70aSDimitry Andric   return TII.isPredicated(In);
5990946e70aSDimitry Andric }
6000946e70aSDimitry Andric 
6010946e70aSDimitry Andric // Check if the definition of RR produces an unspecified value.
6020946e70aSDimitry Andric bool TargetOperandInfo::isClobbering(const MachineInstr &In, unsigned OpNum)
6030946e70aSDimitry Andric       const {
6040946e70aSDimitry Andric   const MachineOperand &Op = In.getOperand(OpNum);
6050946e70aSDimitry Andric   if (Op.isRegMask())
6060946e70aSDimitry Andric     return true;
6070946e70aSDimitry Andric   assert(Op.isReg());
6080946e70aSDimitry Andric   if (In.isCall())
6090946e70aSDimitry Andric     if (Op.isDef() && Op.isDead())
6100946e70aSDimitry Andric       return true;
6110946e70aSDimitry Andric   return false;
6120946e70aSDimitry Andric }
6130946e70aSDimitry Andric 
6140946e70aSDimitry Andric // Check if the given instruction specifically requires
6150946e70aSDimitry Andric bool TargetOperandInfo::isFixedReg(const MachineInstr &In, unsigned OpNum)
6160946e70aSDimitry Andric       const {
6170946e70aSDimitry Andric   if (In.isCall() || In.isReturn() || In.isInlineAsm())
6180946e70aSDimitry Andric     return true;
6190946e70aSDimitry Andric   // Check for a tail call.
6200946e70aSDimitry Andric   if (In.isBranch())
6210946e70aSDimitry Andric     for (const MachineOperand &O : In.operands())
6220946e70aSDimitry Andric       if (O.isGlobal() || O.isSymbol())
6230946e70aSDimitry Andric         return true;
6240946e70aSDimitry Andric 
6250946e70aSDimitry Andric   const MCInstrDesc &D = In.getDesc();
6260946e70aSDimitry Andric   if (!D.getImplicitDefs() && !D.getImplicitUses())
6270946e70aSDimitry Andric     return false;
6280946e70aSDimitry Andric   const MachineOperand &Op = In.getOperand(OpNum);
6290946e70aSDimitry Andric   // If there is a sub-register, treat the operand as non-fixed. Currently,
6300946e70aSDimitry Andric   // fixed registers are those that are listed in the descriptor as implicit
6310946e70aSDimitry Andric   // uses or defs, and those lists do not allow sub-registers.
6320946e70aSDimitry Andric   if (Op.getSubReg() != 0)
6330946e70aSDimitry Andric     return false;
6340946e70aSDimitry Andric   Register Reg = Op.getReg();
6350946e70aSDimitry Andric   const MCPhysReg *ImpR = Op.isDef() ? D.getImplicitDefs()
6360946e70aSDimitry Andric                                      : D.getImplicitUses();
6370946e70aSDimitry Andric   if (!ImpR)
6380946e70aSDimitry Andric     return false;
6390946e70aSDimitry Andric   while (*ImpR)
6400946e70aSDimitry Andric     if (*ImpR++ == Reg)
6410946e70aSDimitry Andric       return true;
6420946e70aSDimitry Andric   return false;
6430946e70aSDimitry Andric }
6440946e70aSDimitry Andric 
6450946e70aSDimitry Andric //
6460946e70aSDimitry Andric // The data flow graph construction.
6470946e70aSDimitry Andric //
6480946e70aSDimitry Andric 
6490946e70aSDimitry Andric DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
6500946e70aSDimitry Andric       const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
6510946e70aSDimitry Andric       const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
6520946e70aSDimitry Andric     : MF(mf), TII(tii), TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
6530946e70aSDimitry Andric       LiveIns(PRI) {
6540946e70aSDimitry Andric }
6550946e70aSDimitry Andric 
6560946e70aSDimitry Andric // The implementation of the definition stack.
6570946e70aSDimitry Andric // Each register reference has its own definition stack. In particular,
6580946e70aSDimitry Andric // for a register references "Reg" and "Reg:subreg" will each have their
6590946e70aSDimitry Andric // own definition stacks.
6600946e70aSDimitry Andric 
6610946e70aSDimitry Andric // Construct a stack iterator.
6620946e70aSDimitry Andric DataFlowGraph::DefStack::Iterator::Iterator(const DataFlowGraph::DefStack &S,
6630946e70aSDimitry Andric       bool Top) : DS(S) {
6640946e70aSDimitry Andric   if (!Top) {
6650946e70aSDimitry Andric     // Initialize to bottom.
6660946e70aSDimitry Andric     Pos = 0;
6670946e70aSDimitry Andric     return;
6680946e70aSDimitry Andric   }
6690946e70aSDimitry Andric   // Initialize to the top, i.e. top-most non-delimiter (or 0, if empty).
6700946e70aSDimitry Andric   Pos = DS.Stack.size();
6710946e70aSDimitry Andric   while (Pos > 0 && DS.isDelimiter(DS.Stack[Pos-1]))
6720946e70aSDimitry Andric     Pos--;
6730946e70aSDimitry Andric }
6740946e70aSDimitry Andric 
6750946e70aSDimitry Andric // Return the size of the stack, including block delimiters.
6760946e70aSDimitry Andric unsigned DataFlowGraph::DefStack::size() const {
6770946e70aSDimitry Andric   unsigned S = 0;
6780946e70aSDimitry Andric   for (auto I = top(), E = bottom(); I != E; I.down())
6790946e70aSDimitry Andric     S++;
6800946e70aSDimitry Andric   return S;
6810946e70aSDimitry Andric }
6820946e70aSDimitry Andric 
6830946e70aSDimitry Andric // Remove the top entry from the stack. Remove all intervening delimiters
6840946e70aSDimitry Andric // so that after this, the stack is either empty, or the top of the stack
6850946e70aSDimitry Andric // is a non-delimiter.
6860946e70aSDimitry Andric void DataFlowGraph::DefStack::pop() {
6870946e70aSDimitry Andric   assert(!empty());
6880946e70aSDimitry Andric   unsigned P = nextDown(Stack.size());
6890946e70aSDimitry Andric   Stack.resize(P);
6900946e70aSDimitry Andric }
6910946e70aSDimitry Andric 
6920946e70aSDimitry Andric // Push a delimiter for block node N on the stack.
6930946e70aSDimitry Andric void DataFlowGraph::DefStack::start_block(NodeId N) {
6940946e70aSDimitry Andric   assert(N != 0);
6950946e70aSDimitry Andric   Stack.push_back(NodeAddr<DefNode*>(nullptr, N));
6960946e70aSDimitry Andric }
6970946e70aSDimitry Andric 
6980946e70aSDimitry Andric // Remove all nodes from the top of the stack, until the delimited for
6990946e70aSDimitry Andric // block node N is encountered. Remove the delimiter as well. In effect,
7000946e70aSDimitry Andric // this will remove from the stack all definitions from block N.
7010946e70aSDimitry Andric void DataFlowGraph::DefStack::clear_block(NodeId N) {
7020946e70aSDimitry Andric   assert(N != 0);
7030946e70aSDimitry Andric   unsigned P = Stack.size();
7040946e70aSDimitry Andric   while (P > 0) {
7050946e70aSDimitry Andric     bool Found = isDelimiter(Stack[P-1], N);
7060946e70aSDimitry Andric     P--;
7070946e70aSDimitry Andric     if (Found)
7080946e70aSDimitry Andric       break;
7090946e70aSDimitry Andric   }
7100946e70aSDimitry Andric   // This will also remove the delimiter, if found.
7110946e70aSDimitry Andric   Stack.resize(P);
7120946e70aSDimitry Andric }
7130946e70aSDimitry Andric 
7140946e70aSDimitry Andric // Move the stack iterator up by one.
7150946e70aSDimitry Andric unsigned DataFlowGraph::DefStack::nextUp(unsigned P) const {
7160946e70aSDimitry Andric   // Get the next valid position after P (skipping all delimiters).
7170946e70aSDimitry Andric   // The input position P does not have to point to a non-delimiter.
7180946e70aSDimitry Andric   unsigned SS = Stack.size();
7190946e70aSDimitry Andric   bool IsDelim;
7200946e70aSDimitry Andric   assert(P < SS);
7210946e70aSDimitry Andric   do {
7220946e70aSDimitry Andric     P++;
7230946e70aSDimitry Andric     IsDelim = isDelimiter(Stack[P-1]);
7240946e70aSDimitry Andric   } while (P < SS && IsDelim);
7250946e70aSDimitry Andric   assert(!IsDelim);
7260946e70aSDimitry Andric   return P;
7270946e70aSDimitry Andric }
7280946e70aSDimitry Andric 
7290946e70aSDimitry Andric // Move the stack iterator down by one.
7300946e70aSDimitry Andric unsigned DataFlowGraph::DefStack::nextDown(unsigned P) const {
7310946e70aSDimitry Andric   // Get the preceding valid position before P (skipping all delimiters).
7320946e70aSDimitry Andric   // The input position P does not have to point to a non-delimiter.
7330946e70aSDimitry Andric   assert(P > 0 && P <= Stack.size());
7340946e70aSDimitry Andric   bool IsDelim = isDelimiter(Stack[P-1]);
7350946e70aSDimitry Andric   do {
7360946e70aSDimitry Andric     if (--P == 0)
7370946e70aSDimitry Andric       break;
7380946e70aSDimitry Andric     IsDelim = isDelimiter(Stack[P-1]);
7390946e70aSDimitry Andric   } while (P > 0 && IsDelim);
7400946e70aSDimitry Andric   assert(!IsDelim);
7410946e70aSDimitry Andric   return P;
7420946e70aSDimitry Andric }
7430946e70aSDimitry Andric 
7440946e70aSDimitry Andric // Register information.
7450946e70aSDimitry Andric 
7460946e70aSDimitry Andric RegisterSet DataFlowGraph::getLandingPadLiveIns() const {
7470946e70aSDimitry Andric   RegisterSet LR;
7480946e70aSDimitry Andric   const Function &F = MF.getFunction();
7490946e70aSDimitry Andric   const Constant *PF = F.hasPersonalityFn() ? F.getPersonalityFn()
7500946e70aSDimitry Andric                                             : nullptr;
7510946e70aSDimitry Andric   const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
7520946e70aSDimitry Andric   if (RegisterId R = TLI.getExceptionPointerRegister(PF))
7530946e70aSDimitry Andric     LR.insert(RegisterRef(R));
7540946e70aSDimitry Andric   if (!isFuncletEHPersonality(classifyEHPersonality(PF))) {
7550946e70aSDimitry Andric     if (RegisterId R = TLI.getExceptionSelectorRegister(PF))
7560946e70aSDimitry Andric       LR.insert(RegisterRef(R));
7570946e70aSDimitry Andric   }
7580946e70aSDimitry Andric   return LR;
7590946e70aSDimitry Andric }
7600946e70aSDimitry Andric 
7610946e70aSDimitry Andric // Node management functions.
7620946e70aSDimitry Andric 
7630946e70aSDimitry Andric // Get the pointer to the node with the id N.
7640946e70aSDimitry Andric NodeBase *DataFlowGraph::ptr(NodeId N) const {
7650946e70aSDimitry Andric   if (N == 0)
7660946e70aSDimitry Andric     return nullptr;
7670946e70aSDimitry Andric   return Memory.ptr(N);
7680946e70aSDimitry Andric }
7690946e70aSDimitry Andric 
7700946e70aSDimitry Andric // Get the id of the node at the address P.
7710946e70aSDimitry Andric NodeId DataFlowGraph::id(const NodeBase *P) const {
7720946e70aSDimitry Andric   if (P == nullptr)
7730946e70aSDimitry Andric     return 0;
7740946e70aSDimitry Andric   return Memory.id(P);
7750946e70aSDimitry Andric }
7760946e70aSDimitry Andric 
7770946e70aSDimitry Andric // Allocate a new node and set the attributes to Attrs.
7780946e70aSDimitry Andric NodeAddr<NodeBase*> DataFlowGraph::newNode(uint16_t Attrs) {
7790946e70aSDimitry Andric   NodeAddr<NodeBase*> P = Memory.New();
7800946e70aSDimitry Andric   P.Addr->init();
7810946e70aSDimitry Andric   P.Addr->setAttrs(Attrs);
7820946e70aSDimitry Andric   return P;
7830946e70aSDimitry Andric }
7840946e70aSDimitry Andric 
7850946e70aSDimitry Andric // Make a copy of the given node B, except for the data-flow links, which
7860946e70aSDimitry Andric // are set to 0.
7870946e70aSDimitry Andric NodeAddr<NodeBase*> DataFlowGraph::cloneNode(const NodeAddr<NodeBase*> B) {
7880946e70aSDimitry Andric   NodeAddr<NodeBase*> NA = newNode(0);
7890946e70aSDimitry Andric   memcpy(NA.Addr, B.Addr, sizeof(NodeBase));
7900946e70aSDimitry Andric   // Ref nodes need to have the data-flow links reset.
7910946e70aSDimitry Andric   if (NA.Addr->getType() == NodeAttrs::Ref) {
7920946e70aSDimitry Andric     NodeAddr<RefNode*> RA = NA;
7930946e70aSDimitry Andric     RA.Addr->setReachingDef(0);
7940946e70aSDimitry Andric     RA.Addr->setSibling(0);
7950946e70aSDimitry Andric     if (NA.Addr->getKind() == NodeAttrs::Def) {
7960946e70aSDimitry Andric       NodeAddr<DefNode*> DA = NA;
7970946e70aSDimitry Andric       DA.Addr->setReachedDef(0);
7980946e70aSDimitry Andric       DA.Addr->setReachedUse(0);
7990946e70aSDimitry Andric     }
8000946e70aSDimitry Andric   }
8010946e70aSDimitry Andric   return NA;
8020946e70aSDimitry Andric }
8030946e70aSDimitry Andric 
8040946e70aSDimitry Andric // Allocation routines for specific node types/kinds.
8050946e70aSDimitry Andric 
8060946e70aSDimitry Andric NodeAddr<UseNode*> DataFlowGraph::newUse(NodeAddr<InstrNode*> Owner,
8070946e70aSDimitry Andric       MachineOperand &Op, uint16_t Flags) {
8080946e70aSDimitry Andric   NodeAddr<UseNode*> UA = newNode(NodeAttrs::Ref | NodeAttrs::Use | Flags);
8090946e70aSDimitry Andric   UA.Addr->setRegRef(&Op, *this);
8100946e70aSDimitry Andric   return UA;
8110946e70aSDimitry Andric }
8120946e70aSDimitry Andric 
8130946e70aSDimitry Andric NodeAddr<PhiUseNode*> DataFlowGraph::newPhiUse(NodeAddr<PhiNode*> Owner,
8140946e70aSDimitry Andric       RegisterRef RR, NodeAddr<BlockNode*> PredB, uint16_t Flags) {
8150946e70aSDimitry Andric   NodeAddr<PhiUseNode*> PUA = newNode(NodeAttrs::Ref | NodeAttrs::Use | Flags);
8160946e70aSDimitry Andric   assert(Flags & NodeAttrs::PhiRef);
8170946e70aSDimitry Andric   PUA.Addr->setRegRef(RR, *this);
8180946e70aSDimitry Andric   PUA.Addr->setPredecessor(PredB.Id);
8190946e70aSDimitry Andric   return PUA;
8200946e70aSDimitry Andric }
8210946e70aSDimitry Andric 
8220946e70aSDimitry Andric NodeAddr<DefNode*> DataFlowGraph::newDef(NodeAddr<InstrNode*> Owner,
8230946e70aSDimitry Andric       MachineOperand &Op, uint16_t Flags) {
8240946e70aSDimitry Andric   NodeAddr<DefNode*> DA = newNode(NodeAttrs::Ref | NodeAttrs::Def | Flags);
8250946e70aSDimitry Andric   DA.Addr->setRegRef(&Op, *this);
8260946e70aSDimitry Andric   return DA;
8270946e70aSDimitry Andric }
8280946e70aSDimitry Andric 
8290946e70aSDimitry Andric NodeAddr<DefNode*> DataFlowGraph::newDef(NodeAddr<InstrNode*> Owner,
8300946e70aSDimitry Andric       RegisterRef RR, uint16_t Flags) {
8310946e70aSDimitry Andric   NodeAddr<DefNode*> DA = newNode(NodeAttrs::Ref | NodeAttrs::Def | Flags);
8320946e70aSDimitry Andric   assert(Flags & NodeAttrs::PhiRef);
8330946e70aSDimitry Andric   DA.Addr->setRegRef(RR, *this);
8340946e70aSDimitry Andric   return DA;
8350946e70aSDimitry Andric }
8360946e70aSDimitry Andric 
8370946e70aSDimitry Andric NodeAddr<PhiNode*> DataFlowGraph::newPhi(NodeAddr<BlockNode*> Owner) {
8380946e70aSDimitry Andric   NodeAddr<PhiNode*> PA = newNode(NodeAttrs::Code | NodeAttrs::Phi);
8390946e70aSDimitry Andric   Owner.Addr->addPhi(PA, *this);
8400946e70aSDimitry Andric   return PA;
8410946e70aSDimitry Andric }
8420946e70aSDimitry Andric 
8430946e70aSDimitry Andric NodeAddr<StmtNode*> DataFlowGraph::newStmt(NodeAddr<BlockNode*> Owner,
8440946e70aSDimitry Andric       MachineInstr *MI) {
8450946e70aSDimitry Andric   NodeAddr<StmtNode*> SA = newNode(NodeAttrs::Code | NodeAttrs::Stmt);
8460946e70aSDimitry Andric   SA.Addr->setCode(MI);
8470946e70aSDimitry Andric   Owner.Addr->addMember(SA, *this);
8480946e70aSDimitry Andric   return SA;
8490946e70aSDimitry Andric }
8500946e70aSDimitry Andric 
8510946e70aSDimitry Andric NodeAddr<BlockNode*> DataFlowGraph::newBlock(NodeAddr<FuncNode*> Owner,
8520946e70aSDimitry Andric       MachineBasicBlock *BB) {
8530946e70aSDimitry Andric   NodeAddr<BlockNode*> BA = newNode(NodeAttrs::Code | NodeAttrs::Block);
8540946e70aSDimitry Andric   BA.Addr->setCode(BB);
8550946e70aSDimitry Andric   Owner.Addr->addMember(BA, *this);
8560946e70aSDimitry Andric   return BA;
8570946e70aSDimitry Andric }
8580946e70aSDimitry Andric 
8590946e70aSDimitry Andric NodeAddr<FuncNode*> DataFlowGraph::newFunc(MachineFunction *MF) {
8600946e70aSDimitry Andric   NodeAddr<FuncNode*> FA = newNode(NodeAttrs::Code | NodeAttrs::Func);
8610946e70aSDimitry Andric   FA.Addr->setCode(MF);
8620946e70aSDimitry Andric   return FA;
8630946e70aSDimitry Andric }
8640946e70aSDimitry Andric 
8650946e70aSDimitry Andric // Build the data flow graph.
8660946e70aSDimitry Andric void DataFlowGraph::build(unsigned Options) {
8670946e70aSDimitry Andric   reset();
8680946e70aSDimitry Andric   Func = newFunc(&MF);
8690946e70aSDimitry Andric 
8700946e70aSDimitry Andric   if (MF.empty())
8710946e70aSDimitry Andric     return;
8720946e70aSDimitry Andric 
8730946e70aSDimitry Andric   for (MachineBasicBlock &B : MF) {
8740946e70aSDimitry Andric     NodeAddr<BlockNode*> BA = newBlock(Func, &B);
8750946e70aSDimitry Andric     BlockNodes.insert(std::make_pair(&B, BA));
8760946e70aSDimitry Andric     for (MachineInstr &I : B) {
8770946e70aSDimitry Andric       if (I.isDebugInstr())
8780946e70aSDimitry Andric         continue;
8790946e70aSDimitry Andric       buildStmt(BA, I);
8800946e70aSDimitry Andric     }
8810946e70aSDimitry Andric   }
8820946e70aSDimitry Andric 
8830946e70aSDimitry Andric   NodeAddr<BlockNode*> EA = Func.Addr->getEntryBlock(*this);
8840946e70aSDimitry Andric   NodeList Blocks = Func.Addr->members(*this);
8850946e70aSDimitry Andric 
8860946e70aSDimitry Andric   // Collect information about block references.
8870946e70aSDimitry Andric   RegisterSet AllRefs;
8880946e70aSDimitry Andric   for (NodeAddr<BlockNode*> BA : Blocks)
8890946e70aSDimitry Andric     for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this))
8900946e70aSDimitry Andric       for (NodeAddr<RefNode*> RA : IA.Addr->members(*this))
8910946e70aSDimitry Andric         AllRefs.insert(RA.Addr->getRegRef(*this));
8920946e70aSDimitry Andric 
8930946e70aSDimitry Andric   // Collect function live-ins and entry block live-ins.
8940946e70aSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
8950946e70aSDimitry Andric   MachineBasicBlock &EntryB = *EA.Addr->getCode();
8960946e70aSDimitry Andric   assert(EntryB.pred_empty() && "Function entry block has predecessors");
8970946e70aSDimitry Andric   for (std::pair<unsigned,unsigned> P : MRI.liveins())
8980946e70aSDimitry Andric     LiveIns.insert(RegisterRef(P.first));
8990946e70aSDimitry Andric   if (MRI.tracksLiveness()) {
9000946e70aSDimitry Andric     for (auto I : EntryB.liveins())
9010946e70aSDimitry Andric       LiveIns.insert(RegisterRef(I.PhysReg, I.LaneMask));
9020946e70aSDimitry Andric   }
9030946e70aSDimitry Andric 
9040946e70aSDimitry Andric   // Add function-entry phi nodes for the live-in registers.
9050946e70aSDimitry Andric   //for (std::pair<RegisterId,LaneBitmask> P : LiveIns) {
9060946e70aSDimitry Andric   for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
9070946e70aSDimitry Andric     RegisterRef RR = *I;
9080946e70aSDimitry Andric     NodeAddr<PhiNode*> PA = newPhi(EA);
9090946e70aSDimitry Andric     uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
9100946e70aSDimitry Andric     NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
9110946e70aSDimitry Andric     PA.Addr->addMember(DA, *this);
9120946e70aSDimitry Andric   }
9130946e70aSDimitry Andric 
9140946e70aSDimitry Andric   // Add phis for landing pads.
9150946e70aSDimitry Andric   // Landing pads, unlike usual backs blocks, are not entered through
9160946e70aSDimitry Andric   // branches in the program, or fall-throughs from other blocks. They
9170946e70aSDimitry Andric   // are entered from the exception handling runtime and target's ABI
9180946e70aSDimitry Andric   // may define certain registers as defined on entry to such a block.
9190946e70aSDimitry Andric   RegisterSet EHRegs = getLandingPadLiveIns();
9200946e70aSDimitry Andric   if (!EHRegs.empty()) {
9210946e70aSDimitry Andric     for (NodeAddr<BlockNode*> BA : Blocks) {
9220946e70aSDimitry Andric       const MachineBasicBlock &B = *BA.Addr->getCode();
9230946e70aSDimitry Andric       if (!B.isEHPad())
9240946e70aSDimitry Andric         continue;
9250946e70aSDimitry Andric 
9260946e70aSDimitry Andric       // Prepare a list of NodeIds of the block's predecessors.
9270946e70aSDimitry Andric       NodeList Preds;
9280946e70aSDimitry Andric       for (MachineBasicBlock *PB : B.predecessors())
9290946e70aSDimitry Andric         Preds.push_back(findBlock(PB));
9300946e70aSDimitry Andric 
9310946e70aSDimitry Andric       // Build phi nodes for each live-in.
9320946e70aSDimitry Andric       for (RegisterRef RR : EHRegs) {
9330946e70aSDimitry Andric         NodeAddr<PhiNode*> PA = newPhi(BA);
9340946e70aSDimitry Andric         uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
9350946e70aSDimitry Andric         // Add def:
9360946e70aSDimitry Andric         NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
9370946e70aSDimitry Andric         PA.Addr->addMember(DA, *this);
9380946e70aSDimitry Andric         // Add uses (no reaching defs for phi uses):
9390946e70aSDimitry Andric         for (NodeAddr<BlockNode*> PBA : Preds) {
9400946e70aSDimitry Andric           NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
9410946e70aSDimitry Andric           PA.Addr->addMember(PUA, *this);
9420946e70aSDimitry Andric         }
9430946e70aSDimitry Andric       }
9440946e70aSDimitry Andric     }
9450946e70aSDimitry Andric   }
9460946e70aSDimitry Andric 
9470946e70aSDimitry Andric   // Build a map "PhiM" which will contain, for each block, the set
9480946e70aSDimitry Andric   // of references that will require phi definitions in that block.
9490946e70aSDimitry Andric   BlockRefsMap PhiM;
9500946e70aSDimitry Andric   for (NodeAddr<BlockNode*> BA : Blocks)
9510946e70aSDimitry Andric     recordDefsForDF(PhiM, BA);
9520946e70aSDimitry Andric   for (NodeAddr<BlockNode*> BA : Blocks)
9530946e70aSDimitry Andric     buildPhis(PhiM, AllRefs, BA);
9540946e70aSDimitry Andric 
9550946e70aSDimitry Andric   // Link all the refs. This will recursively traverse the dominator tree.
9560946e70aSDimitry Andric   DefStackMap DM;
9570946e70aSDimitry Andric   linkBlockRefs(DM, EA);
9580946e70aSDimitry Andric 
9590946e70aSDimitry Andric   // Finally, remove all unused phi nodes.
9600946e70aSDimitry Andric   if (!(Options & BuildOptions::KeepDeadPhis))
9610946e70aSDimitry Andric     removeUnusedPhis();
9620946e70aSDimitry Andric }
9630946e70aSDimitry Andric 
9640946e70aSDimitry Andric RegisterRef DataFlowGraph::makeRegRef(unsigned Reg, unsigned Sub) const {
9650946e70aSDimitry Andric   assert(PhysicalRegisterInfo::isRegMaskId(Reg) ||
9660946e70aSDimitry Andric          Register::isPhysicalRegister(Reg));
9670946e70aSDimitry Andric   assert(Reg != 0);
9680946e70aSDimitry Andric   if (Sub != 0)
9690946e70aSDimitry Andric     Reg = TRI.getSubReg(Reg, Sub);
9700946e70aSDimitry Andric   return RegisterRef(Reg);
9710946e70aSDimitry Andric }
9720946e70aSDimitry Andric 
9730946e70aSDimitry Andric RegisterRef DataFlowGraph::makeRegRef(const MachineOperand &Op) const {
9740946e70aSDimitry Andric   assert(Op.isReg() || Op.isRegMask());
9750946e70aSDimitry Andric   if (Op.isReg())
9760946e70aSDimitry Andric     return makeRegRef(Op.getReg(), Op.getSubReg());
9770946e70aSDimitry Andric   return RegisterRef(PRI.getRegMaskId(Op.getRegMask()), LaneBitmask::getAll());
9780946e70aSDimitry Andric }
9790946e70aSDimitry Andric 
9800946e70aSDimitry Andric // For each stack in the map DefM, push the delimiter for block B on it.
9810946e70aSDimitry Andric void DataFlowGraph::markBlock(NodeId B, DefStackMap &DefM) {
9820946e70aSDimitry Andric   // Push block delimiters.
983fe6060f1SDimitry Andric   for (auto &P : DefM)
984fe6060f1SDimitry Andric     P.second.start_block(B);
9850946e70aSDimitry Andric }
9860946e70aSDimitry Andric 
9870946e70aSDimitry Andric // Remove all definitions coming from block B from each stack in DefM.
9880946e70aSDimitry Andric void DataFlowGraph::releaseBlock(NodeId B, DefStackMap &DefM) {
9890946e70aSDimitry Andric   // Pop all defs from this block from the definition stack. Defs that were
9900946e70aSDimitry Andric   // added to the map during the traversal of instructions will not have a
9910946e70aSDimitry Andric   // delimiter, but for those, the whole stack will be emptied.
992fe6060f1SDimitry Andric   for (auto &P : DefM)
993fe6060f1SDimitry Andric     P.second.clear_block(B);
9940946e70aSDimitry Andric 
9950946e70aSDimitry Andric   // Finally, remove empty stacks from the map.
9960946e70aSDimitry Andric   for (auto I = DefM.begin(), E = DefM.end(), NextI = I; I != E; I = NextI) {
9970946e70aSDimitry Andric     NextI = std::next(I);
9980946e70aSDimitry Andric     // This preserves the validity of iterators other than I.
9990946e70aSDimitry Andric     if (I->second.empty())
10000946e70aSDimitry Andric       DefM.erase(I);
10010946e70aSDimitry Andric   }
10020946e70aSDimitry Andric }
10030946e70aSDimitry Andric 
10040946e70aSDimitry Andric // Push all definitions from the instruction node IA to an appropriate
10050946e70aSDimitry Andric // stack in DefM.
10060946e70aSDimitry Andric void DataFlowGraph::pushAllDefs(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
10070946e70aSDimitry Andric   pushClobbers(IA, DefM);
10080946e70aSDimitry Andric   pushDefs(IA, DefM);
10090946e70aSDimitry Andric }
10100946e70aSDimitry Andric 
10110946e70aSDimitry Andric // Push all definitions from the instruction node IA to an appropriate
10120946e70aSDimitry Andric // stack in DefM.
10130946e70aSDimitry Andric void DataFlowGraph::pushClobbers(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
10140946e70aSDimitry Andric   NodeSet Visited;
10150946e70aSDimitry Andric   std::set<RegisterId> Defined;
10160946e70aSDimitry Andric 
10170946e70aSDimitry Andric   // The important objectives of this function are:
10180946e70aSDimitry Andric   // - to be able to handle instructions both while the graph is being
10190946e70aSDimitry Andric   //   constructed, and after the graph has been constructed, and
10200946e70aSDimitry Andric   // - maintain proper ordering of definitions on the stack for each
10210946e70aSDimitry Andric   //   register reference:
10220946e70aSDimitry Andric   //   - if there are two or more related defs in IA (i.e. coming from
10230946e70aSDimitry Andric   //     the same machine operand), then only push one def on the stack,
10240946e70aSDimitry Andric   //   - if there are multiple unrelated defs of non-overlapping
10250946e70aSDimitry Andric   //     subregisters of S, then the stack for S will have both (in an
10260946e70aSDimitry Andric   //     unspecified order), but the order does not matter from the data-
10270946e70aSDimitry Andric   //     -flow perspective.
10280946e70aSDimitry Andric 
10290946e70aSDimitry Andric   for (NodeAddr<DefNode*> DA : IA.Addr->members_if(IsDef, *this)) {
10300946e70aSDimitry Andric     if (Visited.count(DA.Id))
10310946e70aSDimitry Andric       continue;
10320946e70aSDimitry Andric     if (!(DA.Addr->getFlags() & NodeAttrs::Clobbering))
10330946e70aSDimitry Andric       continue;
10340946e70aSDimitry Andric 
10350946e70aSDimitry Andric     NodeList Rel = getRelatedRefs(IA, DA);
10360946e70aSDimitry Andric     NodeAddr<DefNode*> PDA = Rel.front();
10370946e70aSDimitry Andric     RegisterRef RR = PDA.Addr->getRegRef(*this);
10380946e70aSDimitry Andric 
10390946e70aSDimitry Andric     // Push the definition on the stack for the register and all aliases.
10400946e70aSDimitry Andric     // The def stack traversal in linkNodeUp will check the exact aliasing.
10410946e70aSDimitry Andric     DefM[RR.Reg].push(DA);
10420946e70aSDimitry Andric     Defined.insert(RR.Reg);
10430946e70aSDimitry Andric     for (RegisterId A : PRI.getAliasSet(RR.Reg)) {
10440946e70aSDimitry Andric       // Check that we don't push the same def twice.
10450946e70aSDimitry Andric       assert(A != RR.Reg);
10460946e70aSDimitry Andric       if (!Defined.count(A))
10470946e70aSDimitry Andric         DefM[A].push(DA);
10480946e70aSDimitry Andric     }
10490946e70aSDimitry Andric     // Mark all the related defs as visited.
10500946e70aSDimitry Andric     for (NodeAddr<NodeBase*> T : Rel)
10510946e70aSDimitry Andric       Visited.insert(T.Id);
10520946e70aSDimitry Andric   }
10530946e70aSDimitry Andric }
10540946e70aSDimitry Andric 
10550946e70aSDimitry Andric // Push all definitions from the instruction node IA to an appropriate
10560946e70aSDimitry Andric // stack in DefM.
10570946e70aSDimitry Andric void DataFlowGraph::pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
10580946e70aSDimitry Andric   NodeSet Visited;
10590946e70aSDimitry Andric #ifndef NDEBUG
10600946e70aSDimitry Andric   std::set<RegisterId> Defined;
10610946e70aSDimitry Andric #endif
10620946e70aSDimitry Andric 
10630946e70aSDimitry Andric   // The important objectives of this function are:
10640946e70aSDimitry Andric   // - to be able to handle instructions both while the graph is being
10650946e70aSDimitry Andric   //   constructed, and after the graph has been constructed, and
10660946e70aSDimitry Andric   // - maintain proper ordering of definitions on the stack for each
10670946e70aSDimitry Andric   //   register reference:
10680946e70aSDimitry Andric   //   - if there are two or more related defs in IA (i.e. coming from
10690946e70aSDimitry Andric   //     the same machine operand), then only push one def on the stack,
10700946e70aSDimitry Andric   //   - if there are multiple unrelated defs of non-overlapping
10710946e70aSDimitry Andric   //     subregisters of S, then the stack for S will have both (in an
10720946e70aSDimitry Andric   //     unspecified order), but the order does not matter from the data-
10730946e70aSDimitry Andric   //     -flow perspective.
10740946e70aSDimitry Andric 
10750946e70aSDimitry Andric   for (NodeAddr<DefNode*> DA : IA.Addr->members_if(IsDef, *this)) {
10760946e70aSDimitry Andric     if (Visited.count(DA.Id))
10770946e70aSDimitry Andric       continue;
10780946e70aSDimitry Andric     if (DA.Addr->getFlags() & NodeAttrs::Clobbering)
10790946e70aSDimitry Andric       continue;
10800946e70aSDimitry Andric 
10810946e70aSDimitry Andric     NodeList Rel = getRelatedRefs(IA, DA);
10820946e70aSDimitry Andric     NodeAddr<DefNode*> PDA = Rel.front();
10830946e70aSDimitry Andric     RegisterRef RR = PDA.Addr->getRegRef(*this);
10840946e70aSDimitry Andric #ifndef NDEBUG
10850946e70aSDimitry Andric     // Assert if the register is defined in two or more unrelated defs.
10860946e70aSDimitry Andric     // This could happen if there are two or more def operands defining it.
10870946e70aSDimitry Andric     if (!Defined.insert(RR.Reg).second) {
10880946e70aSDimitry Andric       MachineInstr *MI = NodeAddr<StmtNode*>(IA).Addr->getCode();
10890946e70aSDimitry Andric       dbgs() << "Multiple definitions of register: "
10900946e70aSDimitry Andric              << Print<RegisterRef>(RR, *this) << " in\n  " << *MI << "in "
10910946e70aSDimitry Andric              << printMBBReference(*MI->getParent()) << '\n';
10920946e70aSDimitry Andric       llvm_unreachable(nullptr);
10930946e70aSDimitry Andric     }
10940946e70aSDimitry Andric #endif
10950946e70aSDimitry Andric     // Push the definition on the stack for the register and all aliases.
10960946e70aSDimitry Andric     // The def stack traversal in linkNodeUp will check the exact aliasing.
10970946e70aSDimitry Andric     DefM[RR.Reg].push(DA);
10980946e70aSDimitry Andric     for (RegisterId A : PRI.getAliasSet(RR.Reg)) {
10990946e70aSDimitry Andric       // Check that we don't push the same def twice.
11000946e70aSDimitry Andric       assert(A != RR.Reg);
11010946e70aSDimitry Andric       DefM[A].push(DA);
11020946e70aSDimitry Andric     }
11030946e70aSDimitry Andric     // Mark all the related defs as visited.
11040946e70aSDimitry Andric     for (NodeAddr<NodeBase*> T : Rel)
11050946e70aSDimitry Andric       Visited.insert(T.Id);
11060946e70aSDimitry Andric   }
11070946e70aSDimitry Andric }
11080946e70aSDimitry Andric 
11090946e70aSDimitry Andric // Return the list of all reference nodes related to RA, including RA itself.
11100946e70aSDimitry Andric // See "getNextRelated" for the meaning of a "related reference".
11110946e70aSDimitry Andric NodeList DataFlowGraph::getRelatedRefs(NodeAddr<InstrNode*> IA,
11120946e70aSDimitry Andric       NodeAddr<RefNode*> RA) const {
11130946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
11140946e70aSDimitry Andric 
11150946e70aSDimitry Andric   NodeList Refs;
11160946e70aSDimitry Andric   NodeId Start = RA.Id;
11170946e70aSDimitry Andric   do {
11180946e70aSDimitry Andric     Refs.push_back(RA);
11190946e70aSDimitry Andric     RA = getNextRelated(IA, RA);
11200946e70aSDimitry Andric   } while (RA.Id != 0 && RA.Id != Start);
11210946e70aSDimitry Andric   return Refs;
11220946e70aSDimitry Andric }
11230946e70aSDimitry Andric 
11240946e70aSDimitry Andric // Clear all information in the graph.
11250946e70aSDimitry Andric void DataFlowGraph::reset() {
11260946e70aSDimitry Andric   Memory.clear();
11270946e70aSDimitry Andric   BlockNodes.clear();
11280946e70aSDimitry Andric   Func = NodeAddr<FuncNode*>();
11290946e70aSDimitry Andric }
11300946e70aSDimitry Andric 
11310946e70aSDimitry Andric // Return the next reference node in the instruction node IA that is related
11320946e70aSDimitry Andric // to RA. Conceptually, two reference nodes are related if they refer to the
11330946e70aSDimitry Andric // same instance of a register access, but differ in flags or other minor
11340946e70aSDimitry Andric // characteristics. Specific examples of related nodes are shadow reference
11350946e70aSDimitry Andric // nodes.
11360946e70aSDimitry Andric // Return the equivalent of nullptr if there are no more related references.
11370946e70aSDimitry Andric NodeAddr<RefNode*> DataFlowGraph::getNextRelated(NodeAddr<InstrNode*> IA,
11380946e70aSDimitry Andric       NodeAddr<RefNode*> RA) const {
11390946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
11400946e70aSDimitry Andric 
11410946e70aSDimitry Andric   auto Related = [this,RA](NodeAddr<RefNode*> TA) -> bool {
11420946e70aSDimitry Andric     if (TA.Addr->getKind() != RA.Addr->getKind())
11430946e70aSDimitry Andric       return false;
11440946e70aSDimitry Andric     if (TA.Addr->getRegRef(*this) != RA.Addr->getRegRef(*this))
11450946e70aSDimitry Andric       return false;
11460946e70aSDimitry Andric     return true;
11470946e70aSDimitry Andric   };
11480946e70aSDimitry Andric   auto RelatedStmt = [&Related,RA](NodeAddr<RefNode*> TA) -> bool {
11490946e70aSDimitry Andric     return Related(TA) &&
11500946e70aSDimitry Andric            &RA.Addr->getOp() == &TA.Addr->getOp();
11510946e70aSDimitry Andric   };
11520946e70aSDimitry Andric   auto RelatedPhi = [&Related,RA](NodeAddr<RefNode*> TA) -> bool {
11530946e70aSDimitry Andric     if (!Related(TA))
11540946e70aSDimitry Andric       return false;
11550946e70aSDimitry Andric     if (TA.Addr->getKind() != NodeAttrs::Use)
11560946e70aSDimitry Andric       return true;
11570946e70aSDimitry Andric     // For phi uses, compare predecessor blocks.
11580946e70aSDimitry Andric     const NodeAddr<const PhiUseNode*> TUA = TA;
11590946e70aSDimitry Andric     const NodeAddr<const PhiUseNode*> RUA = RA;
11600946e70aSDimitry Andric     return TUA.Addr->getPredecessor() == RUA.Addr->getPredecessor();
11610946e70aSDimitry Andric   };
11620946e70aSDimitry Andric 
11630946e70aSDimitry Andric   RegisterRef RR = RA.Addr->getRegRef(*this);
11640946e70aSDimitry Andric   if (IA.Addr->getKind() == NodeAttrs::Stmt)
11650946e70aSDimitry Andric     return RA.Addr->getNextRef(RR, RelatedStmt, true, *this);
11660946e70aSDimitry Andric   return RA.Addr->getNextRef(RR, RelatedPhi, true, *this);
11670946e70aSDimitry Andric }
11680946e70aSDimitry Andric 
11690946e70aSDimitry Andric // Find the next node related to RA in IA that satisfies condition P.
11700946e70aSDimitry Andric // If such a node was found, return a pair where the second element is the
11710946e70aSDimitry Andric // located node. If such a node does not exist, return a pair where the
11720946e70aSDimitry Andric // first element is the element after which such a node should be inserted,
11730946e70aSDimitry Andric // and the second element is a null-address.
11740946e70aSDimitry Andric template <typename Predicate>
11750946e70aSDimitry Andric std::pair<NodeAddr<RefNode*>,NodeAddr<RefNode*>>
11760946e70aSDimitry Andric DataFlowGraph::locateNextRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
11770946e70aSDimitry Andric       Predicate P) const {
11780946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
11790946e70aSDimitry Andric 
11800946e70aSDimitry Andric   NodeAddr<RefNode*> NA;
11810946e70aSDimitry Andric   NodeId Start = RA.Id;
11820946e70aSDimitry Andric   while (true) {
11830946e70aSDimitry Andric     NA = getNextRelated(IA, RA);
11840946e70aSDimitry Andric     if (NA.Id == 0 || NA.Id == Start)
11850946e70aSDimitry Andric       break;
11860946e70aSDimitry Andric     if (P(NA))
11870946e70aSDimitry Andric       break;
11880946e70aSDimitry Andric     RA = NA;
11890946e70aSDimitry Andric   }
11900946e70aSDimitry Andric 
11910946e70aSDimitry Andric   if (NA.Id != 0 && NA.Id != Start)
11920946e70aSDimitry Andric     return std::make_pair(RA, NA);
11930946e70aSDimitry Andric   return std::make_pair(RA, NodeAddr<RefNode*>());
11940946e70aSDimitry Andric }
11950946e70aSDimitry Andric 
11960946e70aSDimitry Andric // Get the next shadow node in IA corresponding to RA, and optionally create
11970946e70aSDimitry Andric // such a node if it does not exist.
11980946e70aSDimitry Andric NodeAddr<RefNode*> DataFlowGraph::getNextShadow(NodeAddr<InstrNode*> IA,
11990946e70aSDimitry Andric       NodeAddr<RefNode*> RA, bool Create) {
12000946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
12010946e70aSDimitry Andric 
12020946e70aSDimitry Andric   uint16_t Flags = RA.Addr->getFlags() | NodeAttrs::Shadow;
12030946e70aSDimitry Andric   auto IsShadow = [Flags] (NodeAddr<RefNode*> TA) -> bool {
12040946e70aSDimitry Andric     return TA.Addr->getFlags() == Flags;
12050946e70aSDimitry Andric   };
12060946e70aSDimitry Andric   auto Loc = locateNextRef(IA, RA, IsShadow);
12070946e70aSDimitry Andric   if (Loc.second.Id != 0 || !Create)
12080946e70aSDimitry Andric     return Loc.second;
12090946e70aSDimitry Andric 
12100946e70aSDimitry Andric   // Create a copy of RA and mark is as shadow.
12110946e70aSDimitry Andric   NodeAddr<RefNode*> NA = cloneNode(RA);
12120946e70aSDimitry Andric   NA.Addr->setFlags(Flags | NodeAttrs::Shadow);
12130946e70aSDimitry Andric   IA.Addr->addMemberAfter(Loc.first, NA, *this);
12140946e70aSDimitry Andric   return NA;
12150946e70aSDimitry Andric }
12160946e70aSDimitry Andric 
12170946e70aSDimitry Andric // Get the next shadow node in IA corresponding to RA. Return null-address
12180946e70aSDimitry Andric // if such a node does not exist.
12190946e70aSDimitry Andric NodeAddr<RefNode*> DataFlowGraph::getNextShadow(NodeAddr<InstrNode*> IA,
12200946e70aSDimitry Andric       NodeAddr<RefNode*> RA) const {
12210946e70aSDimitry Andric   assert(IA.Id != 0 && RA.Id != 0);
12220946e70aSDimitry Andric   uint16_t Flags = RA.Addr->getFlags() | NodeAttrs::Shadow;
12230946e70aSDimitry Andric   auto IsShadow = [Flags] (NodeAddr<RefNode*> TA) -> bool {
12240946e70aSDimitry Andric     return TA.Addr->getFlags() == Flags;
12250946e70aSDimitry Andric   };
12260946e70aSDimitry Andric   return locateNextRef(IA, RA, IsShadow).second;
12270946e70aSDimitry Andric }
12280946e70aSDimitry Andric 
12290946e70aSDimitry Andric // Create a new statement node in the block node BA that corresponds to
12300946e70aSDimitry Andric // the machine instruction MI.
12310946e70aSDimitry Andric void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
12320946e70aSDimitry Andric   NodeAddr<StmtNode*> SA = newStmt(BA, &In);
12330946e70aSDimitry Andric 
12340946e70aSDimitry Andric   auto isCall = [] (const MachineInstr &In) -> bool {
12350946e70aSDimitry Andric     if (In.isCall())
12360946e70aSDimitry Andric       return true;
12370946e70aSDimitry Andric     // Is tail call?
12380946e70aSDimitry Andric     if (In.isBranch()) {
12390946e70aSDimitry Andric       for (const MachineOperand &Op : In.operands())
12400946e70aSDimitry Andric         if (Op.isGlobal() || Op.isSymbol())
12410946e70aSDimitry Andric           return true;
12420946e70aSDimitry Andric       // Assume indirect branches are calls. This is for the purpose of
12430946e70aSDimitry Andric       // keeping implicit operands, and so it won't hurt on intra-function
12440946e70aSDimitry Andric       // indirect branches.
12450946e70aSDimitry Andric       if (In.isIndirectBranch())
12460946e70aSDimitry Andric         return true;
12470946e70aSDimitry Andric     }
12480946e70aSDimitry Andric     return false;
12490946e70aSDimitry Andric   };
12500946e70aSDimitry Andric 
12510946e70aSDimitry Andric   auto isDefUndef = [this] (const MachineInstr &In, RegisterRef DR) -> bool {
12520946e70aSDimitry Andric     // This instruction defines DR. Check if there is a use operand that
12530946e70aSDimitry Andric     // would make DR live on entry to the instruction.
12540946e70aSDimitry Andric     for (const MachineOperand &Op : In.operands()) {
12550946e70aSDimitry Andric       if (!Op.isReg() || Op.getReg() == 0 || !Op.isUse() || Op.isUndef())
12560946e70aSDimitry Andric         continue;
12570946e70aSDimitry Andric       RegisterRef UR = makeRegRef(Op);
12580946e70aSDimitry Andric       if (PRI.alias(DR, UR))
12590946e70aSDimitry Andric         return false;
12600946e70aSDimitry Andric     }
12610946e70aSDimitry Andric     return true;
12620946e70aSDimitry Andric   };
12630946e70aSDimitry Andric 
12640946e70aSDimitry Andric   bool IsCall = isCall(In);
12650946e70aSDimitry Andric   unsigned NumOps = In.getNumOperands();
12660946e70aSDimitry Andric 
12670946e70aSDimitry Andric   // Avoid duplicate implicit defs. This will not detect cases of implicit
12680946e70aSDimitry Andric   // defs that define registers that overlap, but it is not clear how to
12690946e70aSDimitry Andric   // interpret that in the absence of explicit defs. Overlapping explicit
12700946e70aSDimitry Andric   // defs are likely illegal already.
12710946e70aSDimitry Andric   BitVector DoneDefs(TRI.getNumRegs());
12720946e70aSDimitry Andric   // Process explicit defs first.
12730946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
12740946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
12750946e70aSDimitry Andric     if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
12760946e70aSDimitry Andric       continue;
12770946e70aSDimitry Andric     Register R = Op.getReg();
12780946e70aSDimitry Andric     if (!R || !Register::isPhysicalRegister(R))
12790946e70aSDimitry Andric       continue;
12800946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::None;
12810946e70aSDimitry Andric     if (TOI.isPreserving(In, OpN)) {
12820946e70aSDimitry Andric       Flags |= NodeAttrs::Preserving;
12830946e70aSDimitry Andric       // If the def is preserving, check if it is also undefined.
12840946e70aSDimitry Andric       if (isDefUndef(In, makeRegRef(Op)))
12850946e70aSDimitry Andric         Flags |= NodeAttrs::Undef;
12860946e70aSDimitry Andric     }
12870946e70aSDimitry Andric     if (TOI.isClobbering(In, OpN))
12880946e70aSDimitry Andric       Flags |= NodeAttrs::Clobbering;
12890946e70aSDimitry Andric     if (TOI.isFixedReg(In, OpN))
12900946e70aSDimitry Andric       Flags |= NodeAttrs::Fixed;
12910946e70aSDimitry Andric     if (IsCall && Op.isDead())
12920946e70aSDimitry Andric       Flags |= NodeAttrs::Dead;
12930946e70aSDimitry Andric     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
12940946e70aSDimitry Andric     SA.Addr->addMember(DA, *this);
12950946e70aSDimitry Andric     assert(!DoneDefs.test(R));
12960946e70aSDimitry Andric     DoneDefs.set(R);
12970946e70aSDimitry Andric   }
12980946e70aSDimitry Andric 
12990946e70aSDimitry Andric   // Process reg-masks (as clobbers).
13000946e70aSDimitry Andric   BitVector DoneClobbers(TRI.getNumRegs());
13010946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
13020946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
13030946e70aSDimitry Andric     if (!Op.isRegMask())
13040946e70aSDimitry Andric       continue;
13050946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::Clobbering | NodeAttrs::Fixed |
13060946e70aSDimitry Andric                      NodeAttrs::Dead;
13070946e70aSDimitry Andric     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
13080946e70aSDimitry Andric     SA.Addr->addMember(DA, *this);
13090946e70aSDimitry Andric     // Record all clobbered registers in DoneDefs.
13100946e70aSDimitry Andric     const uint32_t *RM = Op.getRegMask();
13110946e70aSDimitry Andric     for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i)
13120946e70aSDimitry Andric       if (!(RM[i/32] & (1u << (i%32))))
13130946e70aSDimitry Andric         DoneClobbers.set(i);
13140946e70aSDimitry Andric   }
13150946e70aSDimitry Andric 
13160946e70aSDimitry Andric   // Process implicit defs, skipping those that have already been added
13170946e70aSDimitry Andric   // as explicit.
13180946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
13190946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
13200946e70aSDimitry Andric     if (!Op.isReg() || !Op.isDef() || !Op.isImplicit())
13210946e70aSDimitry Andric       continue;
13220946e70aSDimitry Andric     Register R = Op.getReg();
13230946e70aSDimitry Andric     if (!R || !Register::isPhysicalRegister(R) || DoneDefs.test(R))
13240946e70aSDimitry Andric       continue;
13250946e70aSDimitry Andric     RegisterRef RR = makeRegRef(Op);
13260946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::None;
13270946e70aSDimitry Andric     if (TOI.isPreserving(In, OpN)) {
13280946e70aSDimitry Andric       Flags |= NodeAttrs::Preserving;
13290946e70aSDimitry Andric       // If the def is preserving, check if it is also undefined.
13300946e70aSDimitry Andric       if (isDefUndef(In, RR))
13310946e70aSDimitry Andric         Flags |= NodeAttrs::Undef;
13320946e70aSDimitry Andric     }
13330946e70aSDimitry Andric     if (TOI.isClobbering(In, OpN))
13340946e70aSDimitry Andric       Flags |= NodeAttrs::Clobbering;
13350946e70aSDimitry Andric     if (TOI.isFixedReg(In, OpN))
13360946e70aSDimitry Andric       Flags |= NodeAttrs::Fixed;
13370946e70aSDimitry Andric     if (IsCall && Op.isDead()) {
13380946e70aSDimitry Andric       if (DoneClobbers.test(R))
13390946e70aSDimitry Andric         continue;
13400946e70aSDimitry Andric       Flags |= NodeAttrs::Dead;
13410946e70aSDimitry Andric     }
13420946e70aSDimitry Andric     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
13430946e70aSDimitry Andric     SA.Addr->addMember(DA, *this);
13440946e70aSDimitry Andric     DoneDefs.set(R);
13450946e70aSDimitry Andric   }
13460946e70aSDimitry Andric 
13470946e70aSDimitry Andric   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
13480946e70aSDimitry Andric     MachineOperand &Op = In.getOperand(OpN);
13490946e70aSDimitry Andric     if (!Op.isReg() || !Op.isUse())
13500946e70aSDimitry Andric       continue;
13510946e70aSDimitry Andric     Register R = Op.getReg();
13520946e70aSDimitry Andric     if (!R || !Register::isPhysicalRegister(R))
13530946e70aSDimitry Andric       continue;
13540946e70aSDimitry Andric     uint16_t Flags = NodeAttrs::None;
13550946e70aSDimitry Andric     if (Op.isUndef())
13560946e70aSDimitry Andric       Flags |= NodeAttrs::Undef;
13570946e70aSDimitry Andric     if (TOI.isFixedReg(In, OpN))
13580946e70aSDimitry Andric       Flags |= NodeAttrs::Fixed;
13590946e70aSDimitry Andric     NodeAddr<UseNode*> UA = newUse(SA, Op, Flags);
13600946e70aSDimitry Andric     SA.Addr->addMember(UA, *this);
13610946e70aSDimitry Andric   }
13620946e70aSDimitry Andric }
13630946e70aSDimitry Andric 
13640946e70aSDimitry Andric // Scan all defs in the block node BA and record in PhiM the locations of
13650946e70aSDimitry Andric // phi nodes corresponding to these defs.
13660946e70aSDimitry Andric void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
13670946e70aSDimitry Andric       NodeAddr<BlockNode*> BA) {
13680946e70aSDimitry Andric   // Check all defs from block BA and record them in each block in BA's
13690946e70aSDimitry Andric   // iterated dominance frontier. This information will later be used to
13700946e70aSDimitry Andric   // create phi nodes.
13710946e70aSDimitry Andric   MachineBasicBlock *BB = BA.Addr->getCode();
13720946e70aSDimitry Andric   assert(BB);
13730946e70aSDimitry Andric   auto DFLoc = MDF.find(BB);
13740946e70aSDimitry Andric   if (DFLoc == MDF.end() || DFLoc->second.empty())
13750946e70aSDimitry Andric     return;
13760946e70aSDimitry Andric 
13770946e70aSDimitry Andric   // Traverse all instructions in the block and collect the set of all
13780946e70aSDimitry Andric   // defined references. For each reference there will be a phi created
13790946e70aSDimitry Andric   // in the block's iterated dominance frontier.
13800946e70aSDimitry Andric   // This is done to make sure that each defined reference gets only one
13810946e70aSDimitry Andric   // phi node, even if it is defined multiple times.
13820946e70aSDimitry Andric   RegisterSet Defs;
13830946e70aSDimitry Andric   for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this))
13840946e70aSDimitry Andric     for (NodeAddr<RefNode*> RA : IA.Addr->members_if(IsDef, *this))
13850946e70aSDimitry Andric       Defs.insert(RA.Addr->getRegRef(*this));
13860946e70aSDimitry Andric 
13870946e70aSDimitry Andric   // Calculate the iterated dominance frontier of BB.
13880946e70aSDimitry Andric   const MachineDominanceFrontier::DomSetType &DF = DFLoc->second;
13890946e70aSDimitry Andric   SetVector<MachineBasicBlock*> IDF(DF.begin(), DF.end());
13900946e70aSDimitry Andric   for (unsigned i = 0; i < IDF.size(); ++i) {
13910946e70aSDimitry Andric     auto F = MDF.find(IDF[i]);
13920946e70aSDimitry Andric     if (F != MDF.end())
13930946e70aSDimitry Andric       IDF.insert(F->second.begin(), F->second.end());
13940946e70aSDimitry Andric   }
13950946e70aSDimitry Andric 
13960946e70aSDimitry Andric   // Finally, add the set of defs to each block in the iterated dominance
13970946e70aSDimitry Andric   // frontier.
1398*fcaf7f86SDimitry Andric   for (auto *DB : IDF) {
13990946e70aSDimitry Andric     NodeAddr<BlockNode*> DBA = findBlock(DB);
14000946e70aSDimitry Andric     PhiM[DBA.Id].insert(Defs.begin(), Defs.end());
14010946e70aSDimitry Andric   }
14020946e70aSDimitry Andric }
14030946e70aSDimitry Andric 
14040946e70aSDimitry Andric // Given the locations of phi nodes in the map PhiM, create the phi nodes
14050946e70aSDimitry Andric // that are located in the block node BA.
14060946e70aSDimitry Andric void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, RegisterSet &AllRefs,
14070946e70aSDimitry Andric       NodeAddr<BlockNode*> BA) {
14080946e70aSDimitry Andric   // Check if this blocks has any DF defs, i.e. if there are any defs
14090946e70aSDimitry Andric   // that this block is in the iterated dominance frontier of.
14100946e70aSDimitry Andric   auto HasDF = PhiM.find(BA.Id);
14110946e70aSDimitry Andric   if (HasDF == PhiM.end() || HasDF->second.empty())
14120946e70aSDimitry Andric     return;
14130946e70aSDimitry Andric 
14140946e70aSDimitry Andric   // First, remove all R in Refs in such that there exists T in Refs
14150946e70aSDimitry Andric   // such that T covers R. In other words, only leave those refs that
14160946e70aSDimitry Andric   // are not covered by another ref (i.e. maximal with respect to covering).
14170946e70aSDimitry Andric 
14180946e70aSDimitry Andric   auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
14190946e70aSDimitry Andric     for (RegisterRef I : RRs)
14200946e70aSDimitry Andric       if (I != RR && RegisterAggr::isCoverOf(I, RR, PRI))
14210946e70aSDimitry Andric         RR = I;
14220946e70aSDimitry Andric     return RR;
14230946e70aSDimitry Andric   };
14240946e70aSDimitry Andric 
14250946e70aSDimitry Andric   RegisterSet MaxDF;
14260946e70aSDimitry Andric   for (RegisterRef I : HasDF->second)
14270946e70aSDimitry Andric     MaxDF.insert(MaxCoverIn(I, HasDF->second));
14280946e70aSDimitry Andric 
14290946e70aSDimitry Andric   std::vector<RegisterRef> MaxRefs;
14300946e70aSDimitry Andric   for (RegisterRef I : MaxDF)
14310946e70aSDimitry Andric     MaxRefs.push_back(MaxCoverIn(I, AllRefs));
14320946e70aSDimitry Andric 
14330946e70aSDimitry Andric   // Now, for each R in MaxRefs, get the alias closure of R. If the closure
14340946e70aSDimitry Andric   // only has R in it, create a phi a def for R. Otherwise, create a phi,
14350946e70aSDimitry Andric   // and add a def for each S in the closure.
14360946e70aSDimitry Andric 
14370946e70aSDimitry Andric   // Sort the refs so that the phis will be created in a deterministic order.
14380946e70aSDimitry Andric   llvm::sort(MaxRefs);
14390946e70aSDimitry Andric   // Remove duplicates.
14400946e70aSDimitry Andric   auto NewEnd = std::unique(MaxRefs.begin(), MaxRefs.end());
14410946e70aSDimitry Andric   MaxRefs.erase(NewEnd, MaxRefs.end());
14420946e70aSDimitry Andric 
14430946e70aSDimitry Andric   auto Aliased = [this,&MaxRefs](RegisterRef RR,
14440946e70aSDimitry Andric                                  std::vector<unsigned> &Closure) -> bool {
14450946e70aSDimitry Andric     for (unsigned I : Closure)
14460946e70aSDimitry Andric       if (PRI.alias(RR, MaxRefs[I]))
14470946e70aSDimitry Andric         return true;
14480946e70aSDimitry Andric     return false;
14490946e70aSDimitry Andric   };
14500946e70aSDimitry Andric 
14510946e70aSDimitry Andric   // Prepare a list of NodeIds of the block's predecessors.
14520946e70aSDimitry Andric   NodeList Preds;
14530946e70aSDimitry Andric   const MachineBasicBlock *MBB = BA.Addr->getCode();
14540946e70aSDimitry Andric   for (MachineBasicBlock *PB : MBB->predecessors())
14550946e70aSDimitry Andric     Preds.push_back(findBlock(PB));
14560946e70aSDimitry Andric 
14570946e70aSDimitry Andric   while (!MaxRefs.empty()) {
14580946e70aSDimitry Andric     // Put the first element in the closure, and then add all subsequent
14590946e70aSDimitry Andric     // elements from MaxRefs to it, if they alias at least one element
14600946e70aSDimitry Andric     // already in the closure.
14610946e70aSDimitry Andric     // ClosureIdx: vector of indices in MaxRefs of members of the closure.
14620946e70aSDimitry Andric     std::vector<unsigned> ClosureIdx = { 0 };
14630946e70aSDimitry Andric     for (unsigned i = 1; i != MaxRefs.size(); ++i)
14640946e70aSDimitry Andric       if (Aliased(MaxRefs[i], ClosureIdx))
14650946e70aSDimitry Andric         ClosureIdx.push_back(i);
14660946e70aSDimitry Andric 
14670946e70aSDimitry Andric     // Build a phi for the closure.
14680946e70aSDimitry Andric     unsigned CS = ClosureIdx.size();
14690946e70aSDimitry Andric     NodeAddr<PhiNode*> PA = newPhi(BA);
14700946e70aSDimitry Andric 
14710946e70aSDimitry Andric     // Add defs.
14720946e70aSDimitry Andric     for (unsigned X = 0; X != CS; ++X) {
14730946e70aSDimitry Andric       RegisterRef RR = MaxRefs[ClosureIdx[X]];
14740946e70aSDimitry Andric       uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
14750946e70aSDimitry Andric       NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
14760946e70aSDimitry Andric       PA.Addr->addMember(DA, *this);
14770946e70aSDimitry Andric     }
14780946e70aSDimitry Andric     // Add phi uses.
14790946e70aSDimitry Andric     for (NodeAddr<BlockNode*> PBA : Preds) {
14800946e70aSDimitry Andric       for (unsigned X = 0; X != CS; ++X) {
14810946e70aSDimitry Andric         RegisterRef RR = MaxRefs[ClosureIdx[X]];
14820946e70aSDimitry Andric         NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
14830946e70aSDimitry Andric         PA.Addr->addMember(PUA, *this);
14840946e70aSDimitry Andric       }
14850946e70aSDimitry Andric     }
14860946e70aSDimitry Andric 
14870946e70aSDimitry Andric     // Erase from MaxRefs all elements in the closure.
14880946e70aSDimitry Andric     auto Begin = MaxRefs.begin();
14890eae32dcSDimitry Andric     for (unsigned Idx : llvm::reverse(ClosureIdx))
14900eae32dcSDimitry Andric       MaxRefs.erase(Begin + Idx);
14910946e70aSDimitry Andric   }
14920946e70aSDimitry Andric }
14930946e70aSDimitry Andric 
14940946e70aSDimitry Andric // Remove any unneeded phi nodes that were created during the build process.
14950946e70aSDimitry Andric void DataFlowGraph::removeUnusedPhis() {
14960946e70aSDimitry Andric   // This will remove unused phis, i.e. phis where each def does not reach
14970946e70aSDimitry Andric   // any uses or other defs. This will not detect or remove circular phi
14980946e70aSDimitry Andric   // chains that are otherwise dead. Unused/dead phis are created during
14990946e70aSDimitry Andric   // the build process and this function is intended to remove these cases
15000946e70aSDimitry Andric   // that are easily determinable to be unnecessary.
15010946e70aSDimitry Andric 
15020946e70aSDimitry Andric   SetVector<NodeId> PhiQ;
15030946e70aSDimitry Andric   for (NodeAddr<BlockNode*> BA : Func.Addr->members(*this)) {
15040946e70aSDimitry Andric     for (auto P : BA.Addr->members_if(IsPhi, *this))
15050946e70aSDimitry Andric       PhiQ.insert(P.Id);
15060946e70aSDimitry Andric   }
15070946e70aSDimitry Andric 
15080946e70aSDimitry Andric   static auto HasUsedDef = [](NodeList &Ms) -> bool {
15090946e70aSDimitry Andric     for (NodeAddr<NodeBase*> M : Ms) {
15100946e70aSDimitry Andric       if (M.Addr->getKind() != NodeAttrs::Def)
15110946e70aSDimitry Andric         continue;
15120946e70aSDimitry Andric       NodeAddr<DefNode*> DA = M;
15130946e70aSDimitry Andric       if (DA.Addr->getReachedDef() != 0 || DA.Addr->getReachedUse() != 0)
15140946e70aSDimitry Andric         return true;
15150946e70aSDimitry Andric     }
15160946e70aSDimitry Andric     return false;
15170946e70aSDimitry Andric   };
15180946e70aSDimitry Andric 
15190946e70aSDimitry Andric   // Any phi, if it is removed, may affect other phis (make them dead).
15200946e70aSDimitry Andric   // For each removed phi, collect the potentially affected phis and add
15210946e70aSDimitry Andric   // them back to the queue.
15220946e70aSDimitry Andric   while (!PhiQ.empty()) {
15230946e70aSDimitry Andric     auto PA = addr<PhiNode*>(PhiQ[0]);
15240946e70aSDimitry Andric     PhiQ.remove(PA.Id);
15250946e70aSDimitry Andric     NodeList Refs = PA.Addr->members(*this);
15260946e70aSDimitry Andric     if (HasUsedDef(Refs))
15270946e70aSDimitry Andric       continue;
15280946e70aSDimitry Andric     for (NodeAddr<RefNode*> RA : Refs) {
15290946e70aSDimitry Andric       if (NodeId RD = RA.Addr->getReachingDef()) {
15300946e70aSDimitry Andric         auto RDA = addr<DefNode*>(RD);
15310946e70aSDimitry Andric         NodeAddr<InstrNode*> OA = RDA.Addr->getOwner(*this);
15320946e70aSDimitry Andric         if (IsPhi(OA))
15330946e70aSDimitry Andric           PhiQ.insert(OA.Id);
15340946e70aSDimitry Andric       }
15350946e70aSDimitry Andric       if (RA.Addr->isDef())
15360946e70aSDimitry Andric         unlinkDef(RA, true);
15370946e70aSDimitry Andric       else
15380946e70aSDimitry Andric         unlinkUse(RA, true);
15390946e70aSDimitry Andric     }
15400946e70aSDimitry Andric     NodeAddr<BlockNode*> BA = PA.Addr->getOwner(*this);
15410946e70aSDimitry Andric     BA.Addr->removeMember(PA, *this);
15420946e70aSDimitry Andric   }
15430946e70aSDimitry Andric }
15440946e70aSDimitry Andric 
15450946e70aSDimitry Andric // For a given reference node TA in an instruction node IA, connect the
15460946e70aSDimitry Andric // reaching def of TA to the appropriate def node. Create any shadow nodes
15470946e70aSDimitry Andric // as appropriate.
15480946e70aSDimitry Andric template <typename T>
15490946e70aSDimitry Andric void DataFlowGraph::linkRefUp(NodeAddr<InstrNode*> IA, NodeAddr<T> TA,
15500946e70aSDimitry Andric       DefStack &DS) {
15510946e70aSDimitry Andric   if (DS.empty())
15520946e70aSDimitry Andric     return;
15530946e70aSDimitry Andric   RegisterRef RR = TA.Addr->getRegRef(*this);
15540946e70aSDimitry Andric   NodeAddr<T> TAP;
15550946e70aSDimitry Andric 
15560946e70aSDimitry Andric   // References from the def stack that have been examined so far.
15570946e70aSDimitry Andric   RegisterAggr Defs(PRI);
15580946e70aSDimitry Andric 
15590946e70aSDimitry Andric   for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
15600946e70aSDimitry Andric     RegisterRef QR = I->Addr->getRegRef(*this);
15610946e70aSDimitry Andric 
15620946e70aSDimitry Andric     // Skip all defs that are aliased to any of the defs that we have already
15630946e70aSDimitry Andric     // seen. If this completes a cover of RR, stop the stack traversal.
15640946e70aSDimitry Andric     bool Alias = Defs.hasAliasOf(QR);
15650946e70aSDimitry Andric     bool Cover = Defs.insert(QR).hasCoverOf(RR);
15660946e70aSDimitry Andric     if (Alias) {
15670946e70aSDimitry Andric       if (Cover)
15680946e70aSDimitry Andric         break;
15690946e70aSDimitry Andric       continue;
15700946e70aSDimitry Andric     }
15710946e70aSDimitry Andric 
15720946e70aSDimitry Andric     // The reaching def.
15730946e70aSDimitry Andric     NodeAddr<DefNode*> RDA = *I;
15740946e70aSDimitry Andric 
15750946e70aSDimitry Andric     // Pick the reached node.
15760946e70aSDimitry Andric     if (TAP.Id == 0) {
15770946e70aSDimitry Andric       TAP = TA;
15780946e70aSDimitry Andric     } else {
15790946e70aSDimitry Andric       // Mark the existing ref as "shadow" and create a new shadow.
15800946e70aSDimitry Andric       TAP.Addr->setFlags(TAP.Addr->getFlags() | NodeAttrs::Shadow);
15810946e70aSDimitry Andric       TAP = getNextShadow(IA, TAP, true);
15820946e70aSDimitry Andric     }
15830946e70aSDimitry Andric 
15840946e70aSDimitry Andric     // Create the link.
15850946e70aSDimitry Andric     TAP.Addr->linkToDef(TAP.Id, RDA);
15860946e70aSDimitry Andric 
15870946e70aSDimitry Andric     if (Cover)
15880946e70aSDimitry Andric       break;
15890946e70aSDimitry Andric   }
15900946e70aSDimitry Andric }
15910946e70aSDimitry Andric 
15920946e70aSDimitry Andric // Create data-flow links for all reference nodes in the statement node SA.
15930946e70aSDimitry Andric template <typename Predicate>
15940946e70aSDimitry Andric void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA,
15950946e70aSDimitry Andric       Predicate P) {
15960946e70aSDimitry Andric #ifndef NDEBUG
15970946e70aSDimitry Andric   RegisterSet Defs;
15980946e70aSDimitry Andric #endif
15990946e70aSDimitry Andric 
16000946e70aSDimitry Andric   // Link all nodes (upwards in the data-flow) with their reaching defs.
16010946e70aSDimitry Andric   for (NodeAddr<RefNode*> RA : SA.Addr->members_if(P, *this)) {
16020946e70aSDimitry Andric     uint16_t Kind = RA.Addr->getKind();
16030946e70aSDimitry Andric     assert(Kind == NodeAttrs::Def || Kind == NodeAttrs::Use);
16040946e70aSDimitry Andric     RegisterRef RR = RA.Addr->getRegRef(*this);
16050946e70aSDimitry Andric #ifndef NDEBUG
16060946e70aSDimitry Andric     // Do not expect multiple defs of the same reference.
16070946e70aSDimitry Andric     assert(Kind != NodeAttrs::Def || !Defs.count(RR));
16080946e70aSDimitry Andric     Defs.insert(RR);
16090946e70aSDimitry Andric #endif
16100946e70aSDimitry Andric 
16110946e70aSDimitry Andric     auto F = DefM.find(RR.Reg);
16120946e70aSDimitry Andric     if (F == DefM.end())
16130946e70aSDimitry Andric       continue;
16140946e70aSDimitry Andric     DefStack &DS = F->second;
16150946e70aSDimitry Andric     if (Kind == NodeAttrs::Use)
16160946e70aSDimitry Andric       linkRefUp<UseNode*>(SA, RA, DS);
16170946e70aSDimitry Andric     else if (Kind == NodeAttrs::Def)
16180946e70aSDimitry Andric       linkRefUp<DefNode*>(SA, RA, DS);
16190946e70aSDimitry Andric     else
16200946e70aSDimitry Andric       llvm_unreachable("Unexpected node in instruction");
16210946e70aSDimitry Andric   }
16220946e70aSDimitry Andric }
16230946e70aSDimitry Andric 
16240946e70aSDimitry Andric // Create data-flow links for all instructions in the block node BA. This
16250946e70aSDimitry Andric // will include updating any phi nodes in BA.
16260946e70aSDimitry Andric void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA) {
16270946e70aSDimitry Andric   // Push block delimiters.
16280946e70aSDimitry Andric   markBlock(BA.Id, DefM);
16290946e70aSDimitry Andric 
16300946e70aSDimitry Andric   auto IsClobber = [] (NodeAddr<RefNode*> RA) -> bool {
16310946e70aSDimitry Andric     return IsDef(RA) && (RA.Addr->getFlags() & NodeAttrs::Clobbering);
16320946e70aSDimitry Andric   };
16330946e70aSDimitry Andric   auto IsNoClobber = [] (NodeAddr<RefNode*> RA) -> bool {
16340946e70aSDimitry Andric     return IsDef(RA) && !(RA.Addr->getFlags() & NodeAttrs::Clobbering);
16350946e70aSDimitry Andric   };
16360946e70aSDimitry Andric 
16370946e70aSDimitry Andric   assert(BA.Addr && "block node address is needed to create a data-flow link");
16380946e70aSDimitry Andric   // For each non-phi instruction in the block, link all the defs and uses
16390946e70aSDimitry Andric   // to their reaching defs. For any member of the block (including phis),
16400946e70aSDimitry Andric   // push the defs on the corresponding stacks.
16410946e70aSDimitry Andric   for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this)) {
16420946e70aSDimitry Andric     // Ignore phi nodes here. They will be linked part by part from the
16430946e70aSDimitry Andric     // predecessors.
16440946e70aSDimitry Andric     if (IA.Addr->getKind() == NodeAttrs::Stmt) {
16450946e70aSDimitry Andric       linkStmtRefs(DefM, IA, IsUse);
16460946e70aSDimitry Andric       linkStmtRefs(DefM, IA, IsClobber);
16470946e70aSDimitry Andric     }
16480946e70aSDimitry Andric 
16490946e70aSDimitry Andric     // Push the definitions on the stack.
16500946e70aSDimitry Andric     pushClobbers(IA, DefM);
16510946e70aSDimitry Andric 
16520946e70aSDimitry Andric     if (IA.Addr->getKind() == NodeAttrs::Stmt)
16530946e70aSDimitry Andric       linkStmtRefs(DefM, IA, IsNoClobber);
16540946e70aSDimitry Andric 
16550946e70aSDimitry Andric     pushDefs(IA, DefM);
16560946e70aSDimitry Andric   }
16570946e70aSDimitry Andric 
16580946e70aSDimitry Andric   // Recursively process all children in the dominator tree.
16590946e70aSDimitry Andric   MachineDomTreeNode *N = MDT.getNode(BA.Addr->getCode());
1660*fcaf7f86SDimitry Andric   for (auto *I : *N) {
16610946e70aSDimitry Andric     MachineBasicBlock *SB = I->getBlock();
16620946e70aSDimitry Andric     NodeAddr<BlockNode*> SBA = findBlock(SB);
16630946e70aSDimitry Andric     linkBlockRefs(DefM, SBA);
16640946e70aSDimitry Andric   }
16650946e70aSDimitry Andric 
16660946e70aSDimitry Andric   // Link the phi uses from the successor blocks.
16670946e70aSDimitry Andric   auto IsUseForBA = [BA](NodeAddr<NodeBase*> NA) -> bool {
16680946e70aSDimitry Andric     if (NA.Addr->getKind() != NodeAttrs::Use)
16690946e70aSDimitry Andric       return false;
16700946e70aSDimitry Andric     assert(NA.Addr->getFlags() & NodeAttrs::PhiRef);
16710946e70aSDimitry Andric     NodeAddr<PhiUseNode*> PUA = NA;
16720946e70aSDimitry Andric     return PUA.Addr->getPredecessor() == BA.Id;
16730946e70aSDimitry Andric   };
16740946e70aSDimitry Andric 
16750946e70aSDimitry Andric   RegisterSet EHLiveIns = getLandingPadLiveIns();
16760946e70aSDimitry Andric   MachineBasicBlock *MBB = BA.Addr->getCode();
16770946e70aSDimitry Andric 
16780946e70aSDimitry Andric   for (MachineBasicBlock *SB : MBB->successors()) {
16790946e70aSDimitry Andric     bool IsEHPad = SB->isEHPad();
16800946e70aSDimitry Andric     NodeAddr<BlockNode*> SBA = findBlock(SB);
16810946e70aSDimitry Andric     for (NodeAddr<InstrNode*> IA : SBA.Addr->members_if(IsPhi, *this)) {
16820946e70aSDimitry Andric       // Do not link phi uses for landing pad live-ins.
16830946e70aSDimitry Andric       if (IsEHPad) {
16840946e70aSDimitry Andric         // Find what register this phi is for.
16850946e70aSDimitry Andric         NodeAddr<RefNode*> RA = IA.Addr->getFirstMember(*this);
16860946e70aSDimitry Andric         assert(RA.Id != 0);
16870946e70aSDimitry Andric         if (EHLiveIns.count(RA.Addr->getRegRef(*this)))
16880946e70aSDimitry Andric           continue;
16890946e70aSDimitry Andric       }
16900946e70aSDimitry Andric       // Go over each phi use associated with MBB, and link it.
16910946e70aSDimitry Andric       for (auto U : IA.Addr->members_if(IsUseForBA, *this)) {
16920946e70aSDimitry Andric         NodeAddr<PhiUseNode*> PUA = U;
16930946e70aSDimitry Andric         RegisterRef RR = PUA.Addr->getRegRef(*this);
16940946e70aSDimitry Andric         linkRefUp<UseNode*>(IA, PUA, DefM[RR.Reg]);
16950946e70aSDimitry Andric       }
16960946e70aSDimitry Andric     }
16970946e70aSDimitry Andric   }
16980946e70aSDimitry Andric 
16990946e70aSDimitry Andric   // Pop all defs from this block from the definition stacks.
17000946e70aSDimitry Andric   releaseBlock(BA.Id, DefM);
17010946e70aSDimitry Andric }
17020946e70aSDimitry Andric 
17030946e70aSDimitry Andric // Remove the use node UA from any data-flow and structural links.
17040946e70aSDimitry Andric void DataFlowGraph::unlinkUseDF(NodeAddr<UseNode*> UA) {
17050946e70aSDimitry Andric   NodeId RD = UA.Addr->getReachingDef();
17060946e70aSDimitry Andric   NodeId Sib = UA.Addr->getSibling();
17070946e70aSDimitry Andric 
17080946e70aSDimitry Andric   if (RD == 0) {
17090946e70aSDimitry Andric     assert(Sib == 0);
17100946e70aSDimitry Andric     return;
17110946e70aSDimitry Andric   }
17120946e70aSDimitry Andric 
17130946e70aSDimitry Andric   auto RDA = addr<DefNode*>(RD);
17140946e70aSDimitry Andric   auto TA = addr<UseNode*>(RDA.Addr->getReachedUse());
17150946e70aSDimitry Andric   if (TA.Id == UA.Id) {
17160946e70aSDimitry Andric     RDA.Addr->setReachedUse(Sib);
17170946e70aSDimitry Andric     return;
17180946e70aSDimitry Andric   }
17190946e70aSDimitry Andric 
17200946e70aSDimitry Andric   while (TA.Id != 0) {
17210946e70aSDimitry Andric     NodeId S = TA.Addr->getSibling();
17220946e70aSDimitry Andric     if (S == UA.Id) {
17230946e70aSDimitry Andric       TA.Addr->setSibling(UA.Addr->getSibling());
17240946e70aSDimitry Andric       return;
17250946e70aSDimitry Andric     }
17260946e70aSDimitry Andric     TA = addr<UseNode*>(S);
17270946e70aSDimitry Andric   }
17280946e70aSDimitry Andric }
17290946e70aSDimitry Andric 
17300946e70aSDimitry Andric // Remove the def node DA from any data-flow and structural links.
17310946e70aSDimitry Andric void DataFlowGraph::unlinkDefDF(NodeAddr<DefNode*> DA) {
17320946e70aSDimitry Andric   //
17330946e70aSDimitry Andric   //         RD
17340946e70aSDimitry Andric   //         | reached
17350946e70aSDimitry Andric   //         | def
17360946e70aSDimitry Andric   //         :
17370946e70aSDimitry Andric   //         .
17380946e70aSDimitry Andric   //        +----+
17390946e70aSDimitry Andric   // ... -- | DA | -- ... -- 0  : sibling chain of DA
17400946e70aSDimitry Andric   //        +----+
17410946e70aSDimitry Andric   //         |  | reached
17420946e70aSDimitry Andric   //         |  : def
17430946e70aSDimitry Andric   //         |  .
17440946e70aSDimitry Andric   //         | ...  : Siblings (defs)
17450946e70aSDimitry Andric   //         |
17460946e70aSDimitry Andric   //         : reached
17470946e70aSDimitry Andric   //         . use
17480946e70aSDimitry Andric   //        ... : sibling chain of reached uses
17490946e70aSDimitry Andric 
17500946e70aSDimitry Andric   NodeId RD = DA.Addr->getReachingDef();
17510946e70aSDimitry Andric 
17520946e70aSDimitry Andric   // Visit all siblings of the reached def and reset their reaching defs.
17530946e70aSDimitry Andric   // Also, defs reached by DA are now "promoted" to being reached by RD,
17540946e70aSDimitry Andric   // so all of them will need to be spliced into the sibling chain where
17550946e70aSDimitry Andric   // DA belongs.
17560946e70aSDimitry Andric   auto getAllNodes = [this] (NodeId N) -> NodeList {
17570946e70aSDimitry Andric     NodeList Res;
17580946e70aSDimitry Andric     while (N) {
17590946e70aSDimitry Andric       auto RA = addr<RefNode*>(N);
17600946e70aSDimitry Andric       // Keep the nodes in the exact sibling order.
17610946e70aSDimitry Andric       Res.push_back(RA);
17620946e70aSDimitry Andric       N = RA.Addr->getSibling();
17630946e70aSDimitry Andric     }
17640946e70aSDimitry Andric     return Res;
17650946e70aSDimitry Andric   };
17660946e70aSDimitry Andric   NodeList ReachedDefs = getAllNodes(DA.Addr->getReachedDef());
17670946e70aSDimitry Andric   NodeList ReachedUses = getAllNodes(DA.Addr->getReachedUse());
17680946e70aSDimitry Andric 
17690946e70aSDimitry Andric   if (RD == 0) {
17700946e70aSDimitry Andric     for (NodeAddr<RefNode*> I : ReachedDefs)
17710946e70aSDimitry Andric       I.Addr->setSibling(0);
17720946e70aSDimitry Andric     for (NodeAddr<RefNode*> I : ReachedUses)
17730946e70aSDimitry Andric       I.Addr->setSibling(0);
17740946e70aSDimitry Andric   }
17750946e70aSDimitry Andric   for (NodeAddr<DefNode*> I : ReachedDefs)
17760946e70aSDimitry Andric     I.Addr->setReachingDef(RD);
17770946e70aSDimitry Andric   for (NodeAddr<UseNode*> I : ReachedUses)
17780946e70aSDimitry Andric     I.Addr->setReachingDef(RD);
17790946e70aSDimitry Andric 
17800946e70aSDimitry Andric   NodeId Sib = DA.Addr->getSibling();
17810946e70aSDimitry Andric   if (RD == 0) {
17820946e70aSDimitry Andric     assert(Sib == 0);
17830946e70aSDimitry Andric     return;
17840946e70aSDimitry Andric   }
17850946e70aSDimitry Andric 
17860946e70aSDimitry Andric   // Update the reaching def node and remove DA from the sibling list.
17870946e70aSDimitry Andric   auto RDA = addr<DefNode*>(RD);
17880946e70aSDimitry Andric   auto TA = addr<DefNode*>(RDA.Addr->getReachedDef());
17890946e70aSDimitry Andric   if (TA.Id == DA.Id) {
17900946e70aSDimitry Andric     // If DA is the first reached def, just update the RD's reached def
17910946e70aSDimitry Andric     // to the DA's sibling.
17920946e70aSDimitry Andric     RDA.Addr->setReachedDef(Sib);
17930946e70aSDimitry Andric   } else {
17940946e70aSDimitry Andric     // Otherwise, traverse the sibling list of the reached defs and remove
17950946e70aSDimitry Andric     // DA from it.
17960946e70aSDimitry Andric     while (TA.Id != 0) {
17970946e70aSDimitry Andric       NodeId S = TA.Addr->getSibling();
17980946e70aSDimitry Andric       if (S == DA.Id) {
17990946e70aSDimitry Andric         TA.Addr->setSibling(Sib);
18000946e70aSDimitry Andric         break;
18010946e70aSDimitry Andric       }
18020946e70aSDimitry Andric       TA = addr<DefNode*>(S);
18030946e70aSDimitry Andric     }
18040946e70aSDimitry Andric   }
18050946e70aSDimitry Andric 
18060946e70aSDimitry Andric   // Splice the DA's reached defs into the RDA's reached def chain.
18070946e70aSDimitry Andric   if (!ReachedDefs.empty()) {
18080946e70aSDimitry Andric     auto Last = NodeAddr<DefNode*>(ReachedDefs.back());
18090946e70aSDimitry Andric     Last.Addr->setSibling(RDA.Addr->getReachedDef());
18100946e70aSDimitry Andric     RDA.Addr->setReachedDef(ReachedDefs.front().Id);
18110946e70aSDimitry Andric   }
18120946e70aSDimitry Andric   // Splice the DA's reached uses into the RDA's reached use chain.
18130946e70aSDimitry Andric   if (!ReachedUses.empty()) {
18140946e70aSDimitry Andric     auto Last = NodeAddr<UseNode*>(ReachedUses.back());
18150946e70aSDimitry Andric     Last.Addr->setSibling(RDA.Addr->getReachedUse());
18160946e70aSDimitry Andric     RDA.Addr->setReachedUse(ReachedUses.front().Id);
18170946e70aSDimitry Andric   }
18180946e70aSDimitry Andric }
1819