Source code for psyclone.psyir.transformations.move_trans

# -----------------------------------------------------------------------------
# SPDX-FileCopyrightText: Copyright (c) 2017-2026 Science and Technology
#                         Facilities Council
# SPDX-License-Identifier: BSD-3-Clause
# See the full LICENSE file in the project root for details.
# -----------------------------------------------------------------------------
'''This module provides the MoveTrans transformation.'''

import warnings

from psyclone.psyGen import Transformation
from psyclone.psyir.nodes import Node
from psyclone.psyir.transformations.transformation_error import (
    TransformationError
)
from psyclone.utils import transformation_documentation_wrapper


[docs] @transformation_documentation_wrapper class MoveTrans(Transformation): '''Provides a transformation to move a node in the tree. For example: .. code-block :: python from psyclone.transformations import MoveTrans trans=MoveTrans() trans.apply(schedule.children[0], schedule.children[2], options = {"position":"after") Nodes may only be moved to a new location with the same parent and must not break any dependencies otherwise an exception is raised.''' def __str__(self): return "Move a node to a different location"
[docs] def validate(self, node: Node, location: Node, options=None, **kwargs): # pylint: disable=arguments-differ ''' validity checks for input arguments. :param node: the node to be moved. :param options: a dictionary with options for transformations. :type options: Optional[Dict[str, Any]] :param str options["position"]: either 'before' or 'after'. :raises TransformationError: if the given node is not an instance of :py:class:`psyclone.psyir.nodes.Node` :raises TransformationError: if the location is not valid. ''' if not options: self.validate_options(**kwargs) position = self.get_option("position", **kwargs) else: # TODO #2668: Deprecate options dictionary. position = options.get("position", "before") # Check that the first argument is a Node if not isinstance(node, Node): raise TransformationError( f"The node argument to {self.name} should be a Node but got " f"'{type(node).__name__}'." ) # Check new location conforms to any data dependencies # This also checks the location and position arguments if not node.is_valid_location(location, position=position): raise TransformationError( f"In {self.name}, data dependencies " f"forbid the move to the new location")
[docs] def apply(self, node: Node, location: Node, position: str = "before", options=None, **kwargs): '''Move the node represented by :py:obj:`node` before location :py:obj:`location` (which is also a node) by default and after if the optional `position` argument is set to 'after'. :param node: the node to be moved. :param location: node before or after which the given node should be moved. :param position: whether to place the moved node before or after the location. This must be 'before' or 'after'. :param options: a dictionary with options for transformations. :type options: Optional[Dict[str, Any]] :param str options["position"]: either 'before' or 'after'. :raises TransformationError: if the given node is not an instance of :py:class:`psyclone.psyir.nodes.Node` :raises TransformationError: if the location is not valid. ''' # pylint:disable=arguments-differ self.validate(node, location, options=options, position=position) if options: # TODO #2668: Deprecate options dictionary. position = options.get("position", "before") warnings.warn(self._deprecation_warning, DeprecationWarning, 2) parent = node.parent my_node = parent.children.pop(node.position) location_index = location.position if position == "before": location.parent.children.insert(location_index, my_node) else: location.parent.children.insert(location_index+1, my_node)
__all__ = ["MoveTrans"]