@@ -5498,45 +5498,14 @@ bool SROA::propagateStoredValuesToLoads(AllocaInst &AI, AllocaSlices &AS) {
5498
5498
// that do not overlap with any before them. The slices are sorted by
5499
5499
// increasing beginOffset. We don't use AS.partitions(), as it will use a more
5500
5500
// sophisticated algorithm that takes splittable slices into account.
5501
- auto PartitionBegin = AS.begin ();
5502
- auto PartitionEnd = PartitionBegin;
5503
- uint64_t BeginOffset = PartitionBegin->beginOffset ();
5504
- uint64_t EndOffset = PartitionBegin->endOffset ();
5505
- while (PartitionBegin != AS.end ()) {
5506
- bool AllSameAndValid = true ;
5507
- SmallVector<Instruction *> Insts;
5508
- Type *PartitionType = nullptr ;
5509
- while (PartitionEnd != AS.end () &&
5510
- (PartitionEnd->beginOffset () < EndOffset ||
5511
- PartitionEnd->endOffset () <= EndOffset)) {
5512
- if (AllSameAndValid) {
5513
- AllSameAndValid &= PartitionEnd->beginOffset () == BeginOffset &&
5514
- PartitionEnd->endOffset () == EndOffset;
5515
- Instruction *User =
5516
- cast<Instruction>(PartitionEnd->getUse ()->getUser ());
5517
- if (auto *LI = dyn_cast<LoadInst>(User)) {
5518
- Type *UserTy = LI->getType ();
5519
- // LoadAndStorePromoter requires all the types to be the same.
5520
- if (!LI->isSimple () || (PartitionType && UserTy != PartitionType))
5521
- AllSameAndValid = false ;
5522
- PartitionType = UserTy;
5523
- Insts.push_back (User);
5524
- } else if (auto *SI = dyn_cast<StoreInst>(User)) {
5525
- Type *UserTy = SI->getValueOperand ()->getType ();
5526
- if (!SI->isSimple () || (PartitionType && UserTy != PartitionType))
5527
- AllSameAndValid = false ;
5528
- PartitionType = UserTy;
5529
- Insts.push_back (User);
5530
- } else if (!isAssumeLikeIntrinsic (User)) {
5531
- AllSameAndValid = false ;
5532
- }
5533
- }
5534
- EndOffset = std::max (EndOffset, PartitionEnd->endOffset ());
5535
- ++PartitionEnd;
5536
- }
5501
+ LLVM_DEBUG (dbgs () << " Attempting to propagate values on " << AI << " \n " );
5502
+ bool AllSameAndValid = true ;
5503
+ Type *PartitionType = nullptr ;
5504
+ SmallVector<Instruction *> Insts;
5505
+ uint64_t BeginOffset = 0 ;
5506
+ uint64_t EndOffset = 0 ;
5537
5507
5538
- // So long as all the slices start and end offsets matched, update loads to
5539
- // the values stored in the partition.
5508
+ auto Flush = [&]() {
5540
5509
if (AllSameAndValid && !Insts.empty ()) {
5541
5510
LLVM_DEBUG (dbgs () << " Propagate values on slice [" << BeginOffset << " , "
5542
5511
<< EndOffset << " )\n " );
@@ -5546,14 +5515,56 @@ bool SROA::propagateStoredValuesToLoads(AllocaInst &AI, AllocaSlices &AS) {
5546
5515
BasicLoadAndStorePromoter Promoter (Insts, SSA, PartitionType);
5547
5516
Promoter.run (Insts);
5548
5517
}
5518
+ AllSameAndValid = true ;
5519
+ PartitionType = nullptr ;
5520
+ Insts.clear ();
5521
+ };
5549
5522
5550
- // Step on to the next partition.
5551
- PartitionBegin = PartitionEnd;
5552
- if (PartitionBegin == AS.end ())
5553
- break ;
5554
- BeginOffset = PartitionBegin->beginOffset ();
5555
- EndOffset = PartitionBegin->endOffset ();
5523
+ for (Slice &S : AS) {
5524
+ auto *User = cast<Instruction>(S.getUse ()->getUser ());
5525
+ if (isAssumeLikeIntrinsic (User)) {
5526
+ LLVM_DEBUG ({
5527
+ dbgs () << " Ignoring slice: " ;
5528
+ AS.print (dbgs (), &S);
5529
+ });
5530
+ continue ;
5531
+ }
5532
+ if (S.beginOffset () >= EndOffset) {
5533
+ Flush ();
5534
+ BeginOffset = S.beginOffset ();
5535
+ EndOffset = S.endOffset ();
5536
+ } else if (S.beginOffset () != BeginOffset || S.endOffset () != EndOffset) {
5537
+ if (AllSameAndValid) {
5538
+ LLVM_DEBUG ({
5539
+ dbgs () << " Slice does not match range [" << BeginOffset << " , "
5540
+ << EndOffset << " )" ;
5541
+ AS.print (dbgs (), &S);
5542
+ });
5543
+ AllSameAndValid = false ;
5544
+ }
5545
+ EndOffset = std::max (EndOffset, S.endOffset ());
5546
+ continue ;
5547
+ }
5548
+
5549
+ if (auto *LI = dyn_cast<LoadInst>(User)) {
5550
+ Type *UserTy = LI->getType ();
5551
+ // LoadAndStorePromoter requires all the types to be the same.
5552
+ if (!LI->isSimple () || (PartitionType && UserTy != PartitionType))
5553
+ AllSameAndValid = false ;
5554
+ PartitionType = UserTy;
5555
+ Insts.push_back (User);
5556
+ } else if (auto *SI = dyn_cast<StoreInst>(User)) {
5557
+ Type *UserTy = SI->getValueOperand ()->getType ();
5558
+ if (!SI->isSimple () || (PartitionType && UserTy != PartitionType))
5559
+ AllSameAndValid = false ;
5560
+ PartitionType = UserTy;
5561
+ Insts.push_back (User);
5562
+ } else {
5563
+ AllSameAndValid = false ;
5564
+ }
5556
5565
}
5566
+
5567
+ Flush ();
5557
5568
return true ;
5558
5569
}
5559
5570
0 commit comments