Skip to content

Commit 551b94b

Browse files
committed
[rc-id] Make RCIdentity strip off single-pred arguments.
This was already done in a few different places in the compiler. There is no reason not to have it in RCIdentity directly. rdar://24156136
1 parent 2f37094 commit 551b94b

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@ findDominatingNonPayloadedEdge(SILBasicBlock *IncomingEdgeBB,
244244
return false;
245245
}
246246

247+
static SILValue allIncomingValuesEqual(
248+
llvm::SmallVectorImpl<std::pair<SILBasicBlock *,
249+
SILValue >> &IncomingValues) {
250+
SILValue First = stripRCIdentityPreservingInsts(IncomingValues[0].second);
251+
if (std::all_of(std::next(IncomingValues.begin()), IncomingValues.end(),
252+
[&First](std::pair<SILBasicBlock *, SILValue> P) -> bool {
253+
return stripRCIdentityPreservingInsts(P.second) == First;
254+
}))
255+
return First;
256+
return SILValue();
257+
}
258+
247259
/// Return the underlying SILValue after stripping off SILArguments that cannot
248260
/// affect RC identity.
249261
///
@@ -301,11 +313,16 @@ SILValue RCIdentityFunctionInfo::stripRCIdentityPreservingArgs(SILValue V,
301313

302314
unsigned IVListSize = IncomingValues.size();
303315

304-
// If we only have one incoming value, just return the identity root of that
305-
// incoming value. There can be no loop problems.
306-
if (IVListSize == 1) {
307-
return IncomingValues[0].second;
308-
}
316+
assert(IVListSize != 1 && "Should have been handled in "
317+
"stripRCIdentityPreservingInsts");
318+
319+
// Ok, we have multiple predecessors. See if all of them are the same
320+
// value. If so, just return that value.
321+
//
322+
// This returns a SILValue to save a little bit of compile time since we
323+
// already compute that value here.
324+
if (SILValue V = allIncomingValuesEqual(IncomingValues))
325+
return V;
309326

310327
// Ok, we have multiple predecessors. First find the first non-payloaded enum.
311328
llvm::SmallVector<SILBasicBlock *, 8> NoPayloadEnumBBs;

test/SILOptimizer/rcidentity.sil

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,34 @@ bb4(%6 : $Builtin.NativeObject):
140140
bb5:
141141
return undef : $()
142142
}
143+
144+
// All of the SSA values in the given function besides %6 can be resolved to
145+
// (%0, %1). Because %6 has multiple SSA values and there is nothing tricky we
146+
// can do here, just bail.
147+
//
148+
// CHECK-LABEL: @test_multiple_pred_same_rcid@
149+
// CHECK: RESULT #0: 0 = 0
150+
// CHECK: RESULT #1: 1 = 0
151+
// CHECK: RESULT #2: 2 = 0
152+
// CHECK: RESULT #3: 3 = 0
153+
// CHECK: RESULT #4: 4 = 0
154+
// CHECK: RESULT #5: 5 = 0
155+
sil @test_multiple_pred_same_rcid : $@convention(thin) (Builtin.NativeObject) -> () {
156+
bb0(%0 : $Builtin.NativeObject):
157+
br bb1(%0 : $Builtin.NativeObject, %0 : $Builtin.NativeObject)
158+
159+
bb1(%2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject):
160+
cond_br undef, bb2(%3 : $Builtin.NativeObject), bb3(%2 : $Builtin.NativeObject)
161+
162+
bb2(%4 : $Builtin.NativeObject):
163+
br bb4(%4 : $Builtin.NativeObject)
164+
165+
bb3(%5 : $Builtin.NativeObject):
166+
br bb4(%5 : $Builtin.NativeObject)
167+
168+
bb4(%6 : $Builtin.NativeObject):
169+
br bb5
170+
171+
bb5:
172+
return undef : $()
173+
}

0 commit comments

Comments
 (0)