Skip to content

Commit 1262647

Browse files
committed
ConstantCapturePropagation: refactor Value.isConstant
1 parent e305567 commit 1262647

File tree

2 files changed

+68
-15
lines changed

2 files changed

+68
-15
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ConstantCapturePropagation.swift

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,13 @@ private extension PartialApplyInst {
305305
var nonConstArgs = [Operand]()
306306
var hasKeypath = false
307307
for argOp in argumentOperands {
308-
if argOp.value.isConstant(hasKeypath: &hasKeypath) {
308+
switch argOp.value.isConstant() {
309+
case .constant:
309310
constArgs.append(argOp)
310-
} else {
311+
case .constantWithKeypath:
312+
constArgs.append(argOp)
313+
hasKeypath = true
314+
case .notConstant:
311315
nonConstArgs.append(argOp)
312316
}
313317
}
@@ -337,33 +341,42 @@ private extension FullApplySite {
337341
}
338342
}
339343

344+
private enum ConstantKind {
345+
case notConstant
346+
case constant
347+
case constantWithKeypath
348+
349+
func merge(with other: ConstantKind) -> ConstantKind {
350+
switch (self, other) {
351+
case (.notConstant, _): return .notConstant
352+
case (_, .notConstant): return .notConstant
353+
case (.constant, .constant): return .constant
354+
default: return .constantWithKeypath
355+
}
356+
}
357+
}
358+
340359
private extension Value {
341-
func isConstant(hasKeypath: inout Bool) -> Bool {
360+
func isConstant() -> ConstantKind {
342361
// All instructions handled here must also be handled in
343362
// `FunctionSignatureSpecializationMangler::mangleConstantProp`.
344363
switch self {
345364
case let si as StructInst:
346-
for op in si.operands {
347-
if !op.value.isConstant(hasKeypath: &hasKeypath) {
348-
return false
349-
}
350-
}
351-
return true
365+
return si.operands.reduce(.constant, { $0.merge(with: $1.value.isConstant()) })
352366
case is ThinToThickFunctionInst, is ConvertFunctionInst, is UpcastInst, is OpenExistentialRefInst:
353-
return (self as! UnaryInstruction).operand.value.isConstant(hasKeypath: &hasKeypath)
367+
return (self as! UnaryInstruction).operand.value.isConstant()
354368
case is StringLiteralInst, is IntegerLiteralInst, is FloatLiteralInst, is FunctionRefInst, is GlobalAddrInst:
355-
return true
369+
return .constant
356370
case let keyPath as KeyPathInst:
357-
hasKeypath = true
358371
guard keyPath.operands.isEmpty,
359372
keyPath.hasPattern,
360373
!keyPath.substitutionMap.hasAnySubstitutableParams
361374
else {
362-
return false
375+
return .notConstant
363376
}
364-
return true
377+
return .constantWithKeypath
365378
default:
366-
return false
379+
return .notConstant
367380
}
368381
}
369382
}

test/SILOptimizer/capture_propagation.sil

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,46 @@ bb0:
824824
return %12 : $()
825825
}
826826

827+
// CHECK-LABEL: sil [ossa] @testNonConstStruct1 :
828+
// CHECK: [[S:%.*]] = struct $S
829+
// CHECK: partial_apply [callee_guaranteed] {{%[0-9]+}}([[S]])
830+
// CHECK: } // end sil function 'testNonConstStruct1'
831+
sil [ossa] @testNonConstStruct1 : $@convention(thin) (Int32) -> () {
832+
bb0(%0 : $Int32):
833+
%2 = integer_literal $Builtin.Int1, 0
834+
%3 = struct $Bool (%2)
835+
%4 = struct $S (%0, %3)
836+
%5 = function_ref @closureWithStruct : $@convention(thin) (Str, S) -> Builtin.Int32
837+
%6 = partial_apply [callee_guaranteed] %5(%4) : $@convention(thin) (Str, S) -> Builtin.Int32
838+
%7 = convert_escape_to_noescape %6 to $@noescape @callee_guaranteed (Str) -> Builtin.Int32
839+
%8 = function_ref @useIntClosure : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Builtin.Int32) -> ()
840+
%9 = apply %8(%7) : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Builtin.Int32) -> ()
841+
destroy_value %7
842+
destroy_value %6
843+
%12 = tuple ()
844+
return %12 : $()
845+
}
846+
847+
// CHECK-LABEL: sil [ossa] @testNonConstStruct2 :
848+
// CHECK: [[S:%.*]] = struct $S
849+
// CHECK: partial_apply [callee_guaranteed] {{%[0-9]+}}([[S]])
850+
// CHECK: } // end sil function 'testNonConstStruct2'
851+
sil [ossa] @testNonConstStruct2 : $@convention(thin) (Bool) -> () {
852+
bb0(%0 : $Bool):
853+
%1 = integer_literal $Builtin.Int32, 3
854+
%2 = struct $Int32 (%1)
855+
%4 = struct $S (%2, %0)
856+
%5 = function_ref @closureWithStruct : $@convention(thin) (Str, S) -> Builtin.Int32
857+
%6 = partial_apply [callee_guaranteed] %5(%4) : $@convention(thin) (Str, S) -> Builtin.Int32
858+
%7 = convert_escape_to_noescape %6 to $@noescape @callee_guaranteed (Str) -> Builtin.Int32
859+
%8 = function_ref @useIntClosure : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Builtin.Int32) -> ()
860+
%9 = apply %8(%7) : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Builtin.Int32) -> ()
861+
destroy_value %7
862+
destroy_value %6
863+
%12 = tuple ()
864+
return %12 : $()
865+
}
866+
827867
// CHECK-LABEL: sil shared [ossa] @$s17closureWithStruct4main1SVs5Int32VSbTf3npSSi3Si0_n : $@convention(thin) (Str) -> Builtin.Int32 {
828868
// CHECK: bb0(%0 : $Str):
829869
// CHECK: %1 = integer_literal $Builtin.Int32, 3

0 commit comments

Comments
 (0)