@@ -305,9 +305,13 @@ private extension PartialApplyInst {
305
305
var nonConstArgs = [ Operand] ( )
306
306
var hasKeypath = false
307
307
for argOp in argumentOperands {
308
- if argOp. value. isConstant ( hasKeypath: & hasKeypath) {
308
+ switch argOp. value. isConstant ( ) {
309
+ case . constant:
309
310
constArgs. append ( argOp)
310
- } else {
311
+ case . constantWithKeypath:
312
+ constArgs. append ( argOp)
313
+ hasKeypath = true
314
+ case . notConstant:
311
315
nonConstArgs. append ( argOp)
312
316
}
313
317
}
@@ -337,33 +341,42 @@ private extension FullApplySite {
337
341
}
338
342
}
339
343
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
+
340
359
private extension Value {
341
- func isConstant( hasKeypath : inout Bool ) -> Bool {
360
+ func isConstant( ) -> ConstantKind {
342
361
// All instructions handled here must also be handled in
343
362
// `FunctionSignatureSpecializationMangler::mangleConstantProp`.
344
363
switch self {
345
364
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 ( ) ) } )
352
366
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 ( )
354
368
case is StringLiteralInst , is IntegerLiteralInst , is FloatLiteralInst , is FunctionRefInst , is GlobalAddrInst :
355
- return true
369
+ return . constant
356
370
case let keyPath as KeyPathInst :
357
- hasKeypath = true
358
371
guard keyPath. operands. isEmpty,
359
372
keyPath. hasPattern,
360
373
!keyPath. substitutionMap. hasAnySubstitutableParams
361
374
else {
362
- return false
375
+ return . notConstant
363
376
}
364
- return true
377
+ return . constantWithKeypath
365
378
default :
366
- return false
379
+ return . notConstant
367
380
}
368
381
}
369
382
}
0 commit comments