psyclone.psyir.transformations.inline_trans#
This module contains the InlineTrans transformation.
Classes#
InlineTrans: This transformation takes a Call (which may have a return value)
- class psyclone.psyir.transformations.inline_trans.InlineTrans[source]#
This transformation takes a Call (which may have a return value) and replaces it with the body of the target routine. It is used as follows:
>>> from psyclone.psyir.backend.fortran import FortranWriter >>> from psyclone.psyir.frontend.fortran import FortranReader >>> from psyclone.psyir.nodes import Call, Routine >>> from psyclone.psyir.transformations import InlineTrans >>> code = """ ... module test_mod ... contains ... subroutine run_it() ... integer :: i ... real :: a(10) ... do i=1,10 ... a(i) = 1.0 ... call sub(a(i)) ... end do ... end subroutine run_it ... subroutine sub(x) ... real, intent(inout) :: x ... x = 2.0*x ... end subroutine sub ... end module test_mod""" >>> psyir = FortranReader().psyir_from_source(code) >>> call = psyir.walk(Call)[0] >>> inline_trans = InlineTrans() >>> inline_trans.apply(call) >>> # Uncomment the following line to see a text view of the schedule >>> # print(psyir.walk(Routine)[0].view()) >>> print(FortranWriter()(psyir.walk(Routine)[0])) subroutine run_it() integer :: i real, dimension(10) :: a do i = 1, 10, 1 a(i) = 1.0 a(i) = 2.0 * a(i) enddo end subroutine run_it
The target of the call must already be present in the same Container (module) as the call site. This may be achieved using KernelModuleInlineTrans.
Warning
Routines/calls with any of the following characteristics are not supported and will result in a TransformationError:
the routine contains an early Return statement;
the routine contains a variable with UnknownInterface;
the routine contains a variable with StaticInterface;
the routine contains an UnsupportedType variable with ArgumentInterface;
the shape of any array arguments as declared inside the routine does not match the shape of the arrays being passed as arguments;
the routine accesses an un-resolved symbol;
the routine accesses a symbol declared in the Container to which it belongs.
Some of these restrictions will be lifted by #924.
Inheritance

- apply(node, routine=None, use_first_callee_and_no_arg_check=False, permit_codeblocks=False, permit_unsupported_type_args=False, **kwargs)[source]#
Takes the body of the routine that is the target of the supplied call and replaces the call with it.
- Parameters:
node (
Call) – the Call node to inline.routine (
Optional[Routine]) – Optional Routine to be inlined. (By default, PSyclone will search for a target routine with a matching signature).use_first_callee_and_no_arg_check (
bool) – if True, simply use the first potential callee routine. No argument type-checking is performed.permit_codeblocks (
bool) – If False (the default), raise an Exception if the target routine contains a CodeBlock.permit_unsupported_type_args (
bool) – If True then the target routine is permitted to have arguments of UnsupportedType.
- Raises:
InternalError – if the merge of the symbol tables fails. In theory this should never happen because validate() should catch such a situation.
- validate(node, **kwargs)[source]#
Checks that the supplied node is a valid target for inlining.
- Parameters:
node (
Call) – the target PSyIR Call to inline.routine (psyclone.psyir.nodes.routine.Routine | None) – Optional Routine to be inlined. (By default, PSyclone will search for a target routine with a matching signature).
use_first_callee_and_no_arg_check (bool) – if True, simply use the first potential callee routine. No argument type-checking is performed.
permit_codeblocks (bool) – If False (the default), raise an Exception if the target routine contains a CodeBlock.
permit_unsupported_type_args (bool) – If True then the target routine is permitted to have arguments of UnsupportedType.
- Raises:
TransformationError – if the supplied node is not a Call, is an IntrinsicCall or a call to a PSyclone-generated or ELEMENTAL routine.
TransformationError – if the routine body contains a Return that is not the first or last statement.
TransformationError – if the routine body contains a CodeBlock and permit_codeblocks is not True.
TransformationError – if the routine contains an ALLOCATE (as we don’t support adding the required DEALLOCATE).
TransformationError – if the called routine has a named argument.
TransformationError – if the call-site is not within a Routine.
TransformationError – if any of the variables declared within the called routine are of UnknownInterface.
TransformationError – if any of the variables declared within the called routine have a StaticInterface.
TransformationError – if any of the subroutine arguments is of UnsupportedType.
TransformationError – if a symbol of a given name is imported from different containers at the call site and within the routine.
TransformationError – if the routine accesses an un-resolved symbol.
TransformationError – if the number of arguments in the call does not match the number of formal arguments of the routine.
TransformationError – if a symbol declared in the parent container is accessed in the target routine.
TransformationError – if the shape of an array formal argument does not match that of the corresponding actual argument.
TransformationError – if one of the declaratoins in the routine depends on an argument that is written to prior to the call.
InternalError – if an unhandled Node type is returned by Reference.previous_accesses().
- Return type:
None