@@ -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+
340359private 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}
0 commit comments