Skip to content

Commit 7c403ed

Browse files
committed
[temp-rvalueopt] Teach how to promote fix_lifetime.
In the case of copy_addr, we move it onto the source address and in the case of a store, put it on the source object. I just noted this pattern happening a bunch in the stdlib when I was looking through it for ownership patterns.
1 parent 57f54dd commit 7c403ed

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,11 @@ bool TempRValueOptPass::collectLoads(
272272
return false;
273273
loadInsts.insert(user);
274274
return true;
275-
275+
case SILInstructionKind::FixLifetimeInst:
276+
// If we have a fixed lifetime on our alloc_stack, we can just treat it like
277+
// a load and re-write it so that it is on the old memory or old src object.
278+
loadInsts.insert(user);
279+
return true;
276280
case SILInstructionKind::CopyAddrInst: {
277281
// copy_addr which read from the temporary are like loads.
278282
auto *copyFromTmp = cast<CopyAddrInst>(user);
@@ -639,6 +643,13 @@ TempRValueOptPass::tryOptimizeStoreIntoTemp(StoreInst *si) {
639643
toDelete.push_back(li);
640644
break;
641645
}
646+
case SILInstructionKind::FixLifetimeInst: {
647+
auto *fli = cast<FixLifetimeInst>(user);
648+
SILBuilderWithScope builder(fli);
649+
builder.createFixLifetime(fli->getLoc(), si->getSrc());
650+
toDelete.push_back(fli);
651+
break;
652+
}
642653

643654
// ASSUMPTION: no operations that may be handled by this default clause can
644655
// destroy tempObj. This includes operations that load the value from memory

test/SILOptimizer/temp_rvalue_opt.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,19 @@ bb0(%0 : $*Builtin.NativeObject):
655655
%v = tuple ()
656656
return %v : $()
657657
}
658+
659+
// CHECK-LABEL: sil @eliminate_fix_lifetime_on_dest_copyaddr : $@convention(thin) (@inout Klass) -> () {
660+
// CHECK-NOT: alloc_stack
661+
// CHECK: fix_lifetime %0
662+
// CHECK-NOT: alloc_stack
663+
// CHECK: } // end sil function 'eliminate_fix_lifetime_on_dest_copyaddr'
664+
sil @eliminate_fix_lifetime_on_dest_copyaddr : $@convention(thin) (@inout Klass) -> () {
665+
bb0(%0 : $*Klass):
666+
%3 = alloc_stack $Klass
667+
copy_addr %0 to [initialization] %3 : $*Klass
668+
fix_lifetime %3 : $*Klass
669+
destroy_addr %3 : $*Klass
670+
dealloc_stack %3 : $*Klass
671+
%9999 = tuple()
672+
return %9999 : $()
673+
}

test/SILOptimizer/temp_rvalue_opt_ossa.sil

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,3 +1124,38 @@ bb0(%0 : $*Optional<GS<Klass>>, %1 : @owned $Optional<GS<Klass>>):
11241124
%9999 = tuple()
11251125
return %9999 : $()
11261126
}
1127+
1128+
// CHECK-LABEL: sil [ossa] @eliminate_fix_lifetime_on_dest_copyaddr : $@convention(thin) (@inout Klass) -> () {
1129+
// CHECK-NOT: alloc_stack
1130+
// CHECK: fix_lifetime %0
1131+
// CHECK-NOT: alloc_stack
1132+
// CHECK: } // end sil function 'eliminate_fix_lifetime_on_dest_copyaddr'
1133+
sil [ossa] @eliminate_fix_lifetime_on_dest_copyaddr : $@convention(thin) (@inout Klass) -> () {
1134+
bb0(%0 : $*Klass):
1135+
%3 = alloc_stack $Klass
1136+
copy_addr %0 to [initialization] %3 : $*Klass
1137+
fix_lifetime %3 : $*Klass
1138+
destroy_addr %3 : $*Klass
1139+
dealloc_stack %3 : $*Klass
1140+
%9999 = tuple()
1141+
return %9999 : $()
1142+
}
1143+
1144+
// CHECK-LABEL: sil [ossa] @eliminate_fix_lifetime_on_dest_store : $@convention(thin) (@inout Klass) -> () {
1145+
// CHECK-NOT: alloc_stack
1146+
// CHECK: [[VALUE:%.*]] = load [copy] %0
1147+
// CHECK-NEXT: fix_lifetime [[VALUE]]
1148+
// CHECK-NEXT: destroy_value [[VALUE]]
1149+
// CHECK-NOT: alloc_stack
1150+
// CHECK: } // end sil function 'eliminate_fix_lifetime_on_dest_store'
1151+
sil [ossa] @eliminate_fix_lifetime_on_dest_store : $@convention(thin) (@inout Klass) -> () {
1152+
bb0(%0 : $*Klass):
1153+
%2 = load [copy] %0 : $*Klass
1154+
%3 = alloc_stack $Klass
1155+
store %2 to [init] %3 : $*Klass
1156+
fix_lifetime %3 : $*Klass
1157+
destroy_addr %3 : $*Klass
1158+
dealloc_stack %3 : $*Klass
1159+
%9999 = tuple()
1160+
return %9999 : $()
1161+
}

0 commit comments

Comments
 (0)