|
23 | 23 | import typed_python.compiler |
24 | 24 | import typed_python.compiler.native_ast as native_ast |
25 | 25 | from typed_python.compiler.native_function_pointer import NativeFunctionPointer |
26 | | -from sortedcontainers import SortedSet |
27 | | -from typed_python.compiler.directed_graph import DirectedGraph |
28 | 26 | from typed_python.compiler.type_wrappers.wrapper import Wrapper |
29 | 27 | from typed_python.compiler.type_wrappers.class_wrapper import ClassWrapper |
30 | 28 | from typed_python.compiler.python_object_representation import typedPythonTypeToTypeWrapper |
|
33 | 31 | from typed_python.compiler.type_wrappers.python_typed_function_wrapper import ( |
34 | 32 | PythonTypedFunctionWrapper, CannotBeDetermined, NoReturnTypeSpecified |
35 | 33 | ) |
| 34 | +from typed_python.compiler.function_dependency_graph import FunctionDependencyGraph |
36 | 35 | from typed_python.compiler.typed_call_target import TypedCallTarget |
37 | 36 |
|
38 | 37 | typeWrapper = lambda t: typed_python.compiler.python_object_representation.typedPythonTypeToTypeWrapper(t) |
|
41 | 40 | VALIDATE_FUNCTION_DEFINITIONS_STABLE = False |
42 | 41 |
|
43 | 42 |
|
44 | | -class FunctionDependencyGraph: |
45 | | - def __init__(self): |
46 | | - self._dependencies = DirectedGraph() |
47 | | - |
48 | | - # the search depth in the dependency to find 'identity' |
49 | | - # the _first_ time we ever saw it. We prefer to update |
50 | | - # nodes with higher search depth, so we don't recompute |
51 | | - # earlier nodes until their children are complete. |
52 | | - self._identity_levels = {} |
53 | | - |
54 | | - # nodes that need to recompute |
55 | | - self._dirty_inflight_functions = set() |
56 | | - |
57 | | - # (priority, node) pairs that need to recompute |
58 | | - self._dirty_inflight_functions_with_order = SortedSet(key=lambda pair: pair[0]) |
59 | | - |
60 | | - def dropNode(self, node): |
61 | | - self._dependencies.dropNode(node, False) |
62 | | - if node in self._identity_levels: |
63 | | - del self._identity_levels[node] |
64 | | - self._dirty_inflight_functions.discard(node) |
65 | | - |
66 | | - def getNextDirtyNode(self): |
67 | | - while self._dirty_inflight_functions_with_order: |
68 | | - priority, identity = self._dirty_inflight_functions_with_order.pop() |
69 | | - |
70 | | - if identity in self._dirty_inflight_functions: |
71 | | - self._dirty_inflight_functions.discard(identity) |
72 | | - |
73 | | - return identity |
74 | | - |
75 | | - def addRoot(self, identity): |
76 | | - if identity not in self._identity_levels: |
77 | | - self._identity_levels[identity] = 0 |
78 | | - self.markDirty(identity) |
79 | | - |
80 | | - def addEdge(self, caller, callee): |
81 | | - if caller not in self._identity_levels: |
82 | | - raise Exception(f"unknown identity {caller} found in the graph") |
83 | | - |
84 | | - if callee not in self._identity_levels: |
85 | | - self._identity_levels[callee] = self._identity_levels[caller] + 1 |
86 | | - |
87 | | - self.markDirty(callee, isNew=True) |
88 | | - |
89 | | - self._dependencies.addEdge(caller, callee) |
90 | | - |
91 | | - def getNamesDependedOn(self, caller): |
92 | | - return self._dependencies.outgoing(caller) |
93 | | - |
94 | | - def markDirtyWithLowPriority(self, callee): |
95 | | - # mark this dirty, but call it back after new functions. |
96 | | - self._dirty_inflight_functions.add(callee) |
97 | | - |
98 | | - level = self._identity_levels[callee] |
99 | | - self._dirty_inflight_functions_with_order.add((-1000000 + level, callee)) |
100 | | - |
101 | | - def markDirty(self, callee, isNew=False): |
102 | | - self._dirty_inflight_functions.add(callee) |
103 | | - |
104 | | - if isNew: |
105 | | - # if its a new node, compute it with higher priority the _higher_ it is in the stack |
106 | | - # so that we do a depth-first search on the way down |
107 | | - level = 1000000 - self._identity_levels[callee] |
108 | | - else: |
109 | | - level = self._identity_levels[callee] |
110 | | - |
111 | | - self._dirty_inflight_functions_with_order.add((level, callee)) |
112 | | - |
113 | | - def functionReturnSignatureChanged(self, identity): |
114 | | - for caller in self._dependencies.incoming(identity): |
115 | | - self.markDirty(caller) |
116 | | - |
117 | | - |
118 | 43 | class PythonToNativeConverter: |
119 | 44 | def __init__(self, llvmCompiler, compilerCache): |
120 | 45 | object.__init__(self) |
|
0 commit comments