Skip to content

Commit fcb4cb6

Browse files
committed
Merge pull request #1662 from gottesmm/inguaranteed_loaded_values_are_guaranteed
[arc] A value loaded from an @in_guaranteed parameter is @guaranteed.
2 parents 6d045b0 + 8298df2 commit fcb4cb6

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

lib/SILOptimizer/ARC/RCStateTransitionVisitors.cpp

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,43 @@ visitAutoreleasePoolCall(ValueBase *V) {
5151
return DataflowResult(RCStateTransitionDataflowResultKind::NoEffects);
5252
}
5353

54+
// private helper method since C++ does not have extensions... *sigh*.
55+
//
56+
// TODO: This needs a better name.
57+
template <class ARCState>
58+
static bool isKnownSafe(BottomUpDataflowRCStateVisitor<ARCState> *State,
59+
SILInstruction *I, SILValue Op) {
60+
// If we are running with 'frozen' owned arg releases, check if we have a
61+
// frozen use in the side table. If so, this release must be known safe.
62+
if (State->FreezeOwnedArgEpilogueReleases)
63+
if (auto *OwnedRelease =
64+
State->EpilogueReleaseMatcher.getSingleReleaseForArgument(Op))
65+
if (I != OwnedRelease)
66+
return true;
67+
68+
// A guaranteed function argument is guaranteed to outlive the function we are
69+
// processing. So bottom up for such a parameter, we are always known safe.
70+
if (auto *Arg = dyn_cast<SILArgument>(Op)) {
71+
if (Arg->isFunctionArg() &&
72+
Arg->hasConvention(SILArgumentConvention::Direct_Guaranteed)) {
73+
return true;
74+
}
75+
}
76+
77+
// If Op is a load from an in_guaranteed parameter, it is guaranteed as well.
78+
if (auto *LI = dyn_cast<LoadInst>(Op)) {
79+
SILValue RCIdentity = State->RCFI->getRCIdentityRoot(LI->getOperand());
80+
if (auto *Arg = dyn_cast<SILArgument>(RCIdentity)) {
81+
if (Arg->isFunctionArg() &&
82+
Arg->hasConvention(SILArgumentConvention::Indirect_In_Guaranteed)) {
83+
return true;
84+
}
85+
}
86+
}
87+
88+
return false;
89+
}
90+
5491
template <class ARCState>
5592
typename BottomUpDataflowRCStateVisitor<ARCState>::DataflowResult
5693
BottomUpDataflowRCStateVisitor<ARCState>::visitStrongDecrement(ValueBase *V) {
@@ -70,23 +107,8 @@ BottomUpDataflowRCStateVisitor<ARCState>::visitStrongDecrement(ValueBase *V) {
70107
BottomUpRefCountState &State = DataflowState.getBottomUpRefCountState(Op);
71108
bool NestingDetected = State.initWithMutatorInst(SetFactory.get(I), RCFI);
72109

73-
// If we are running with 'frozen' owned arg releases, check if we have a
74-
// frozen use in the side table. If so, this release must be known safe.
75-
if (FreezeOwnedArgEpilogueReleases) {
76-
if (auto *OwnedRelease = EpilogueReleaseMatcher.getSingleReleaseForArgument(Op)) {
77-
if (I != OwnedRelease) {
78-
State.updateKnownSafe(true);
79-
}
80-
}
81-
}
82-
83-
// A guaranteed function argument is guaranteed to outlive the function we are
84-
// processing. So bottom up for such a parameter, we are always known safe.
85-
if (auto *Arg = dyn_cast<SILArgument>(Op)) {
86-
if (Arg->isFunctionArg() &&
87-
Arg->hasConvention(SILArgumentConvention::Direct_Guaranteed)) {
88-
State.updateKnownSafe(true);
89-
}
110+
if (isKnownSafe(this, I, Op)) {
111+
State.updateKnownSafe(true);
90112
}
91113

92114
DEBUG(llvm::dbgs() << " REF COUNT DECREMENT! Known Safe: "

test/SILOptimizer/arcsequenceopts.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,4 +2130,20 @@ bb0(%0 : $Builtin.NativeObject):
21302130
apply %1(%0) : $@convention(thin) (Builtin.NativeObject) -> ()
21312131
strong_release %0 : $Builtin.NativeObject
21322132
return undef : $()
2133+
}
2134+
2135+
// CHECK-LABEL: sil @in_guaranteed_always_known_safe_bu : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
2136+
// CHECK: strong_retain
2137+
// CHECK-NOT: strong_retain
2138+
// CHECK-NOT: strong_release
2139+
sil @in_guaranteed_always_known_safe_bu : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
2140+
bb0(%0 : $*Builtin.NativeObject):
2141+
%1 = load %0 : $*Builtin.NativeObject
2142+
strong_retain %1 : $Builtin.NativeObject
2143+
strong_retain %1 : $Builtin.NativeObject
2144+
%2 = function_ref @use : $@convention(thin) (Builtin.NativeObject) -> ()
2145+
apply %2(%1) : $@convention(thin) (Builtin.NativeObject) -> ()
2146+
apply %2(%1) : $@convention(thin) (Builtin.NativeObject) -> ()
2147+
strong_release %1 : $Builtin.NativeObject
2148+
return undef : $()
21332149
}

0 commit comments

Comments
 (0)