@@ -281,18 +281,48 @@ 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
+ assert (S <= Undo.size ());
291
+ while (S < Undo.size ()) {
292
+ Vals[Undo.back ().first ] = Undo.back ().second ;
293
+ Undo.pop_back ();
294
+ }
295
+ }
296
+
297
+ void resize (size_t Sz) { Vals.resize (Sz); }
298
+
299
+ size_t undoSize () const { return Undo.size (); }
300
+
301
+ const T &operator [](size_t Idx) const { return Vals[Idx]; }
302
+
303
+ void set (size_t Idx, const T &Val) {
304
+ if (Vals[Idx] == Val)
305
+ return ;
306
+ Undo.emplace_back (Idx, Vals[Idx]);
307
+ Vals[Idx] = Val;
308
+ }
309
+
310
+ void init (size_t Idx, const T &Val) {
311
+ assert (Undo.empty ());
312
+ Vals[Idx] = Val;
313
+ }
314
+ };
315
+
284
316
// / Data package used by RenamePass().
285
317
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)) {}
318
+ RenamePassData (BasicBlock *B, BasicBlock *P, size_t V, size_t L)
319
+ : BB(B), Pred(P), UndoVals(V), UndoLocs(L) {}
291
320
292
321
BasicBlock *BB;
293
322
BasicBlock *Pred;
294
- ValVector Values;
295
- LocationVector Locations;
323
+
324
+ size_t UndoVals;
325
+ size_t UndoLocs;
296
326
};
297
327
298
328
// / This assigns and keeps a per-bb relative ordering of load/store
@@ -393,10 +423,10 @@ struct PromoteMem2Reg {
393
423
SmallVector<unsigned > BBNumPreds;
394
424
395
425
// / The state of incoming values for the current DFS step.
396
- RenamePassData::ValVector IncomingVals;
426
+ VectorWithUndo<Value *> IncomingVals;
397
427
398
428
// / The state of incoming locations for the current DFS step.
399
- RenamePassData::LocationVector IncomingLocs;
429
+ VectorWithUndo<DebugLoc> IncomingLocs;
400
430
401
431
// DFS work stack.
402
432
SmallVector<RenamePassData, 8 > Worklist;
@@ -445,17 +475,16 @@ struct PromoteMem2Reg {
445
475
DVRAssignsToDelete.clear ();
446
476
}
447
477
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));
478
+ void pushToWorklist (BasicBlock *BB, BasicBlock *Pred) {
479
+ Worklist.emplace_back (BB, Pred, IncomingVals.undoSize (),
480
+ IncomingLocs.undoSize ());
452
481
}
453
482
454
483
RenamePassData popFromWorklist () {
455
- RenamePassData R = std::move ( Worklist.back () );
484
+ RenamePassData R = Worklist.back ();
456
485
Worklist.pop_back ();
457
- IncomingVals = std::move (R.Values );
458
- IncomingLocs = std::move (R.Locations );
486
+ IncomingVals. undo (R.UndoVals );
487
+ IncomingLocs. undo (R.UndoLocs );
459
488
return R;
460
489
}
461
490
};
@@ -871,22 +900,20 @@ void PromoteMem2Reg::run() {
871
900
// been stored yet. In this case, it will get this null value.
872
901
IncomingVals.resize (Allocas.size ());
873
902
for (unsigned i = 0 , e = Allocas.size (); i != e; ++i)
874
- IncomingVals[i] = UndefValue::get (Allocas[i]->getAllocatedType ());
903
+ IncomingVals. init (i, UndefValue::get (Allocas[i]->getAllocatedType () ));
875
904
876
905
// When handling debug info, treat all incoming values as if they have unknown
877
906
// locations until proven otherwise.
878
907
IncomingLocs.resize (Allocas.size ());
879
908
880
909
// The renamer uses the Visited set to avoid infinite loops.
881
- Visited.resize (F.getMaxBlockNumber ());
910
+ Visited.resize (F.getMaxBlockNumber (), false );
911
+
912
+ // Add the entry block to the worklist, with a null predecessor.
913
+ pushToWorklist (&F.front (), nullptr );
882
914
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
915
do {
888
916
RenamePassData RPD = popFromWorklist ();
889
- // RenamePass may add new worklist entries.
890
917
RenamePass (RPD.BB , RPD.Pred );
891
918
} while (!Worklist.empty ());
892
919
@@ -1153,7 +1180,7 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
1153
1180
APN->setHasNoSignedZeros (true );
1154
1181
1155
1182
// The currently active variable for this block is now the PHI.
1156
- IncomingVals[ AllocaNo] = APN;
1183
+ IncomingVals. set ( AllocaNo, APN) ;
1157
1184
AllocaATInfo[AllocaNo].updateForNewPhi (APN, DIB);
1158
1185
auto ConvertDbgDeclares = [&](auto &Container) {
1159
1186
for (auto *DbgItem : Container)
@@ -1211,10 +1238,10 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
1211
1238
1212
1239
// what value were we writing?
1213
1240
unsigned AllocaNo = ai->second ;
1214
- IncomingVals[ AllocaNo] = SI->getOperand (0 );
1241
+ IncomingVals. set ( AllocaNo, SI->getOperand (0 ) );
1215
1242
1216
1243
// Record debuginfo for the store before removing it.
1217
- IncomingLocs[ AllocaNo] = SI->getDebugLoc ();
1244
+ IncomingLocs. set ( AllocaNo, SI->getDebugLoc () );
1218
1245
AllocaATInfo[AllocaNo].updateForDeletedStore (SI, DIB, &DbgAssignsToDelete,
1219
1246
&DVRAssignsToDelete);
1220
1247
auto ConvertDbgDeclares = [&](auto &Container) {
@@ -1234,14 +1261,8 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
1234
1261
SmallPtrSet<BasicBlock *, 8 > VisitedSuccs;
1235
1262
1236
1263
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
- }
1264
+ if (VisitedSuccs.insert (S).second )
1265
+ pushToWorklist (S, BB);
1245
1266
}
1246
1267
1247
1268
void llvm::PromoteMemToReg (ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
0 commit comments