Skip to content

Commit 234d29a

Browse files
committed
Insert end_borrow before any destroy_value while ending lifetime of a reborrow with dependencies
1 parent 180b3bd commit 234d29a

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed

lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,15 +557,32 @@ bool DCE::removeDead() {
557557
BranchesChanged = true;
558558
continue;
559559
}
560+
561+
auto *phiArg = cast<SILPhiArgument>(arg);
560562
// In OSSA, we have to delete a dead phi argument and insert destroy or
561563
// end_borrow at its predecessors if the incoming values are live.
562564
// This is not necessary in non-OSSA, and will infact be incorrect.
563565
// Because, passing a value as a phi argument does not imply end of
564566
// lifetime in non-OSSA.
565567
for (auto *pred : BB.getPredecessorBlocks()) {
566568
auto *predTerm = pred->getTerminator();
567-
auto predArg = predTerm->getAllOperands()[i].get();
568-
endLifetimeOfLiveValue(predArg, predTerm);
569+
SILInstruction *insertPt = predTerm;
570+
if (phiArg->getOwnershipKind() == OwnershipKind::Guaranteed) {
571+
// If the phiArg is dead and had reborrow dependencies, its baseValue
572+
// may also have been dead and a destroy_value of its baseValue may
573+
// have been inserted before the pred's terminator. Make sure to
574+
// adjust the insertPt before any destroy_value.
575+
for (SILInstruction &predInst : llvm::reverse(*pred)) {
576+
if (&predInst == predTerm)
577+
continue;
578+
if (!isa<DestroyValueInst>(&predInst)) {
579+
insertPt = &*std::next(predInst.getIterator());
580+
break;
581+
}
582+
}
583+
}
584+
585+
endLifetimeOfLiveValue(phiArg->getIncomingPhiValue(pred), insertPt);
569586
}
570587
erasePhiArgument(&BB, i);
571588
Changed = true;

test/SILOptimizer/dead_code_elimination_nontrivial_ossa.sil

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,91 @@ bb1(%copy2 : @owned $NonTrivialStruct, %borrow2 : @guaranteed $NonTrivialStruct)
375375
return %newcopy : $NonTrivialStruct
376376
}
377377

378+
// CHECK-LABEL: sil [ossa] @dce_borrowlifetime2 :
379+
// CHECK: bb1:
380+
// CHECK-LABEL: } // end sil function 'dce_borrowlifetime2'
381+
sil [ossa] @dce_borrowlifetime2 : $@convention(thin) (@guaranteed Klass) -> () {
382+
bb0(%0 : @guaranteed $Klass):
383+
%copy = copy_value %0 : $Klass
384+
%borrow = begin_borrow %copy : $Klass
385+
%2 = function_ref @$use_klass2 : $@convention(thin) (@guaranteed Klass) -> ()
386+
%3 = apply %2(%borrow) : $@convention(thin) (@guaranteed Klass) -> ()
387+
%5 = apply %2(%copy) : $@convention(thin) (@guaranteed Klass) -> ()
388+
br bb1(%copy : $Klass, %borrow : $Klass)
389+
390+
bb1(%copy2 : @owned $Klass, %borrow2 : @guaranteed $Klass):
391+
end_borrow %borrow2 : $Klass
392+
destroy_value %copy2 : $Klass
393+
%res = tuple ()
394+
return %res : $()
395+
}
396+
397+
// CHECK-LABEL: sil [ossa] @dce_borrowlifetime3 :
398+
// CHECK: bb1:
399+
// CHECK-LABEL: } // end sil function 'dce_borrowlifetime3'
400+
sil [ossa] @dce_borrowlifetime3 : $@convention(thin) (@guaranteed Klass) -> () {
401+
bb0(%0 : @guaranteed $Klass):
402+
%copy = copy_value %0 : $Klass
403+
%borrow = begin_borrow %copy : $Klass
404+
%2 = function_ref @$use_klass2 : $@convention(thin) (@guaranteed Klass) -> ()
405+
%3 = apply %2(%borrow) : $@convention(thin) (@guaranteed Klass) -> ()
406+
%5 = apply %2(%copy) : $@convention(thin) (@guaranteed Klass) -> ()
407+
br bb1(%borrow : $Klass, %copy : $Klass)
408+
409+
bb1(%borrow2 : @guaranteed $Klass, %copy2 : @owned $Klass):
410+
end_borrow %borrow2 : $Klass
411+
destroy_value %copy2 : $Klass
412+
%res = tuple ()
413+
return %res : $()
414+
}
415+
416+
// CHECK-LABEL: sil [ossa] @dce_borrowlifetime4 :
417+
// CHECK: bb1:
418+
// CHECK-LABEL: } // end sil function 'dce_borrowlifetime4'
419+
sil [ossa] @dce_borrowlifetime4 : $@convention(thin) (@guaranteed Klass) -> () {
420+
bb0(%0 : @guaranteed $Klass):
421+
%copy = copy_value %0 : $Klass
422+
%borrow = begin_borrow %copy : $Klass
423+
%2 = function_ref @$use_klass2 : $@convention(thin) (@guaranteed Klass) -> ()
424+
%3 = apply %2(%borrow) : $@convention(thin) (@guaranteed Klass) -> ()
425+
%5 = apply %2(%copy) : $@convention(thin) (@guaranteed Klass) -> ()
426+
br bb1(%borrow : $Klass)
427+
428+
bb1(%borrow2 : @guaranteed $Klass):
429+
end_borrow %borrow2 : $Klass
430+
br bb2(%copy : $Klass)
431+
432+
bb2(%copy2 : @owned $Klass):
433+
destroy_value %copy2 : $Klass
434+
%res = tuple ()
435+
return %res : $()
436+
}
437+
438+
// CHECK-LABEL: sil [ossa] @dce_borrowlifetime5 :
439+
// CHECK: bb1:
440+
// CHECK-LABEL: } // end sil function 'dce_borrowlifetime5'
441+
sil [ossa] @dce_borrowlifetime5 : $@convention(thin) (@guaranteed Klass) -> () {
442+
bb0(%0 : @guaranteed $Klass):
443+
%copy1 = copy_value %0 : $Klass
444+
%copy2 = copy_value %0 : $Klass
445+
%borrow1 = begin_borrow %copy1 : $Klass
446+
%borrow2 = begin_borrow %copy2 : $Klass
447+
%2 = function_ref @$use_klass2 : $@convention(thin) (@guaranteed Klass) -> ()
448+
%3 = apply %2(%borrow1) : $@convention(thin) (@guaranteed Klass) -> ()
449+
%4 = apply %2(%borrow2) : $@convention(thin) (@guaranteed Klass) -> ()
450+
%5 = apply %2(%copy1) : $@convention(thin) (@guaranteed Klass) -> ()
451+
%6 = apply %2(%copy2) : $@convention(thin) (@guaranteed Klass) -> ()
452+
br bb1(%copy1 : $Klass, %borrow1 : $Klass, %borrow2 : $Klass)
453+
454+
bb1(%newcopy : @owned $Klass, %newborrow1 : @guaranteed $Klass, %newborrow2 : @guaranteed $Klass):
455+
end_borrow %newborrow1 : $Klass
456+
end_borrow %newborrow2 : $Klass
457+
destroy_value %newcopy : $Klass
458+
destroy_value %copy2 : $Klass
459+
%res = tuple ()
460+
return %res : $()
461+
}
462+
378463
// CHECK-LABEL: sil [ossa] @infinite_loop :
379464
// CHECK-NOT: copy_value
380465
// CHECK-LABEL: } // end sil function 'infinite_loop'

0 commit comments

Comments
 (0)