Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/psyclone/domain/common/psylayer/global_reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
''' This module provides the GlobalReduction base class. '''

import copy
from typing import List

from psyclone.configuration import Config
from psyclone.core import AccessType
Expand Down Expand Up @@ -82,3 +83,21 @@ def args(self) -> list[KernelArgument]:
''':returns: the list of arguments associated with this node. Override
the base method and simply return our argument.'''
return [self._scalar]

def next_accesses(self) -> List[Node]:
'''
next_accesses on base GlobalReduction class just uses the base
Statement implementation, returning an empty list.

:returns: an empty list.
'''
return super().next_accesses()

def previous_accesses(self) -> List[Node]:
'''
previous_accesses on base GlobalReduction class just uses the base
Statement implementation, returning an empty list.

:returns: an empty list.
'''
return super().previous_accesses()
36 changes: 36 additions & 0 deletions src/psyclone/psyGen.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,24 @@ def node_str(self, colour=True):
f"type='{self._halo_type}', depth={self._halo_depth}, "
f"check_dirty={self._check_dirty}]")

def next_accesses(self) -> list[Node]:
'''
next_accesses on base HaloExchange class just uses the base Statement
implementation, returning an empty list.

:returns: an empty list.
'''
return super().next_accesses()

def previous_accesses(self) -> list[Node]:
'''
previous_accesses on base HaloExchange class just uses the base
Statement implementation, returning an empty list.

:returns: an empty list.
'''
return super().previous_accesses()


class Kern(Statement):
'''Base class representing a call to a sub-program unit from within the
Expand Down Expand Up @@ -1131,6 +1149,24 @@ def lower_to_language_level(self):

return super().lower_to_language_level()

def next_accesses(self) -> list[Node]:
'''
next_accesses on base Kern class just uses the base Statement
implementation, returning an empty list.

:returns: an empty list.
'''
return super().next_accesses()

def previous_accesses(self) -> list[Node]:
'''
previous_accesses on base Kern class just uses the base Statement
implementation, returning an empty list.

:returns: an empty list.
'''
return super().previous_accesses()


class CodedKern(Kern):
'''
Expand Down
24 changes: 18 additions & 6 deletions src/psyclone/psyir/nodes/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

''' This module contains the Assignment node implementation.'''

from psyclone.core import VariablesAccessMap, AccessType, Signature
from psyclone.core import VariablesAccessMap, AccessType
from psyclone.errors import InternalError
from psyclone.psyir.nodes.literal import Literal
from psyclone.psyir.nodes.array_reference import ArrayReference
Expand Down Expand Up @@ -213,7 +213,7 @@ def is_literal_assignment(self):
'''
return isinstance(self.rhs, Literal)

def previous_accesses(self) -> dict[Signature, list[Node]]:
def previous_accesses(self) -> list[Node]:
'''
:returns: the nodes containing the previous accesses of the symbols
accessed within this node. It can be multiple nodes for
Expand All @@ -229,9 +229,15 @@ def previous_accesses(self) -> dict[Signature, list[Node]]:
# pylint: disable=import-outside-toplevel
from psyclone.psyir.tools import DefinitionUseChain
chain = DefinitionUseChain(refs)
return chain.find_backward_accesses()

def next_accesses(self) -> dict[Signature, list[Node]]:
accesses = chain.find_backward_accesses()
results = []
for sig in accesses:
for access in accesses[sig]:
if all(x is not access for x in results):
results.append(access)
return results

def next_accesses(self) -> list[Node]:
'''
:returns: the nodes containing the next accesses of the symbols
accessed within this node. It can be multiple nodes for
Expand All @@ -247,4 +253,10 @@ def next_accesses(self) -> dict[Signature, list[Node]]:
# pylint: disable=import-outside-toplevel
from psyclone.psyir.tools import DefinitionUseChain
chain = DefinitionUseChain(refs)
return chain.find_forward_accesses()
accesses = chain.find_forward_accesses()
results = []
for sig in accesses:
for access in accesses[sig]:
if all(x is not access for x in results):
results.append(access)
return results
45 changes: 40 additions & 5 deletions src/psyclone/psyir/nodes/call.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from __future__ import annotations

from collections.abc import Iterable
from typing import List, Tuple, Union, Optional
from typing import Tuple, Union, Optional

from psyclone.configuration import Config
from psyclone.core import AccessType, VariablesAccessMap
Expand All @@ -20,6 +20,7 @@
from psyclone.psyir.nodes.container import Container
from psyclone.psyir.nodes.statement import Statement
from psyclone.psyir.nodes.datanode import DataNode
from psyclone.psyir.nodes.node import Node
from psyclone.psyir.nodes.reference import Reference
from psyclone.psyir.nodes.routine import Routine
from psyclone.psyir.symbols import (
Expand Down Expand Up @@ -502,7 +503,7 @@ def copy(self):

return new_copy

def get_callees(self) -> List[Routine]:
def get_callees(self) -> list[Routine]:
'''
Searches for the implementation(s) of all potential target routines
for this Call. It does *not* attempt to resolve static polymorphism
Expand Down Expand Up @@ -758,7 +759,7 @@ def type_symbols_match(type1: Union[DataTypeSymbol, DataType],
f"'{routine_arg_str}' ({dummy_type})"
)

