23
23
// <10.1145/2086696.2086706>. <hal-00647369>
24
24
//
25
25
#include " llvm/ADT/BitVector.h"
26
+ #include " llvm/ADT/DenseMap.h"
26
27
#include " llvm/ADT/STLExtras.h"
27
28
#include " llvm/ADT/SetVector.h"
29
+ #include " llvm/ADT/SmallSet.h"
28
30
#include " llvm/CodeGen/MachineBasicBlock.h"
29
31
#include " llvm/CodeGen/MachineDominanceFrontier.h"
30
32
#include " llvm/CodeGen/MachineDominators.h"
@@ -108,7 +110,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
108
110
const RegisterAggr &DefRRs) {
109
111
NodeList RDefs; // Return value.
110
112
SetVector<NodeId> DefQ;
111
- SetVector<NodeId> Owners ;
113
+ DenseMap<MachineInstr*, uint32_t > OrdMap ;
112
114
113
115
// Dead defs will be treated as if they were live, since they are actually
114
116
// on the data-flow path. They cannot be ignored because even though they
@@ -151,18 +153,9 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
151
153
for (auto S : DFG.getRelatedRefs (TA.Addr ->getOwner (DFG), TA))
152
154
if (NodeId RD = NodeAddr<RefNode*>(S).Addr ->getReachingDef ())
153
155
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.
166
159
}
167
160
168
161
// Return the MachineBasicBlock containing a given instruction.
@@ -174,38 +167,81 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
174
167
NodeAddr<BlockNode*> BA = PA.Addr ->getOwner (DFG);
175
168
return BA.Addr ->getCode ();
176
169
};
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) {
179
189
if (A == B)
180
190
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);
186
193
bool StmtA = OA.Addr ->getKind () == NodeAttrs::Stmt;
187
194
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.
203
214
return A < B;
204
215
}
216
+ // Only one of them is a phi. Phis always precede statements.
217
+ return !StmtA;
205
218
};
206
219
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
+ }
209
245
210
246
// The vector is a list of instructions, so that defs coming from
211
247
// the same instruction don't need to be artificially ordered.
@@ -220,14 +256,18 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
220
256
// *d3<C> If A \incl BuC, and B \incl AuC, then *d2 would be
221
257
// covered if we added A first, and A would be covered
222
258
// 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.
223
262
224
263
RegisterAggr RRs (DefRRs);
225
264
226
265
auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool {
227
266
return TA.Addr ->getKind () == NodeAttrs::Def &&
228
267
Defs.count (TA.Id );
229
268
};
230
- for (NodeId T : Tmp) {
269
+
270
+ for (NodeId T : TmpInst) {
231
271
if (!FullChain && RRs.hasCoverOf (RefRR))
232
272
break ;
233
273
auto TA = DFG.addr <InstrNode*>(T);
0 commit comments