1080dd10fSScott Constable //===- RDFGraph.cpp -------------------------------------------------------===//
2080dd10fSScott Constable //
3080dd10fSScott Constable // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4080dd10fSScott Constable // See https://llvm.org/LICENSE.txt for license information.
5080dd10fSScott Constable // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6080dd10fSScott Constable //
7080dd10fSScott Constable //===----------------------------------------------------------------------===//
8080dd10fSScott Constable //
9080dd10fSScott Constable // Target-independent, SSA-based data flow graph for register data flow (RDF).
10080dd10fSScott Constable //
11989f1c72Sserge-sans-paille #include "llvm/CodeGen/RDFGraph.h"
12080dd10fSScott Constable #include "llvm/ADT/BitVector.h"
13080dd10fSScott Constable #include "llvm/ADT/STLExtras.h"
14080dd10fSScott Constable #include "llvm/ADT/SetVector.h"
15080dd10fSScott Constable #include "llvm/CodeGen/MachineBasicBlock.h"
16080dd10fSScott Constable #include "llvm/CodeGen/MachineDominanceFrontier.h"
17080dd10fSScott Constable #include "llvm/CodeGen/MachineDominators.h"
18080dd10fSScott Constable #include "llvm/CodeGen/MachineFunction.h"
19080dd10fSScott Constable #include "llvm/CodeGen/MachineInstr.h"
20080dd10fSScott Constable #include "llvm/CodeGen/MachineOperand.h"
21080dd10fSScott Constable #include "llvm/CodeGen/MachineRegisterInfo.h"
22080dd10fSScott Constable #include "llvm/CodeGen/RDFRegisters.h"
23080dd10fSScott Constable #include "llvm/CodeGen/TargetInstrInfo.h"
24080dd10fSScott Constable #include "llvm/CodeGen/TargetLowering.h"
25080dd10fSScott Constable #include "llvm/CodeGen/TargetRegisterInfo.h"
26080dd10fSScott Constable #include "llvm/CodeGen/TargetSubtargetInfo.h"
27080dd10fSScott Constable #include "llvm/IR/Function.h"
28080dd10fSScott Constable #include "llvm/MC/LaneBitmask.h"
29080dd10fSScott Constable #include "llvm/MC/MCInstrDesc.h"
30080dd10fSScott Constable #include "llvm/Support/ErrorHandling.h"
31080dd10fSScott Constable #include "llvm/Support/raw_ostream.h"
32080dd10fSScott Constable #include <algorithm>
33080dd10fSScott Constable #include <cassert>
34080dd10fSScott Constable #include <cstdint>
35080dd10fSScott Constable #include <cstring>
36080dd10fSScott Constable #include <iterator>
37080dd10fSScott Constable #include <set>
38080dd10fSScott Constable #include <utility>
39080dd10fSScott Constable #include <vector>
40080dd10fSScott Constable 
41080dd10fSScott Constable using namespace llvm;
42080dd10fSScott Constable using namespace rdf;
43080dd10fSScott Constable 
44080dd10fSScott Constable // Printing functions. Have them here first, so that the rest of the code
45080dd10fSScott Constable // can use them.
46080dd10fSScott Constable namespace llvm {
47080dd10fSScott Constable namespace rdf {
48080dd10fSScott Constable 
operator <<(raw_ostream & OS,const PrintLaneMaskOpt & P)49080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P) {
50080dd10fSScott Constable   if (!P.Mask.all())
51080dd10fSScott Constable     OS << ':' << PrintLaneMask(P.Mask);
52080dd10fSScott Constable   return OS;
53080dd10fSScott Constable }
54080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<RegisterRef> & P)55080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterRef> &P) {
56080dd10fSScott Constable   auto &TRI = P.G.getTRI();
57080dd10fSScott Constable   if (P.Obj.Reg > 0 && P.Obj.Reg < TRI.getNumRegs())
58080dd10fSScott Constable     OS << TRI.getName(P.Obj.Reg);
59080dd10fSScott Constable   else
60080dd10fSScott Constable     OS << '#' << P.Obj.Reg;
61080dd10fSScott Constable   OS << PrintLaneMaskOpt(P.Obj.Mask);
62080dd10fSScott Constable   return OS;
63080dd10fSScott Constable }
64080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeId> & P)65080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeId> &P) {
66080dd10fSScott Constable   auto NA = P.G.addr<NodeBase*>(P.Obj);
67080dd10fSScott Constable   uint16_t Attrs = NA.Addr->getAttrs();
68080dd10fSScott Constable   uint16_t Kind = NodeAttrs::kind(Attrs);
69080dd10fSScott Constable   uint16_t Flags = NodeAttrs::flags(Attrs);
70080dd10fSScott Constable   switch (NodeAttrs::type(Attrs)) {
71080dd10fSScott Constable     case NodeAttrs::Code:
72080dd10fSScott Constable       switch (Kind) {
73080dd10fSScott Constable         case NodeAttrs::Func:   OS << 'f'; break;
74080dd10fSScott Constable         case NodeAttrs::Block:  OS << 'b'; break;
75080dd10fSScott Constable         case NodeAttrs::Stmt:   OS << 's'; break;
76080dd10fSScott Constable         case NodeAttrs::Phi:    OS << 'p'; break;
77080dd10fSScott Constable         default:                OS << "c?"; break;
78080dd10fSScott Constable       }
79080dd10fSScott Constable       break;
80080dd10fSScott Constable     case NodeAttrs::Ref:
81080dd10fSScott Constable       if (Flags & NodeAttrs::Undef)
82080dd10fSScott Constable         OS << '/';
83080dd10fSScott Constable       if (Flags & NodeAttrs::Dead)
84080dd10fSScott Constable         OS << '\\';
85080dd10fSScott Constable       if (Flags & NodeAttrs::Preserving)
86080dd10fSScott Constable         OS << '+';
87080dd10fSScott Constable       if (Flags & NodeAttrs::Clobbering)
88080dd10fSScott Constable         OS << '~';
89080dd10fSScott Constable       switch (Kind) {
90080dd10fSScott Constable         case NodeAttrs::Use:    OS << 'u'; break;
91080dd10fSScott Constable         case NodeAttrs::Def:    OS << 'd'; break;
92080dd10fSScott Constable         case NodeAttrs::Block:  OS << 'b'; break;
93080dd10fSScott Constable         default:                OS << "r?"; break;
94080dd10fSScott Constable       }
95080dd10fSScott Constable       break;
96080dd10fSScott Constable     default:
97080dd10fSScott Constable       OS << '?';
98080dd10fSScott Constable       break;
99080dd10fSScott Constable   }
100080dd10fSScott Constable   OS << P.Obj;
101080dd10fSScott Constable   if (Flags & NodeAttrs::Shadow)
102080dd10fSScott Constable     OS << '"';
103080dd10fSScott Constable   return OS;
104080dd10fSScott Constable }
105080dd10fSScott Constable 
printRefHeader(raw_ostream & OS,const NodeAddr<RefNode * > RA,const DataFlowGraph & G)106080dd10fSScott Constable static void printRefHeader(raw_ostream &OS, const NodeAddr<RefNode*> RA,
107080dd10fSScott Constable                 const DataFlowGraph &G) {
108080dd10fSScott Constable   OS << Print<NodeId>(RA.Id, G) << '<'
109080dd10fSScott Constable      << Print<RegisterRef>(RA.Addr->getRegRef(G), G) << '>';
110080dd10fSScott Constable   if (RA.Addr->getFlags() & NodeAttrs::Fixed)
111080dd10fSScott Constable     OS << '!';
112080dd10fSScott Constable }
113080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<DefNode * >> & P)114080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<DefNode*>> &P) {
115080dd10fSScott Constable   printRefHeader(OS, P.Obj, P.G);
116080dd10fSScott Constable   OS << '(';
117080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getReachingDef())
118080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
119080dd10fSScott Constable   OS << ',';
120080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getReachedDef())
121080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
122080dd10fSScott Constable   OS << ',';
123080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getReachedUse())
124080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
125080dd10fSScott Constable   OS << "):";
126080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getSibling())
127080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
128080dd10fSScott Constable   return OS;
129080dd10fSScott Constable }
130080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<UseNode * >> & P)131080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<UseNode*>> &P) {
132080dd10fSScott Constable   printRefHeader(OS, P.Obj, P.G);
133080dd10fSScott Constable   OS << '(';
134080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getReachingDef())
135080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
136080dd10fSScott Constable   OS << "):";
137080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getSibling())
138080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
139080dd10fSScott Constable   return OS;
140080dd10fSScott Constable }
141080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<PhiUseNode * >> & P)142080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS,
143080dd10fSScott Constable       const Print<NodeAddr<PhiUseNode*>> &P) {
144080dd10fSScott Constable   printRefHeader(OS, P.Obj, P.G);
145080dd10fSScott Constable   OS << '(';
146080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getReachingDef())
147080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
148080dd10fSScott Constable   OS << ',';
149080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getPredecessor())
150080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
151080dd10fSScott Constable   OS << "):";
152080dd10fSScott Constable   if (NodeId N = P.Obj.Addr->getSibling())
153080dd10fSScott Constable     OS << Print<NodeId>(N, P.G);
154080dd10fSScott Constable   return OS;
155080dd10fSScott Constable }
156080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<RefNode * >> & P)157080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<RefNode*>> &P) {
158080dd10fSScott Constable   switch (P.Obj.Addr->getKind()) {
159080dd10fSScott Constable     case NodeAttrs::Def:
160080dd10fSScott Constable       OS << PrintNode<DefNode*>(P.Obj, P.G);
161080dd10fSScott Constable       break;
162080dd10fSScott Constable     case NodeAttrs::Use:
163080dd10fSScott Constable       if (P.Obj.Addr->getFlags() & NodeAttrs::PhiRef)
164080dd10fSScott Constable         OS << PrintNode<PhiUseNode*>(P.Obj, P.G);
165080dd10fSScott Constable       else
166080dd10fSScott Constable         OS << PrintNode<UseNode*>(P.Obj, P.G);
167080dd10fSScott Constable       break;
168080dd10fSScott Constable   }
169080dd10fSScott Constable   return OS;
170080dd10fSScott Constable }
171080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeList> & P)172080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeList> &P) {
173080dd10fSScott Constable   unsigned N = P.Obj.size();
174080dd10fSScott Constable   for (auto I : P.Obj) {
175080dd10fSScott Constable     OS << Print<NodeId>(I.Id, P.G);
176080dd10fSScott Constable     if (--N)
177080dd10fSScott Constable       OS << ' ';
178080dd10fSScott Constable   }
179080dd10fSScott Constable   return OS;
180080dd10fSScott Constable }
181080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeSet> & P)182080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeSet> &P) {
183080dd10fSScott Constable   unsigned N = P.Obj.size();
184080dd10fSScott Constable   for (auto I : P.Obj) {
185080dd10fSScott Constable     OS << Print<NodeId>(I, P.G);
186080dd10fSScott Constable     if (--N)
187080dd10fSScott Constable       OS << ' ';
188080dd10fSScott Constable   }
189080dd10fSScott Constable   return OS;
190080dd10fSScott Constable }
191080dd10fSScott Constable 
192080dd10fSScott Constable namespace {
193080dd10fSScott Constable 
194080dd10fSScott Constable   template <typename T>
195080dd10fSScott Constable   struct PrintListV {
PrintListVllvm::rdf::__anonf5887b320111::PrintListV196080dd10fSScott Constable     PrintListV(const NodeList &L, const DataFlowGraph &G) : List(L), G(G) {}
197080dd10fSScott Constable 
198080dd10fSScott Constable     using Type = T;
199080dd10fSScott Constable     const NodeList &List;
200080dd10fSScott Constable     const DataFlowGraph &G;
201080dd10fSScott Constable   };
202080dd10fSScott Constable 
203080dd10fSScott Constable   template <typename T>
operator <<(raw_ostream & OS,const PrintListV<T> & P)204080dd10fSScott Constable   raw_ostream &operator<< (raw_ostream &OS, const PrintListV<T> &P) {
205080dd10fSScott Constable     unsigned N = P.List.size();
206080dd10fSScott Constable     for (NodeAddr<T> A : P.List) {
207080dd10fSScott Constable       OS << PrintNode<T>(A, P.G);
208080dd10fSScott Constable       if (--N)
209080dd10fSScott Constable         OS << ", ";
210080dd10fSScott Constable     }
211080dd10fSScott Constable     return OS;
212080dd10fSScott Constable   }
213080dd10fSScott Constable 
214080dd10fSScott Constable } // end anonymous namespace
215080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<PhiNode * >> & P)216080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<PhiNode*>> &P) {
217080dd10fSScott Constable   OS << Print<NodeId>(P.Obj.Id, P.G) << ": phi ["
218080dd10fSScott Constable      << PrintListV<RefNode*>(P.Obj.Addr->members(P.G), P.G) << ']';
219080dd10fSScott Constable   return OS;
220080dd10fSScott Constable }
221080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<StmtNode * >> & P)222080dd10fSScott Constable raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<StmtNode *>> &P) {
223080dd10fSScott Constable   const MachineInstr &MI = *P.Obj.Addr->getCode();
224080dd10fSScott Constable   unsigned Opc = MI.getOpcode();
225080dd10fSScott Constable   OS << Print<NodeId>(P.Obj.Id, P.G) << ": " << P.G.getTII().getName(Opc);
226080dd10fSScott Constable   // Print the target for calls and branches (for readability).
227080dd10fSScott Constable   if (MI.isCall() || MI.isBranch()) {
228080dd10fSScott Constable     MachineInstr::const_mop_iterator T =
229080dd10fSScott Constable           llvm::find_if(MI.operands(),
230080dd10fSScott Constable                         [] (const MachineOperand &Op) -> bool {
231080dd10fSScott Constable                           return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
232080dd10fSScott Constable                         });
233080dd10fSScott Constable     if (T != MI.operands_end()) {
234080dd10fSScott Constable       OS << ' ';
235080dd10fSScott Constable       if (T->isMBB())
236080dd10fSScott Constable         OS << printMBBReference(*T->getMBB());
237080dd10fSScott Constable       else if (T->isGlobal())
238080dd10fSScott Constable         OS << T->getGlobal()->getName();
239080dd10fSScott Constable       else if (T->isSymbol())
240080dd10fSScott Constable         OS << T->getSymbolName();
241080dd10fSScott Constable     }
242080dd10fSScott Constable   }
243080dd10fSScott Constable   OS << " [" << PrintListV<RefNode*>(P.Obj.Addr->members(P.G), P.G) << ']';
244080dd10fSScott Constable   return OS;
245080dd10fSScott Constable }
246080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<InstrNode * >> & P)247080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS,
248080dd10fSScott Constable       const Print<NodeAddr<InstrNode*>> &P) {
249080dd10fSScott Constable   switch (P.Obj.Addr->getKind()) {
250080dd10fSScott Constable     case NodeAttrs::Phi:
251080dd10fSScott Constable       OS << PrintNode<PhiNode*>(P.Obj, P.G);
252080dd10fSScott Constable       break;
253080dd10fSScott Constable     case NodeAttrs::Stmt:
254080dd10fSScott Constable       OS << PrintNode<StmtNode*>(P.Obj, P.G);
255080dd10fSScott Constable       break;
256080dd10fSScott Constable     default:
257080dd10fSScott Constable       OS << "instr? " << Print<NodeId>(P.Obj.Id, P.G);
258080dd10fSScott Constable       break;
259080dd10fSScott Constable   }
260080dd10fSScott Constable   return OS;
261080dd10fSScott Constable }
262080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<BlockNode * >> & P)263080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS,
264080dd10fSScott Constable       const Print<NodeAddr<BlockNode*>> &P) {
265080dd10fSScott Constable   MachineBasicBlock *BB = P.Obj.Addr->getCode();
266080dd10fSScott Constable   unsigned NP = BB->pred_size();
267080dd10fSScott Constable   std::vector<int> Ns;
268080dd10fSScott Constable   auto PrintBBs = [&OS] (std::vector<int> Ns) -> void {
269080dd10fSScott Constable     unsigned N = Ns.size();
270080dd10fSScott Constable     for (int I : Ns) {
271080dd10fSScott Constable       OS << "%bb." << I;
272080dd10fSScott Constable       if (--N)
273080dd10fSScott Constable         OS << ", ";
274080dd10fSScott Constable     }
275080dd10fSScott Constable   };
276080dd10fSScott Constable 
277080dd10fSScott Constable   OS << Print<NodeId>(P.Obj.Id, P.G) << ": --- " << printMBBReference(*BB)
278080dd10fSScott Constable      << " --- preds(" << NP << "): ";
279080dd10fSScott Constable   for (MachineBasicBlock *B : BB->predecessors())
280080dd10fSScott Constable     Ns.push_back(B->getNumber());
281080dd10fSScott Constable   PrintBBs(Ns);
282080dd10fSScott Constable 
283080dd10fSScott Constable   unsigned NS = BB->succ_size();
284080dd10fSScott Constable   OS << "  succs(" << NS << "): ";
285080dd10fSScott Constable   Ns.clear();
286080dd10fSScott Constable   for (MachineBasicBlock *B : BB->successors())
287080dd10fSScott Constable     Ns.push_back(B->getNumber());
288080dd10fSScott Constable   PrintBBs(Ns);
289080dd10fSScott Constable   OS << '\n';
290080dd10fSScott Constable 
291080dd10fSScott Constable   for (auto I : P.Obj.Addr->members(P.G))
292080dd10fSScott Constable     OS << PrintNode<InstrNode*>(I, P.G) << '\n';
293080dd10fSScott Constable   return OS;
294080dd10fSScott Constable }
295080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<NodeAddr<FuncNode * >> & P)296080dd10fSScott Constable raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<FuncNode *>> &P) {
297080dd10fSScott Constable   OS << "DFG dump:[\n" << Print<NodeId>(P.Obj.Id, P.G) << ": Function: "
298080dd10fSScott Constable      << P.Obj.Addr->getCode()->getName() << '\n';
299080dd10fSScott Constable   for (auto I : P.Obj.Addr->members(P.G))
300080dd10fSScott Constable     OS << PrintNode<BlockNode*>(I, P.G) << '\n';
301080dd10fSScott Constable   OS << "]\n";
302080dd10fSScott Constable   return OS;
303080dd10fSScott Constable }
304080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<RegisterSet> & P)305080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterSet> &P) {
306080dd10fSScott Constable   OS << '{';
307080dd10fSScott Constable   for (auto I : P.Obj)
308080dd10fSScott Constable     OS << ' ' << Print<RegisterRef>(I, P.G);
309080dd10fSScott Constable   OS << " }";
310080dd10fSScott Constable   return OS;
311080dd10fSScott Constable }
312080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<RegisterAggr> & P)313080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterAggr> &P) {
314080dd10fSScott Constable   P.Obj.print(OS);
315080dd10fSScott Constable   return OS;
316080dd10fSScott Constable }
317080dd10fSScott Constable 
operator <<(raw_ostream & OS,const Print<DataFlowGraph::DefStack> & P)318080dd10fSScott Constable raw_ostream &operator<< (raw_ostream &OS,
319080dd10fSScott Constable       const Print<DataFlowGraph::DefStack> &P) {
320080dd10fSScott Constable   for (auto I = P.Obj.top(), E = P.Obj.bottom(); I != E; ) {
321080dd10fSScott Constable     OS << Print<NodeId>(I->Id, P.G)
322080dd10fSScott Constable        << '<' << Print<RegisterRef>(I->Addr->getRegRef(P.G), P.G) << '>';
323080dd10fSScott Constable     I.down();
324080dd10fSScott Constable     if (I != E)
325080dd10fSScott Constable       OS << ' ';
326080dd10fSScott Constable   }
327080dd10fSScott Constable   return OS;
328080dd10fSScott Constable }
329080dd10fSScott Constable 
330080dd10fSScott Constable } // end namespace rdf
331080dd10fSScott Constable } // end namespace llvm
332080dd10fSScott Constable 
333080dd10fSScott Constable // Node allocation functions.
334080dd10fSScott Constable //
335080dd10fSScott Constable // Node allocator is like a slab memory allocator: it allocates blocks of
336080dd10fSScott Constable // memory in sizes that are multiples of the size of a node. Each block has
337080dd10fSScott Constable // the same size. Nodes are allocated from the currently active block, and
338080dd10fSScott Constable // when it becomes full, a new one is created.
339080dd10fSScott Constable // There is a mapping scheme between node id and its location in a block,
340080dd10fSScott Constable // and within that block is described in the header file.
341080dd10fSScott Constable //
startNewBlock()342080dd10fSScott Constable void NodeAllocator::startNewBlock() {
343080dd10fSScott Constable   void *T = MemPool.Allocate(NodesPerBlock*NodeMemSize, NodeMemSize);
344080dd10fSScott Constable   char *P = static_cast<char*>(T);
345080dd10fSScott Constable   Blocks.push_back(P);
346080dd10fSScott Constable   // Check if the block index is still within the allowed range, i.e. less
347080dd10fSScott Constable   // than 2^N, where N is the number of bits in NodeId for the block index.
348080dd10fSScott Constable   // BitsPerIndex is the number of bits per node index.
349080dd10fSScott Constable   assert((Blocks.size() < ((size_t)1 << (8*sizeof(NodeId)-BitsPerIndex))) &&
350080dd10fSScott Constable          "Out of bits for block index");
351080dd10fSScott Constable   ActiveEnd = P;
352080dd10fSScott Constable }
353080dd10fSScott Constable 
needNewBlock()354080dd10fSScott Constable bool NodeAllocator::needNewBlock() {
355080dd10fSScott Constable   if (Blocks.empty())
356080dd10fSScott Constable     return true;
357080dd10fSScott Constable 
358080dd10fSScott Constable   char *ActiveBegin = Blocks.back();
359080dd10fSScott Constable   uint32_t Index = (ActiveEnd-ActiveBegin)/NodeMemSize;
360080dd10fSScott Constable   return Index >= NodesPerBlock;
361080dd10fSScott Constable }
362080dd10fSScott Constable 
New()363080dd10fSScott Constable NodeAddr<NodeBase*> NodeAllocator::New() {
364080dd10fSScott Constable   if (needNewBlock())
365080dd10fSScott Constable     startNewBlock();
366080dd10fSScott Constable 
367080dd10fSScott Constable   uint32_t ActiveB = Blocks.size()-1;
368080dd10fSScott Constable   uint32_t Index = (ActiveEnd - Blocks[ActiveB])/NodeMemSize;
369080dd10fSScott Constable   NodeAddr<NodeBase*> NA = { reinterpret_cast<NodeBase*>(ActiveEnd),
370080dd10fSScott Constable                              makeId(ActiveB, Index) };
371080dd10fSScott Constable   ActiveEnd += NodeMemSize;
372080dd10fSScott Constable   return NA;
373080dd10fSScott Constable }
374080dd10fSScott Constable 
id(const NodeBase * P) const375080dd10fSScott Constable NodeId NodeAllocator::id(const NodeBase *P) const {
376080dd10fSScott Constable   uintptr_t A = reinterpret_cast<uintptr_t>(P);
377080dd10fSScott Constable   for (unsigned i = 0, n = Blocks.size(); i != n; ++i) {
378080dd10fSScott Constable     uintptr_t B = reinterpret_cast<uintptr_t>(Blocks[i]);
379080dd10fSScott Constable     if (A < B || A >= B + NodesPerBlock*NodeMemSize)
380080dd10fSScott Constable       continue;
381080dd10fSScott Constable     uint32_t Idx = (A-B)/NodeMemSize;
382080dd10fSScott Constable     return makeId(i, Idx);
383080dd10fSScott Constable   }
384080dd10fSScott Constable   llvm_unreachable("Invalid node address");
385080dd10fSScott Constable }
386080dd10fSScott Constable 
clear()387080dd10fSScott Constable void NodeAllocator::clear() {
388080dd10fSScott Constable   MemPool.Reset();
389080dd10fSScott Constable   Blocks.clear();
390080dd10fSScott Constable   ActiveEnd = nullptr;
391080dd10fSScott Constable }
392080dd10fSScott Constable 
393080dd10fSScott Constable // Insert node NA after "this" in the circular chain.
append(NodeAddr<NodeBase * > NA)394080dd10fSScott Constable void NodeBase::append(NodeAddr<NodeBase*> NA) {
395080dd10fSScott Constable   NodeId Nx = Next;
396080dd10fSScott Constable   // If NA is already "next", do nothing.
397080dd10fSScott Constable   if (Next != NA.Id) {
398080dd10fSScott Constable     Next = NA.Id;
399080dd10fSScott Constable     NA.Addr->Next = Nx;
400080dd10fSScott Constable   }
401080dd10fSScott Constable }
402080dd10fSScott Constable 
403080dd10fSScott Constable // Fundamental node manipulator functions.
404080dd10fSScott Constable 
405080dd10fSScott Constable // Obtain the register reference from a reference node.
getRegRef(const DataFlowGraph & G) const406080dd10fSScott Constable RegisterRef RefNode::getRegRef(const DataFlowGraph &G) const {
407080dd10fSScott Constable   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
408080dd10fSScott Constable   if (NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef)
409080dd10fSScott Constable     return G.unpack(Ref.PR);
410080dd10fSScott Constable   assert(Ref.Op != nullptr);
411080dd10fSScott Constable   return G.makeRegRef(*Ref.Op);
412080dd10fSScott Constable }
413080dd10fSScott Constable 
414080dd10fSScott Constable // Set the register reference in the reference node directly (for references
415080dd10fSScott Constable // in phi nodes).
setRegRef(RegisterRef RR,DataFlowGraph & G)416080dd10fSScott Constable void RefNode::setRegRef(RegisterRef RR, DataFlowGraph &G) {
417080dd10fSScott Constable   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
418080dd10fSScott Constable   assert(NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef);
419080dd10fSScott Constable   Ref.PR = G.pack(RR);
420080dd10fSScott Constable }
421080dd10fSScott Constable 
422080dd10fSScott Constable // Set the register reference in the reference node based on a machine
423080dd10fSScott Constable // operand (for references in statement nodes).
setRegRef(MachineOperand * Op,DataFlowGraph & G)424080dd10fSScott Constable void RefNode::setRegRef(MachineOperand *Op, DataFlowGraph &G) {
425080dd10fSScott Constable   assert(NodeAttrs::type(Attrs) == NodeAttrs::Ref);
426080dd10fSScott Constable   assert(!(NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef));
427080dd10fSScott Constable   (void)G;
428080dd10fSScott Constable   Ref.Op = Op;
429080dd10fSScott Constable }
430080dd10fSScott Constable 
431080dd10fSScott Constable // Get the owner of a given reference node.
getOwner(const DataFlowGraph & G)432080dd10fSScott Constable NodeAddr<NodeBase*> RefNode::getOwner(const DataFlowGraph &G) {
433080dd10fSScott Constable   NodeAddr<NodeBase*> NA = G.addr<NodeBase*>(getNext());
434080dd10fSScott Constable 
435080dd10fSScott Constable   while (NA.Addr != this) {
436080dd10fSScott Constable     if (NA.Addr->getType() == NodeAttrs::Code)
437080dd10fSScott Constable       return NA;
438080dd10fSScott Constable     NA = G.addr<NodeBase*>(NA.Addr->getNext());
439080dd10fSScott Constable   }
440080dd10fSScott Constable   llvm_unreachable("No owner in circular list");
441080dd10fSScott Constable }
442080dd10fSScott Constable 
443080dd10fSScott Constable // Connect the def node to the reaching def node.
linkToDef(NodeId Self,NodeAddr<DefNode * > DA)444080dd10fSScott Constable void DefNode::linkToDef(NodeId Self, NodeAddr<DefNode*> DA) {
445080dd10fSScott Constable   Ref.RD = DA.Id;
446080dd10fSScott Constable   Ref.Sib = DA.Addr->getReachedDef();
447080dd10fSScott Constable   DA.Addr->setReachedDef(Self);
448080dd10fSScott Constable }
449080dd10fSScott Constable 
450080dd10fSScott Constable // Connect the use node to the reaching def node.
linkToDef(NodeId Self,NodeAddr<DefNode * > DA)451080dd10fSScott Constable void UseNode::linkToDef(NodeId Self, NodeAddr<DefNode*> DA) {
452080dd10fSScott Constable   Ref.RD = DA.Id;
453080dd10fSScott Constable   Ref.Sib = DA.Addr->getReachedUse();
454080dd10fSScott Constable   DA.Addr->setReachedUse(Self);
455080dd10fSScott Constable }
456080dd10fSScott Constable 
457080dd10fSScott Constable // Get the first member of the code node.
getFirstMember(const DataFlowGraph & G) const458080dd10fSScott Constable NodeAddr<NodeBase*> CodeNode::getFirstMember(const DataFlowGraph &G) const {
459080dd10fSScott Constable   if (Code.FirstM == 0)
460080dd10fSScott Constable     return NodeAddr<NodeBase*>();
461080dd10fSScott Constable   return G.addr<NodeBase*>(Code.FirstM);
462080dd10fSScott Constable }
463080dd10fSScott Constable 
464080dd10fSScott Constable // Get the last member of the code node.
getLastMember(const DataFlowGraph & G) const465080dd10fSScott Constable NodeAddr<NodeBase*> CodeNode::getLastMember(const DataFlowGraph &G) const {
466080dd10fSScott Constable   if (Code.LastM == 0)
467080dd10fSScott Constable     return NodeAddr<NodeBase*>();
468080dd10fSScott Constable   return G.addr<NodeBase*>(Code.LastM);
469080dd10fSScott Constable }
470080dd10fSScott Constable 
471080dd10fSScott Constable // Add node NA at the end of the member list of the given code node.
addMember(NodeAddr<NodeBase * > NA,const DataFlowGraph & G)472080dd10fSScott Constable void CodeNode::addMember(NodeAddr<NodeBase*> NA, const DataFlowGraph &G) {
473080dd10fSScott Constable   NodeAddr<NodeBase*> ML = getLastMember(G);
474080dd10fSScott Constable   if (ML.Id != 0) {
475080dd10fSScott Constable     ML.Addr->append(NA);
476080dd10fSScott Constable   } else {
477080dd10fSScott Constable     Code.FirstM = NA.Id;
478080dd10fSScott Constable     NodeId Self = G.id(this);
479080dd10fSScott Constable     NA.Addr->setNext(Self);
480080dd10fSScott Constable   }
481080dd10fSScott Constable   Code.LastM = NA.Id;
482080dd10fSScott Constable }
483080dd10fSScott Constable 
484080dd10fSScott Constable // Add node NA after member node MA in the given code node.
addMemberAfter(NodeAddr<NodeBase * > MA,NodeAddr<NodeBase * > NA,const DataFlowGraph & G)485080dd10fSScott Constable void CodeNode::addMemberAfter(NodeAddr<NodeBase*> MA, NodeAddr<NodeBase*> NA,
486080dd10fSScott Constable       const DataFlowGraph &G) {
487080dd10fSScott Constable   MA.Addr->append(NA);
488080dd10fSScott Constable   if (Code.LastM == MA.Id)
489080dd10fSScott Constable     Code.LastM = NA.Id;
490080dd10fSScott Constable }
491080dd10fSScott Constable 
492080dd10fSScott Constable // Remove member node NA from the given code node.
removeMember(NodeAddr<NodeBase * > NA,const DataFlowGraph & G)493080dd10fSScott Constable void CodeNode::removeMember(NodeAddr<NodeBase*> NA, const DataFlowGraph &G) {
494080dd10fSScott Constable   NodeAddr<NodeBase*> MA = getFirstMember(G);
495080dd10fSScott Constable   assert(MA.Id != 0);
496080dd10fSScott Constable 
497080dd10fSScott Constable   // Special handling if the member to remove is the first member.
498080dd10fSScott Constable   if (MA.Id == NA.Id) {
499080dd10fSScott Constable     if (Code.LastM == MA.Id) {
500080dd10fSScott Constable       // If it is the only member, set both first and last to 0.
501080dd10fSScott Constable       Code.FirstM = Code.LastM = 0;
502080dd10fSScott Constable     } else {
503080dd10fSScott Constable       // Otherwise, advance the first member.
504080dd10fSScott Constable       Code.FirstM = MA.Addr->getNext();
505080dd10fSScott Constable     }
506080dd10fSScott Constable     return;
507080dd10fSScott Constable   }
508080dd10fSScott Constable 
509080dd10fSScott Constable   while (MA.Addr != this) {
510080dd10fSScott Constable     NodeId MX = MA.Addr->getNext();
511080dd10fSScott Constable     if (MX == NA.Id) {
512080dd10fSScott Constable       MA.Addr->setNext(NA.Addr->getNext());
513080dd10fSScott Constable       // If the member to remove happens to be the last one, update the
514080dd10fSScott Constable       // LastM indicator.
515080dd10fSScott Constable       if (Code.LastM == NA.Id)
516080dd10fSScott Constable         Code.LastM = MA.Id;
517080dd10fSScott Constable       return;
518080dd10fSScott Constable     }
519080dd10fSScott Constable     MA = G.addr<NodeBase*>(MX);
520080dd10fSScott Constable   }
521080dd10fSScott Constable   llvm_unreachable("No such member");
522080dd10fSScott Constable }
523080dd10fSScott Constable 
524080dd10fSScott Constable // Return the list of all members of the code node.
members(const DataFlowGraph & G) const525080dd10fSScott Constable NodeList CodeNode::members(const DataFlowGraph &G) const {
526080dd10fSScott Constable   static auto True = [] (NodeAddr<NodeBase*>) -> bool { return true; };
527080dd10fSScott Constable   return members_if(True, G);
528080dd10fSScott Constable }
529080dd10fSScott Constable 
530080dd10fSScott Constable // Return the owner of the given instr node.
getOwner(const DataFlowGraph & G)531080dd10fSScott Constable NodeAddr<NodeBase*> InstrNode::getOwner(const DataFlowGraph &G) {
532080dd10fSScott Constable   NodeAddr<NodeBase*> NA = G.addr<NodeBase*>(getNext());
533080dd10fSScott Constable 
534080dd10fSScott Constable   while (NA.Addr != this) {
535080dd10fSScott Constable     assert(NA.Addr->getType() == NodeAttrs::Code);
536080dd10fSScott Constable     if (NA.Addr->getKind() == NodeAttrs::Block)
537080dd10fSScott Constable       return NA;
538080dd10fSScott Constable     NA = G.addr<NodeBase*>(NA.Addr->getNext());
539080dd10fSScott Constable   }
540080dd10fSScott Constable   llvm_unreachable("No owner in circular list");
541080dd10fSScott Constable }
542080dd10fSScott Constable 
543080dd10fSScott Constable // Add the phi node PA to the given block node.
addPhi(NodeAddr<PhiNode * > PA,const DataFlowGraph & G)544080dd10fSScott Constable void BlockNode::addPhi(NodeAddr<PhiNode*> PA, const DataFlowGraph &G) {
545080dd10fSScott Constable   NodeAddr<NodeBase*> M = getFirstMember(G);
546080dd10fSScott Constable   if (M.Id == 0) {
547080dd10fSScott Constable     addMember(PA, G);
548080dd10fSScott Constable     return;
549080dd10fSScott Constable   }
550080dd10fSScott Constable 
551080dd10fSScott Constable   assert(M.Addr->getType() == NodeAttrs::Code);
552080dd10fSScott Constable   if (M.Addr->getKind() == NodeAttrs::Stmt) {
553080dd10fSScott Constable     // If the first member of the block is a statement, insert the phi as
554080dd10fSScott Constable     // the first member.
555080dd10fSScott Constable     Code.FirstM = PA.Id;
556080dd10fSScott Constable     PA.Addr->setNext(M.Id);
557080dd10fSScott Constable   } else {
558080dd10fSScott Constable     // If the first member is a phi, find the last phi, and append PA to it.
559080dd10fSScott Constable     assert(M.Addr->getKind() == NodeAttrs::Phi);
560080dd10fSScott Constable     NodeAddr<NodeBase*> MN = M;
561080dd10fSScott Constable     do {
562080dd10fSScott Constable       M = MN;
563080dd10fSScott Constable       MN = G.addr<NodeBase*>(M.Addr->getNext());
564080dd10fSScott Constable       assert(MN.Addr->getType() == NodeAttrs::Code);
565080dd10fSScott Constable     } while (MN.Addr->getKind() == NodeAttrs::Phi);
566080dd10fSScott Constable 
567080dd10fSScott Constable     // M is the last phi.
568080dd10fSScott Constable     addMemberAfter(M, PA, G);
569080dd10fSScott Constable   }
570080dd10fSScott Constable }
571080dd10fSScott Constable 
572080dd10fSScott Constable // Find the block node corresponding to the machine basic block BB in the
573080dd10fSScott Constable // given func node.
findBlock(const MachineBasicBlock * BB,const DataFlowGraph & G) const574080dd10fSScott Constable NodeAddr<BlockNode*> FuncNode::findBlock(const MachineBasicBlock *BB,
575080dd10fSScott Constable       const DataFlowGraph &G) const {
576080dd10fSScott Constable   auto EqBB = [BB] (NodeAddr<NodeBase*> NA) -> bool {
577080dd10fSScott Constable     return NodeAddr<BlockNode*>(NA).Addr->getCode() == BB;
578080dd10fSScott Constable   };
579080dd10fSScott Constable   NodeList Ms = members_if(EqBB, G);
580080dd10fSScott Constable   if (!Ms.empty())
581080dd10fSScott Constable     return Ms[0];
582080dd10fSScott Constable   return NodeAddr<BlockNode*>();
583080dd10fSScott Constable }
584080dd10fSScott Constable 
585080dd10fSScott Constable // Get the block node for the entry block in the given function.
getEntryBlock(const DataFlowGraph & G)586080dd10fSScott Constable NodeAddr<BlockNode*> FuncNode::getEntryBlock(const DataFlowGraph &G) {
587080dd10fSScott Constable   MachineBasicBlock *EntryB = &getCode()->front();
588080dd10fSScott Constable   return findBlock(EntryB, G);
589080dd10fSScott Constable }
590080dd10fSScott Constable 
591080dd10fSScott Constable // Target operand information.
592080dd10fSScott Constable //
593080dd10fSScott Constable 
594080dd10fSScott Constable // For a given instruction, check if there are any bits of RR that can remain
595080dd10fSScott Constable // unchanged across this def.
isPreserving(const MachineInstr & In,unsigned OpNum) const596080dd10fSScott Constable bool TargetOperandInfo::isPreserving(const MachineInstr &In, unsigned OpNum)
597080dd10fSScott Constable       const {
598080dd10fSScott Constable   return TII.isPredicated(In);
599080dd10fSScott Constable }
600080dd10fSScott Constable 
601080dd10fSScott Constable // Check if the definition of RR produces an unspecified value.
isClobbering(const MachineInstr & In,unsigned OpNum) const602080dd10fSScott Constable bool TargetOperandInfo::isClobbering(const MachineInstr &In, unsigned OpNum)
603080dd10fSScott Constable       const {
604080dd10fSScott Constable   const MachineOperand &Op = In.getOperand(OpNum);
605080dd10fSScott Constable   if (Op.isRegMask())
606080dd10fSScott Constable     return true;
607080dd10fSScott Constable   assert(Op.isReg());
608080dd10fSScott Constable   if (In.isCall())
609080dd10fSScott Constable     if (Op.isDef() && Op.isDead())
610080dd10fSScott Constable       return true;
611080dd10fSScott Constable   return false;
612080dd10fSScott Constable }
613080dd10fSScott Constable 
614080dd10fSScott Constable // Check if the given instruction specifically requires
isFixedReg(const MachineInstr & In,unsigned OpNum) const615080dd10fSScott Constable bool TargetOperandInfo::isFixedReg(const MachineInstr &In, unsigned OpNum)
616080dd10fSScott Constable       const {
617080dd10fSScott Constable   if (In.isCall() || In.isReturn() || In.isInlineAsm())
618080dd10fSScott Constable     return true;
619080dd10fSScott Constable   // Check for a tail call.
620080dd10fSScott Constable   if (In.isBranch())
621080dd10fSScott Constable     for (const MachineOperand &O : In.operands())
622080dd10fSScott Constable       if (O.isGlobal() || O.isSymbol())
623080dd10fSScott Constable         return true;
624080dd10fSScott Constable 
625080dd10fSScott Constable   const MCInstrDesc &D = In.getDesc();
626080dd10fSScott Constable   if (!D.getImplicitDefs() && !D.getImplicitUses())
627080dd10fSScott Constable     return false;
628080dd10fSScott Constable   const MachineOperand &Op = In.getOperand(OpNum);
629080dd10fSScott Constable   // If there is a sub-register, treat the operand as non-fixed. Currently,
630080dd10fSScott Constable   // fixed registers are those that are listed in the descriptor as implicit
631080dd10fSScott Constable   // uses or defs, and those lists do not allow sub-registers.
632080dd10fSScott Constable   if (Op.getSubReg() != 0)
633080dd10fSScott Constable     return false;
634080dd10fSScott Constable   Register Reg = Op.getReg();
635080dd10fSScott Constable   const MCPhysReg *ImpR = Op.isDef() ? D.getImplicitDefs()
636080dd10fSScott Constable                                      : D.getImplicitUses();
637080dd10fSScott Constable   if (!ImpR)
638080dd10fSScott Constable     return false;
639080dd10fSScott Constable   while (*ImpR)
640080dd10fSScott Constable     if (*ImpR++ == Reg)
641080dd10fSScott Constable       return true;
642080dd10fSScott Constable   return false;
643080dd10fSScott Constable }
644080dd10fSScott Constable 
645080dd10fSScott Constable //
646080dd10fSScott Constable // The data flow graph construction.
647080dd10fSScott Constable //
648080dd10fSScott Constable 
DataFlowGraph(MachineFunction & mf,const TargetInstrInfo & tii,const TargetRegisterInfo & tri,const MachineDominatorTree & mdt,const MachineDominanceFrontier & mdf,const TargetOperandInfo & toi)649080dd10fSScott Constable DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
650080dd10fSScott Constable       const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
651080dd10fSScott Constable       const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
652080dd10fSScott Constable     : MF(mf), TII(tii), TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
653080dd10fSScott Constable       LiveIns(PRI) {
654080dd10fSScott Constable }
655080dd10fSScott Constable 
656080dd10fSScott Constable // The implementation of the definition stack.
657080dd10fSScott Constable // Each register reference has its own definition stack. In particular,
658080dd10fSScott Constable // for a register references "Reg" and "Reg:subreg" will each have their
659080dd10fSScott Constable // own definition stacks.
660080dd10fSScott Constable 
661080dd10fSScott Constable // Construct a stack iterator.
Iterator(const DataFlowGraph::DefStack & S,bool Top)662080dd10fSScott Constable DataFlowGraph::DefStack::Iterator::Iterator(const DataFlowGraph::DefStack &S,
663080dd10fSScott Constable       bool Top) : DS(S) {
664080dd10fSScott Constable   if (!Top) {
665080dd10fSScott Constable     // Initialize to bottom.
666080dd10fSScott Constable     Pos = 0;
667080dd10fSScott Constable     return;
668080dd10fSScott Constable   }
669080dd10fSScott Constable   // Initialize to the top, i.e. top-most non-delimiter (or 0, if empty).
670080dd10fSScott Constable   Pos = DS.Stack.size();
671080dd10fSScott Constable   while (Pos > 0 && DS.isDelimiter(DS.Stack[Pos-1]))
672080dd10fSScott Constable     Pos--;
673080dd10fSScott Constable }
674080dd10fSScott Constable 
675080dd10fSScott Constable // Return the size of the stack, including block delimiters.
size() const676080dd10fSScott Constable unsigned DataFlowGraph::DefStack::size() const {
677080dd10fSScott Constable   unsigned S = 0;
678080dd10fSScott Constable   for (auto I = top(), E = bottom(); I != E; I.down())
679080dd10fSScott Constable     S++;
680080dd10fSScott Constable   return S;
681080dd10fSScott Constable }
682080dd10fSScott Constable 
683080dd10fSScott Constable // Remove the top entry from the stack. Remove all intervening delimiters
684080dd10fSScott Constable // so that after this, the stack is either empty, or the top of the stack
685080dd10fSScott Constable // is a non-delimiter.
pop()686080dd10fSScott Constable void DataFlowGraph::DefStack::pop() {
687080dd10fSScott Constable   assert(!empty());
688080dd10fSScott Constable   unsigned P = nextDown(Stack.size());
689080dd10fSScott Constable   Stack.resize(P);
690080dd10fSScott Constable }
691080dd10fSScott Constable 
692080dd10fSScott Constable // Push a delimiter for block node N on the stack.
start_block(NodeId N)693080dd10fSScott Constable void DataFlowGraph::DefStack::start_block(NodeId N) {
694080dd10fSScott Constable   assert(N != 0);
695080dd10fSScott Constable   Stack.push_back(NodeAddr<DefNode*>(nullptr, N));
696080dd10fSScott Constable }
697080dd10fSScott Constable 
698080dd10fSScott Constable // Remove all nodes from the top of the stack, until the delimited for
699080dd10fSScott Constable // block node N is encountered. Remove the delimiter as well. In effect,
700080dd10fSScott Constable // this will remove from the stack all definitions from block N.
clear_block(NodeId N)701080dd10fSScott Constable void DataFlowGraph::DefStack::clear_block(NodeId N) {
702080dd10fSScott Constable   assert(N != 0);
703080dd10fSScott Constable   unsigned P = Stack.size();
704080dd10fSScott Constable   while (P > 0) {
705080dd10fSScott Constable     bool Found = isDelimiter(Stack[P-1], N);
706080dd10fSScott Constable     P--;
707080dd10fSScott Constable     if (Found)
708080dd10fSScott Constable       break;
709080dd10fSScott Constable   }
710080dd10fSScott Constable   // This will also remove the delimiter, if found.
711080dd10fSScott Constable   Stack.resize(P);
712080dd10fSScott Constable }
713080dd10fSScott Constable 
714080dd10fSScott Constable // Move the stack iterator up by one.
nextUp(unsigned P) const715080dd10fSScott Constable unsigned DataFlowGraph::DefStack::nextUp(unsigned P) const {
716080dd10fSScott Constable   // Get the next valid position after P (skipping all delimiters).
717080dd10fSScott Constable   // The input position P does not have to point to a non-delimiter.
718080dd10fSScott Constable   unsigned SS = Stack.size();
719080dd10fSScott Constable   bool IsDelim;
720080dd10fSScott Constable   assert(P < SS);
721080dd10fSScott Constable   do {
722080dd10fSScott Constable     P++;
723080dd10fSScott Constable     IsDelim = isDelimiter(Stack[P-1]);
724080dd10fSScott Constable   } while (P < SS && IsDelim);
725080dd10fSScott Constable   assert(!IsDelim);
726080dd10fSScott Constable   return P;
727080dd10fSScott Constable }
728080dd10fSScott Constable 
729080dd10fSScott Constable // Move the stack iterator down by one.
nextDown(unsigned P) const730080dd10fSScott Constable unsigned DataFlowGraph::DefStack::nextDown(unsigned P) const {
731080dd10fSScott Constable   // Get the preceding valid position before P (skipping all delimiters).
732080dd10fSScott Constable   // The input position P does not have to point to a non-delimiter.
733080dd10fSScott Constable   assert(P > 0 && P <= Stack.size());
734080dd10fSScott Constable   bool IsDelim = isDelimiter(Stack[P-1]);
735080dd10fSScott Constable   do {
736080dd10fSScott Constable     if (--P == 0)
737080dd10fSScott Constable       break;
738080dd10fSScott Constable     IsDelim = isDelimiter(Stack[P-1]);
739080dd10fSScott Constable   } while (P > 0 && IsDelim);
740080dd10fSScott Constable   assert(!IsDelim);
741080dd10fSScott Constable   return P;
742080dd10fSScott Constable }
743080dd10fSScott Constable 
744080dd10fSScott Constable // Register information.
745080dd10fSScott Constable 
getLandingPadLiveIns() const746080dd10fSScott Constable RegisterSet DataFlowGraph::getLandingPadLiveIns() const {
747080dd10fSScott Constable   RegisterSet LR;
748080dd10fSScott Constable   const Function &F = MF.getFunction();
749080dd10fSScott Constable   const Constant *PF = F.hasPersonalityFn() ? F.getPersonalityFn()
750080dd10fSScott Constable                                             : nullptr;
751080dd10fSScott Constable   const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
752080dd10fSScott Constable   if (RegisterId R = TLI.getExceptionPointerRegister(PF))
753080dd10fSScott Constable     LR.insert(RegisterRef(R));
754080dd10fSScott Constable   if (!isFuncletEHPersonality(classifyEHPersonality(PF))) {
755080dd10fSScott Constable     if (RegisterId R = TLI.getExceptionSelectorRegister(PF))
756080dd10fSScott Constable       LR.insert(RegisterRef(R));
757080dd10fSScott Constable   }
758080dd10fSScott Constable   return LR;
759080dd10fSScott Constable }
760080dd10fSScott Constable 
761080dd10fSScott Constable // Node management functions.
762080dd10fSScott Constable 
763080dd10fSScott Constable // Get the pointer to the node with the id N.
ptr(NodeId N) const764080dd10fSScott Constable NodeBase *DataFlowGraph::ptr(NodeId N) const {
765080dd10fSScott Constable   if (N == 0)
766080dd10fSScott Constable     return nullptr;
767080dd10fSScott Constable   return Memory.ptr(N);
768080dd10fSScott Constable }
769080dd10fSScott Constable 
770080dd10fSScott Constable // Get the id of the node at the address P.
id(const NodeBase * P) const771080dd10fSScott Constable NodeId DataFlowGraph::id(const NodeBase *P) const {
772080dd10fSScott Constable   if (P == nullptr)
773080dd10fSScott Constable     return 0;
774080dd10fSScott Constable   return Memory.id(P);
775080dd10fSScott Constable }
776080dd10fSScott Constable 
777080dd10fSScott Constable // Allocate a new node and set the attributes to Attrs.
newNode(uint16_t Attrs)778080dd10fSScott Constable NodeAddr<NodeBase*> DataFlowGraph::newNode(uint16_t Attrs) {
779080dd10fSScott Constable   NodeAddr<NodeBase*> P = Memory.New();
780080dd10fSScott Constable   P.Addr->init();
781080dd10fSScott Constable   P.Addr->setAttrs(Attrs);
782080dd10fSScott Constable   return P;
783080dd10fSScott Constable }
784080dd10fSScott Constable 
785080dd10fSScott Constable // Make a copy of the given node B, except for the data-flow links, which
786080dd10fSScott Constable // are set to 0.
cloneNode(const NodeAddr<NodeBase * > B)787080dd10fSScott Constable NodeAddr<NodeBase*> DataFlowGraph::cloneNode(const NodeAddr<NodeBase*> B) {
788080dd10fSScott Constable   NodeAddr<NodeBase*> NA = newNode(0);
789080dd10fSScott Constable   memcpy(NA.Addr, B.Addr, sizeof(NodeBase));
790080dd10fSScott Constable   // Ref nodes need to have the data-flow links reset.
791080dd10fSScott Constable   if (NA.Addr->getType() == NodeAttrs::Ref) {
792080dd10fSScott Constable     NodeAddr<RefNode*> RA = NA;
793080dd10fSScott Constable     RA.Addr->setReachingDef(0);
794080dd10fSScott Constable     RA.Addr->setSibling(0);
795080dd10fSScott Constable     if (NA.Addr->getKind() == NodeAttrs::Def) {
796080dd10fSScott Constable       NodeAddr<DefNode*> DA = NA;
797080dd10fSScott Constable       DA.Addr->setReachedDef(0);
798080dd10fSScott Constable       DA.Addr->setReachedUse(0);
799080dd10fSScott Constable     }
800080dd10fSScott Constable   }
801080dd10fSScott Constable   return NA;
802080dd10fSScott Constable }
803080dd10fSScott Constable 
804080dd10fSScott Constable // Allocation routines for specific node types/kinds.
805080dd10fSScott Constable 
newUse(NodeAddr<InstrNode * > Owner,MachineOperand & Op,uint16_t Flags)806080dd10fSScott Constable NodeAddr<UseNode*> DataFlowGraph::newUse(NodeAddr<InstrNode*> Owner,
807080dd10fSScott Constable       MachineOperand &Op, uint16_t Flags) {
808080dd10fSScott Constable   NodeAddr<UseNode*> UA = newNode(NodeAttrs::Ref | NodeAttrs::Use | Flags);
809080dd10fSScott Constable   UA.Addr->setRegRef(&Op, *this);
810080dd10fSScott Constable   return UA;
811080dd10fSScott Constable }
812080dd10fSScott Constable 
newPhiUse(NodeAddr<PhiNode * > Owner,RegisterRef RR,NodeAddr<BlockNode * > PredB,uint16_t Flags)813080dd10fSScott Constable NodeAddr<PhiUseNode*> DataFlowGraph::newPhiUse(NodeAddr<PhiNode*> Owner,
814080dd10fSScott Constable       RegisterRef RR, NodeAddr<BlockNode*> PredB, uint16_t Flags) {
815080dd10fSScott Constable   NodeAddr<PhiUseNode*> PUA = newNode(NodeAttrs::Ref | NodeAttrs::Use | Flags);
816080dd10fSScott Constable   assert(Flags & NodeAttrs::PhiRef);
817080dd10fSScott Constable   PUA.Addr->setRegRef(RR, *this);
818080dd10fSScott Constable   PUA.Addr->setPredecessor(PredB.Id);
819080dd10fSScott Constable   return PUA;
820080dd10fSScott Constable }
821080dd10fSScott Constable 
newDef(NodeAddr<InstrNode * > Owner,MachineOperand & Op,uint16_t Flags)822080dd10fSScott Constable NodeAddr<DefNode*> DataFlowGraph::newDef(NodeAddr<InstrNode*> Owner,
823080dd10fSScott Constable       MachineOperand &Op, uint16_t Flags) {
824080dd10fSScott Constable   NodeAddr<DefNode*> DA = newNode(NodeAttrs::Ref | NodeAttrs::Def | Flags);
825080dd10fSScott Constable   DA.Addr->setRegRef(&Op, *this);
826080dd10fSScott Constable   return DA;
827080dd10fSScott Constable }
828080dd10fSScott Constable 
newDef(NodeAddr<InstrNode * > Owner,RegisterRef RR,uint16_t Flags)829080dd10fSScott Constable NodeAddr<DefNode*> DataFlowGraph::newDef(NodeAddr<InstrNode*> Owner,
830080dd10fSScott Constable       RegisterRef RR, uint16_t Flags) {
831080dd10fSScott Constable   NodeAddr<DefNode*> DA = newNode(NodeAttrs::Ref | NodeAttrs::Def | Flags);
832080dd10fSScott Constable   assert(Flags & NodeAttrs::PhiRef);
833080dd10fSScott Constable   DA.Addr->setRegRef(RR, *this);
834080dd10fSScott Constable   return DA;
835080dd10fSScott Constable }
836080dd10fSScott Constable 
newPhi(NodeAddr<BlockNode * > Owner)837080dd10fSScott Constable NodeAddr<PhiNode*> DataFlowGraph::newPhi(NodeAddr<BlockNode*> Owner) {
838080dd10fSScott Constable   NodeAddr<PhiNode*> PA = newNode(NodeAttrs::Code | NodeAttrs::Phi);
839080dd10fSScott Constable   Owner.Addr->addPhi(PA, *this);
840080dd10fSScott Constable   return PA;
841080dd10fSScott Constable }
842080dd10fSScott Constable 
newStmt(NodeAddr<BlockNode * > Owner,MachineInstr * MI)843080dd10fSScott Constable NodeAddr<StmtNode*> DataFlowGraph::newStmt(NodeAddr<BlockNode*> Owner,
844080dd10fSScott Constable       MachineInstr *MI) {
845080dd10fSScott Constable   NodeAddr<StmtNode*> SA = newNode(NodeAttrs::Code | NodeAttrs::Stmt);
846080dd10fSScott Constable   SA.Addr->setCode(MI);
847080dd10fSScott Constable   Owner.Addr->addMember(SA, *this);
848080dd10fSScott Constable   return SA;
849080dd10fSScott Constable }
850080dd10fSScott Constable 
newBlock(NodeAddr<FuncNode * > Owner,MachineBasicBlock * BB)851080dd10fSScott Constable NodeAddr<BlockNode*> DataFlowGraph::newBlock(NodeAddr<FuncNode*> Owner,
852080dd10fSScott Constable       MachineBasicBlock *BB) {
853080dd10fSScott Constable   NodeAddr<BlockNode*> BA = newNode(NodeAttrs::Code | NodeAttrs::Block);
854080dd10fSScott Constable   BA.Addr->setCode(BB);
855080dd10fSScott Constable   Owner.Addr->addMember(BA, *this);
856080dd10fSScott Constable   return BA;
857080dd10fSScott Constable }
858080dd10fSScott Constable 
newFunc(MachineFunction * MF)859080dd10fSScott Constable NodeAddr<FuncNode*> DataFlowGraph::newFunc(MachineFunction *MF) {
860080dd10fSScott Constable   NodeAddr<FuncNode*> FA = newNode(NodeAttrs::Code | NodeAttrs::Func);
861080dd10fSScott Constable   FA.Addr->setCode(MF);
862080dd10fSScott Constable   return FA;
863080dd10fSScott Constable }
864080dd10fSScott Constable 
865080dd10fSScott Constable // Build the data flow graph.
build(unsigned Options)866080dd10fSScott Constable void DataFlowGraph::build(unsigned Options) {
867080dd10fSScott Constable   reset();
868080dd10fSScott Constable   Func = newFunc(&MF);
869080dd10fSScott Constable 
870080dd10fSScott Constable   if (MF.empty())
871080dd10fSScott Constable     return;
872080dd10fSScott Constable 
873080dd10fSScott Constable   for (MachineBasicBlock &B : MF) {
874080dd10fSScott Constable     NodeAddr<BlockNode*> BA = newBlock(Func, &B);
875080dd10fSScott Constable     BlockNodes.insert(std::make_pair(&B, BA));
876080dd10fSScott Constable     for (MachineInstr &I : B) {
877080dd10fSScott Constable       if (I.isDebugInstr())
878080dd10fSScott Constable         continue;
879080dd10fSScott Constable       buildStmt(BA, I);
880080dd10fSScott Constable     }
881080dd10fSScott Constable   }
882080dd10fSScott Constable 
883080dd10fSScott Constable   NodeAddr<BlockNode*> EA = Func.Addr->getEntryBlock(*this);
884080dd10fSScott Constable   NodeList Blocks = Func.Addr->members(*this);
885080dd10fSScott Constable 
886080dd10fSScott Constable   // Collect information about block references.
887080dd10fSScott Constable   RegisterSet AllRefs;
888080dd10fSScott Constable   for (NodeAddr<BlockNode*> BA : Blocks)
889080dd10fSScott Constable     for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this))
890080dd10fSScott Constable       for (NodeAddr<RefNode*> RA : IA.Addr->members(*this))
891080dd10fSScott Constable         AllRefs.insert(RA.Addr->getRegRef(*this));
892080dd10fSScott Constable 
893080dd10fSScott Constable   // Collect function live-ins and entry block live-ins.
894080dd10fSScott Constable   MachineRegisterInfo &MRI = MF.getRegInfo();
895080dd10fSScott Constable   MachineBasicBlock &EntryB = *EA.Addr->getCode();
896080dd10fSScott Constable   assert(EntryB.pred_empty() && "Function entry block has predecessors");
897080dd10fSScott Constable   for (std::pair<unsigned,unsigned> P : MRI.liveins())
898080dd10fSScott Constable     LiveIns.insert(RegisterRef(P.first));
899080dd10fSScott Constable   if (MRI.tracksLiveness()) {
900080dd10fSScott Constable     for (auto I : EntryB.liveins())
901080dd10fSScott Constable       LiveIns.insert(RegisterRef(I.PhysReg, I.LaneMask));
902080dd10fSScott Constable   }
903080dd10fSScott Constable 
904080dd10fSScott Constable   // Add function-entry phi nodes for the live-in registers.
905080dd10fSScott Constable   //for (std::pair<RegisterId,LaneBitmask> P : LiveIns) {
906080dd10fSScott Constable   for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
907080dd10fSScott Constable     RegisterRef RR = *I;
908080dd10fSScott Constable     NodeAddr<PhiNode*> PA = newPhi(EA);
909080dd10fSScott Constable     uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
910080dd10fSScott Constable     NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
911080dd10fSScott Constable     PA.Addr->addMember(DA, *this);
912080dd10fSScott Constable   }
913080dd10fSScott Constable 
914080dd10fSScott Constable   // Add phis for landing pads.
915080dd10fSScott Constable   // Landing pads, unlike usual backs blocks, are not entered through
916080dd10fSScott Constable   // branches in the program, or fall-throughs from other blocks. They
917080dd10fSScott Constable   // are entered from the exception handling runtime and target's ABI
918080dd10fSScott Constable   // may define certain registers as defined on entry to such a block.
919080dd10fSScott Constable   RegisterSet EHRegs = getLandingPadLiveIns();
920080dd10fSScott Constable   if (!EHRegs.empty()) {
921080dd10fSScott Constable     for (NodeAddr<BlockNode*> BA : Blocks) {
922080dd10fSScott Constable       const MachineBasicBlock &B = *BA.Addr->getCode();
923080dd10fSScott Constable       if (!B.isEHPad())
924080dd10fSScott Constable         continue;
925080dd10fSScott Constable 
926080dd10fSScott Constable       // Prepare a list of NodeIds of the block's predecessors.
927080dd10fSScott Constable       NodeList Preds;
928080dd10fSScott Constable       for (MachineBasicBlock *PB : B.predecessors())
929080dd10fSScott Constable         Preds.push_back(findBlock(PB));
930080dd10fSScott Constable 
931080dd10fSScott Constable       // Build phi nodes for each live-in.
932080dd10fSScott Constable       for (RegisterRef RR : EHRegs) {
933080dd10fSScott Constable         NodeAddr<PhiNode*> PA = newPhi(BA);
934080dd10fSScott Constable         uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
935080dd10fSScott Constable         // Add def:
936080dd10fSScott Constable         NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
937080dd10fSScott Constable         PA.Addr->addMember(DA, *this);
938080dd10fSScott Constable         // Add uses (no reaching defs for phi uses):
939080dd10fSScott Constable         for (NodeAddr<BlockNode*> PBA : Preds) {
940080dd10fSScott Constable           NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
941080dd10fSScott Constable           PA.Addr->addMember(PUA, *this);
942080dd10fSScott Constable         }
943080dd10fSScott Constable       }
944080dd10fSScott Constable     }
945080dd10fSScott Constable   }
946080dd10fSScott Constable 
947080dd10fSScott Constable   // Build a map "PhiM" which will contain, for each block, the set
948080dd10fSScott Constable   // of references that will require phi definitions in that block.
949080dd10fSScott Constable   BlockRefsMap PhiM;
950080dd10fSScott Constable   for (NodeAddr<BlockNode*> BA : Blocks)
951080dd10fSScott Constable     recordDefsForDF(PhiM, BA);
952080dd10fSScott Constable   for (NodeAddr<BlockNode*> BA : Blocks)
953080dd10fSScott Constable     buildPhis(PhiM, AllRefs, BA);
954080dd10fSScott Constable 
955080dd10fSScott Constable   // Link all the refs. This will recursively traverse the dominator tree.
956080dd10fSScott Constable   DefStackMap DM;
957080dd10fSScott Constable   linkBlockRefs(DM, EA);
958080dd10fSScott Constable 
959080dd10fSScott Constable   // Finally, remove all unused phi nodes.
960080dd10fSScott Constable   if (!(Options & BuildOptions::KeepDeadPhis))
961080dd10fSScott Constable     removeUnusedPhis();
962080dd10fSScott Constable }
963080dd10fSScott Constable 
makeRegRef(unsigned Reg,unsigned Sub) const964080dd10fSScott Constable RegisterRef DataFlowGraph::makeRegRef(unsigned Reg, unsigned Sub) const {
965080dd10fSScott Constable   assert(PhysicalRegisterInfo::isRegMaskId(Reg) ||
966080dd10fSScott Constable          Register::isPhysicalRegister(Reg));
967080dd10fSScott Constable   assert(Reg != 0);
968080dd10fSScott Constable   if (Sub != 0)
969080dd10fSScott Constable     Reg = TRI.getSubReg(Reg, Sub);
970080dd10fSScott Constable   return RegisterRef(Reg);
971080dd10fSScott Constable }
972080dd10fSScott Constable 
makeRegRef(const MachineOperand & Op) const973080dd10fSScott Constable RegisterRef DataFlowGraph::makeRegRef(const MachineOperand &Op) const {
974080dd10fSScott Constable   assert(Op.isReg() || Op.isRegMask());
975080dd10fSScott Constable   if (Op.isReg())
976080dd10fSScott Constable     return makeRegRef(Op.getReg(), Op.getSubReg());
977080dd10fSScott Constable   return RegisterRef(PRI.getRegMaskId(Op.getRegMask()), LaneBitmask::getAll());
978080dd10fSScott Constable }
979080dd10fSScott Constable 
980080dd10fSScott Constable // For each stack in the map DefM, push the delimiter for block B on it.
markBlock(NodeId B,DefStackMap & DefM)981080dd10fSScott Constable void DataFlowGraph::markBlock(NodeId B, DefStackMap &DefM) {
982080dd10fSScott Constable   // Push block delimiters.
98361efa3d9SKazu Hirata   for (auto &P : DefM)
98461efa3d9SKazu Hirata     P.second.start_block(B);
985080dd10fSScott Constable }
986080dd10fSScott Constable 
987080dd10fSScott Constable // Remove all definitions coming from block B from each stack in DefM.
releaseBlock(NodeId B,DefStackMap & DefM)988080dd10fSScott Constable void DataFlowGraph::releaseBlock(NodeId B, DefStackMap &DefM) {
989080dd10fSScott Constable   // Pop all defs from this block from the definition stack. Defs that were
990080dd10fSScott Constable   // added to the map during the traversal of instructions will not have a
991080dd10fSScott Constable   // delimiter, but for those, the whole stack will be emptied.
99261efa3d9SKazu Hirata   for (auto &P : DefM)
99361efa3d9SKazu Hirata     P.second.clear_block(B);
994080dd10fSScott Constable 
995080dd10fSScott Constable   // Finally, remove empty stacks from the map.
996080dd10fSScott Constable   for (auto I = DefM.begin(), E = DefM.end(), NextI = I; I != E; I = NextI) {
997080dd10fSScott Constable     NextI = std::next(I);
998080dd10fSScott Constable     // This preserves the validity of iterators other than I.
999080dd10fSScott Constable     if (I->second.empty())
1000080dd10fSScott Constable       DefM.erase(I);
1001080dd10fSScott Constable   }
1002080dd10fSScott Constable }
1003080dd10fSScott Constable 
1004080dd10fSScott Constable // Push all definitions from the instruction node IA to an appropriate
1005080dd10fSScott Constable // stack in DefM.
pushAllDefs(NodeAddr<InstrNode * > IA,DefStackMap & DefM)1006080dd10fSScott Constable void DataFlowGraph::pushAllDefs(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
1007080dd10fSScott Constable   pushClobbers(IA, DefM);
1008080dd10fSScott Constable   pushDefs(IA, DefM);
1009080dd10fSScott Constable }
1010080dd10fSScott Constable 
1011080dd10fSScott Constable // Push all definitions from the instruction node IA to an appropriate
1012080dd10fSScott Constable // stack in DefM.
pushClobbers(NodeAddr<InstrNode * > IA,DefStackMap & DefM)1013080dd10fSScott Constable void DataFlowGraph::pushClobbers(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
1014080dd10fSScott Constable   NodeSet Visited;
1015080dd10fSScott Constable   std::set<RegisterId> Defined;
1016080dd10fSScott Constable 
1017080dd10fSScott Constable   // The important objectives of this function are:
1018080dd10fSScott Constable   // - to be able to handle instructions both while the graph is being
1019080dd10fSScott Constable   //   constructed, and after the graph has been constructed, and
1020080dd10fSScott Constable   // - maintain proper ordering of definitions on the stack for each
1021080dd10fSScott Constable   //   register reference:
1022080dd10fSScott Constable   //   - if there are two or more related defs in IA (i.e. coming from
1023080dd10fSScott Constable   //     the same machine operand), then only push one def on the stack,
1024080dd10fSScott Constable   //   - if there are multiple unrelated defs of non-overlapping
1025080dd10fSScott Constable   //     subregisters of S, then the stack for S will have both (in an
1026080dd10fSScott Constable   //     unspecified order), but the order does not matter from the data-
1027080dd10fSScott Constable   //     -flow perspective.
1028080dd10fSScott Constable 
1029080dd10fSScott Constable   for (NodeAddr<DefNode*> DA : IA.Addr->members_if(IsDef, *this)) {
1030080dd10fSScott Constable     if (Visited.count(DA.Id))
1031080dd10fSScott Constable       continue;
1032080dd10fSScott Constable     if (!(DA.Addr->getFlags() & NodeAttrs::Clobbering))
1033080dd10fSScott Constable       continue;
1034080dd10fSScott Constable 
1035080dd10fSScott Constable     NodeList Rel = getRelatedRefs(IA, DA);
1036080dd10fSScott Constable     NodeAddr<DefNode*> PDA = Rel.front();
1037080dd10fSScott Constable     RegisterRef RR = PDA.Addr->getRegRef(*this);
1038080dd10fSScott Constable 
1039080dd10fSScott Constable     // Push the definition on the stack for the register and all aliases.
1040080dd10fSScott Constable     // The def stack traversal in linkNodeUp will check the exact aliasing.
1041080dd10fSScott Constable     DefM[RR.Reg].push(DA);
1042080dd10fSScott Constable     Defined.insert(RR.Reg);
1043080dd10fSScott Constable     for (RegisterId A : PRI.getAliasSet(RR.Reg)) {
1044080dd10fSScott Constable       // Check that we don't push the same def twice.
1045080dd10fSScott Constable       assert(A != RR.Reg);
1046080dd10fSScott Constable       if (!Defined.count(A))
1047080dd10fSScott Constable         DefM[A].push(DA);
1048080dd10fSScott Constable     }
1049080dd10fSScott Constable     // Mark all the related defs as visited.
1050080dd10fSScott Constable     for (NodeAddr<NodeBase*> T : Rel)
1051080dd10fSScott Constable       Visited.insert(T.Id);
1052080dd10fSScott Constable   }
1053080dd10fSScott Constable }
1054080dd10fSScott Constable 
1055080dd10fSScott Constable // Push all definitions from the instruction node IA to an appropriate
1056080dd10fSScott Constable // stack in DefM.
pushDefs(NodeAddr<InstrNode * > IA,DefStackMap & DefM)1057080dd10fSScott Constable void DataFlowGraph::pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
1058080dd10fSScott Constable   NodeSet Visited;
1059080dd10fSScott Constable #ifndef NDEBUG
1060080dd10fSScott Constable   std::set<RegisterId> Defined;
1061080dd10fSScott Constable #endif
1062080dd10fSScott Constable 
1063080dd10fSScott Constable   // The important objectives of this function are:
1064080dd10fSScott Constable   // - to be able to handle instructions both while the graph is being
1065080dd10fSScott Constable   //   constructed, and after the graph has been constructed, and
1066080dd10fSScott Constable   // - maintain proper ordering of definitions on the stack for each
1067080dd10fSScott Constable   //   register reference:
1068080dd10fSScott Constable   //   - if there are two or more related defs in IA (i.e. coming from
1069080dd10fSScott Constable   //     the same machine operand), then only push one def on the stack,
1070080dd10fSScott Constable   //   - if there are multiple unrelated defs of non-overlapping
1071080dd10fSScott Constable   //     subregisters of S, then the stack for S will have both (in an
1072080dd10fSScott Constable   //     unspecified order), but the order does not matter from the data-
1073080dd10fSScott Constable   //     -flow perspective.
1074080dd10fSScott Constable 
1075080dd10fSScott Constable   for (NodeAddr<DefNode*> DA : IA.Addr->members_if(IsDef, *this)) {
1076080dd10fSScott Constable     if (Visited.count(DA.Id))
1077080dd10fSScott Constable       continue;
1078080dd10fSScott Constable     if (DA.Addr->getFlags() & NodeAttrs::Clobbering)
1079080dd10fSScott Constable       continue;
1080080dd10fSScott Constable 
1081080dd10fSScott Constable     NodeList Rel = getRelatedRefs(IA, DA);
1082080dd10fSScott Constable     NodeAddr<DefNode*> PDA = Rel.front();
1083080dd10fSScott Constable     RegisterRef RR = PDA.Addr->getRegRef(*this);
1084080dd10fSScott Constable #ifndef NDEBUG
1085080dd10fSScott Constable     // Assert if the register is defined in two or more unrelated defs.
1086080dd10fSScott Constable     // This could happen if there are two or more def operands defining it.
1087080dd10fSScott Constable     if (!Defined.insert(RR.Reg).second) {
1088080dd10fSScott Constable       MachineInstr *MI = NodeAddr<StmtNode*>(IA).Addr->getCode();
1089080dd10fSScott Constable       dbgs() << "Multiple definitions of register: "
1090080dd10fSScott Constable              << Print<RegisterRef>(RR, *this) << " in\n  " << *MI << "in "
1091080dd10fSScott Constable              << printMBBReference(*MI->getParent()) << '\n';
1092080dd10fSScott Constable       llvm_unreachable(nullptr);
1093080dd10fSScott Constable     }
1094080dd10fSScott Constable #endif
1095080dd10fSScott Constable     // Push the definition on the stack for the register and all aliases.
1096080dd10fSScott Constable     // The def stack traversal in linkNodeUp will check the exact aliasing.
1097080dd10fSScott Constable     DefM[RR.Reg].push(DA);
1098080dd10fSScott Constable     for (RegisterId A : PRI.getAliasSet(RR.Reg)) {
1099080dd10fSScott Constable       // Check that we don't push the same def twice.
1100080dd10fSScott Constable       assert(A != RR.Reg);
1101080dd10fSScott Constable       DefM[A].push(DA);
1102080dd10fSScott Constable     }
1103080dd10fSScott Constable     // Mark all the related defs as visited.
1104080dd10fSScott Constable     for (NodeAddr<NodeBase*> T : Rel)
1105080dd10fSScott Constable       Visited.insert(T.Id);
1106080dd10fSScott Constable   }
1107080dd10fSScott Constable }
1108080dd10fSScott Constable 
1109080dd10fSScott Constable // Return the list of all reference nodes related to RA, including RA itself.
1110080dd10fSScott Constable // See "getNextRelated" for the meaning of a "related reference".
getRelatedRefs(NodeAddr<InstrNode * > IA,NodeAddr<RefNode * > RA) const1111080dd10fSScott Constable NodeList DataFlowGraph::getRelatedRefs(NodeAddr<InstrNode*> IA,
1112080dd10fSScott Constable       NodeAddr<RefNode*> RA) const {
1113080dd10fSScott Constable   assert(IA.Id != 0 && RA.Id != 0);
1114080dd10fSScott Constable 
1115080dd10fSScott Constable   NodeList Refs;
1116080dd10fSScott Constable   NodeId Start = RA.Id;
1117080dd10fSScott Constable   do {
1118080dd10fSScott Constable     Refs.push_back(RA);
1119080dd10fSScott Constable     RA = getNextRelated(IA, RA);
1120080dd10fSScott Constable   } while (RA.Id != 0 && RA.Id != Start);
1121080dd10fSScott Constable   return Refs;
1122080dd10fSScott Constable }
1123080dd10fSScott Constable 
1124080dd10fSScott Constable // Clear all information in the graph.
reset()1125080dd10fSScott Constable void DataFlowGraph::reset() {
1126080dd10fSScott Constable   Memory.clear();
1127080dd10fSScott Constable   BlockNodes.clear();
1128080dd10fSScott Constable   Func = NodeAddr<FuncNode*>();
1129080dd10fSScott Constable }
1130080dd10fSScott Constable 
1131080dd10fSScott Constable // Return the next reference node in the instruction node IA that is related
1132080dd10fSScott Constable // to RA. Conceptually, two reference nodes are related if they refer to the
1133080dd10fSScott Constable // same instance of a register access, but differ in flags or other minor
1134080dd10fSScott Constable // characteristics. Specific examples of related nodes are shadow reference
1135080dd10fSScott Constable // nodes.
1136080dd10fSScott Constable // Return the equivalent of nullptr if there are no more related references.
getNextRelated(NodeAddr<InstrNode * > IA,NodeAddr<RefNode * > RA) const1137080dd10fSScott Constable NodeAddr<RefNode*> DataFlowGraph::getNextRelated(NodeAddr<InstrNode*> IA,
1138080dd10fSScott Constable       NodeAddr<RefNode*> RA) const {
1139080dd10fSScott Constable   assert(IA.Id != 0 && RA.Id != 0);
1140080dd10fSScott Constable 
1141080dd10fSScott Constable   auto Related = [this,RA](NodeAddr<RefNode*> TA) -> bool {
1142080dd10fSScott Constable     if (TA.Addr->getKind() != RA.Addr->getKind())
1143080dd10fSScott Constable       return false;
1144080dd10fSScott Constable     if (TA.Addr->getRegRef(*this) != RA.Addr->getRegRef(*this))
1145080dd10fSScott Constable       return false;
1146080dd10fSScott Constable     return true;
1147080dd10fSScott Constable   };
1148080dd10fSScott Constable   auto RelatedStmt = [&Related,RA](NodeAddr<RefNode*> TA) -> bool {
1149080dd10fSScott Constable     return Related(TA) &&
1150080dd10fSScott Constable            &RA.Addr->getOp() == &TA.Addr->getOp();
1151080dd10fSScott Constable   };
1152080dd10fSScott Constable   auto RelatedPhi = [&Related,RA](NodeAddr<RefNode*> TA) -> bool {
1153080dd10fSScott Constable     if (!Related(TA))
1154080dd10fSScott Constable       return false;
1155080dd10fSScott Constable     if (TA.Addr->getKind() != NodeAttrs::Use)
1156080dd10fSScott Constable       return true;
1157080dd10fSScott Constable     // For phi uses, compare predecessor blocks.
1158080dd10fSScott Constable     const NodeAddr<const PhiUseNode*> TUA = TA;
1159080dd10fSScott Constable     const NodeAddr<const PhiUseNode*> RUA = RA;
1160080dd10fSScott Constable     return TUA.Addr->getPredecessor() == RUA.Addr->getPredecessor();
1161080dd10fSScott Constable   };
1162080dd10fSScott Constable 
1163080dd10fSScott Constable   RegisterRef RR = RA.Addr->getRegRef(*this);
1164080dd10fSScott Constable   if (IA.Addr->getKind() == NodeAttrs::Stmt)
1165080dd10fSScott Constable     return RA.Addr->getNextRef(RR, RelatedStmt, true, *this);
1166080dd10fSScott Constable   return RA.Addr->getNextRef(RR, RelatedPhi, true, *this);
1167080dd10fSScott Constable }
1168080dd10fSScott Constable 
1169080dd10fSScott Constable // Find the next node related to RA in IA that satisfies condition P.
1170080dd10fSScott Constable // If such a node was found, return a pair where the second element is the
1171080dd10fSScott Constable // located node. If such a node does not exist, return a pair where the
1172080dd10fSScott Constable // first element is the element after which such a node should be inserted,
1173080dd10fSScott Constable // and the second element is a null-address.
1174080dd10fSScott Constable template <typename Predicate>
1175080dd10fSScott Constable std::pair<NodeAddr<RefNode*>,NodeAddr<RefNode*>>
locateNextRef(NodeAddr<InstrNode * > IA,NodeAddr<RefNode * > RA,Predicate P) const1176080dd10fSScott Constable DataFlowGraph::locateNextRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
1177080dd10fSScott Constable       Predicate P) const {
1178080dd10fSScott Constable   assert(IA.Id != 0 && RA.Id != 0);
1179080dd10fSScott Constable 
1180080dd10fSScott Constable   NodeAddr<RefNode*> NA;
1181080dd10fSScott Constable   NodeId Start = RA.Id;
1182080dd10fSScott Constable   while (true) {
1183080dd10fSScott Constable     NA = getNextRelated(IA, RA);
1184080dd10fSScott Constable     if (NA.Id == 0 || NA.Id == Start)
1185080dd10fSScott Constable       break;
1186080dd10fSScott Constable     if (P(NA))
1187080dd10fSScott Constable       break;
1188080dd10fSScott Constable     RA = NA;
1189080dd10fSScott Constable   }
1190080dd10fSScott Constable 
1191080dd10fSScott Constable   if (NA.Id != 0 && NA.Id != Start)
1192080dd10fSScott Constable     return std::make_pair(RA, NA);
1193080dd10fSScott Constable   return std::make_pair(RA, NodeAddr<RefNode*>());
1194080dd10fSScott Constable }
1195080dd10fSScott Constable 
1196080dd10fSScott Constable // Get the next shadow node in IA corresponding to RA, and optionally create
1197080dd10fSScott Constable // such a node if it does not exist.
getNextShadow(NodeAddr<InstrNode * > IA,NodeAddr<RefNode * > RA,bool Create)1198080dd10fSScott Constable NodeAddr<RefNode*> DataFlowGraph::getNextShadow(NodeAddr<InstrNode*> IA,
1199080dd10fSScott Constable       NodeAddr<RefNode*> RA, bool Create) {
1200080dd10fSScott Constable   assert(IA.Id != 0 && RA.Id != 0);
1201080dd10fSScott Constable 
1202080dd10fSScott Constable   uint16_t Flags = RA.Addr->getFlags() | NodeAttrs::Shadow;
1203080dd10fSScott Constable   auto IsShadow = [Flags] (NodeAddr<RefNode*> TA) -> bool {
1204080dd10fSScott Constable     return TA.Addr->getFlags() == Flags;
1205080dd10fSScott Constable   };
1206080dd10fSScott Constable   auto Loc = locateNextRef(IA, RA, IsShadow);
1207080dd10fSScott Constable   if (Loc.second.Id != 0 || !Create)
1208080dd10fSScott Constable     return Loc.second;
1209080dd10fSScott Constable 
1210080dd10fSScott Constable   // Create a copy of RA and mark is as shadow.
1211080dd10fSScott Constable   NodeAddr<RefNode*> NA = cloneNode(RA);
1212080dd10fSScott Constable   NA.Addr->setFlags(Flags | NodeAttrs::Shadow);
1213080dd10fSScott Constable   IA.Addr->addMemberAfter(Loc.first, NA, *this);
1214080dd10fSScott Constable   return NA;
1215080dd10fSScott Constable }
1216080dd10fSScott Constable 
1217080dd10fSScott Constable // Get the next shadow node in IA corresponding to RA. Return null-address
1218080dd10fSScott Constable // if such a node does not exist.
getNextShadow(NodeAddr<InstrNode * > IA,NodeAddr<RefNode * > RA) const1219080dd10fSScott Constable NodeAddr<RefNode*> DataFlowGraph::getNextShadow(NodeAddr<InstrNode*> IA,
1220080dd10fSScott Constable       NodeAddr<RefNode*> RA) const {
1221080dd10fSScott Constable   assert(IA.Id != 0 && RA.Id != 0);
1222080dd10fSScott Constable   uint16_t Flags = RA.Addr->getFlags() | NodeAttrs::Shadow;
1223080dd10fSScott Constable   auto IsShadow = [Flags] (NodeAddr<RefNode*> TA) -> bool {
1224080dd10fSScott Constable     return TA.Addr->getFlags() == Flags;
1225080dd10fSScott Constable   };
1226080dd10fSScott Constable   return locateNextRef(IA, RA, IsShadow).second;
1227080dd10fSScott Constable }
1228080dd10fSScott Constable 
1229080dd10fSScott Constable // Create a new statement node in the block node BA that corresponds to
1230080dd10fSScott Constable // the machine instruction MI.
buildStmt(NodeAddr<BlockNode * > BA,MachineInstr & In)1231080dd10fSScott Constable void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
1232080dd10fSScott Constable   NodeAddr<StmtNode*> SA = newStmt(BA, &In);
1233080dd10fSScott Constable 
1234080dd10fSScott Constable   auto isCall = [] (const MachineInstr &In) -> bool {
1235080dd10fSScott Constable     if (In.isCall())
1236080dd10fSScott Constable       return true;
1237080dd10fSScott Constable     // Is tail call?
1238080dd10fSScott Constable     if (In.isBranch()) {
1239080dd10fSScott Constable       for (const MachineOperand &Op : In.operands())
1240080dd10fSScott Constable         if (Op.isGlobal() || Op.isSymbol())
1241080dd10fSScott Constable           return true;
1242080dd10fSScott Constable       // Assume indirect branches are calls. This is for the purpose of
1243080dd10fSScott Constable       // keeping implicit operands, and so it won't hurt on intra-function
1244080dd10fSScott Constable       // indirect branches.
1245080dd10fSScott Constable       if (In.isIndirectBranch())
1246080dd10fSScott Constable         return true;
1247080dd10fSScott Constable     }
1248080dd10fSScott Constable     return false;
1249080dd10fSScott Constable   };
1250080dd10fSScott Constable 
1251080dd10fSScott Constable   auto isDefUndef = [this] (const MachineInstr &In, RegisterRef DR) -> bool {
1252080dd10fSScott Constable     // This instruction defines DR. Check if there is a use operand that
1253080dd10fSScott Constable     // would make DR live on entry to the instruction.
1254080dd10fSScott Constable     for (const MachineOperand &Op : In.operands()) {
1255080dd10fSScott Constable       if (!Op.isReg() || Op.getReg() == 0 || !Op.isUse() || Op.isUndef())
1256080dd10fSScott Constable         continue;
1257080dd10fSScott Constable       RegisterRef UR = makeRegRef(Op);
1258080dd10fSScott Constable       if (PRI.alias(DR, UR))
1259080dd10fSScott Constable         return false;
1260080dd10fSScott Constable     }
1261080dd10fSScott Constable     return true;
1262080dd10fSScott Constable   };
1263080dd10fSScott Constable 
1264080dd10fSScott Constable   bool IsCall = isCall(In);
1265080dd10fSScott Constable   unsigned NumOps = In.getNumOperands();
1266080dd10fSScott Constable 
1267080dd10fSScott Constable   // Avoid duplicate implicit defs. This will not detect cases of implicit
1268080dd10fSScott Constable   // defs that define registers that overlap, but it is not clear how to
1269080dd10fSScott Constable   // interpret that in the absence of explicit defs. Overlapping explicit
1270080dd10fSScott Constable   // defs are likely illegal already.
1271080dd10fSScott Constable   BitVector DoneDefs(TRI.getNumRegs());
1272080dd10fSScott Constable   // Process explicit defs first.
1273080dd10fSScott Constable   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
1274080dd10fSScott Constable     MachineOperand &Op = In.getOperand(OpN);
1275080dd10fSScott Constable     if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1276080dd10fSScott Constable       continue;
1277080dd10fSScott Constable     Register R = Op.getReg();
1278080dd10fSScott Constable     if (!R || !Register::isPhysicalRegister(R))
1279080dd10fSScott Constable       continue;
1280080dd10fSScott Constable     uint16_t Flags = NodeAttrs::None;
1281080dd10fSScott Constable     if (TOI.isPreserving(In, OpN)) {
1282080dd10fSScott Constable       Flags |= NodeAttrs::Preserving;
1283080dd10fSScott Constable       // If the def is preserving, check if it is also undefined.
1284080dd10fSScott Constable       if (isDefUndef(In, makeRegRef(Op)))
1285080dd10fSScott Constable         Flags |= NodeAttrs::Undef;
1286080dd10fSScott Constable     }
1287080dd10fSScott Constable     if (TOI.isClobbering(In, OpN))
1288080dd10fSScott Constable       Flags |= NodeAttrs::Clobbering;
1289080dd10fSScott Constable     if (TOI.isFixedReg(In, OpN))
1290080dd10fSScott Constable       Flags |= NodeAttrs::Fixed;
1291080dd10fSScott Constable     if (IsCall && Op.isDead())
1292080dd10fSScott Constable       Flags |= NodeAttrs::Dead;
1293080dd10fSScott Constable     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
1294080dd10fSScott Constable     SA.Addr->addMember(DA, *this);
1295080dd10fSScott Constable     assert(!DoneDefs.test(R));
1296080dd10fSScott Constable     DoneDefs.set(R);
1297080dd10fSScott Constable   }
1298080dd10fSScott Constable 
1299080dd10fSScott Constable   // Process reg-masks (as clobbers).
1300080dd10fSScott Constable   BitVector DoneClobbers(TRI.getNumRegs());
1301080dd10fSScott Constable   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
1302080dd10fSScott Constable     MachineOperand &Op = In.getOperand(OpN);
1303080dd10fSScott Constable     if (!Op.isRegMask())
1304080dd10fSScott Constable       continue;
1305080dd10fSScott Constable     uint16_t Flags = NodeAttrs::Clobbering | NodeAttrs::Fixed |
1306080dd10fSScott Constable                      NodeAttrs::Dead;
1307080dd10fSScott Constable     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
1308080dd10fSScott Constable     SA.Addr->addMember(DA, *this);
1309080dd10fSScott Constable     // Record all clobbered registers in DoneDefs.
1310080dd10fSScott Constable     const uint32_t *RM = Op.getRegMask();
1311080dd10fSScott Constable     for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i)
1312080dd10fSScott Constable       if (!(RM[i/32] & (1u << (i%32))))
1313080dd10fSScott Constable         DoneClobbers.set(i);
1314080dd10fSScott Constable   }
1315080dd10fSScott Constable 
1316080dd10fSScott Constable   // Process implicit defs, skipping those that have already been added
1317080dd10fSScott Constable   // as explicit.
1318080dd10fSScott Constable   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
1319080dd10fSScott Constable     MachineOperand &Op = In.getOperand(OpN);
1320080dd10fSScott Constable     if (!Op.isReg() || !Op.isDef() || !Op.isImplicit())
1321080dd10fSScott Constable       continue;
1322080dd10fSScott Constable     Register R = Op.getReg();
1323080dd10fSScott Constable     if (!R || !Register::isPhysicalRegister(R) || DoneDefs.test(R))
1324080dd10fSScott Constable       continue;
1325080dd10fSScott Constable     RegisterRef RR = makeRegRef(Op);
1326080dd10fSScott Constable     uint16_t Flags = NodeAttrs::None;
1327080dd10fSScott Constable     if (TOI.isPreserving(In, OpN)) {
1328080dd10fSScott Constable       Flags |= NodeAttrs::Preserving;
1329080dd10fSScott Constable       // If the def is preserving, check if it is also undefined.
1330080dd10fSScott Constable       if (isDefUndef(In, RR))
1331080dd10fSScott Constable         Flags |= NodeAttrs::Undef;
1332080dd10fSScott Constable     }
1333080dd10fSScott Constable     if (TOI.isClobbering(In, OpN))
1334080dd10fSScott Constable       Flags |= NodeAttrs::Clobbering;
1335080dd10fSScott Constable     if (TOI.isFixedReg(In, OpN))
1336080dd10fSScott Constable       Flags |= NodeAttrs::Fixed;
1337080dd10fSScott Constable     if (IsCall && Op.isDead()) {
1338080dd10fSScott Constable       if (DoneClobbers.test(R))
1339080dd10fSScott Constable         continue;
1340080dd10fSScott Constable       Flags |= NodeAttrs::Dead;
1341080dd10fSScott Constable     }
1342080dd10fSScott Constable     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
1343080dd10fSScott Constable     SA.Addr->addMember(DA, *this);
1344080dd10fSScott Constable     DoneDefs.set(R);
1345080dd10fSScott Constable   }
1346080dd10fSScott Constable 
1347080dd10fSScott Constable   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
1348080dd10fSScott Constable     MachineOperand &Op = In.getOperand(OpN);
1349080dd10fSScott Constable     if (!Op.isReg() || !Op.isUse())
1350080dd10fSScott Constable       continue;
1351080dd10fSScott Constable     Register R = Op.getReg();
1352080dd10fSScott Constable     if (!R || !Register::isPhysicalRegister(R))
1353080dd10fSScott Constable       continue;
1354080dd10fSScott Constable     uint16_t Flags = NodeAttrs::None;
1355080dd10fSScott Constable     if (Op.isUndef())
1356080dd10fSScott Constable       Flags |= NodeAttrs::Undef;
1357080dd10fSScott Constable     if (TOI.isFixedReg(In, OpN))
1358080dd10fSScott Constable       Flags |= NodeAttrs::Fixed;
1359080dd10fSScott Constable     NodeAddr<UseNode*> UA = newUse(SA, Op, Flags);
1360080dd10fSScott Constable     SA.Addr->addMember(UA, *this);
1361080dd10fSScott Constable   }
1362080dd10fSScott Constable }
1363080dd10fSScott Constable 
1364080dd10fSScott Constable // Scan all defs in the block node BA and record in PhiM the locations of
1365080dd10fSScott Constable // phi nodes corresponding to these defs.
recordDefsForDF(BlockRefsMap & PhiM,NodeAddr<BlockNode * > BA)1366080dd10fSScott Constable void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
1367080dd10fSScott Constable       NodeAddr<BlockNode*> BA) {
1368080dd10fSScott Constable   // Check all defs from block BA and record them in each block in BA's
1369080dd10fSScott Constable   // iterated dominance frontier. This information will later be used to
1370080dd10fSScott Constable   // create phi nodes.
1371080dd10fSScott Constable   MachineBasicBlock *BB = BA.Addr->getCode();
1372080dd10fSScott Constable   assert(BB);
1373080dd10fSScott Constable   auto DFLoc = MDF.find(BB);
1374080dd10fSScott Constable   if (DFLoc == MDF.end() || DFLoc->second.empty())
1375080dd10fSScott Constable     return;
1376080dd10fSScott Constable 
1377080dd10fSScott Constable   // Traverse all instructions in the block and collect the set of all
1378080dd10fSScott Constable   // defined references. For each reference there will be a phi created
1379080dd10fSScott Constable   // in the block's iterated dominance frontier.
1380080dd10fSScott Constable   // This is done to make sure that each defined reference gets only one
1381080dd10fSScott Constable   // phi node, even if it is defined multiple times.
1382080dd10fSScott Constable   RegisterSet Defs;
1383080dd10fSScott Constable   for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this))
1384080dd10fSScott Constable     for (NodeAddr<RefNode*> RA : IA.Addr->members_if(IsDef, *this))
1385080dd10fSScott Constable       Defs.insert(RA.Addr->getRegRef(*this));
1386080dd10fSScott Constable 
1387080dd10fSScott Constable   // Calculate the iterated dominance frontier of BB.
1388080dd10fSScott Constable   const MachineDominanceFrontier::DomSetType &DF = DFLoc->second;
1389080dd10fSScott Constable   SetVector<MachineBasicBlock*> IDF(DF.begin(), DF.end());
1390080dd10fSScott Constable   for (unsigned i = 0; i < IDF.size(); ++i) {
1391080dd10fSScott Constable     auto F = MDF.find(IDF[i]);
1392080dd10fSScott Constable     if (F != MDF.end())
1393080dd10fSScott Constable       IDF.insert(F->second.begin(), F->second.end());
1394080dd10fSScott Constable   }
1395080dd10fSScott Constable 
1396080dd10fSScott Constable   // Finally, add the set of defs to each block in the iterated dominance
1397080dd10fSScott Constable   // frontier.
1398*9e6d1f4bSKazu Hirata   for (auto *DB : IDF) {
1399080dd10fSScott Constable     NodeAddr<BlockNode*> DBA = findBlock(DB);
1400080dd10fSScott Constable     PhiM[DBA.Id].insert(Defs.begin(), Defs.end());
1401080dd10fSScott Constable   }
1402080dd10fSScott Constable }
1403080dd10fSScott Constable 
1404080dd10fSScott Constable // Given the locations of phi nodes in the map PhiM, create the phi nodes
1405080dd10fSScott Constable // that are located in the block node BA.
buildPhis(BlockRefsMap & PhiM,RegisterSet & AllRefs,NodeAddr<BlockNode * > BA)1406080dd10fSScott Constable void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, RegisterSet &AllRefs,
1407080dd10fSScott Constable       NodeAddr<BlockNode*> BA) {
1408080dd10fSScott Constable   // Check if this blocks has any DF defs, i.e. if there are any defs
1409080dd10fSScott Constable   // that this block is in the iterated dominance frontier of.
1410080dd10fSScott Constable   auto HasDF = PhiM.find(BA.Id);
1411080dd10fSScott Constable   if (HasDF == PhiM.end() || HasDF->second.empty())
1412080dd10fSScott Constable     return;
1413080dd10fSScott Constable 
1414080dd10fSScott Constable   // First, remove all R in Refs in such that there exists T in Refs
1415080dd10fSScott Constable   // such that T covers R. In other words, only leave those refs that
1416080dd10fSScott Constable   // are not covered by another ref (i.e. maximal with respect to covering).
1417080dd10fSScott Constable 
1418080dd10fSScott Constable   auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
1419080dd10fSScott Constable     for (RegisterRef I : RRs)
1420080dd10fSScott Constable       if (I != RR && RegisterAggr::isCoverOf(I, RR, PRI))
1421080dd10fSScott Constable         RR = I;
1422080dd10fSScott Constable     return RR;
1423080dd10fSScott Constable   };
1424080dd10fSScott Constable 
1425080dd10fSScott Constable   RegisterSet MaxDF;
1426080dd10fSScott Constable   for (RegisterRef I : HasDF->second)
1427080dd10fSScott Constable     MaxDF.insert(MaxCoverIn(I, HasDF->second));
1428080dd10fSScott Constable 
1429080dd10fSScott Constable   std::vector<RegisterRef> MaxRefs;
1430080dd10fSScott Constable   for (RegisterRef I : MaxDF)
1431080dd10fSScott Constable     MaxRefs.push_back(MaxCoverIn(I, AllRefs));
1432080dd10fSScott Constable 
1433080dd10fSScott Constable   // Now, for each R in MaxRefs, get the alias closure of R. If the closure
1434080dd10fSScott Constable   // only has R in it, create a phi a def for R. Otherwise, create a phi,
1435080dd10fSScott Constable   // and add a def for each S in the closure.
1436080dd10fSScott Constable 
1437080dd10fSScott Constable   // Sort the refs so that the phis will be created in a deterministic order.
1438080dd10fSScott Constable   llvm::sort(MaxRefs);
1439080dd10fSScott Constable   // Remove duplicates.
1440080dd10fSScott Constable   auto NewEnd = std::unique(MaxRefs.begin(), MaxRefs.end());
1441080dd10fSScott Constable   MaxRefs.erase(NewEnd, MaxRefs.end());
1442080dd10fSScott Constable 
1443080dd10fSScott Constable   auto Aliased = [this,&MaxRefs](RegisterRef RR,
1444080dd10fSScott Constable                                  std::vector<unsigned> &Closure) -> bool {
1445080dd10fSScott Constable     for (unsigned I : Closure)
1446080dd10fSScott Constable       if (PRI.alias(RR, MaxRefs[I]))
1447080dd10fSScott Constable         return true;
1448080dd10fSScott Constable     return false;
1449080dd10fSScott Constable   };
1450080dd10fSScott Constable 
1451080dd10fSScott Constable   // Prepare a list of NodeIds of the block's predecessors.
1452080dd10fSScott Constable   NodeList Preds;
1453080dd10fSScott Constable   const MachineBasicBlock *MBB = BA.Addr->getCode();
1454080dd10fSScott Constable   for (MachineBasicBlock *PB : MBB->predecessors())
1455080dd10fSScott Constable     Preds.push_back(findBlock(PB));
1456080dd10fSScott Constable 
1457080dd10fSScott Constable   while (!MaxRefs.empty()) {
1458080dd10fSScott Constable     // Put the first element in the closure, and then add all subsequent
1459080dd10fSScott Constable     // elements from MaxRefs to it, if they alias at least one element
1460080dd10fSScott Constable     // already in the closure.
1461080dd10fSScott Constable     // ClosureIdx: vector of indices in MaxRefs of members of the closure.
1462080dd10fSScott Constable     std::vector<unsigned> ClosureIdx = { 0 };
1463080dd10fSScott Constable     for (unsigned i = 1; i != MaxRefs.size(); ++i)
1464080dd10fSScott Constable       if (Aliased(MaxRefs[i], ClosureIdx))
1465080dd10fSScott Constable         ClosureIdx.push_back(i);
1466080dd10fSScott Constable 
1467080dd10fSScott Constable     // Build a phi for the closure.
1468080dd10fSScott Constable     unsigned CS = ClosureIdx.size();
1469080dd10fSScott Constable     NodeAddr<PhiNode*> PA = newPhi(BA);
1470080dd10fSScott Constable 
1471080dd10fSScott Constable     // Add defs.
1472080dd10fSScott Constable     for (unsigned X = 0; X != CS; ++X) {
1473080dd10fSScott Constable       RegisterRef RR = MaxRefs[ClosureIdx[X]];
1474080dd10fSScott Constable       uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
1475080dd10fSScott Constable       NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
1476080dd10fSScott Constable       PA.Addr->addMember(DA, *this);
1477080dd10fSScott Constable     }
1478080dd10fSScott Constable     // Add phi uses.
1479080dd10fSScott Constable     for (NodeAddr<BlockNode*> PBA : Preds) {
1480080dd10fSScott Constable       for (unsigned X = 0; X != CS; ++X) {
1481080dd10fSScott Constable         RegisterRef RR = MaxRefs[ClosureIdx[X]];
1482080dd10fSScott Constable         NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
1483080dd10fSScott Constable         PA.Addr->addMember(PUA, *this);
1484080dd10fSScott Constable       }
1485080dd10fSScott Constable     }
1486080dd10fSScott Constable 
1487080dd10fSScott Constable     // Erase from MaxRefs all elements in the closure.
1488080dd10fSScott Constable     auto Begin = MaxRefs.begin();
1489bb6447a7SKazu Hirata     for (unsigned Idx : llvm::reverse(ClosureIdx))
1490bb6447a7SKazu Hirata       MaxRefs.erase(Begin + Idx);
1491080dd10fSScott Constable   }
1492080dd10fSScott Constable }
1493080dd10fSScott Constable 
1494080dd10fSScott Constable // Remove any unneeded phi nodes that were created during the build process.
removeUnusedPhis()1495080dd10fSScott Constable void DataFlowGraph::removeUnusedPhis() {
1496080dd10fSScott Constable   // This will remove unused phis, i.e. phis where each def does not reach
1497080dd10fSScott Constable   // any uses or other defs. This will not detect or remove circular phi
1498080dd10fSScott Constable   // chains that are otherwise dead. Unused/dead phis are created during
1499080dd10fSScott Constable   // the build process and this function is intended to remove these cases
1500080dd10fSScott Constable   // that are easily determinable to be unnecessary.
1501080dd10fSScott Constable 
1502080dd10fSScott Constable   SetVector<NodeId> PhiQ;
1503080dd10fSScott Constable   for (NodeAddr<BlockNode*> BA : Func.Addr->members(*this)) {
1504080dd10fSScott Constable     for (auto P : BA.Addr->members_if(IsPhi, *this))
1505080dd10fSScott Constable       PhiQ.insert(P.Id);
1506080dd10fSScott Constable   }
1507080dd10fSScott Constable 
1508080dd10fSScott Constable   static auto HasUsedDef = [](NodeList &Ms) -> bool {
1509080dd10fSScott Constable     for (NodeAddr<NodeBase*> M : Ms) {
1510080dd10fSScott Constable       if (M.Addr->getKind() != NodeAttrs::Def)
1511080dd10fSScott Constable         continue;
1512080dd10fSScott Constable       NodeAddr<DefNode*> DA = M;
1513080dd10fSScott Constable       if (DA.Addr->getReachedDef() != 0 || DA.Addr->getReachedUse() != 0)
1514080dd10fSScott Constable         return true;
1515080dd10fSScott Constable     }
1516080dd10fSScott Constable     return false;
1517080dd10fSScott Constable   };
1518080dd10fSScott Constable 
1519080dd10fSScott Constable   // Any phi, if it is removed, may affect other phis (make them dead).
1520080dd10fSScott Constable   // For each removed phi, collect the potentially affected phis and add
1521080dd10fSScott Constable   // them back to the queue.
1522080dd10fSScott Constable   while (!PhiQ.empty()) {
1523080dd10fSScott Constable     auto PA = addr<PhiNode*>(PhiQ[0]);
1524080dd10fSScott Constable     PhiQ.remove(PA.Id);
1525080dd10fSScott Constable     NodeList Refs = PA.Addr->members(*this);
1526080dd10fSScott Constable     if (HasUsedDef(Refs))
1527080dd10fSScott Constable       continue;
1528080dd10fSScott Constable     for (NodeAddr<RefNode*> RA : Refs) {
1529080dd10fSScott Constable       if (NodeId RD = RA.Addr->getReachingDef()) {
1530080dd10fSScott Constable         auto RDA = addr<DefNode*>(RD);
1531080dd10fSScott Constable         NodeAddr<InstrNode*> OA = RDA.Addr->getOwner(*this);
1532080dd10fSScott Constable         if (IsPhi(OA))
1533080dd10fSScott Constable           PhiQ.insert(OA.Id);
1534080dd10fSScott Constable       }
1535080dd10fSScott Constable       if (RA.Addr->isDef())
1536080dd10fSScott Constable         unlinkDef(RA, true);
1537080dd10fSScott Constable       else
1538080dd10fSScott Constable         unlinkUse(RA, true);
1539080dd10fSScott Constable     }
1540080dd10fSScott Constable     NodeAddr<BlockNode*> BA = PA.Addr->getOwner(*this);
1541080dd10fSScott Constable     BA.Addr->removeMember(PA, *this);
1542080dd10fSScott Constable   }
1543080dd10fSScott Constable }
1544080dd10fSScott Constable 
1545080dd10fSScott Constable // For a given reference node TA in an instruction node IA, connect the
1546080dd10fSScott Constable // reaching def of TA to the appropriate def node. Create any shadow nodes
1547080dd10fSScott Constable // as appropriate.
1548080dd10fSScott Constable template <typename T>
linkRefUp(NodeAddr<InstrNode * > IA,NodeAddr<T> TA,DefStack & DS)1549080dd10fSScott Constable void DataFlowGraph::linkRefUp(NodeAddr<InstrNode*> IA, NodeAddr<T> TA,
1550080dd10fSScott Constable       DefStack &DS) {
1551080dd10fSScott Constable   if (DS.empty())
1552080dd10fSScott Constable     return;
1553080dd10fSScott Constable   RegisterRef RR = TA.Addr->getRegRef(*this);
1554080dd10fSScott Constable   NodeAddr<T> TAP;
1555080dd10fSScott Constable 
1556080dd10fSScott Constable   // References from the def stack that have been examined so far.
1557080dd10fSScott Constable   RegisterAggr Defs(PRI);
1558080dd10fSScott Constable 
1559080dd10fSScott Constable   for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
1560080dd10fSScott Constable     RegisterRef QR = I->Addr->getRegRef(*this);
1561080dd10fSScott Constable 
1562080dd10fSScott Constable     // Skip all defs that are aliased to any of the defs that we have already
1563080dd10fSScott Constable     // seen. If this completes a cover of RR, stop the stack traversal.
1564080dd10fSScott Constable     bool Alias = Defs.hasAliasOf(QR);
1565080dd10fSScott Constable     bool Cover = Defs.insert(QR).hasCoverOf(RR);
1566080dd10fSScott Constable     if (Alias) {
1567080dd10fSScott Constable       if (Cover)
1568080dd10fSScott Constable         break;
1569080dd10fSScott Constable       continue;
1570080dd10fSScott Constable     }
1571080dd10fSScott Constable 
1572080dd10fSScott Constable     // The reaching def.
1573080dd10fSScott Constable     NodeAddr<DefNode*> RDA = *I;
1574080dd10fSScott Constable 
1575080dd10fSScott Constable     // Pick the reached node.
1576080dd10fSScott Constable     if (TAP.Id == 0) {
1577080dd10fSScott Constable       TAP = TA;
1578080dd10fSScott Constable     } else {
1579080dd10fSScott Constable       // Mark the existing ref as "shadow" and create a new shadow.
1580080dd10fSScott Constable       TAP.Addr->setFlags(TAP.Addr->getFlags() | NodeAttrs::Shadow);
1581080dd10fSScott Constable       TAP = getNextShadow(IA, TAP, true);
1582080dd10fSScott Constable     }
1583080dd10fSScott Constable 
1584080dd10fSScott Constable     // Create the link.
1585080dd10fSScott Constable     TAP.Addr->linkToDef(TAP.Id, RDA);
1586080dd10fSScott Constable 
1587080dd10fSScott Constable     if (Cover)
1588080dd10fSScott Constable       break;
1589080dd10fSScott Constable   }
1590080dd10fSScott Constable }
1591080dd10fSScott Constable 
1592080dd10fSScott Constable // Create data-flow links for all reference nodes in the statement node SA.
1593080dd10fSScott Constable template <typename Predicate>
linkStmtRefs(DefStackMap & DefM,NodeAddr<StmtNode * > SA,Predicate P)1594080dd10fSScott Constable void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA,
1595080dd10fSScott Constable       Predicate P) {
1596080dd10fSScott Constable #ifndef NDEBUG
1597080dd10fSScott Constable   RegisterSet Defs;
1598080dd10fSScott Constable #endif
1599080dd10fSScott Constable 
1600080dd10fSScott Constable   // Link all nodes (upwards in the data-flow) with their reaching defs.
1601080dd10fSScott Constable   for (NodeAddr<RefNode*> RA : SA.Addr->members_if(P, *this)) {
1602080dd10fSScott Constable     uint16_t Kind = RA.Addr->getKind();
1603080dd10fSScott Constable     assert(Kind == NodeAttrs::Def || Kind == NodeAttrs::Use);
1604080dd10fSScott Constable     RegisterRef RR = RA.Addr->getRegRef(*this);
1605080dd10fSScott Constable #ifndef NDEBUG
1606080dd10fSScott Constable     // Do not expect multiple defs of the same reference.
1607080dd10fSScott Constable     assert(Kind != NodeAttrs::Def || !Defs.count(RR));
1608080dd10fSScott Constable     Defs.insert(RR);
1609080dd10fSScott Constable #endif
1610080dd10fSScott Constable 
1611080dd10fSScott Constable     auto F = DefM.find(RR.Reg);
1612080dd10fSScott Constable     if (F == DefM.end())
1613080dd10fSScott Constable       continue;
1614080dd10fSScott Constable     DefStack &DS = F->second;
1615080dd10fSScott Constable     if (Kind == NodeAttrs::Use)
1616080dd10fSScott Constable       linkRefUp<UseNode*>(SA, RA, DS);
1617080dd10fSScott Constable     else if (Kind == NodeAttrs::Def)
1618080dd10fSScott Constable       linkRefUp<DefNode*>(SA, RA, DS);
1619080dd10fSScott Constable     else
1620080dd10fSScott Constable       llvm_unreachable("Unexpected node in instruction");
1621080dd10fSScott Constable   }
1622080dd10fSScott Constable }
1623080dd10fSScott Constable 
1624080dd10fSScott Constable // Create data-flow links for all instructions in the block node BA. This
1625080dd10fSScott Constable // will include updating any phi nodes in BA.
linkBlockRefs(DefStackMap & DefM,NodeAddr<BlockNode * > BA)1626080dd10fSScott Constable void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA) {
1627080dd10fSScott Constable   // Push block delimiters.
1628080dd10fSScott Constable   markBlock(BA.Id, DefM);
1629080dd10fSScott Constable 
1630080dd10fSScott Constable   auto IsClobber = [] (NodeAddr<RefNode*> RA) -> bool {
1631080dd10fSScott Constable     return IsDef(RA) && (RA.Addr->getFlags() & NodeAttrs::Clobbering);
1632080dd10fSScott Constable   };
1633080dd10fSScott Constable   auto IsNoClobber = [] (NodeAddr<RefNode*> RA) -> bool {
1634080dd10fSScott Constable     return IsDef(RA) && !(RA.Addr->getFlags() & NodeAttrs::Clobbering);
1635080dd10fSScott Constable   };
1636080dd10fSScott Constable 
1637080dd10fSScott Constable   assert(BA.Addr && "block node address is needed to create a data-flow link");
1638080dd10fSScott Constable   // For each non-phi instruction in the block, link all the defs and uses
1639080dd10fSScott Constable   // to their reaching defs. For any member of the block (including phis),
1640080dd10fSScott Constable   // push the defs on the corresponding stacks.
1641080dd10fSScott Constable   for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this)) {
1642080dd10fSScott Constable     // Ignore phi nodes here. They will be linked part by part from the
1643080dd10fSScott Constable     // predecessors.
1644080dd10fSScott Constable     if (IA.Addr->getKind() == NodeAttrs::Stmt) {
1645080dd10fSScott Constable       linkStmtRefs(DefM, IA, IsUse);
1646080dd10fSScott Constable       linkStmtRefs(DefM, IA, IsClobber);
1647080dd10fSScott Constable     }
1648080dd10fSScott Constable 
1649080dd10fSScott Constable     // Push the definitions on the stack.
1650080dd10fSScott Constable     pushClobbers(IA, DefM);
1651080dd10fSScott Constable 
1652080dd10fSScott Constable     if (IA.Addr->getKind() == NodeAttrs::Stmt)
1653080dd10fSScott Constable       linkStmtRefs(DefM, IA, IsNoClobber);
1654080dd10fSScott Constable 
1655080dd10fSScott Constable     pushDefs(IA, DefM);
1656080dd10fSScott Constable   }
1657080dd10fSScott Constable 
1658080dd10fSScott Constable   // Recursively process all children in the dominator tree.
1659080dd10fSScott Constable   MachineDomTreeNode *N = MDT.getNode(BA.Addr->getCode());
1660*9e6d1f4bSKazu Hirata   for (auto *I : *N) {
1661080dd10fSScott Constable     MachineBasicBlock *SB = I->getBlock();
1662080dd10fSScott Constable     NodeAddr<BlockNode*> SBA = findBlock(SB);
1663080dd10fSScott Constable     linkBlockRefs(DefM, SBA);
1664080dd10fSScott Constable   }
1665080dd10fSScott Constable 
1666080dd10fSScott Constable   // Link the phi uses from the successor blocks.
1667080dd10fSScott Constable   auto IsUseForBA = [BA](NodeAddr<NodeBase*> NA) -> bool {
1668080dd10fSScott Constable     if (NA.Addr->getKind() != NodeAttrs::Use)
1669080dd10fSScott Constable       return false;
1670080dd10fSScott Constable     assert(NA.Addr->getFlags() & NodeAttrs::PhiRef);
1671080dd10fSScott Constable     NodeAddr<PhiUseNode*> PUA = NA;
1672080dd10fSScott Constable     return PUA.Addr->getPredecessor() == BA.Id;
1673080dd10fSScott Constable   };
1674080dd10fSScott Constable 
1675080dd10fSScott Constable   RegisterSet EHLiveIns = getLandingPadLiveIns();
1676080dd10fSScott Constable   MachineBasicBlock *MBB = BA.Addr->getCode();
1677080dd10fSScott Constable 
1678080dd10fSScott Constable   for (MachineBasicBlock *SB : MBB->successors()) {
1679080dd10fSScott Constable     bool IsEHPad = SB->isEHPad();
1680080dd10fSScott Constable     NodeAddr<BlockNode*> SBA = findBlock(SB);
1681080dd10fSScott Constable     for (NodeAddr<InstrNode*> IA : SBA.Addr->members_if(IsPhi, *this)) {
1682080dd10fSScott Constable       // Do not link phi uses for landing pad live-ins.
1683080dd10fSScott Constable       if (IsEHPad) {
1684080dd10fSScott Constable         // Find what register this phi is for.
1685080dd10fSScott Constable         NodeAddr<RefNode*> RA = IA.Addr->getFirstMember(*this);
1686080dd10fSScott Constable         assert(RA.Id != 0);
1687080dd10fSScott Constable         if (EHLiveIns.count(RA.Addr->getRegRef(*this)))
1688080dd10fSScott Constable           continue;
1689080dd10fSScott Constable       }
1690080dd10fSScott Constable       // Go over each phi use associated with MBB, and link it.
1691080dd10fSScott Constable       for (auto U : IA.Addr->members_if(IsUseForBA, *this)) {
1692080dd10fSScott Constable         NodeAddr<PhiUseNode*> PUA = U;
1693080dd10fSScott Constable         RegisterRef RR = PUA.Addr->getRegRef(*this);
1694080dd10fSScott Constable         linkRefUp<UseNode*>(IA, PUA, DefM[RR.Reg]);
1695080dd10fSScott Constable       }
1696080dd10fSScott Constable     }
1697080dd10fSScott Constable   }
1698080dd10fSScott Constable 
1699080dd10fSScott Constable   // Pop all defs from this block from the definition stacks.
1700080dd10fSScott Constable   releaseBlock(BA.Id, DefM);
1701080dd10fSScott Constable }
1702080dd10fSScott Constable 
1703080dd10fSScott Constable // Remove the use node UA from any data-flow and structural links.
unlinkUseDF(NodeAddr<UseNode * > UA)1704080dd10fSScott Constable void DataFlowGraph::unlinkUseDF(NodeAddr<UseNode*> UA) {
1705080dd10fSScott Constable   NodeId RD = UA.Addr->getReachingDef();
1706080dd10fSScott Constable   NodeId Sib = UA.Addr->getSibling();
1707080dd10fSScott Constable 
1708080dd10fSScott Constable   if (RD == 0) {
1709080dd10fSScott Constable     assert(Sib == 0);
1710080dd10fSScott Constable     return;
1711080dd10fSScott Constable   }
1712080dd10fSScott Constable 
1713080dd10fSScott Constable   auto RDA = addr<DefNode*>(RD);
1714080dd10fSScott Constable   auto TA = addr<UseNode*>(RDA.Addr->getReachedUse());
1715080dd10fSScott Constable   if (TA.Id == UA.Id) {
1716080dd10fSScott Constable     RDA.Addr->setReachedUse(Sib);
1717080dd10fSScott Constable     return;
1718080dd10fSScott Constable   }
1719080dd10fSScott Constable 
1720080dd10fSScott Constable   while (TA.Id != 0) {
1721080dd10fSScott Constable     NodeId S = TA.Addr->getSibling();
1722080dd10fSScott Constable     if (S == UA.Id) {
1723080dd10fSScott Constable       TA.Addr->setSibling(UA.Addr->getSibling());
1724080dd10fSScott Constable       return;
1725080dd10fSScott Constable     }
1726080dd10fSScott Constable     TA = addr<UseNode*>(S);
1727080dd10fSScott Constable   }
1728080dd10fSScott Constable }
1729080dd10fSScott Constable 
1730080dd10fSScott Constable // Remove the def node DA from any data-flow and structural links.
unlinkDefDF(NodeAddr<DefNode * > DA)1731080dd10fSScott Constable void DataFlowGraph::unlinkDefDF(NodeAddr<DefNode*> DA) {
1732080dd10fSScott Constable   //
1733080dd10fSScott Constable   //         RD
1734080dd10fSScott Constable   //         | reached
1735080dd10fSScott Constable   //         | def
1736080dd10fSScott Constable   //         :
1737080dd10fSScott Constable   //         .
1738080dd10fSScott Constable   //        +----+
1739080dd10fSScott Constable   // ... -- | DA | -- ... -- 0  : sibling chain of DA
1740080dd10fSScott Constable   //        +----+
1741080dd10fSScott Constable   //         |  | reached
1742080dd10fSScott Constable   //         |  : def
1743080dd10fSScott Constable   //         |  .
1744080dd10fSScott Constable   //         | ...  : Siblings (defs)
1745080dd10fSScott Constable   //         |
1746080dd10fSScott Constable   //         : reached
1747080dd10fSScott Constable   //         . use
1748080dd10fSScott Constable   //        ... : sibling chain of reached uses
1749080dd10fSScott Constable 
1750080dd10fSScott Constable   NodeId RD = DA.Addr->getReachingDef();
1751080dd10fSScott Constable 
1752080dd10fSScott Constable   // Visit all siblings of the reached def and reset their reaching defs.
1753080dd10fSScott Constable   // Also, defs reached by DA are now "promoted" to being reached by RD,
1754080dd10fSScott Constable   // so all of them will need to be spliced into the sibling chain where
1755080dd10fSScott Constable   // DA belongs.
1756080dd10fSScott Constable   auto getAllNodes = [this] (NodeId N) -> NodeList {
1757080dd10fSScott Constable     NodeList Res;
1758080dd10fSScott Constable     while (N) {
1759080dd10fSScott Constable       auto RA = addr<RefNode*>(N);
1760080dd10fSScott Constable       // Keep the nodes in the exact sibling order.
1761080dd10fSScott Constable       Res.push_back(RA);
1762080dd10fSScott Constable       N = RA.Addr->getSibling();
1763080dd10fSScott Constable     }
1764080dd10fSScott Constable     return Res;
1765080dd10fSScott Constable   };
1766080dd10fSScott Constable   NodeList ReachedDefs = getAllNodes(DA.Addr->getReachedDef());
1767080dd10fSScott Constable   NodeList ReachedUses = getAllNodes(DA.Addr->getReachedUse());
1768080dd10fSScott Constable 
1769080dd10fSScott Constable   if (RD == 0) {
1770080dd10fSScott Constable     for (NodeAddr<RefNode*> I : ReachedDefs)
1771080dd10fSScott Constable       I.Addr->setSibling(0);
1772080dd10fSScott Constable     for (NodeAddr<RefNode*> I : ReachedUses)
1773080dd10fSScott Constable       I.Addr->setSibling(0);
1774080dd10fSScott Constable   }
1775080dd10fSScott Constable   for (NodeAddr<DefNode*> I : ReachedDefs)
1776080dd10fSScott Constable     I.Addr->setReachingDef(RD);
1777080dd10fSScott Constable   for (NodeAddr<UseNode*> I : ReachedUses)
1778080dd10fSScott Constable     I.Addr->setReachingDef(RD);
1779080dd10fSScott Constable 
1780080dd10fSScott Constable   NodeId Sib = DA.Addr->getSibling();
1781080dd10fSScott Constable   if (RD == 0) {
1782080dd10fSScott Constable     assert(Sib == 0);
1783080dd10fSScott Constable     return;
1784080dd10fSScott Constable   }
1785080dd10fSScott Constable 
1786080dd10fSScott Constable   // Update the reaching def node and remove DA from the sibling list.
1787080dd10fSScott Constable   auto RDA = addr<DefNode*>(RD);
1788080dd10fSScott Constable   auto TA = addr<DefNode*>(RDA.Addr->getReachedDef());
1789080dd10fSScott Constable   if (TA.Id == DA.Id) {
1790080dd10fSScott Constable     // If DA is the first reached def, just update the RD's reached def
1791080dd10fSScott Constable     // to the DA's sibling.
1792080dd10fSScott Constable     RDA.Addr->setReachedDef(Sib);
1793080dd10fSScott Constable   } else {
1794080dd10fSScott Constable     // Otherwise, traverse the sibling list of the reached defs and remove
1795080dd10fSScott Constable     // DA from it.
1796080dd10fSScott Constable     while (TA.Id != 0) {
1797080dd10fSScott Constable       NodeId S = TA.Addr->getSibling();
1798080dd10fSScott Constable       if (S == DA.Id) {
1799080dd10fSScott Constable         TA.Addr->setSibling(Sib);
1800080dd10fSScott Constable         break;
1801080dd10fSScott Constable       }
1802080dd10fSScott Constable       TA = addr<DefNode*>(S);
1803080dd10fSScott Constable     }
1804080dd10fSScott Constable   }
1805080dd10fSScott Constable 
1806080dd10fSScott Constable   // Splice the DA's reached defs into the RDA's reached def chain.
1807080dd10fSScott Constable   if (!ReachedDefs.empty()) {
1808080dd10fSScott Constable     auto Last = NodeAddr<DefNode*>(ReachedDefs.back());
1809080dd10fSScott Constable     Last.Addr->setSibling(RDA.Addr->getReachedDef());
1810080dd10fSScott Constable     RDA.Addr->setReachedDef(ReachedDefs.front().Id);
1811080dd10fSScott Constable   }
1812080dd10fSScott Constable   // Splice the DA's reached uses into the RDA's reached use chain.
1813080dd10fSScott Constable   if (!ReachedUses.empty()) {
1814080dd10fSScott Constable     auto Last = NodeAddr<UseNode*>(ReachedUses.back());
1815080dd10fSScott Constable     Last.Addr->setSibling(RDA.Addr->getReachedUse());
1816080dd10fSScott Constable     RDA.Addr->setReachedUse(ReachedUses.front().Id);
1817080dd10fSScott Constable   }
1818080dd10fSScott Constable }
1819