Skip to content

Commit f39df1d

Browse files
committed
[sil-combine] Address comments from post-commit review of cd7c9e9.
1 parent 47f76f1 commit f39df1d

File tree

2 files changed

+61
-28
lines changed

2 files changed

+61
-28
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,14 @@ static bool canBeUsedAsCastDestination(SILValue value, CastInst *castInst,
569569

570570
SILInstruction *SILCombiner::visitUnconditionalCheckedCastAddrInst(
571571
UnconditionalCheckedCastAddrInst *uccai) {
572-
// Optimize the unconditional_checked_cast_addr in this pattern:
572+
573+
// Optimize the unconditional_checked_cast_addr in the following non-ossa/ossa
574+
// pattern:
575+
//
576+
// Non-OSSA Pattern
573577
//
578+
// %value = ...
579+
// ...
574580
// %box = alloc_existential_box $Error, $ConcreteError
575581
// %a = project_existential_box $ConcreteError in %b : $Error
576582
// store %value to %a : $*ConcreteError
@@ -581,33 +587,67 @@ SILInstruction *SILCombiner::visitUnconditionalCheckedCastAddrInst(
581587
// ConcreteError in %dest : $*ConcreteError
582588
//
583589
// to:
584-
// ...
590+
//
585591
// retain_value %value : $ConcreteError
592+
// ...
593+
// %box = alloc_existential_box $Error, $ConcreteError
594+
// %a = project_existential_box $ConcreteError in %b : $Error
595+
// store %value to %a : $*ConcreteError
596+
// %err = alloc_stack $Error
597+
// store %box to %err : $*Error
586598
// destroy_addr %err : $*Error
587599
// store %value to %dest $*ConcreteError
588600
//
589-
// This lets the alloc_existential_box become dead and it can be removed in
590-
// following optimizations.
601+
// OSSA Pattern:
602+
//
603+
// %value = ...
604+
// ...
605+
// %box = alloc_existential_box $Error, $ConcreteError
606+
// %a = project_existential_box $ConcreteError in %b : $Error
607+
// store %value to [init] %a : $*ConcreteError
608+
// %err = alloc_stack $Error
609+
// store %box to [init] %err : $*Error
610+
// %dest = alloc_stack $ConcreteError
611+
// unconditional_checked_cast_addr Error in %err : $*Error to
612+
// ConcreteError in %dest : $*ConcreteError
613+
//
614+
// to:
615+
//
616+
// %value_copy = copy_value %value
617+
// ...
618+
// %box = alloc_existential_box $Error, $ConcreteError
619+
// %a = project_existential_box $ConcreteError in %b : $Error
620+
// store %value to [init] %a : $*ConcreteError
621+
// %err = alloc_stack $Error
622+
// store %box to [init] %err : $*Error
623+
// destroy_addr %err : $*Error
624+
// store %value to %dest $*ConcreteError
625+
//
626+
// In both cases, this lets the alloc_existential_box become dead and it can
627+
// be removed in other subsequent optimizations.
591628
SILValue val = getConcreteValueOfExistentialBoxAddr(uccai->getSrc(), uccai);
592629
while (auto *cvi = dyn_cast_or_null<CopyValueInst>(val))
593630
val = cvi->getOperand();
594631
if (canBeUsedAsCastDestination(val, uccai, DA)) {
595632
// We need to copy the value at its insertion point.
596633
{
597-
auto *valInsertPt = val->getDefiningInsertionPoint();
598-
if (!valInsertPt)
634+
auto *nextInsertPt = val->getNextInstruction();
635+
if (!nextInsertPt)
599636
return nullptr;
600-
auto valInsertPtIter = valInsertPt->getIterator();
601637
// If our value is defined by an instruction (not an argument), we want to
602638
// insert the copy after that. Otherwise, we have an argument and we want
603639
// to insert the copy right at the beginning of the block.
604-
if (val->getDefiningInstruction())
605-
valInsertPtIter = std::next(valInsertPtIter);
606-
SILBuilderWithScope builder(valInsertPtIter, Builder);
607-
val = builder.emitCopyValueOperation(valInsertPtIter->getLoc(), val);
640+
SILBuilderWithScope builder(nextInsertPt, Builder);
641+
// We use an autogenerated location to ensure that if next is a
642+
// terminator, we do not trip an assertion around mismatched debug info.
643+
//
644+
// FIXME: We should find a better way of solving this than losing location
645+
// info!
646+
auto loc = RegularLocation::getAutoGeneratedLocation();
647+
val = builder.emitCopyValueOperation(loc, val);
608648
}
609649

610-
// Then we insert the destroy value/store at the cast location.
650+
// Then we insert the destroy addr/store at the cast location.
611651
SILBuilderWithScope builder(uccai, Builder);
612652
SILLocation loc = uccai->getLoc();
613653
builder.createDestroyAddr(loc, uccai->getSrc());
@@ -816,17 +856,12 @@ visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CCABI) {
816856
// We need to insert the copy after the defining instruction of val or at
817857
// the top of the block if val is an argument.
818858
{
819-
auto *valInsertPt = val->getDefiningInsertionPoint();
820-
if (!valInsertPt)
859+
auto *nextInsertPt = val->getNextInstruction();
860+
if (!nextInsertPt)
821861
return nullptr;
822-
auto valInsertPtIter = valInsertPt->getIterator();
823-
// If our value is defined by an instruction (not an argument), we want to
824-
// insert the copy after that. Otherwise, we have an argument and we want
825-
// to insert the copy right at the beginning of the block.
826-
if (val->getDefiningInstruction())
827-
valInsertPtIter = std::next(valInsertPtIter);
828-
SILBuilderWithScope builder(valInsertPtIter, Builder);
829-
val = builder.emitCopyValueOperation(valInsertPtIter->getLoc(), val);
862+
SILBuilderWithScope builder(nextInsertPt, Builder);
863+
auto loc = RegularLocation::getAutoGeneratedLocation();
864+
val = builder.emitCopyValueOperation(loc, val);
830865
}
831866

832867
SILBuilderWithScope builder(CCABI, Builder);

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "swift/AST/GenericSignature.h"
1515
#include "swift/AST/SemanticAttrs.h"
1616
#include "swift/AST/SubstitutionMap.h"
17+
#include "swift/Basic/SmallPtrSetVector.h"
1718
#include "swift/SIL/ApplySite.h"
1819
#include "swift/SIL/BasicBlockUtils.h"
1920
#include "swift/SIL/DebugUtils.h"
@@ -701,11 +702,9 @@ SILValue swift::
701702
getConcreteValueOfExistentialBox(AllocExistentialBoxInst *existentialBox,
702703
SILInstruction *ignoreUser) {
703704
StoreInst *singleStore = nullptr;
704-
SmallVector<Operand *, 32> worklist;
705-
SmallPtrSet<Operand *, 8> addedToWorklistPreviously;
705+
SmallPtrSetVector<Operand *, 32> worklist;
706706
for (auto *use : getNonDebugUses(existentialBox)) {
707-
worklist.push_back(use);
708-
addedToWorklistPreviously.insert(use);
707+
worklist.insert(use);
709708
}
710709

711710
while (!worklist.empty()) {
@@ -722,8 +721,7 @@ getConcreteValueOfExistentialBox(AllocExistentialBoxInst *existentialBox,
722721
// Look through copy_value, begin_borrow
723722
for (SILValue result : user->getResults())
724723
for (auto *transitiveUse : result->getUses())
725-
if (!addedToWorklistPreviously.insert(transitiveUse).second)
726-
worklist.push_back(use);
724+
worklist.insert(transitiveUse);
727725
break;
728726
case SILInstructionKind::ProjectExistentialBoxInst: {
729727
auto *projectedAddr = cast<ProjectExistentialBoxInst>(user);

0 commit comments

Comments
 (0)