2323// <10.1145/2086696.2086706>. <hal-00647369>
2424//
2525#include " llvm/ADT/BitVector.h"
26+ #include " llvm/ADT/DenseMap.h"
2627#include " llvm/ADT/STLExtras.h"
2728#include " llvm/ADT/SetVector.h"
29+ #include " llvm/ADT/SmallSet.h"
2830#include " llvm/CodeGen/MachineBasicBlock.h"
2931#include " llvm/CodeGen/MachineDominanceFrontier.h"
3032#include " llvm/CodeGen/MachineDominators.h"
@@ -108,7 +110,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
108110 const RegisterAggr &DefRRs) {
109111 NodeList RDefs; // Return value.
110112 SetVector<NodeId> DefQ;
111- SetVector<NodeId> Owners ;
113+ DenseMap<MachineInstr*, uint32_t > OrdMap ;
112114
113115 // Dead defs will be treated as if they were live, since they are actually
114116 // on the data-flow path. They cannot be ignored because even though they
@@ -151,18 +153,9 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
151153 for (auto S : DFG.getRelatedRefs (TA.Addr ->getOwner (DFG), TA))
152154 if (NodeId RD = NodeAddr<RefNode*>(S).Addr ->getReachingDef ())
153155 DefQ.insert (RD);
154- }
155-
156- // Remove all non-phi defs that are not aliased to RefRR, and collect
157- // the owners of the remaining defs.
158- SetVector<NodeId> Defs;
159- for (NodeId N : DefQ) {
160- auto TA = DFG.addr <DefNode*>(N);
161- bool IsPhi = TA.Addr ->getFlags () & NodeAttrs::PhiRef;
162- if (!IsPhi && !PRI.alias (RefRR, TA.Addr ->getRegRef (DFG)))
163- continue ;
164- Defs.insert (TA.Id );
165- Owners.insert (TA.Addr ->getOwner (DFG).Id );
156+ // Don't visit sibling defs. They share the same reaching def (which
157+ // will be visited anyway), but they define something not aliased to
158+ // this ref.
166159 }
167160
168161 // Return the MachineBasicBlock containing a given instruction.
@@ -174,38 +167,81 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
174167 NodeAddr<BlockNode*> BA = PA.Addr ->getOwner (DFG);
175168 return BA.Addr ->getCode ();
176169 };
177- // Less(A,B) iff instruction A is further down in the dominator tree than B.
178- auto Less = [&Block,this ] (NodeId A, NodeId B) -> bool {
170+
171+ SmallSet<NodeId,32 > Defs;
172+
173+ // Remove all non-phi defs that are not aliased to RefRR, and segregate
174+ // the the remaining defs into buckets for containing blocks.
175+ std::map<NodeId, NodeAddr<InstrNode*>> Owners;
176+ std::map<MachineBasicBlock*, SmallVector<NodeId,32 >> Blocks;
177+ for (NodeId N : DefQ) {
178+ auto TA = DFG.addr <DefNode*>(N);
179+ bool IsPhi = TA.Addr ->getFlags () & NodeAttrs::PhiRef;
180+ if (!IsPhi && !PRI.alias (RefRR, TA.Addr ->getRegRef (DFG)))
181+ continue ;
182+ Defs.insert (TA.Id );
183+ NodeAddr<InstrNode*> IA = TA.Addr ->getOwner (DFG);
184+ Owners[TA.Id ] = IA;
185+ Blocks[Block (IA)].push_back (IA.Id );
186+ }
187+
188+ auto Precedes = [this ,&OrdMap] (NodeId A, NodeId B) {
179189 if (A == B)
180190 return false ;
181- auto OA = DFG.addr <InstrNode*>(A), OB = DFG.addr <InstrNode*>(B);
182- MachineBasicBlock *BA = Block (OA), *BB = Block (OB);
183- if (BA != BB)
184- return MDT.dominates (BB, BA);
185- // They are in the same block.
191+ NodeAddr<InstrNode*> OA = DFG.addr <InstrNode*>(A);
192+ NodeAddr<InstrNode*> OB = DFG.addr <InstrNode*>(B);
186193 bool StmtA = OA.Addr ->getKind () == NodeAttrs::Stmt;
187194 bool StmtB = OB.Addr ->getKind () == NodeAttrs::Stmt;
188- if (StmtA) {
189- if (!StmtB) // OB is a phi and phis dominate statements.
190- return true ;
191- MachineInstr *CA = NodeAddr<StmtNode*>(OA).Addr ->getCode ();
192- MachineInstr *CB = NodeAddr<StmtNode*>(OB).Addr ->getCode ();
193- // The order must be linear, so tie-break such equalities.
194- if (CA == CB)
195- return A < B;
196- return MDT.dominates (CB, CA);
197- } else {
198- // OA is a phi.
199- if (StmtB)
200- return false ;
201- // Both are phis. There is no ordering between phis (in terms of
202- // the data-flow), so tie-break this via node id comparison.
195+ if (StmtA && StmtB) {
196+ const MachineInstr *InA = NodeAddr<StmtNode*>(OA).Addr ->getCode ();
197+ const MachineInstr *InB = NodeAddr<StmtNode*>(OB).Addr ->getCode ();
198+ assert (InA->getParent () == InB->getParent ());
199+ auto FA = OrdMap.find (InA);
200+ if (FA != OrdMap.end ())
201+ return FA->second < OrdMap.find (InB)->second ;
202+ const MachineBasicBlock *BB = InA->getParent ();
203+ for (auto It = BB->begin (), E = BB->end (); It != E; ++It) {
204+ if (It == InA->getIterator ())
205+ return true ;
206+ if (It == InB->getIterator ())
207+ return false ;
208+ }
209+ llvm_unreachable (" InA and InB should be in the same block" );
210+ }
211+ // One of them is a phi node.
212+ if (!StmtA && !StmtB) {
213+ // Both are phis, which are unordered. Break the tie by id numbers.
203214 return A < B;
204215 }
216+ // Only one of them is a phi. Phis always precede statements.
217+ return !StmtA;
205218 };
206219
207- std::vector<NodeId> Tmp (Owners.begin (), Owners.end ());
208- llvm::sort (Tmp, Less);
220+ auto GetOrder = [&OrdMap] (MachineBasicBlock &B) {
221+ uint32_t Pos = 0 ;
222+ for (MachineInstr &In : B)
223+ OrdMap.insert ({&In, ++Pos});
224+ };
225+
226+ // For each block, sort the nodes in it.
227+ std::vector<MachineBasicBlock*> TmpBB;
228+ for (auto &Bucket : Blocks) {
229+ TmpBB.push_back (Bucket.first );
230+ if (Bucket.second .size () > 2 )
231+ GetOrder (*Bucket.first );
232+ std::sort (Bucket.second .begin (), Bucket.second .end (), Precedes);
233+ }
234+
235+ // Sort the blocks with respect to dominance.
236+ std::sort (TmpBB.begin (), TmpBB.end (), [this ](auto A, auto B) {
237+ return MDT.dominates (A, B);
238+ });
239+
240+ std::vector<NodeId> TmpInst;
241+ for (auto I = TmpBB.rbegin (), E = TmpBB.rend (); I != E; ++I) {
242+ auto &Bucket = Blocks[*I];
243+ TmpInst.insert (TmpInst.end (), Bucket.rbegin (), Bucket.rend ());
244+ }
209245
210246 // The vector is a list of instructions, so that defs coming from
211247 // the same instruction don't need to be artificially ordered.
@@ -220,14 +256,18 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
220256 // *d3<C> If A \incl BuC, and B \incl AuC, then *d2 would be
221257 // covered if we added A first, and A would be covered
222258 // if we added B first.
259+ // In this example we want both A and B, because we don't want to give
260+ // either one priority over the other, since they belong to the same
261+ // statement.
223262
224263 RegisterAggr RRs (DefRRs);
225264
226265 auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool {
227266 return TA.Addr ->getKind () == NodeAttrs::Def &&
228267 Defs.count (TA.Id );
229268 };
230- for (NodeId T : Tmp) {
269+
270+ for (NodeId T : TmpInst) {
231271 if (!FullChain && RRs.hasCoverOf (RefRR))
232272 break ;
233273 auto TA = DFG.addr <InstrNode*>(T);
0 commit comments