@@ -906,6 +906,15 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
906
906
traceMessage.c_str (), witness->getOriginalFunction ());
907
907
908
908
assert (witness->isDefinition ());
909
+ SILFunction *orig = witness->getOriginalFunction ();
910
+
911
+ // We can generate empty JVP / VJP for functions available externally. These
912
+ // functions have the same linkage as the original ones sans `external`
913
+ // flag. Important exception here hidden_external functions as they are
914
+ // serializable but corresponding hidden ones would be not and the SIL
915
+ // verifier will fail. Patch `serializeFunctions` for this case.
916
+ if (orig->getLinkage () == SILLinkage::HiddenExternal)
917
+ serializeFunctions = IsNotSerialized;
909
918
910
919
// If the JVP doesn't exist, need to synthesize it.
911
920
if (!witness->getJVP ()) {
@@ -914,9 +923,8 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
914
923
// - Functions with unsupported control flow.
915
924
if (context.getASTContext ()
916
925
.LangOpts .hasFeature (Feature::ForwardModeDifferentiation) &&
917
- (diagnoseNoReturn (context, witness->getOriginalFunction (), invoker) ||
918
- diagnoseUnsupportedControlFlow (
919
- context, witness->getOriginalFunction (), invoker)))
926
+ (diagnoseNoReturn (context, orig, invoker) ||
927
+ diagnoseUnsupportedControlFlow (context, orig, invoker)))
920
928
return true ;
921
929
922
930
// Create empty JVP.
@@ -933,10 +941,10 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
933
941
!witness->getVJP ()) {
934
942
// JVP and differential generation do not currently support functions with
935
943
// multiple basic blocks.
936
- if (witness-> getOriginalFunction () ->size () > 1 ) {
937
- context.emitNondifferentiabilityError (
938
- witness-> getOriginalFunction ()-> getLocation (). getSourceLoc () ,
939
- invoker, diag::autodiff_jvp_control_flow_not_supported);
944
+ if (orig ->size () > 1 ) {
945
+ context.emitNondifferentiabilityError (orig-> getLocation (). getSourceLoc (),
946
+ invoker ,
947
+ diag::autodiff_jvp_control_flow_not_supported);
940
948
return true ;
941
949
}
942
950
// Emit JVP function.
@@ -950,7 +958,7 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
950
958
" _fatalErrorForwardModeDifferentiationDisabled" );
951
959
LLVM_DEBUG (getADDebugStream ()
952
960
<< " Generated empty JVP for "
953
- << witness-> getOriginalFunction () ->getName () << " :\n "
961
+ << orig ->getName () << " :\n "
954
962
<< *jvp);
955
963
}
956
964
}
@@ -960,9 +968,8 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
960
968
// Diagnose:
961
969
// - Functions with no return.
962
970
// - Functions with unsupported control flow.
963
- if (diagnoseNoReturn (context, witness->getOriginalFunction (), invoker) ||
964
- diagnoseUnsupportedControlFlow (
965
- context, witness->getOriginalFunction (), invoker))
971
+ if (diagnoseNoReturn (context, orig, invoker) ||
972
+ diagnoseUnsupportedControlFlow (context, orig, invoker))
966
973
return true ;
967
974
968
975
// Create empty VJP.
0 commit comments