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