@@ -725,64 +725,66 @@ static SILValue emitCodeForSymbolicValue(SymbolicValue symVal,
725
725
assert (expectedType->is <AnyFunctionType>() ||
726
726
expectedType->is <SILFunctionType>());
727
727
728
- SymbolicClosure *closure = symVal.getClosure ();
729
- SubstitutionMap callSubstMap = closure->getCallSubstitutionMap ();
730
728
SILModule &module = builder.getModule ();
731
- ArrayRef<SymbolicClosureArgument> captures = closure->getCaptures ();
732
-
733
- // Recursively emit code for all captured values that are mapped to a
734
- // symbolic value. If there is a captured value that is not mapped
735
- // to a symbolic value, use the captured value as such (after possibly
736
- // copying non-trivial captures).
737
- SmallVector<SILValue, 4 > capturedSILVals;
738
- for (SymbolicClosureArgument capture : captures) {
739
- SILValue captureOperand = capture.first ;
740
- Optional<SymbolicValue> captureSymVal = capture.second ;
741
- if (!captureSymVal) {
742
- SILFunction &fun = builder.getFunction ();
743
- assert (captureOperand->getFunction () == &fun &&
744
- " non-constant captured arugment not defined in this function" );
745
- // If the captureOperand is a non-trivial value, it should be copied
746
- // as it now used in a new folded closure.
747
- SILValue captureCopy = makeOwnedCopyOfSILValue (captureOperand, fun);
748
- capturedSILVals.push_back (captureCopy);
749
- continue ;
729
+ SymbolicClosure *closure = symVal.getClosure ();
730
+ SILValue resultVal;
731
+ if (!closure->hasOnlyConstantCaptures ()) {
732
+ // If the closure captures a value that is not a constant, it should only
733
+ // come from the caller of the log call. Therefore, assert this and reuse
734
+ // the closure value.
735
+ SingleValueInstruction *originalClosureInst = closure->getClosureInst ();
736
+ SILFunction &fun = builder.getFunction ();
737
+ assert (originalClosureInst->getFunction () == &fun &&
738
+ " closure with non-constant captures not defined in this function" );
739
+ // Copy the closure, since the returned value must be owned.
740
+ resultVal = makeOwnedCopyOfSILValue (originalClosureInst, fun);
741
+ } else {
742
+ SubstitutionMap callSubstMap = closure->getCallSubstitutionMap ();
743
+ ArrayRef<SymbolicClosureArgument> captures = closure->getCaptures ();
744
+ // Recursively emit code for all captured values which must be mapped to a
745
+ // symbolic value.
746
+ SmallVector<SILValue, 4 > capturedSILVals;
747
+ for (SymbolicClosureArgument capture : captures) {
748
+ SILValue captureOperand = capture.first ;
749
+ Optional<SymbolicValue> captureSymVal = capture.second ;
750
+ assert (captureSymVal);
751
+ // Note that the captured operand type may have generic parameters which
752
+ // has to be substituted with the substitution map that was inferred by
753
+ // the constant evaluator at the partial-apply site.
754
+ SILType operandType = captureOperand->getType ();
755
+ SILType captureType = operandType.subst (module, callSubstMap);
756
+ SILValue captureSILVal = emitCodeForSymbolicValue (
757
+ captureSymVal.getValue (), captureType.getASTType (), builder, loc,
758
+ stringInfo);
759
+ capturedSILVals.push_back (captureSILVal);
750
760
}
751
- // Here, we have a symbolic value for the capture. Therefore, use it to
752
- // create a new constant at this point. Note that the captured operand
753
- // type may have generic parameters which has to be substituted with the
754
- // substitution map that was inferred by the constant evaluator at the
755
- // partial-apply site.
756
- SILType operandType = captureOperand->getType ();
757
- SILType captureType = operandType.subst (module, callSubstMap);
758
- SILValue captureSILVal = emitCodeForSymbolicValue (
759
- captureSymVal.getValue (), captureType.getASTType (), builder, loc,
760
- stringInfo);
761
- capturedSILVals.push_back (captureSILVal);
761
+ FunctionRefInst *functionRef =
762
+ builder.createFunctionRef (loc, closure->getTarget ());
763
+ SILType closureType = closure->getClosureType ();
764
+ ParameterConvention convention =
765
+ closureType.getAs <SILFunctionType>()->getCalleeConvention ();
766
+ resultVal = builder.createPartialApply (loc, functionRef, callSubstMap,
767
+ capturedSILVals, convention);
762
768
}
763
-
764
- FunctionRefInst *functionRef =
765
- builder.createFunctionRef (loc, closure->getTarget ());
766
- SILType closureType = closure->getClosureType ();
767
- ParameterConvention convention =
768
- closureType.getAs <SILFunctionType>()->getCalleeConvention ();
769
- PartialApplyInst *papply = builder.createPartialApply (
770
- loc, functionRef, callSubstMap, capturedSILVals, convention);
771
- // The type of the created closure must be a lowering of the expected type.
772
- auto resultType = papply->getType ().castTo <SILFunctionType>();
769
+ // If the expected type is a SILFunctionType convert the closure to the
770
+ // expected type using a convert_function instruction. Otherwise, if the
771
+ // expected type is AnyFunctionType, nothing needs to be done.
772
+ // Note that we cannot assert the lowering in the latter case, as that
773
+ // utility doesn't exist yet.
774
+ auto resultType = resultVal->getType ().castTo <SILFunctionType>();
773
775
CanType expectedCanType = expectedType->getCanonicalType ();
774
776
if (auto expectedFnType = dyn_cast<SILFunctionType>(expectedCanType)) {
775
777
assert (expectedFnType->getUnsubstitutedType (module)
776
778
== resultType->getUnsubstitutedType (module));
777
779
// Convert to the expected type if necessary.
778
780
if (expectedFnType != resultType) {
779
- auto convert = builder.createConvertFunction (loc, papply,
780
- SILType::getPrimitiveObjectType (expectedFnType),
781
- false );
781
+ auto convert = builder.createConvertFunction (
782
+ loc, resultVal, SILType::getPrimitiveObjectType (expectedFnType),
783
+ false );
782
784
return convert;
783
785
}
784
786
}
785
- return papply ;
787
+ return resultVal ;
786
788
}
787
789
default : {
788
790
llvm_unreachable (" Symbolic value kind is not supported" );
0 commit comments