Skip to content

Commit 50f6430

Browse files
committed
[embedded] Convert thick->thin metatypes on array builtins (copy, take, assign) in mandatory optimizations
1 parent 78a5b68 commit 50f6430

File tree

7 files changed

+82
-0
lines changed

7 files changed

+82
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ extension BuiltinInst : OnoneSimplifyable {
3232
.Strideof,
3333
.Alignof:
3434
optimizeTargetTypeConst(context)
35+
case .CopyArray,
36+
.TakeArrayNoAlias,
37+
.TakeArrayFrontToBack,
38+
.TakeArrayBackToFront,
39+
.AssignCopyArrayNoAlias,
40+
.AssignCopyArrayFrontToBack,
41+
.AssignCopyArrayBackToFront,
42+
.AssignTakeArray:
43+
optimizeArrayBuiltin(context)
3544
default:
3645
if let literal = constantFold(context) {
3746
uses.replaceAll(with: literal, context)
@@ -162,6 +171,23 @@ private extension BuiltinInst {
162171
uses.replaceAll(with: literal, context)
163172
context.erase(instruction: self)
164173
}
174+
175+
func optimizeArrayBuiltin(_ context: SimplifyContext) {
176+
guard let metatypeInst = operands[0].value as? MetatypeInst,
177+
metatypeInst.type.representationOfMetatype(in: parentFunction) == .Thick else {
178+
return
179+
}
180+
181+
// Must be single use so that we can use replaceAll
182+
guard metatypeInst.uses.isSingleUse else {
183+
return
184+
}
185+
186+
let instanceType = metatypeInst.type.instanceTypeOfMetatype(in: parentFunction)
187+
let builder = Builder(before: self, context)
188+
let metatype = builder.createMetatype(of: instanceType, representation: .Thin)
189+
metatypeInst.uses.replaceAll(with: metatype, context)
190+
}
165191
}
166192

167193
private func hasSideEffectForBuiltinOnce(_ instruction: Instruction) -> Bool {

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,9 @@ public struct Builder {
309309
useConformancesOf.bridged)
310310
return notifyNew(initExistential.getAs(InitExistentialRefInst.self))
311311
}
312+
313+
public func createMetatype(of type: Type, representation: swift.MetatypeRepresentation) -> MetatypeInst {
314+
let metatype = bridged.createMetatype(type.bridged, representation)
315+
return notifyNew(metatype.getAs(MetatypeInst.self))
316+
}
312317
}

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
9090
bridged.getInstanceTypeOfMetatype(function.bridged.getFunction()).type
9191
}
9292

93+
public func representationOfMetatype(in function: Function) -> swift.MetatypeRepresentation {
94+
bridged.getRepresentationOfMetatype(function.bridged.getFunction())
95+
}
96+
9397
public var isCalleeConsumedFunction: Bool { bridged.isCalleeConsumedFunction() }
9498

9599
public var isMarkedAsImmortal: Bool { bridged.isMarkedAsImmortal() }

include/swift/SIL/SILBridging.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,13 @@ struct BridgedBuilder{
13571357
instance.getSILValue(),
13581358
src->getConformances())};
13591359
}
1360+
1361+
SWIFT_IMPORT_UNSAFE
1362+
BridgedInstruction createMetatype(swift::SILType type, swift::MetatypeRepresentation representation) const {
1363+
swift::MetatypeType *mt = swift::MetatypeType::get(type.getASTType(), representation);
1364+
swift::SILType t = swift::SILType::getPrimitiveObjectType(swift::CanType(mt));
1365+
return {builder().createMetatype(regularLoc(), t)};
1366+
}
13601367
};
13611368

13621369
// AST bridging

include/swift/SIL/SILType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,8 @@ class SILType {
864864

865865
SILType getInstanceTypeOfMetatype(SILFunction *function) const;
866866

867+
MetatypeRepresentation getRepresentationOfMetatype(SILFunction *function) const;
868+
867869
bool isOrContainsObjectiveCClass() const;
868870

869871
bool isCalleeConsumedFunction() const {

lib/SIL/IR/SILType.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,11 @@ SILType SILType::getInstanceTypeOfMetatype(SILFunction *function) const {
10761076
return tl.getLoweredType();
10771077
}
10781078

1079+
MetatypeRepresentation SILType::getRepresentationOfMetatype(SILFunction *function) const {
1080+
auto metaType = castTo<MetatypeType>();
1081+
return metaType->getRepresentation();
1082+
}
1083+
10791084
bool SILType::isOrContainsObjectiveCClass() const {
10801085
return getASTType().findIf([](Type ty) {
10811086
if (ClassDecl *cd = ty->getClassOrBoundGenericClass()) {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %target-swift-emit-ir %s -parse-stdlib -module-name Swift -enable-experimental-feature Embedded -target arm64e-apple-none | %FileCheck %s
2+
3+
class MyClass {}
4+
5+
struct MyStruct {
6+
var c: MyClass
7+
}
8+
9+
public func foo(x: Builtin.RawPointer, y: Builtin.RawPointer, count: Builtin.Word) {
10+
var s = MyGenericStruct<MyStruct>()
11+
s.foo(x: x, y: y, count: count)
12+
}
13+
14+
public struct MyGenericStruct<T> {
15+
public func foo(x: Builtin.RawPointer, y: Builtin.RawPointer, count: Builtin.Word) {
16+
Builtin.copyArray(T.self, x, y, count)
17+
Builtin.copyArray(T.self, x, y, count)
18+
Builtin.takeArrayNoAlias(T.self, x, y, count)
19+
Builtin.takeArrayFrontToBack(T.self, x, y, count)
20+
Builtin.takeArrayBackToFront(T.self, x, y, count)
21+
Builtin.assignCopyArrayNoAlias(T.self, x, y, count)
22+
Builtin.assignCopyArrayFrontToBack(T.self, x, y, count)
23+
Builtin.assignCopyArrayBackToFront(T.self, x, y, count)
24+
Builtin.assignTakeArray(T.self, x, y, count)
25+
}
26+
}
27+
28+
// No runtime calls should be present.
29+
// CHECK-NOT: @swift_arrayInitWithCopy
30+
// CHECK-NOT: @swift_arrayAssignWithCopyNoAlias
31+
// CHECK-NOT: @swift_arrayAssignWithCopyFrontToBack
32+
// CHECK-NOT: @swift_arrayAssignWithCopyBackToFront
33+
// CHECK-NOT: @swift_arrayAssignWithTake

0 commit comments

Comments
 (0)