Skip to content

Commit 0b50c21

Browse files
committed
Don't emit upcast to the same type in SimplifyAllocRefDynamic, add test, add comment
1 parent d1e3828 commit 0b50c21

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyAllocRefDynamic.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,29 @@ extension AllocRefDynamicInst : OnoneSimplifyable {
2626
/// %8 = (... some use of ...) %7 : $BaseClass
2727

2828
let type: Type
29+
let emitUpcast: Bool
2930
if let metatypeInst = metatypeOperand.value as? MetatypeInst {
3031
type = metatypeInst.type.loweredInstanceTypeOfMetatype(in: parentFunction)
32+
emitUpcast = false
3133
} else if let upcastInst = metatypeOperand.value as? UpcastInst,
3234
let metatypeInst = upcastInst.operands[0].value as? MetatypeInst {
3335
type = metatypeInst.type.loweredInstanceTypeOfMetatype(in: parentFunction)
36+
emitUpcast = true
3437
} else {
3538
return
3639
}
3740

3841
let builder = Builder(before: self, context)
3942
let newAlloc = builder.createAllocRef(type, isObjC: self.isObjC, canAllocOnStack: self.canAllocOnStack, isBare: false,
4043
tailAllocatedTypes: self.tailAllocatedTypes, tailAllocatedCounts: Array(self.tailAllocatedCounts.values))
41-
let newCast = builder.createUpcast(from: newAlloc, to: self.type)
42-
uses.replaceAll(with: newCast, context)
44+
45+
let result: Value
46+
if emitUpcast {
47+
result = builder.createUpcast(from: newAlloc, to: self.type)
48+
} else {
49+
result = newAlloc
50+
}
51+
uses.replaceAll(with: result, context)
4352
context.erase(instruction: self)
4453
}
4554
}

stdlib/public/core/ManagedBuffer.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ extension ManagedBuffer where Element: ~Copyable {
7878
@_preInverseGenerics
7979
@inlinable
8080
#if $Embedded
81+
// Transparent in Embedded Swift to avoid needing "self" as a metatype. By
82+
// inlining into the caller, we'll know the concrete type instead.
8183
@_transparent
8284
#endif
8385
public final class func create(

test/SILOptimizer/simplify_alloc_ref_dynamic.sil

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,16 @@ class SubClass: BaseClass {
1313
override init()
1414
}
1515

16-
// CHECK-LABEL: sil [ossa] @test
16+
// CHECK-LABEL: sil [ossa] @test_alloc_ref_dynamic_with_upcast
1717
// CHECK: bb0(%0 : $Int):
1818
// CHECK: struct_extract %0 : $Int, #Int._value
1919
// CHECK: builtin "truncOrBitCast_Int64_Word"({{.*}} : $Builtin.Int64) : $Builtin.Word
2020
// CHECK: [[AL:%.*]] = alloc_ref [tail_elems $Int * {{.*}} : $Builtin.Word] $SubClass
2121
// CHECK: [[UP:%.*]] = upcast [[AL]] : $SubClass to $BaseClass
2222
// CHECK: [[MO:%.*]] = move_value [lexical] [var_decl] [[UP]] : $BaseClass
2323
// CHECK: return [[MO]] : $BaseClass
24-
// CHECK: } // end sil function 'test'
25-
sil [ossa] @test : $@convention(thin) (Int) -> @owned BaseClass {
26-
// %0 "minimumCapacity"
24+
// CHECK: } // end sil function 'test_alloc_ref_dynamic_with_upcast'
25+
sil [ossa] @test_alloc_ref_dynamic_with_upcast : $@convention(thin) (Int) -> @owned BaseClass {
2726
bb0(%0 : $Int):
2827
%4 = metatype $@thick SubClass.Type
2928
%5 = upcast %4 : $@thick SubClass.Type to $@thick BaseClass.Type
@@ -33,3 +32,21 @@ bb0(%0 : $Int):
3332
%13 = move_value [lexical] [var_decl] %12 : $BaseClass
3433
return %13 : $BaseClass
3534
}
35+
36+
// CHECK-LABEL: sil [ossa] @test_alloc_ref_dynamic_without_upcast
37+
// CHECK: bb0(%0 : $Int):
38+
// CHECK: struct_extract %0 : $Int, #Int._value
39+
// CHECK: builtin "truncOrBitCast_Int64_Word"({{.*}} : $Builtin.Int64) : $Builtin.Word
40+
// CHECK: [[AL:%.*]] = alloc_ref [tail_elems $Int * {{.*}} : $Builtin.Word] $BaseClass
41+
// CHECK: [[MO:%.*]] = move_value [lexical] [var_decl] [[AL]] : $BaseClass
42+
// CHECK: return [[MO]] : $BaseClass
43+
// CHECK: } // end sil function 'test_alloc_ref_dynamic_without_upcast'
44+
sil [ossa] @test_alloc_ref_dynamic_without_upcast : $@convention(thin) (Int) -> @owned BaseClass {
45+
bb0(%0 : $Int):
46+
%4 = metatype $@thick BaseClass.Type
47+
%10 = struct_extract %0 : $Int, #Int._value
48+
%11 = builtin "truncOrBitCast_Int64_Word"(%10 : $Builtin.Int64) : $Builtin.Word
49+
%12 = alloc_ref_dynamic [tail_elems $Int * %11 : $Builtin.Word] %4 : $@thick BaseClass.Type, $BaseClass
50+
%13 = move_value [lexical] [var_decl] %12 : $BaseClass
51+
return %13 : $BaseClass
52+
}

0 commit comments

Comments
 (0)