def get_argument_map(self, routine: Routine) -> List[int]:
def get_argument_map(self, routine: Routine) -> list[int]:
'''Return a list of indices mapping from each argument of this
call to the corresponding entry in the argument list of the
supplied routine.
Expand All @@ -774,7 +775,7 @@ def get_argument_map(self, routine: Routine) -> List[int]:
'''
# Create a copy of the list of actual arguments to the routine.
# Once an argument has been successfully matched, set it to 'None'
routine_argument_list: List[DataSymbol] = (
routine_argument_list: list[DataSymbol] = (
routine.symbol_table.argument_list[:]
)

Expand Down Expand Up @@ -859,7 +860,7 @@ def get_argument_map(self, routine: Routine) -> List[int]:
def get_callee(
self,
use_first_callee_and_no_arg_check: bool = False
) -> Tuple[Routine, List[int]]:
) -> Tuple[Routine, list[int]]:
'''
Searches for the implementation(s) of the target routine for this Call
including argument checks.
Expand Down Expand Up @@ -911,3 +912,37 @@ def get_callee(
f"No matching routine found for '{call_str}':"
"\n" + error_msg
)

def next_accesses(self) -> list[Node]:
'''
:returns: the next_accesses of children of this Call.
'''
# Avoid circular import
# pylint: disable=import-outside-toplevel
from psyclone.psyir.tools import DefinitionUseChain
next_accesses = []
# Find all the children references
refs = [ref for ref in self.walk(Reference) if not
isinstance(ref.symbol, RoutineSymbol)]
chain = DefinitionUseChain(refs)
access_dict = chain.find_forward_accesses()
for access in access_dict:
self._merge_accesses(next_accesses, access_dict[access])
return next_accesses

def previous_accesses(self) -> list[Node]:
'''
:returns: the previous_accesses of children of this Call.
'''
# Avoid circular import
# pylint: disable=import-outside-toplevel
from psyclone.psyir.tools import DefinitionUseChain
prev_accesses = []
# Find all the children references
refs = [ref for ref in self.walk(Reference) if not
isinstance(ref.symbol, RoutineSymbol)]
chain = DefinitionUseChain(refs)
access_dict = chain.find_backward_accesses()
for access in access_dict:
self._merge_accesses(prev_accesses, access_dict[access])
return prev_accesses
30 changes: 30 additions & 0 deletions src/psyclone/psyir/nodes/codeblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,36 @@ def get_fortran_lines(self) -> list[str]:
return []
raise NotImplementedError("Use appropriate CodeBlock subclass")

def next_accesses(self) -> list[Node]:
'''
:returns: the next_accesses for the child References of this
CodeBlock.
'''
# Avoid circular import
# pylint: disable=import-outside-toplevel
from psyclone.psyir.tools import DefinitionUseChain
next_accesses = []
chain = DefinitionUseChain(self.children)
accesses = chain.find_forward_accesses()
for access in accesses:
self._merge_accesses(next_accesses, accesses[access])
return next_accesses

def previous_accesses(self) -> list[Node]:
'''
:returns: the previous_accesses for the child References of this
CodeBlock.
'''
# Avoid circular import
# pylint: disable=import-outside-toplevel
from psyclone.psyir.tools import DefinitionUseChain
prev_accesses = []
chain = DefinitionUseChain(self.children)
accesses = chain.find_backward_accesses()
for access in accesses:
self._merge_accesses(prev_accesses, accesses[access])
return prev_accesses


class Fparser2CodeBlock(CodeBlock):
''' The fparser2 implementation of CodeBlock. '''
Expand Down
17 changes: 17 additions & 0 deletions src/psyclone/psyir/nodes/directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from psyclone.psyir.nodes.array_of_structures_reference import (
ArrayOfStructuresReference)
from psyclone.psyir.nodes.clause import Clause
from psyclone.psyir.nodes.node import Node
from psyclone.psyir.nodes.reference import Reference
from psyclone.psyir.nodes.schedule import Schedule
from psyclone.psyir.nodes.statement import Statement
Expand Down Expand Up @@ -147,6 +148,22 @@ def create_data_movement_deep_copy_refs(self):
*base_args, members)
return read_only, write_only, readwrites

def next_accesses(self) -> list[Node]:
'''
Directive classes don't have next_accesses to compute.

