Skip to content

Commit cc8a86b

Browse files
committed
Optimize array.getContiguousArrayStorageType calls
1 parent 9f2b6a4 commit cc8a86b

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

include/swift/AST/SemanticAttrs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ SEMANTICS_ATTR(ARRAY_COUNT, "array.count")
6363
SEMANTICS_ATTR(ARRAY_DEALLOC_UNINITIALIZED, "array.dealloc_uninitialized")
6464
SEMANTICS_ATTR(ARRAY_UNINITIALIZED_INTRINSIC, "array.uninitialized_intrinsic")
6565
SEMANTICS_ATTR(ARRAY_FINALIZE_INTRINSIC, "array.finalize_intrinsic")
66+
SEMANTICS_ATTR(ARRAY_GET_CONTIGUOUSARRAYSTORAGETYPE, "array.getContiguousArrayStorageType")
6667

6768
SEMANTICS_ATTR(SEQUENCE_FOR_EACH, "sequence.forEach")
6869
SEMANTICS_ATTR(TYPENAME, "typeName")

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,40 @@ bool SILCombiner::optimizeIdentityCastComposition(ApplyInst *fInverseApply,
15711571
return true;
15721572
}
15731573

1574+
/// Should replace a call to `getContiguousArrayStorageType<A>(for:)` by the
1575+
/// metadata constructor.
1576+
/// We know that `getContiguousArrayStorageType` will not return the AnyObject
1577+
/// type optimization for any non class or objc existential type instantiation.
1578+
static bool shouldReplaceCallByMetadataConstructor(CanType storageMetaTy) {
1579+
auto metaTy = dyn_cast<MetatypeType>(storageMetaTy);
1580+
if (!metaTy || metaTy->getRepresentation() != MetatypeRepresentation::Thick)
1581+
return false;
1582+
1583+
auto storageTy = metaTy.getInstanceType()->getCanonicalType();
1584+
if (!storageTy->is_ContiguousArrayStorage())
1585+
return false;
1586+
1587+
auto boundGenericTy = dyn_cast<BoundGenericType>(storageTy);
1588+
if (!boundGenericTy)
1589+
return false;
1590+
1591+
for (auto TP : boundGenericTy->getGenericArgs()) {
1592+
auto ty = TP->getCanonicalType();
1593+
if (ty->getStructOrBoundGenericStruct() ||
1594+
ty->getEnumOrBoundGenericEnum() ||
1595+
isa<BuiltinVectorType>(ty) ||
1596+
isa<BuiltinIntegerType>(ty) ||
1597+
isa<BuiltinFloatType>(ty) ||
1598+
isa<TupleType>(ty) ||
1599+
isa<AnyFunctionType>(ty) ||
1600+
(ty->isAnyExistentialType() && !ty->isObjCExistentialType()))
1601+
return true;
1602+
1603+
return false;
1604+
}
1605+
return false;
1606+
}
1607+
15741608
SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
15751609
Builder.setCurrentDebugScope(AI->getDebugScope());
15761610
// apply{partial_apply(x,y)}(z) -> apply(z,x,y) is triggered
@@ -1604,6 +1638,16 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
16041638
return nullptr;
16051639
}
16061640
}
1641+
if (SF->hasSemanticsAttr(semantics::ARRAY_GET_CONTIGUOUSARRAYSTORAGETYPE)) {
1642+
auto silTy = AI->getType();
1643+
auto storageTy = AI->getType().getASTType();
1644+
if (shouldReplaceCallByMetadataConstructor(storageTy)) {
1645+
auto metatype = Builder.createMetatype(AI->getLoc(), silTy);
1646+
AI->replaceAllUsesWith(metatype);
1647+
eraseInstFromFunction(*AI);
1648+
return nullptr;
1649+
}
1650+
}
16071651
}
16081652

16091653

test/SILOptimizer/stack_promotion_2_modules.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ import Module
6464
// Check if the array literal can be stack promoted.
6565

6666
// CHECK-LABEL: sil @$s4main6testit6Module3FooVyF
67-
// CHECK: alloc_ref_dynamic [stack] [tail_elems $Foo.FooElement
67+
// CHECK: alloc_ref{{.*}} [stack] [tail_elems $Foo.FooElement
6868
// CHECK: } // end sil function '$s4main6testit6Module3FooVyF'
6969

7070
public func testit() -> Foo {

test/SILOptimizer/stack_promotion_array_literal.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// stack promoted.
66

77
// CHECK-LABEL: sil @{{.*}}testit
8-
// CHECK: alloc_ref_dynamic [stack] [tail_elems
8+
// CHECK: alloc_ref{{.*}} [stack] [tail_elems
99

1010
public func testit(_ N: Int, _ x: Int) {
1111
for _ in 0..<N {

0 commit comments

Comments
 (0)