Skip to content

Commit 30a57fc

Browse files
authored
Merge pull request #35805 from meg-gupta/fixmem2reg
Fix Mem2Reg for store [assign]
2 parents 182a011 + aed2dcb commit 30a57fc

File tree

2 files changed

+103
-44
lines changed

2 files changed

+103
-44
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -495,46 +495,30 @@ StackAllocationPromoter::promoteAllocationInBlock(SILBasicBlock *BB) {
495495
if (SI->getDest() != ASI)
496496
continue;
497497

498-
// Special handling of entry block
499-
// If we have a store [assign] in the first block, OSSA guarantees we can
500-
// find the previous value stored in the stack location in RunningVal.
501-
// Create destroy_value of the RunningVal.
502-
// For all other blocks we may not know the previous value stored in the
503-
// stack location. So we will create destroy_value in
504-
// StackAllocationPromoter::fixBranchesAndUses, by getting the live-in
505-
// value to the block.
506-
if (BB->isEntry()) {
507-
if (SI->getOwnershipQualifier() == StoreOwnershipQualifier::Assign) {
508-
assert(RunningVal);
498+
// If we see a store [assign], always convert it to a store [init]. This
499+
// simplifies further processing.
500+
if (SI->getOwnershipQualifier() == StoreOwnershipQualifier::Assign) {
501+
if (RunningVal) {
509502
SILBuilderWithScope(SI).createDestroyValue(SI->getLoc(), RunningVal);
503+
} else {
504+
SILBuilderWithScope localBuilder(SI);
505+
auto *newLoad = localBuilder.createLoad(SI->getLoc(), ASI,
506+
LoadOwnershipQualifier::Take);
507+
localBuilder.createDestroyValue(SI->getLoc(), newLoad);
510508
}
509+
SI->setOwnershipQualifier(StoreOwnershipQualifier::Init);
511510
}
512511

513512
// If we met a store before this one, delete it.
514-
// If the LastStore was a store with [assign], delete it only if we know
515-
// the RunningValue to destroy. If not, it will be deleted in
516-
// StackAllocationPromoter::fixBranchesAndUses.
517513
if (LastStore) {
518-
if (LastStore->getOwnershipQualifier() ==
519-
StoreOwnershipQualifier::Assign) {
520-
if (RunningVal) {
521-
// For entry block, we would have already created the destroy_value,
522-
// skip it.
523-
if (!BB->isEntry()) {
524-
SILBuilderWithScope(LastStore).createDestroyValue(
525-
LastStore->getLoc(), RunningVal);
526-
}
527-
LLVM_DEBUG(llvm::dbgs()
528-
<< "*** Removing redundant store: " << *LastStore);
529-
++NumInstRemoved;
530-
LastStore->eraseFromParent();
531-
}
532-
} else {
533-
LLVM_DEBUG(llvm::dbgs()
534-
<< "*** Removing redundant store: " << *LastStore);
535-
++NumInstRemoved;
536-
LastStore->eraseFromParent();
537-
}
514+
assert(LastStore->getOwnershipQualifier() !=
515+
StoreOwnershipQualifier::Assign &&
516+
"store [assign] to the stack location should have been "
517+
"transformed to a store [init]");
518+
LLVM_DEBUG(llvm::dbgs()
519+
<< "*** Removing redundant store: " << *LastStore);
520+
++NumInstRemoved;
521+
LastStore->eraseFromParent();
538522
}
539523

540524
// The stored value is the new running value.
@@ -578,7 +562,12 @@ StackAllocationPromoter::promoteAllocationInBlock(SILBasicBlock *BB) {
578562
break;
579563
}
580564
}
565+
581566
if (LastStore) {
567+
assert(LastStore->getOwnershipQualifier() !=
568+
StoreOwnershipQualifier::Assign &&
569+
"store [assign] to the stack location should have been "
570+
"transformed to a store [init]");
582571
LLVM_DEBUG(llvm::dbgs() << "*** Finished promotion. Last store: "
583572
<< *LastStore);
584573
} else {
@@ -756,6 +745,7 @@ void StackAllocationPromoter::fixPhiPredBlock(BlockSet &PhiBlocks,
756745
void StackAllocationPromoter::fixBranchesAndUses(BlockSet &PhiBlocks) {
757746
// First update uses of the value.
758747
SmallVector<LoadInst *, 4> collectedLoads;
748+
759749
for (auto UI = ASI->use_begin(), E = ASI->use_end(); UI != E;) {
760750
auto *Inst = UI->getUser();
761751
++UI;
@@ -789,16 +779,6 @@ void StackAllocationPromoter::fixBranchesAndUses(BlockSet &PhiBlocks) {
789779
// on.
790780
SILBasicBlock *BB = Inst->getParent();
791781

792-
if (!BB->isEntry()) {
793-
if (auto *SI = dyn_cast<StoreInst>(Inst)) {
794-
if (SI->getOwnershipQualifier() == StoreOwnershipQualifier::Assign) {
795-
SILValue Def = getLiveInValue(PhiBlocks, BB);
796-
SILBuilderWithScope(SI).createDestroyValue(SI->getLoc(), Def);
797-
continue;
798-
}
799-
}
800-
}
801-
802782
if (auto *DVAI = dyn_cast<DebugValueAddrInst>(Inst)) {
803783
// Replace DebugValueAddr with DebugValue.
804784
SILValue Def = getLiveInValue(PhiBlocks, BB);

test/SILOptimizer/mem2reg_ossa_nontrivial.sil

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,84 @@ bb3:
188188
return %ret : $()
189189
}
190190

191+
// CHECK-LABEL: sil [ossa] @multiple_store_vals6 :
192+
// CHECK-NOT: alloc_stack
193+
// CHECK-LABEL: } // end sil function 'multiple_store_vals6'
194+
sil [ossa] @multiple_store_vals6 : $@convention(thin) (@owned Klass, @owned Klass) -> () {
195+
bb0(%0 : @owned $Klass, %1 : @owned $Klass):
196+
br bb1
197+
198+
bb1:
199+
%2 = alloc_stack $Klass
200+
store %0 to [init] %2 : $*Klass
201+
%3 = integer_literal $Builtin.Int1, 0
202+
cond_fail %3 : $Builtin.Int1
203+
store %1 to [assign] %2 : $*Klass
204+
br bb2
205+
206+
bb2:
207+
%4 = function_ref @blackhole_spl : $@convention(thin) (@guaranteed Klass) -> ()
208+
%5 = load [take] %2 : $*Klass
209+
%6 = apply %4(%5) : $@convention(thin) (@guaranteed Klass) -> ()
210+
destroy_value %5 : $Klass
211+
dealloc_stack %2 : $*Klass
212+
%7 = tuple ()
213+
return %7 : $()
214+
}
215+
216+
// CHECK-LABEL: sil [ossa] @multiple_store_vals7 :
217+
// CHECK-NOT: alloc_stack
218+
// CHECK-LABEL: } // end sil function 'multiple_store_vals7'
219+
sil [ossa] @multiple_store_vals7 : $@convention(thin) (@owned Klass, @owned Klass, @owned Klass) -> () {
220+
bb0(%0 : @owned $Klass, %1 : @owned $Klass, %2 : @owned $Klass):
221+
%stk = alloc_stack $Klass
222+
store %0 to [init] %stk : $*Klass
223+
%3 = integer_literal $Builtin.Int1, 0
224+
cond_fail %3 : $Builtin.Int1
225+
br bb1
226+
227+
bb1:
228+
store %1 to [assign] %stk : $*Klass
229+
store %2 to [assign] %stk : $*Klass
230+
br bb2
231+
232+
bb2:
233+
%4 = function_ref @blackhole_spl : $@convention(thin) (@guaranteed Klass) -> ()
234+
%5 = load [take] %stk : $*Klass
235+
%6 = apply %4(%5) : $@convention(thin) (@guaranteed Klass) -> ()
236+
destroy_value %5 : $Klass
237+
dealloc_stack %stk : $*Klass
238+
%7 = tuple ()
239+
return %7 : $()
240+
}
241+
242+
// CHECK-LABEL: sil [ossa] @multiple_store_vals8 :
243+
// CHECK-NOT: alloc_stack
244+
// CHECK-LABEL: } // end sil function 'multiple_store_vals8'
245+
sil [ossa] @multiple_store_vals8 : $@convention(thin) (@owned Klass, @owned Klass, @owned Klass) -> () {
246+
bb0(%0 : @owned $Klass, %1 : @owned $Klass, %2 : @owned $Klass):
247+
%stk = alloc_stack $Klass
248+
store %0 to [init] %stk : $*Klass
249+
%3 = integer_literal $Builtin.Int1, 0
250+
cond_fail %3 : $Builtin.Int1
251+
br bb1
252+
253+
bb1:
254+
store %1 to [assign] %stk : $*Klass
255+
destroy_addr %stk : $*Klass
256+
store %2 to [init] %stk : $*Klass
257+
br bb2
258+
259+
bb2:
260+
%4 = function_ref @blackhole_spl : $@convention(thin) (@guaranteed Klass) -> ()
261+
%5 = load [take] %stk : $*Klass
262+
%6 = apply %4(%5) : $@convention(thin) (@guaranteed Klass) -> ()
263+
destroy_value %5 : $Klass
264+
dealloc_stack %stk : $*Klass
265+
%7 = tuple ()
266+
return %7 : $()
267+
}
268+
191269
// CHECK-LABEL: sil [ossa] @with_loads :
192270
// CHECK-NOT: alloc_stack
193271
// CHECK-LABEL: } // end sil function 'with_loads'
@@ -676,3 +754,4 @@ bbret(%new : @owned $Klass):
676754
dealloc_stack %stk1 : $*Klass
677755
return %new : $Klass
678756
}
757+

0 commit comments

Comments
 (0)