Skip to content

Commit 352386b

Browse files
authored
Merge pull request swiftlang#5140 from eeckstein/silcombine-alloc-ref-dynamic
SILCombine: handle upcasts when converting from alloc_ref_dynamic to alloc_ref
2 parents 24dc2af + bf7ac4a commit 352386b

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,34 +1238,44 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
12381238
// ->
12391239
// alloc_ref X
12401240
Builder.setCurrentDebugScope(ARDI->getDebugScope());
1241-
if (MetatypeInst *MI = dyn_cast<MetatypeInst>(ARDI->getOperand())) {
1241+
1242+
SILValue MDVal = ARDI->getOperand();
1243+
if (auto *UC = dyn_cast<UpcastInst>(MDVal))
1244+
MDVal = UC->getOperand();
1245+
1246+
SILInstruction *NewInst = nullptr;
1247+
if (MetatypeInst *MI = dyn_cast<MetatypeInst>(MDVal)) {
12421248
auto &Mod = ARDI->getModule();
12431249
auto SILInstanceTy = MI->getType().getMetatypeInstanceType(Mod);
1244-
auto *ARI = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
1245-
ARDI->isObjC(), false);
1246-
return ARI;
1247-
}
12481250

1249-
// checked_cast_br [exact] $Y.Type to $X.Type, bbSuccess, bbFailure
1250-
// ...
1251-
// bbSuccess(%T: $X.Type)
1252-
// alloc_ref_dynamic %T : $X.Type, $X
1253-
// ->
1254-
// alloc_ref $X
1255-
if (isa<SILArgument>(ARDI->getOperand())) {
1251+
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
1252+
ARDI->isObjC(), false);
1253+
1254+
} else if (isa<SILArgument>(MDVal)) {
1255+
1256+
// checked_cast_br [exact] $Y.Type to $X.Type, bbSuccess, bbFailure
1257+
// ...
1258+
// bbSuccess(%T: $X.Type)
1259+
// alloc_ref_dynamic %T : $X.Type, $X
1260+
// ->
1261+
// alloc_ref $X
12561262
auto *PredBB = ARDI->getParent()->getSinglePredecessor();
12571263
if (!PredBB)
12581264
return nullptr;
12591265
auto *CCBI = dyn_cast<CheckedCastBranchInst>(PredBB->getTerminator());
12601266
if (CCBI && CCBI->isExact() && ARDI->getParent() == CCBI->getSuccessBB()) {
12611267
auto &Mod = ARDI->getModule();
12621268
auto SILInstanceTy = CCBI->getCastType().getMetatypeInstanceType(Mod);
1263-
auto *ARI = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
1269+
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
12641270
ARDI->isObjC(), false);
1265-
return ARI;
12661271
}
12671272
}
1268-
return nullptr;
1273+
if (NewInst && NewInst->getType() != ARDI->getType()) {
1274+
// In case the argument was an upcast of the metatype, we have to upcast the
1275+
// resulting reference.
1276+
NewInst = Builder.createUpcast(ARDI->getLoc(), NewInst, ARDI->getType());
1277+
}
1278+
return NewInst;
12691279
}
12701280

12711281
SILInstruction *SILCombiner::visitEnumInst(EnumInst *EI) {

test/SILOptimizer/sil_combine.sil

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,6 +2256,22 @@ sil @alloc_ref_dynamic_with_metatype : $() -> () {
22562256
return %4 : $()
22572257
}
22582258

2259+
// CHECK-LABEL: sil @alloc_ref_dynamic_with_upcast_metatype
2260+
// CHECK: bb0
2261+
// CHECK-NOT: alloc_ref_dynamic
2262+
// CHECK-NEXT: [[R:%[0-9]+]] = alloc_ref $E
2263+
// CHECK-NEXT: [[C:%[0-9]+]] = upcast [[R]] : $E to $B
2264+
// CHECK-NEXT: strong_release [[C]]
2265+
// CHECK: return
2266+
sil @alloc_ref_dynamic_with_upcast_metatype : $() -> () {
2267+
%1 = metatype $@thick E.Type
2268+
%2 = upcast %1 : $@thick E.Type to $@thick B.Type
2269+
%3 = alloc_ref_dynamic %2 : $@thick B.Type, $B
2270+
strong_release %3 : $B
2271+
%4 = tuple()
2272+
return %4 : $()
2273+
}
2274+
22592275
// CHECK-LABEL: @alloc_ref_dynamic_after_successful_checked_cast_br
22602276
// CHECK: checked_cast_br
22612277
// CHECK: bb1
@@ -2279,6 +2295,32 @@ bb3 (%10: $Builtin.Int32):
22792295
return %10 : $Builtin.Int32
22802296
}
22812297

2298+
// CHECK-LABEL: @alloc_ref_dynamic_upcast_after_successful_checked_cast_br
2299+
// CHECK: checked_cast_br
2300+
// CHECK: bb1
2301+
// CHECK-NOT: alloc_ref_dynamic
2302+
// CHECK: [[R:%[0-9]+]] = alloc_ref $E
2303+
// CHECK-NEXT: [[C:%[0-9]+]] = upcast [[R]] : $E to $B
2304+
// CHECK-NEXT: strong_release [[C]]
2305+
sil @alloc_ref_dynamic_upcast_after_successful_checked_cast_br : $(@thick B.Type) -> Builtin.Int32 {
2306+
bb0(%1 : $@thick B.Type):
2307+
checked_cast_br [exact] %1 : $@thick B.Type to $@thick E.Type, bb1, bb2
2308+
2309+
bb1(%2 : $@thick E.Type):
2310+
%3 = upcast %2 : $@thick E.Type to $@thick B.Type
2311+
%4 = alloc_ref_dynamic %3 : $@thick B.Type, $B
2312+
strong_release %4 : $B
2313+
%5 = integer_literal $Builtin.Int32, 1
2314+
br bb3 (%5 : $Builtin.Int32)
2315+
2316+
bb2:
2317+
%6 = integer_literal $Builtin.Int32, 2
2318+
br bb3 (%6 : $Builtin.Int32)
2319+
2320+
bb3 (%10: $Builtin.Int32):
2321+
return %10 : $Builtin.Int32
2322+
}
2323+
22822324
// CHECK-LABEL: sil @delete_dead_alloc_stack
22832325
// CHECK: bb0
22842326
// CHECK-NEXT: tuple

0 commit comments

Comments
 (0)