@@ -223,20 +223,20 @@ static bool isStdlibIntegerOrBoolDecl(NominalTypeDecl *numberDecl,
223
223
numberDecl == astCtx.getBoolDecl ());
224
224
}
225
225
226
- // / Return true if and only if the given SIL type represents a String or
227
- // / a Stdlib or builtin integer type.
228
- static bool isIntegerOrStringType (SILType silType, ASTContext &astContext) {
226
+ // / Return true if and only if the given SIL type represents a Stdlib or builtin
227
+ // / integer type or a Bool type.
228
+ static bool isIntegerOrBoolType (SILType silType, ASTContext &astContext) {
229
229
if (silType.is <BuiltinIntegerType>()) {
230
230
return true ;
231
231
}
232
-
233
232
NominalTypeDecl *nominalDecl = silType.getNominalOrBoundGenericNominal ();
234
- if (!nominalDecl) {
235
- return false ;
236
- }
233
+ return nominalDecl && isStdlibIntegerOrBoolDecl (nominalDecl, astContext);
234
+ }
237
235
238
- return (nominalDecl == astContext.getStringDecl ()) ||
239
- isStdlibIntegerOrBoolDecl (nominalDecl, astContext);
236
+ // / Return true if and only if the given SIL type represents a String type.
237
+ static bool isStringType (SILType silType, ASTContext &astContext) {
238
+ NominalTypeDecl *nominalDecl = silType.getNominalOrBoundGenericNominal ();
239
+ return nominalDecl && nominalDecl == astContext.getStringDecl ();
240
240
}
241
241
242
242
// / Decide if the given instruction (which could possibly be a call) should
@@ -272,32 +272,43 @@ evaluateOrSkip(ConstExprStepEvaluator &stepEval,
272
272
return stepEval.skipByMakingEffectsNonConstant (instI);
273
273
}
274
274
275
- // / Check whether a single-valued instruction is foldable. String or integer
276
- // / valued instructions are foldable with the exceptions:
277
- // / - Addresses-valued instructions cannot be folded.
278
- // / - Literal instruction need not be folded.
279
- // / - "String.makeUTF8" instrinsic initializer need not be folded as it is
280
- // / used only on string literals.
281
- // / - StructInst cannot be folded. We can only fold its arguments and not the
282
- // / instruction itself.
275
+ // / Return true iff the given value is a stdlib Int or Bool and it not a direct
276
+ // / construction of Int or Bool.
277
+ static bool isFoldableIntOrBool (SILValue value, SILInstruction *definingInst,
278
+ ASTContext &astContext) {
279
+ assert (definingInst);
280
+ return !isa<StructInst>(definingInst) &&
281
+ isIntegerOrBoolType (value->getType (), astContext);
282
+ }
283
+
284
+ // / Return true iff the given value is a string and is not an initialization
285
+ // / of an string from a string literal.
286
+ static bool isFoldableString (SILValue value, SILInstruction *definingInst,
287
+ ASTContext &astContext) {
288
+ assert (definingInst);
289
+ return isStringType (value->getType (), astContext) &&
290
+ !getStringMakeUTF8Init (definingInst);
291
+ }
292
+
293
+ // / Check whether a SILValue is foldable. String, integer, array and
294
+ // / function values are foldable with the following exceptions:
295
+ // / - Addresses cannot be folded.
296
+ // / - Literals need not be folded.
297
+ // / - Results of ownership instructions like load_borrow/copy_value need not
298
+ // / be folded
299
+ // / - Constructors such as \c struct Int or \c string.init() need not be folded.
283
300
static bool isSILValueFoldable (SILValue value) {
284
301
SILInstruction *definingInst = value->getDefiningInstruction ();
285
302
if (!definingInst)
286
303
return false ;
287
-
288
304
ASTContext &astContext = definingInst->getFunction ()->getASTContext ();
289
305
SILType silType = value->getType ();
290
-
291
- // Fold only SIL values of integer or string type that are not one of the
292
- // following: addresses, literals, instructions marking ownership access and
293
- // scope, copy_value (as its operand will be folded), struct creations, or
294
- // call to string literal initializer.
295
306
return (!silType.isAddress () && !isa<LiteralInst>(definingInst) &&
296
307
!isa<LoadBorrowInst>(definingInst) &&
297
308
!isa<BeginBorrowInst>(definingInst) &&
298
- !isa<CopyValueInst>(definingInst) && !isa<StructInst>(definingInst) &&
299
- ! getStringMakeUTF8Init ( definingInst) &&
300
- isIntegerOrStringType (silType, astContext));
309
+ !isa<CopyValueInst>(definingInst) &&
310
+ ( isFoldableIntOrBool (value, definingInst, astContext) ||
311
+ isFoldableString (value, definingInst, astContext) ));
301
312
}
302
313
303
314
// / Diagnose failure during evaluation of a call to a constant-evaluable
@@ -453,15 +464,15 @@ static Optional<SymbolicValue> collectConstants(FoldState &foldState) {
453
464
// / \param stringInfo String.init and metatype information for generating code
454
465
// / for string literals.
455
466
static SILValue emitCodeForSymbolicValue (SymbolicValue symVal,
456
- SILType & expectedType,
457
- SILBuilder &builder, SILLocation &loc,
467
+ Type expectedType, SILBuilder &builder ,
468
+ SILLocation &loc,
458
469
StringSILInfo &stringInfo) {
459
- ASTContext &astContext = expectedType. getASTContext ();
470
+ ASTContext &astContext = expectedType-> getASTContext ();
460
471
461
472
switch (symVal.getKind ()) {
462
473
case SymbolicValue::String: {
463
474
assert (astContext.getStringDecl () ==
464
- expectedType. getNominalOrBoundGenericNominal ());
475
+ expectedType-> getNominalOrBoundGenericNominal ());
465
476
466
477
StringRef stringVal = symVal.getStringValue ();
467
478
StringLiteralInst *stringLitInst = builder.createStringLiteral (
@@ -491,26 +502,34 @@ static SILValue emitCodeForSymbolicValue(SymbolicValue symVal,
491
502
}
492
503
case SymbolicValue::Integer: { // Builtin integer types.
493
504
APInt resInt = symVal.getIntegerValue ();
494
- assert (expectedType. is <BuiltinIntegerType>());
505
+ assert (expectedType-> is <BuiltinIntegerType>());
495
506
507
+ SILType builtinIntType =
508
+ SILType::getPrimitiveObjectType (expectedType->getCanonicalType ());
496
509
IntegerLiteralInst *intLiteralInst =
497
- builder.createIntegerLiteral (loc, expectedType , resInt);
510
+ builder.createIntegerLiteral (loc, builtinIntType , resInt);
498
511
return intLiteralInst;
499
512
}
500
513
case SymbolicValue::Aggregate: {
501
514
// Support only stdlib integer or bool structs.
502
- StructDecl *structDecl = expectedType. getStructOrBoundGenericStruct ();
515
+ StructDecl *structDecl = expectedType-> getStructOrBoundGenericStruct ();
503
516
assert (structDecl);
504
517
assert (isStdlibIntegerOrBoolDecl (structDecl, astContext));
518
+ assert (symVal.getAggregateType ()->isEqual (expectedType) &&
519
+ " aggregate symbolic value's type and expected type do not match" );
505
520
506
521
VarDecl *propertyDecl = structDecl->getStoredProperties ().front ();
507
- SILType propertyType =
508
- expectedType. getFieldType ( propertyDecl, builder. getModule () );
522
+ Type propertyType = expectedType-> getTypeOfMember (
523
+ propertyDecl-> getModuleContext (), propertyDecl );
509
524
SymbolicValue propertyVal = symVal.lookThroughSingleElementAggregates ();
510
525
SILValue newPropertySIL = emitCodeForSymbolicValue (
511
526
propertyVal, propertyType, builder, loc, stringInfo);
527
+ // The lowered SIL type of an integer/bool type is just the primitive
528
+ // object type containing the Swift type.
529
+ SILType aggregateType =
530
+ SILType::getPrimitiveObjectType (expectedType->getCanonicalType ());
512
531
StructInst *newStructInst = builder.createStruct (
513
- loc, expectedType , ArrayRef<SILValue>(newPropertySIL));
532
+ loc, aggregateType , ArrayRef<SILValue>(newPropertySIL));
514
533
return newStructInst;
515
534
}
516
535
default : {
@@ -684,7 +703,7 @@ static void substituteConstants(FoldState &foldState) {
684
703
685
704
SILBuilderWithScope builder (definingInst);
686
705
SILLocation loc = definingInst->getLoc ();
687
- SILType instType = constantSILValue->getType ();
706
+ CanType instType = constantSILValue->getType (). getASTType ();
688
707
SILValue foldedSILVal = emitCodeForSymbolicValue (
689
708
constantSymbolicVal, instType, builder, loc, foldState.stringInfo );
690
709
0 commit comments