Skip to content

Commit 91a425e

Browse files
authored
Merge pull request swiftlang#30868 from atrick/simplify-metatype
Simplify metatype instructions.
2 parents b6df6ef + 69a22f6 commit 91a425e

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/SILOptimizer/Analysis/SimplifyInstruction.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ namespace {
6565
SILValue visitThinFunctionToPointerInst(ThinFunctionToPointerInst *TFTPI);
6666
SILValue visitPointerToThinFunctionInst(PointerToThinFunctionInst *PTTFI);
6767
SILValue visitBeginAccessInst(BeginAccessInst *BAI);
68+
SILValue visitMetatypeInst(MetatypeInst *MTI);
6869

6970
SILValue simplifyOverflowBuiltin(BuiltinInst *BI);
7071
};
@@ -453,6 +454,24 @@ SILValue InstSimplifier::visitBeginAccessInst(BeginAccessInst *BAI) {
453454
return SILValue();
454455
}
455456

457+
SILValue InstSimplifier::visitMetatypeInst(MetatypeInst *MI) {
458+
auto metaType = MI->getType().castTo<MetatypeType>();
459+
auto instanceType = metaType.getInstanceType();
460+
// Tuple, Struct, and Enum MetatypeTypes have a single value.
461+
// If this metatype is already passed as an argument reuse it to enable
462+
// downstream CSE/SILCombine optimizations.
463+
// Note: redundant metatype instructions are already handled by CSE.
464+
if (isa<TupleType>(instanceType)
465+
|| instanceType.getStructOrBoundGenericStruct()
466+
|| instanceType.getEnumOrBoundGenericEnum()) {
467+
for (SILArgument *argument : MI->getFunction()->getArguments()) {
468+
if (argument->getType().getASTType() == metaType)
469+
return argument;
470+
}
471+
}
472+
return SILValue();
473+
}
474+
456475
static SILValue simplifyBuiltin(BuiltinInst *BI) {
457476

458477
switch (BI->getBuiltinInfo().ID) {

test/SILOptimizer/sil_simplify_instrs.sil

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,22 @@ bb0(%0 : $A):
352352
// CHECK-NEXT: %{{.*}} = tuple ()
353353
// CHECK-NEXT: return %{{.*}} : $()
354354
// CHECK-LABEL: } // end sil function 'simplify_accesssil'
355+
356+
// Test replacement of metatype instructions with metatype arguments.
357+
protocol SomeP {}
358+
359+
public enum SpecialEnum : SomeP {}
360+
361+
// CHECK-LABEL: sil @testSimplifyMetatype : $@convention(thin) (@thick SpecialEnum.Type) -> Bool {
362+
// CHECK: init_existential_metatype %0 : $@thick SpecialEnum.Type, $@thick Any.Type
363+
// CHECK: init_existential_metatype %0 : $@thick SpecialEnum.Type, $@thick Any.Type
364+
// CHECK-LABEL: } // end sil function 'testSimplifyMetatype'
365+
sil @testSimplifyMetatype : $@convention(thin) (@thick SpecialEnum.Type) -> Bool {
366+
bb0(%0 : $@thick SpecialEnum.Type):
367+
%1 = init_existential_metatype %0 : $@thick SpecialEnum.Type, $@thick Any.Type
368+
%2 = metatype $@thick SpecialEnum.Type
369+
%3 = init_existential_metatype %2 : $@thick SpecialEnum.Type, $@thick Any.Type
370+
%4 = builtin "is_same_metatype"(%1 : $@thick Any.Type, %3 : $@thick Any.Type) : $Builtin.Int1
371+
%5 = struct $Bool (%4 : $Builtin.Int1)
372+
return %5 : $Bool
373+
}

0 commit comments

Comments
 (0)