Skip to content

Commit 3675019

Browse files
author
Joe Shajrawi
committed
[SILCombiner] Remove strong retains and strong releases of tagged strings. A retain/release of a string literal is a no-op.
1 parent 6538d54 commit 3675019

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,20 @@ SILInstruction *SILCombiner::visitCondFailInst(CondFailInst *CFI) {
686686
return nullptr;
687687
}
688688

689+
static bool isValueToBridgeObjectremovable(ValueToBridgeObjectInst *VTBOI) {
690+
SILValue operand = VTBOI->getOperand();
691+
// If operand is a struct $UInt (% : $Builtin.), fetch the real source
692+
if (auto *SI = dyn_cast<StructInst>(operand)) {
693+
assert(SI->SILInstruction::getAllOperands().size() == 1 &&
694+
"Excted a single operand");
695+
operand = SI->getOperand(0);
696+
}
697+
if (auto *BI = dyn_cast<BuiltinInst>(operand)) {
698+
return (BI->getBuiltinInfo().ID == BuiltinValueKind::StringObjectOr);
699+
}
700+
return false;
701+
}
702+
689703
SILInstruction *SILCombiner::visitStrongRetainInst(StrongRetainInst *SRI) {
690704
// Retain of ThinToThickFunction is a no-op.
691705
SILValue funcOper = SRI->getOperand();
@@ -699,6 +713,15 @@ SILInstruction *SILCombiner::visitStrongRetainInst(StrongRetainInst *SRI) {
699713
isa<ObjCMetatypeToObjectInst>(SRI->getOperand()))
700714
return eraseInstFromFunction(*SRI);
701715

716+
// Retain and Release of tagged strings is a no-op.
717+
// The builtin code pattern to find tagged strings is:
718+
// builtin "stringObjectOr_Int64" (or to tag the string)
719+
// value_to_bridge_object (cast the UInt to bridge object)
720+
if (auto *VTBOI = dyn_cast<ValueToBridgeObjectInst>(SRI->getOperand())) {
721+
if (isValueToBridgeObjectremovable(VTBOI))
722+
return eraseInstFromFunction(*SRI);
723+
}
724+
702725
// Sometimes in the stdlib due to hand offs, we will see code like:
703726
//
704727
// strong_release %0
@@ -1141,6 +1164,15 @@ SILInstruction *SILCombiner::visitStrongReleaseInst(StrongReleaseInst *SRI) {
11411164
isa<ObjCMetatypeToObjectInst>(SRI->getOperand()))
11421165
return eraseInstFromFunction(*SRI);
11431166

1167+
// Retain and Release of tagged strings is a no-op.
1168+
// The builtin code pattern to find tagged strings is:
1169+
// builtin "stringObjectOr_Int64" (or to tag the string)
1170+
// value_to_bridge_object (cast the UInt to bridge object)
1171+
if (auto *VTBOI = dyn_cast<ValueToBridgeObjectInst>(SRI->getOperand())) {
1172+
if (isValueToBridgeObjectremovable(VTBOI))
1173+
return eraseInstFromFunction(*SRI);
1174+
}
1175+
11441176
// Release of a classbound existential converted from a class is just a
11451177
// release of the class, squish the conversion.
11461178
if (auto ier = dyn_cast<InitExistentialRefInst>(SRI->getOperand()))

0 commit comments

Comments
 (0)