Skip to content

Commit 5237bcd

Browse files
committed
[silcombine] Eliminate mark_dependence whose base is a trivial object.
This pattern comes up when faking a base using Builtin.convertUnsafeUnownedToGuaranteed. rdar://59735604
1 parent e35ae37 commit 5237bcd

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,36 +1681,48 @@ SILInstruction *SILCombiner::visitEnumInst(EnumInst *EI) {
16811681
return nullptr;
16821682
}
16831683

1684-
SILInstruction *SILCombiner::visitMarkDependenceInst(MarkDependenceInst *MDI) {
1684+
SILInstruction *SILCombiner::visitMarkDependenceInst(MarkDependenceInst *mdi) {
16851685
// Simplify the base operand of a MarkDependenceInst to eliminate unnecessary
16861686
// instructions that aren't adding value.
16871687
//
16881688
// Conversions to Optional.Some(x) often happen here, this isn't important
16891689
// for us, we can just depend on 'x' directly.
1690-
if (auto eiBase = dyn_cast<EnumInst>(MDI->getBase())) {
1690+
if (auto *eiBase = dyn_cast<EnumInst>(mdi->getBase())) {
16911691
if (eiBase->hasOperand() && eiBase->hasOneUse()) {
1692-
MDI->setBase(eiBase->getOperand());
1692+
mdi->setBase(eiBase->getOperand());
16931693
eraseInstFromFunction(*eiBase);
1694-
return MDI;
1694+
return mdi;
16951695
}
16961696
}
16971697

16981698
// Conversions from a class to AnyObject also happen a lot, we can just depend
16991699
// on the class reference.
1700-
if (auto ier = dyn_cast<InitExistentialRefInst>(MDI->getBase())) {
1701-
MDI->setBase(ier->getOperand());
1700+
if (auto *ier = dyn_cast<InitExistentialRefInst>(mdi->getBase())) {
1701+
mdi->setBase(ier->getOperand());
17021702
if (ier->use_empty())
17031703
eraseInstFromFunction(*ier);
1704-
return MDI;
1704+
return mdi;
17051705
}
17061706

17071707
// Conversions from a class to AnyObject also happen a lot, we can just depend
17081708
// on the class reference.
1709-
if (auto oeri = dyn_cast<OpenExistentialRefInst>(MDI->getBase())) {
1710-
MDI->setBase(oeri->getOperand());
1709+
if (auto *oeri = dyn_cast<OpenExistentialRefInst>(mdi->getBase())) {
1710+
mdi->setBase(oeri->getOperand());
17111711
if (oeri->use_empty())
17121712
eraseInstFromFunction(*oeri);
1713-
return MDI;
1713+
return mdi;
1714+
}
1715+
1716+
// Sometimes due to specialization/builtins, we can get a mark_dependence
1717+
// whose base is a trivial typed object. In such a case, the mark_dependence
1718+
// does not have a meaning, so just eliminate it.
1719+
{
1720+
SILType baseType = mdi->getBase()->getType();
1721+
if (baseType.isObject() && baseType.isTrivial(*mdi->getFunction())) {
1722+
SILValue value = mdi->getValue();
1723+
mdi->replaceAllUsesWith(value);
1724+
return eraseInstFromFunction(*mdi);
1725+
}
17141726
}
17151727

17161728
return nullptr;

test/SILOptimizer/sil_combine.sil

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,6 +3449,19 @@ bb0(%0 : $*Builtin.Int64, %1 : $B):
34493449
return %4 : $Builtin.Int64
34503450
}
34513451

3452+
// CHECK-LABEL: sil @mark_dependence_trivial_object_base :
3453+
// CHECK: bb0(
3454+
// CHECK-NEXT: strong_retain
3455+
// CHECK-NEXT: return
3456+
// CHECK: } // end sil function 'mark_dependence_trivial_object_base'
3457+
sil @mark_dependence_trivial_object_base : $@convention(thin) (@guaranteed B) -> @owned B {
3458+
bb0(%0 : $B):
3459+
strong_retain %0 : $B
3460+
%1 = enum $Optional<Int>, #Optional.none!enumelt
3461+
%2 = mark_dependence %0 : $B on %1 : $Optional<Int>
3462+
return %2 : $B
3463+
}
3464+
34523465
protocol _NSArrayCore {}
34533466

34543467
// CHECK-LABEL: sil @mark_dependence_base2

0 commit comments

Comments
 (0)