@@ -725,64 +725,66 @@ static SILValue emitCodeForSymbolicValue(SymbolicValue symVal,
725725 assert (expectedType->is <AnyFunctionType>() ||
726726 expectedType->is <SILFunctionType>());
727727
728- SymbolicClosure *closure = symVal.getClosure ();
729- SubstitutionMap callSubstMap = closure->getCallSubstitutionMap ();
730728 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);
750760 }
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);
762768 }
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>();
773775 CanType expectedCanType = expectedType->getCanonicalType ();
774776 if (auto expectedFnType = dyn_cast<SILFunctionType>(expectedCanType)) {
775777 assert (expectedFnType->getUnsubstitutedType (module )
776778 == resultType->getUnsubstitutedType (module ));
777779 // Convert to the expected type if necessary.
778780 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 );
782784 return convert;
783785 }
784786 }
785- return papply ;
787+ return resultVal ;
786788 }
787789 default : {
788790 llvm_unreachable (" Symbolic value kind is not supported" );
0 commit comments