:returns: an empty list.
'''
return []

def previous_accesses(self) -> list[Node]:
'''
Directive classes don't have previous_accesses to compute.

:returns: an empty list.
'''
return []


class RegionDirective(Directive):
'''
Expand Down
39 changes: 39 additions & 0 deletions src/psyclone/psyir/nodes/if_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from psyclone.core import VariablesAccessMap
from psyclone.errors import InternalError, GenerationError
from psyclone.psyir.nodes.datanode import DataNode
from psyclone.psyir.nodes.node import Node
from psyclone.psyir.nodes.reference import Reference
from psyclone.psyir.nodes.schedule import Schedule
from psyclone.psyir.nodes.statement import Statement

Expand Down Expand Up @@ -164,3 +166,40 @@ def reference_accesses(self) -> VariablesAccessMap:
if self.else_body:
var_accesses.update(self.else_body.reference_accesses())
return var_accesses

def next_accesses(self) -> list[Node]:
'''
:returns: the combined next_accesses for the children of this IfBlock.
'''
next_accesses = []
# Find all the next_accesses for the References in the condition.
for ref in self.condition.walk(Reference):
new_accesses = ref.next_accesses()
self._merge_accesses(next_accesses, new_accesses)
for child in self.if_body:
self._merge_accesses(next_accesses, child.next_accesses())
if self.else_body:
for child in self.else_body:
self._merge_accesses(next_accesses, child.next_accesses())

# FIXME Should we sort the output in some way?
return next_accesses

def previous_accesses(self) -> list[Node]:
'''
:returns: the combined previous_accesses for the children of this
IfBlock.
'''
prev_accesses = []
# Find all the next_accesses for the References in the condition.
for ref in self.condition.walk(Reference):
new_accesses = ref.previous_accesses()
self._merge_accesses(prev_accesses, new_accesses)
for child in self.if_body:
self._merge_accesses(prev_accesses, child.previous_accesses())
if self.else_body:
for child in self.else_body:
self._merge_accesses(prev_accesses, child.previous_accesses())

# FIXME Should we sort the output in some way?
return prev_accesses
30 changes: 30 additions & 0 deletions src/psyclone/psyir/nodes/loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from psyclone.core import VariablesAccessMap
from psyclone.psyir.nodes.datanode import DataNode
from psyclone.psyir.nodes.node import Node
from psyclone.psyir.nodes.statement import Statement
from psyclone.psyir.nodes.routine import Routine
from psyclone.psyir.nodes.reference import Reference
Expand Down Expand Up @@ -513,3 +514,32 @@ def enters_scope(self, scope, visited_nodes=None) -> bool:
'''
# pylint: disable=unused-argument
return False

def next_accesses(self) -> list[Node]:
'''
:returns: the combined next_accesses for the children of this Loop.
'''
next_accesses = []
# Loop through the non loop_body children and compute accesses.
for child in self.children[0:4]:
for ref in child.walk(Reference):
var_accesses = ref.next_accesses()
self._merge_accesses(next_accesses, var_accesses)
for child in self.loop_body:
self._merge_accesses(next_accesses, child.next_accesses())
return next_accesses

def previous_accesses(self) -> list[Node]:
'''
:returns: the combined previous_accesses for the children of this
Loop.
'''
prev_accesses = []
# Loop through the non loop_body children and compute accesses.
for child in self.children[0:4]:
for ref in child.walk(Reference):
var_accesses = ref.previous_accesses()
self._merge_accesses(prev_accesses, var_accesses)
for child in self.loop_body:
self._merge_accesses(prev_accesses, child.previous_accesses())
return prev_accesses
13 changes: 13 additions & 0 deletions src/psyclone/psyir/nodes/psy_data_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,19 @@ def gen_type_bound_call(typename, methodname, argument_list=None,
self.detach()
return self.parent

def next_accesses(self) -> list[Node]:
'''
:returns: an empty list as next_accesses isn't needed for PSyDataNode.
'''
return []

def previous_accesses(self) -> list[Node]:
'''
:returns: an empty list as previous_accesses isn't needed for
PSyDataNode.
'''
return []


# For AutoAPI documentation generation
__all__ = ['PSyDataNode']
Loading
Loading