36 '''This module contains the FoldConditionalReturnExpressionsTrans. '''
46 ''' Provides a transformation that folds conditional expressions with only
47 a return statement inside so that the Return statement is moved to the end
48 of the Routine and therefore it can be safely removed. This simplifies the
49 control flow of the kernel to facilitate other transformations like kernel
50 fusions. For example, the following code:
52 .. code-block:: fortran
64 will be transformed to:
66 .. code-block:: fortran
69 if (.not.(i < 5)) then
70 if (.not.(i > 10)) then
79 return (
"Re-structure kernel statements to eliminate conditional "
80 "Return expressions.")
84 '''Returns the name of this transformation as a string.'''
85 return "FoldConditionalReturnExpressionsTrans"
88 '''Ensure that it is valid to apply this transformation to the
91 :param node: the node to validate.
92 :type node: :py:class:`psyclone.psyir.nodes.Routine`
93 :param options: a dictionary with options for transformations.
94 :type options: Optional[Dict[str, Any]]
96 :raises TransformationError: if the node is not a Routine.
99 if not isinstance(node, Routine):
101 f
"Error in {self.name} transformation. This transformation "
102 f
"can only be applied to 'Routine' nodes, but found "
103 f
"'{type(node).__name__}'.")
105 def apply(self, node, options=None):
106 '''Apply this transformation to the supplied node.
108 :param node: the node to transform.
109 :type node: :py:class:`psyclone.psyir.nodes.Routine`
110 :param options: a dictionary with options for transformations.
111 :type options: Optional[Dict[str, Any]]
117 def is_conditional_return(node):
119 :param node: node to evaluate.
120 :type node: :py:class:`psyclone.psyir.nodes.Node`
122 :returns: whether the given node represents a conditional return \
125 if not isinstance(node, IfBlock):
127 if node.else_body
is not None:
129 return isinstance(node.if_body[0], Return)
131 for statement
in routine[:]:
132 if is_conditional_return(statement):
134 new_condition = UnaryOperation.create(
135 UnaryOperation.Operator.NOT,
136 statement.condition.copy())
137 statement.children[0] = new_condition
140 statement.if_body.children = []
143 while len(statement.parent.children) > statement.position + 1:
144 move = statement.parent.children.pop()
145 statement.if_body.children.insert(0, move)
149 __all__ = [
'FoldConditionalReturnExpressionsTrans']