@@ -270,17 +270,21 @@ static bool isScopeAffectingInstructionDead(SILInstruction *inst) {
270
270
return true ;
271
271
}
272
272
case SILInstructionKind::ApplyInst: {
273
- // Given a call to a function annotated as constant_evaluable, the call
274
- // will be removed as long as the following holds:
275
- // 1. If the call destroys its arguments: when removing the call, a destroy
276
- // of each argument is added.
277
- // 2. If the call returns a dead value i.e., a value that is only
278
- // destroyed: both the call and corresponding destroy will be removed.
279
- // Note that a value returned by a constant evaluable function must either
280
- // contain constant pure values (trivial instances or array/string
281
- // literals), or the arguments passed to the call. Given that its arguments
282
- // will be destroyed explicitly, it is okay to remove the destroys of the
283
- // return value of a constant evaluable function.
273
+ // The following property holds for constant evaluable functions:
274
+ // 1. they do not create objects having deinitializers with global
275
+ // side effects.
276
+ // 2. they do not use global variables and will only use objects reachable
277
+ // from parameters.
278
+ // The above two properties imply that a value returned by a constant
279
+ // evaluable function either does not have a deinitializer with global side
280
+ // effects, or if it does, the deinitializer that has the global side effect
281
+ // must be that of a parameter.
282
+ //
283
+ // A read-only constant evaluable call only reads and/or destroys its
284
+ // parameters. Therefore, if its return value is used only in destroys, the
285
+ // constant evaluable call can be removed provided the parameters it
286
+ // consumes are explicitly destroyed at the call site, which is taken care
287
+ // of by the function: \c deleteInstruction
284
288
FullApplySite applySite (cast<ApplyInst>(inst));
285
289
return isReadOnlyConstantEvaluableCall (applySite);
286
290
}
0 commit comments