diff options
author | Dan Moldovan <mdan@google.com> | 2018-10-09 09:34:47 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-10-09 09:53:26 -0700 |
commit | 3ef35b81fd753401e3d69989b3bd1146749cc3b3 (patch) | |
tree | 3db4c4f9fdfaa85f5f7907f5fb0a2ad5bafb45ad /tensorflow/python/autograph/pyct/static_analysis/liveness.py | |
parent | 5d6adc910b8323b73a61d3089f3a3028be411e90 (diff) |
Include live-in symbols in liveness analysis. These are required for control flow conversion.
PiperOrigin-RevId: 216370439
Diffstat (limited to 'tensorflow/python/autograph/pyct/static_analysis/liveness.py')
-rw-r--r-- | tensorflow/python/autograph/pyct/static_analysis/liveness.py | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/tensorflow/python/autograph/pyct/static_analysis/liveness.py b/tensorflow/python/autograph/pyct/static_analysis/liveness.py index 41c903beb9..36960d0103 100644 --- a/tensorflow/python/autograph/pyct/static_analysis/liveness.py +++ b/tensorflow/python/autograph/pyct/static_analysis/liveness.py @@ -14,8 +14,13 @@ # ============================================================================== """Live variable analysis. -This analysis attaches a set containing the live symbols that are live at the -exit of control flow statements. +See https://en.wikipedia.org/wiki/Live_variable_analysis for a definition of +the following idioms: live variable, live in, live out, which are used +throughout this file. + +This analysis attaches the following: + * symbols that are live at the exit of control flow statements + * symbols that are live at the entry of control flow statements Requires activity analysis. """ @@ -164,23 +169,34 @@ class Annotator(transformer.Base): self.current_analyzer = parent_analyzer return node - def _aggregate_successors_live_in(self, node): + def _block_statement_live_out(self, node): successors = self.current_analyzer.graph.stmt_next[node] - node_live_out = set() + stmt_live_out = set() for s in successors: - node_live_out.update(self.current_analyzer.in_[s]) - anno.setanno(node, anno.Static.LIVE_VARS_OUT, frozenset(node_live_out)) - node = self.generic_visit(node) + stmt_live_out.update(self.current_analyzer.in_[s]) + anno.setanno(node, anno.Static.LIVE_VARS_OUT, frozenset(stmt_live_out)) + return node + + def _block_statement_live_in(self, node, entry_node): + cfg_node = self.current_analyzer.graph.index[entry_node] + stmt_live_in = frozenset(self.current_analyzer.in_[cfg_node]) + anno.setanno(node, anno.Static.LIVE_VARS_IN, stmt_live_in) return node def visit_If(self, node): - return self._aggregate_successors_live_in(node) + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.test) def visit_For(self, node): - return self._aggregate_successors_live_in(node) + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.iter) def visit_While(self, node): - return self._aggregate_successors_live_in(node) + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.test) def resolve(node, source_info, graphs): |