@@ -58,6 +58,26 @@ def __init__(self):
58
58
# (priority, node) pairs that need to recompute
59
59
self ._dirty_inflight_functions_with_order = SortedSet (key = lambda pair : pair [0 ])
60
60
61
+ def reachableInSet (self , rootIdentity , activeSet ):
62
+ """Produce the subset of 'activeSet' that are reachable from 'rootIdentity'"""
63
+ reachable = set ()
64
+
65
+ def walk (node ):
66
+ if node in reachable or node not in activeSet :
67
+ return
68
+
69
+ reachable .add (node )
70
+
71
+ for child in self ._dependencies .outgoing (node ):
72
+ walk (child )
73
+
74
+ walk (rootIdentity )
75
+
76
+ return reachable
77
+
78
+ def clearOutgoingEdgesFor (self , identity ):
79
+ self ._dependencies .clearOutgoing (identity )
80
+
61
81
def dropNode (self , node ):
62
82
self ._dependencies .dropNode (node , False )
63
83
if node in self ._identity_levels :
@@ -341,8 +361,7 @@ def defineNonPythonFunction(self, name, identityTuple, context):
341
361
if self ._currentlyConverting is None :
342
362
# force the function to resolve immediately
343
363
self ._resolveAllInflightFunctions ()
344
- self ._installInflightFunctions ()
345
- self ._inflight_function_conversions .clear ()
364
+ self ._installInflightFunctions (identity )
346
365
347
366
return self .getTarget (linkName )
348
367
@@ -540,6 +559,8 @@ def _resolveAllInflightFunctions(self):
540
559
541
560
# this calls back into convert with dependencies
542
561
# they get registered as dirty
562
+ self ._dependencies .clearOutgoingEdgesFor (identity )
563
+
543
564
nativeFunction , actual_output_type = functionConverter .convertToNativeFunction ()
544
565
545
566
if nativeFunction is not None :
@@ -900,7 +921,7 @@ def convert(
900
921
if isRoot :
901
922
try :
902
923
self ._resolveAllInflightFunctions ()
903
- self ._installInflightFunctions ()
924
+ self ._installInflightFunctions (identity )
904
925
return self .getTarget (name )
905
926
finally :
906
927
self ._inflight_function_conversions .clear ()
@@ -915,7 +936,7 @@ def convert(
915
936
raise RuntimeError (f"Unexpected conversion error for { name } " )
916
937
return None
917
938
918
- def _installInflightFunctions (self ):
939
+ def _installInflightFunctions (self , rootIdentity ):
919
940
"""Add all function definitions corresponding to keys in inflight_function_conversions to the relevant dictionaries."""
920
941
if VALIDATE_FUNCTION_DEFINITIONS_STABLE :
921
942
# this should always be true, but its expensive so we have it off by default
@@ -929,7 +950,17 @@ def _installInflightFunctions(self):
929
950
finally :
930
951
self ._currentlyConverting = None
931
952
953
+ # restrict to the set of inflight functions that are reachable from rootName
954
+ # we produce copies of functions that we don't actually need to compile during
955
+ # early phases of type inference
956
+ reachable = self ._dependencies .reachableInSet (
957
+ rootIdentity ,
958
+ set (self ._inflight_function_conversions )
959
+ )
960
+
932
961
for identifier , functionConverter in self ._inflight_function_conversions .items ():
962
+ if identifier not in reachable :
963
+ continue
933
964
outboundTargets = []
934
965
for outboundFuncId in self ._dependencies .getNamesDependedOn (identifier ):
935
966
name = self ._link_name_for_identity [outboundFuncId ]
@@ -987,3 +1018,6 @@ def _installInflightFunctions(self):
987
1018
988
1019
self ._definitions [name ] = nativeFunction
989
1020
self ._new_native_functions .add (name )
1021
+
1022
+ self ._inflight_definitions .clear ()
1023
+ self ._inflight_function_conversions .clear ()
0 commit comments