@@ -281,18 +281,44 @@ struct AllocaInfo {
281
281
}
282
282
};
283
283
284
+ template <typename T> class VectorWithUndo {
285
+ SmallVector<T, 8 > Vals;
286
+ SmallVector<std::pair<size_t , T>, 8 > Undo;
287
+
288
+ public:
289
+ void undo (size_t S) {
290
+ while (S < Undo.size ()) {
291
+ Vals[Undo.back ().first ] = Undo.back ().second ;
292
+ Undo.pop_back ();
293
+ }
294
+ }
295
+
296
+ void assign (size_t Sz, const T &Val) { Vals.assign (Sz, Val); }
297
+
298
+ size_t size () const { return Undo.size (); }
299
+
300
+ const T &operator [](size_t Idx) const { return Vals[Idx]; }
301
+
302
+ void set (size_t Idx, const T &Val) {
303
+ if (Vals[Idx] == Val)
304
+ return ;
305
+ Undo.emplace_back (Idx, Vals[Idx]);
306
+ Vals[Idx] = Val;
307
+ }
308
+
309
+ void init (size_t Idx, const T &Val) { Vals[Idx] = Val; }
310
+ };
311
+
284
312
// / Data package used by RenamePass().
285
313
struct RenamePassData {
286
- using ValVector = std::vector<Value *>;
287
- using LocationVector = std::vector<DebugLoc>;
288
-
289
- RenamePassData (BasicBlock *B, BasicBlock *P, ValVector V, LocationVector L)
290
- : BB(B), Pred(P), Values(std::move(V)), Locations(std::move(L)) {}
314
+ RenamePassData (BasicBlock *B, BasicBlock *P, size_t V, size_t L)
315
+ : BB(B), Pred(P), UndoVals(V), UndoLocs(L) {}
291
316
292
317
BasicBlock *BB;
293
318
BasicBlock *Pred;
294
- ValVector Values;
295
- LocationVector Locations;
319
+
320
+ size_t UndoVals;
321
+ size_t UndoLocs;
296
322
};
297
323
298
324
// / This assigns and keeps a per-bb relative ordering of load/store
@@ -393,10 +419,10 @@ struct PromoteMem2Reg {
393
419
SmallVector<unsigned > BBNumPreds;
394
420
395
421
// / The state of incoming values for the current DFS step.
396
- RenamePassData::ValVector IncomingVals;
422
+ VectorWithUndo<Value *> IncomingVals;
397
423
398
424
// / The state of incoming locations for the current DFS step.
399
- RenamePassData::LocationVector IncomingLocs;
425
+ VectorWithUndo<DebugLoc> IncomingLocs;
400
426
401
427
// DFS work stack.
402
428
SmallVector<RenamePassData, 8 > Worklist;
@@ -445,17 +471,15 @@ struct PromoteMem2Reg {
445
471
DVRAssignsToDelete.clear ();
446
472
}
447
473
448
- void pushToWorklist (BasicBlock *BB, BasicBlock *Pred,
449
- RenamePassData::ValVector IncVals,
450
- RenamePassData::LocationVector IncLocs) {
451
- Worklist.emplace_back (BB, Pred, std::move (IncVals), std::move (IncLocs));
474
+ void pushToWorklist (BasicBlock *BB, BasicBlock *Pred) {
475
+ Worklist.emplace_back (BB, Pred, IncomingVals.size (), IncomingVals.size ());
452
476
}
453
477
454
478
RenamePassData popFromWorklist () {
455
- RenamePassData R = std::move ( Worklist.back () );
479
+ RenamePassData R = Worklist.back ();
456
480
Worklist.pop_back ();
457
- IncomingVals = std::move (R.Values );
458
- IncomingLocs = std::move (R.Locations );
481
+ IncomingVals. undo (R.UndoVals );
482
+ IncomingLocs. undo (R.UndoLocs );
459
483
return R;
460
484
}
461
485
};
@@ -871,22 +895,20 @@ void PromoteMem2Reg::run() {
871
895
// been stored yet. In this case, it will get this null value.
872
896
IncomingVals.assign (Allocas.size (), nullptr );
873
897
for (unsigned i = 0 , e = Allocas.size (); i != e; ++i)
874
- IncomingVals[i] = UndefValue::get (Allocas[i]->getAllocatedType ());
898
+ IncomingVals. init (i, UndefValue::get (Allocas[i]->getAllocatedType () ));
875
899
876
900
// When handling debug info, treat all incoming values as if they have unknown
877
901
// locations until proven otherwise.
878
902
IncomingLocs.assign (Allocas.size (), {});
879
903
880
904
// The renamer uses the Visited set to avoid infinite loops.
881
- Visited.resize (F.getMaxBlockNumber ());
905
+ Visited.resize (F.getMaxBlockNumber (), false );
906
+
907
+ // Add the entry block to the worklist, with a null predecessor.
908
+ pushToWorklist (&F.front (), nullptr );
882
909
883
- // Walks all basic blocks in the function performing the SSA rename algorithm
884
- // and inserting the phi nodes we marked as necessary
885
- pushToWorklist (&F.front (), nullptr , std::move (IncomingVals),
886
- std::move (IncomingLocs));
887
910
do {
888
911
RenamePassData RPD = popFromWorklist ();
889
- // RenamePass may add new worklist entries.
890
912
RenamePass (RPD.BB , RPD.Pred );
891
913
} while (!Worklist.empty ());
892
914
@@ -1153,7 +1175,7 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
1153
1175
APN->setHasNoSignedZeros (true );
1154
1176
1155
1177
// The currently active variable for this block is now the PHI.
1156
- IncomingVals[ AllocaNo] = APN;
1178
+ IncomingVals. set ( AllocaNo, APN) ;
1157
1179
AllocaATInfo[AllocaNo].updateForNewPhi (APN, DIB);
1158
1180
auto ConvertDbgDeclares = [&](auto &Container) {
1159
1181
for (auto *DbgItem : Container)
@@ -1211,10 +1233,10 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
1211
1233
1212
1234
// what value were we writing?
1213
1235
unsigned AllocaNo = ai->second ;
1214
- IncomingVals[ AllocaNo] = SI->getOperand (0 );
1236
+ IncomingVals. set ( AllocaNo, SI->getOperand (0 ) );
1215
1237
1216
1238
// Record debuginfo for the store before removing it.
1217
- IncomingLocs[ AllocaNo] = SI->getDebugLoc ();
1239
+ IncomingLocs. set ( AllocaNo, SI->getDebugLoc () );
1218
1240
AllocaATInfo[AllocaNo].updateForDeletedStore (SI, DIB, &DbgAssignsToDelete,
1219
1241
&DVRAssignsToDelete);
1220
1242
auto ConvertDbgDeclares = [&](auto &Container) {
@@ -1234,14 +1256,8 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
1234
1256
SmallPtrSet<BasicBlock *, 8 > VisitedSuccs;
1235
1257
1236
1258
for (BasicBlock *S : reverse (successors (BB)))
1237
- if (VisitedSuccs.insert (S).second ) {
1238
- if (VisitedSuccs.size () > 1 ) {
1239
- // Let the first successor own allocated arrays, other will make a copy.
1240
- IncomingVals = Worklist.back ().Values ;
1241
- IncomingLocs = Worklist.back ().Locations ;
1242
- }
1243
- pushToWorklist (S, BB, std::move (IncomingVals), std::move (IncomingLocs));
1244
- }
1259
+ if (VisitedSuccs.insert (S).second )
1260
+ pushToWorklist (S, BB);
1245
1261
}
1246
1262
1247
1263
void llvm::PromoteMemToReg (ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
0 commit comments