From f3b75237e04a980d8a67b54bbdae1de1c67b2f00 Mon Sep 17 00:00:00 2001 From: SCHREIBER Martin Date: Tue, 10 Feb 2026 22:33:01 +0100 Subject: [PATCH 1/4] Minor updates to DefUseChains --- .../psyir/tools/definition_use_chains.py | 27 +++++++++++--- ...tion_use_chains_forward_dependence_test.py | 35 +++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/psyclone/psyir/tools/definition_use_chains.py b/src/psyclone/psyir/tools/definition_use_chains.py index d2cdfd7a26..b2285b4fe5 100644 --- a/src/psyclone/psyir/tools/definition_use_chains.py +++ b/src/psyclone/psyir/tools/definition_use_chains.py @@ -90,6 +90,7 @@ def __init__( control_flow_region=None, start_point=None, stop_point=None, + stop_at_call=True, ): if not isinstance(reference, Reference): raise TypeError( @@ -116,6 +117,7 @@ def __init__( ) self._start_point = start_point self._stop_point = stop_point + self._stop_at_call = stop_at_call if control_flow_region is None: self._scope = [reference.ancestor(Routine)] if self._scope[0] is None: @@ -264,6 +266,7 @@ def find_forward_accesses(self): body, start_point=ancestor.abs_position, stop_point=sub_stop_point, + stop_at_call=self._stop_at_call ) chains.insert(0, chain) # If its a while loop, create a basic block for the while @@ -276,6 +279,7 @@ def find_forward_accesses(self): [ancestor.condition], start_point=ancestor.abs_position, stop_point=sub_stop_point, + stop_at_call=self._stop_at_call ) chains.insert(0, chain) ancestor = ancestor.ancestor((Loop, WhileLoop)) @@ -298,6 +302,7 @@ def find_forward_accesses(self): [ancestor.lhs], start_point=ancestor.lhs.abs_position - 1, stop_point=ancestor.lhs.abs_position + 1, + stop_at_call=self._stop_at_call ) control_flow_nodes.append(None) chains.append(chain) @@ -317,6 +322,7 @@ def find_forward_accesses(self): block, start_point=self._start_point, stop_point=self._stop_point, + stop_at_call=self._stop_at_call ) chains.append(chain) for i, chain in enumerate(chains): @@ -394,6 +400,7 @@ def find_forward_accesses(self): [ancestor.lhs], start_point=ancestor.lhs.abs_position - 1, stop_point=ancestor.lhs.abs_position + 1, + stop_at_call=self._stop_at_call ) # Find any forward_accesses in the lhs. chain.find_forward_accesses() @@ -509,11 +516,16 @@ def _compute_forward_uses(self, basic_block_list): # catch the arguments that are passed into the call # later as References. continue - # For now just assume calls are bad if we have a non-local - # variable and we treat them as though they were a write. - if defs_out is not None: - self._killed.append(defs_out) - defs_out = reference + + if self._stop_at_call: + # For now just assume calls are bad if we have a non-local + # variable and we treat them as though they were a write. + if defs_out is not None: + self._killed.append(defs_out) + + defs_out = reference + else: + self._uses.append(reference) continue elif reference.get_signature_and_indices()[0] == sig: # Work out if its read only or not. @@ -911,6 +923,7 @@ def find_backward_accesses(self): block, start_point=self._start_point, stop_point=self._stop_point, + stop_at_call=self._stop_at_call ) chains.append(chain) # If this is the top level access, we need to check if the @@ -950,6 +963,7 @@ def find_backward_accesses(self): body, start_point=sub_start_point, stop_point=sub_stop_point, + stop_at_call=self._stop_at_call ) chains.append(chain) control_flow_nodes.append(ancestor) @@ -963,6 +977,7 @@ def find_backward_accesses(self): [ancestor.condition], start_point=ancestor.abs_position, stop_point=sub_stop_point, + stop_at_call=self._stop_at_call ) chains.append(chain) ancestor = ancestor.ancestor((Loop, WhileLoop)) @@ -981,6 +996,7 @@ def find_backward_accesses(self): ancestor.rhs.children[:], start_point=ancestor.rhs.abs_position, stop_point=end.abs_position, + stop_at_call=self._stop_at_call ) control_flow_nodes.append(None) chains.append(chain) @@ -1070,6 +1086,7 @@ def find_backward_accesses(self): [ancestor.rhs], start_point=ancestor.rhs.abs_position, stop_point=sys.maxsize, + stop_at_call=self._stop_at_call ) # Find any backward_accesses in the rhs. chain.find_backward_accesses() diff --git a/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py b/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py index 0c9c15f45f..074c464552 100644 --- a/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py +++ b/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py @@ -1159,3 +1159,38 @@ def test_definition_use_chain_find_forward_accesses_pure_call( # result is first argument of the pure subroutine call argument = routine.walk(Call)[0].children[1] assert reaches[0] is argument + + +def test_definition_use_chain_find_forward_accesses_continue_at_call( + fortran_reader, +): + """Functionality test for the find_forward_accesses routine. This + tests the behaviour for a pure subrotuine call.""" + code = """ + subroutine x(a, b) + integer, intent(inout) :: a, b + a = 2 + b = 1 + b = 1+a ! Stops dependency + call foo(b) + a = a + 2 + call bar(b) + a = a + 3 + end subroutine""" + psyir = fortran_reader.psyir_from_source(code) + routine = psyir.walk(Routine)[0] + + # Start from 'a' + ref_a = routine.walk(Assignment)[0].lhs + chains = DefinitionUseChain(ref_a) + reaches = chains.find_forward_accesses() + + assert len(reaches) == 2 + assert isinstance(reaches[1], Call) + + ref_a = routine.walk(Assignment)[0].lhs + chains = DefinitionUseChain(ref_a, stop_at_call=False) + reaches = chains.find_forward_accesses() + + assert len(reaches) == 5 + assert isinstance(reaches[1], Call) From 06f686f2ba26e99c95dd1fcf17abd6f5663b39ab Mon Sep 17 00:00:00 2001 From: SCHREIBER Martin Date: Tue, 10 Feb 2026 22:34:03 +0100 Subject: [PATCH 2/4] some minor updates to support following references beyond calls --- src/psyclone/psyir/tools/definition_use_chains.py | 1 + .../psyir/tools/definition_use_chains_forward_dependence_test.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/psyclone/psyir/tools/definition_use_chains.py b/src/psyclone/psyir/tools/definition_use_chains.py index b2285b4fe5..4ac99c718f 100644 --- a/src/psyclone/psyir/tools/definition_use_chains.py +++ b/src/psyclone/psyir/tools/definition_use_chains.py @@ -32,6 +32,7 @@ # POSSIBILITY OF SUCH DAMAGE. # ----------------------------------------------------------------------------- # Author: A. B. G. Chalk, STFC Daresbury Lab +# Minor contributions: M. Schreiber, Univ. Grenoble Alpes # ----------------------------------------------------------------------------- """This module contains the DefinitionUseChain class""" diff --git a/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py b/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py index 074c464552..d9a7bcd675 100644 --- a/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py +++ b/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py @@ -32,6 +32,7 @@ # POSSIBILITY OF SUCH DAMAGE. # ----------------------------------------------------------------------------- # Author: A. B. G. Chalk, STFC Daresbury Lab +# Minor contributions: M. Schreiber, Univ. Grenoble Alpes # ----------------------------------------------------------------------------- '''This module contains the tests for the DefinitionUseChain class's forward_accesses routine.''' From c0c9c8860633ba894ff88d6a58c6263f1d618a60 Mon Sep 17 00:00:00 2001 From: SCHREIBER Martin Date: Tue, 10 Feb 2026 22:50:10 +0100 Subject: [PATCH 3/4] update for flake8 --- src/psyclone/psyir/tools/definition_use_chains.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/psyclone/psyir/tools/definition_use_chains.py b/src/psyclone/psyir/tools/definition_use_chains.py index 4ac99c718f..2c7c5d4582 100644 --- a/src/psyclone/psyir/tools/definition_use_chains.py +++ b/src/psyclone/psyir/tools/definition_use_chains.py @@ -519,8 +519,9 @@ def _compute_forward_uses(self, basic_block_list): continue if self._stop_at_call: - # For now just assume calls are bad if we have a non-local - # variable and we treat them as though they were a write. + # For now just assume calls are bad if we have a + # non-local variable and we treat them as though + # they were a write. if defs_out is not None: self._killed.append(defs_out) From 06e0e37ad6e5700a806d807967dbf3649c9b5954 Mon Sep 17 00:00:00 2001 From: SCHREIBER Martin Date: Wed, 4 Mar 2026 17:44:48 +0100 Subject: [PATCH 4/4] cleanups --- ...ion_use_chains_backward_dependence_test.py | 36 +++++++++++++++++++ ...tion_use_chains_forward_dependence_test.py | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py b/src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py index 07397c34b7..10afe526d1 100644 --- a/src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py +++ b/src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py @@ -820,3 +820,39 @@ def test_definition_use_chain_find_backward_accesses_pure_call( assert len(reaches) == 1 # We should find the argument in the pure subroutine call assert reaches[0] is routine.walk(Call)[0].children[1] + + +def test_definition_use_chain_find_backward_accesses_continue_at_call( + fortran_reader, +): + """Functionality test for the find_backward_accesses routine. This + tests the behaviour for a pure subrotuine call.""" + code = """ + subroutine x(a, b) + integer, intent(inout) :: a, b, c + a = 2 + b = 1 + call foo(b) + a = a + 2 + b = 3 + a + call bar(b) + c = 2 + a + b = 1 + a ! Stops dependency + end subroutine""" + psyir = fortran_reader.psyir_from_source(code) + routine = psyir.walk(Routine)[0] + + # Start from last assignment 'a' + ref_a = routine.walk(Assignment)[-1].rhs.children[1] + chains = DefinitionUseChain(ref_a) + reaches = chains.find_backward_accesses() + + assert len(reaches) == 2 + assert isinstance(reaches[1], Call) + + ref_a = routine.walk(Assignment)[0].lhs + chains = DefinitionUseChain(ref_a, stop_at_call=False) + reaches = chains.find_forward_accesses() + + assert len(reaches) == 4 + assert isinstance(reaches[2], Call) diff --git a/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py b/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py index d9a7bcd675..b699d2ca29 100644 --- a/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py +++ b/src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py @@ -1172,7 +1172,7 @@ def test_definition_use_chain_find_forward_accesses_continue_at_call( integer, intent(inout) :: a, b a = 2 b = 1 - b = 1+a ! Stops dependency + b = 1 + a ! Stops dependency call foo(b) a = a + 2 call bar(b)