36 '''This module contains the base class LoopTrans. All transformations which
37 act on a loop sub-class this one.
44 import TransformationError
52 This abstract class is a base class for all transformations that act
53 on a Loop node. It gives access to a validate function that
54 makes sure that the supplied node is a Loop.
55 We also check that all nodes to be enclosed are valid for this
56 transformation - this requires that the sub-class populate the
57 `excluded_node_types` tuple.
62 excluded_node_types = ()
65 '''Checks that the supplied node is a valid target for a loop
68 :param node: target PSyIR node.
69 :type node: subclass of :py:class:`psyclone.psyir.nodes.Node`
70 :param options: a dictionary with options for transformations.
71 :type options: Optional[Dict[str, Any]]
72 :param bool options["node-type-check"]: this flag controls if the \
73 type of the nodes enclosed in the loop should be tested to \
74 avoid including unsupported nodes in a transformation.
76 :raises TransformationError: if the supplied node is not a (fully- \
78 :raises TransformationError: if any of the nodes within the loop are \
79 of an unsupported type.
80 :raises TransformationError: if the loop is of 'null' type.
81 :raises TransformationError: if the supplied options are not a \
86 if not isinstance(node, Loop):
87 raise TransformationError(
88 f
"Target of {self.name} transformation must be a sub-class of "
89 f
"Loop but got '{type(node).__name__}'")
92 if len(node.children) != 4:
93 raise TransformationError(
94 f
"Error in {self.name} transformation. The target loop "
95 f
"must have four children but found: "
96 f
"{[type(child).__name__ for child in node.children]}.")
100 if not isinstance(options, dict):
101 raise TransformationError(
102 f
"Transformation validate method 'options' argument must be a "
103 f
"dictionary but found '{type(options).__name__}'.")
106 if options.get(
"node-type-check",
True):
109 flat_list = [item
for item
in node.walk(object, stop_type=Kern)
110 if not isinstance(item, Schedule)]
111 for item
in flat_list:
113 raise TransformationError(
114 f
"Nodes of type '{type(item).__name__}' cannot be "
115 f
"enclosed by a {self.name} transformation")
128 if isinstance(node, PSyLoop)
and node.loop_type ==
'null':
129 raise TransformationError(
130 f
"Cannot apply a {self.name} transformation to a 'null' loop.")
135 :returns: the name of this class.
138 return self.__class__.__name__
142 __all__ = [
"LoopTrans"]