def make_sir_compliant(schedule): ''' Applies various transformations to the supplied schedule to replace any features that cannot be represented in SIR with alternative forms: 1. Converts any accesses of individual array elements into 1-trip loops. 2. Transforms array assignments into loops. 3. Replaces any ABS, SIGN, MIN or MAX intrinsics with equivalent PSyIR. 4. Hoists any loop-invariant assignments out of loops over levels. :param schedule: the schedule to transform. :type schedule: :py:class:`psyclone.psyir.nodes.Schedule` ''' abs_trans = Abs2CodeTrans() sign_trans = Sign2CodeTrans() min_trans = Min2CodeTrans() max_trans = Max2CodeTrans() array_range_trans = NemoAllArrayRange2LoopTrans() array_access_trans = NemoAllArrayAccess2LoopTrans() hoist_trans = HoistTrans() # Transform any single index accesses in array assignments # (e.g. a(1)) into 1-trip loops. for assignment in schedule.walk(Assignment): array_access_trans.apply(assignment) # Transform any array assignments (Fortran ':' notation) into loops. for assignment in schedule.walk(Assignment): array_range_trans.apply(assignment) for kernel in schedule.walk(NemoKern): kernel_schedule = kernel.get_kernel_schedule() for oper in kernel_schedule.walk(Operation): if oper.operator == UnaryOperation.Operator.ABS: # Apply ABS transformation abs_trans.apply(oper) elif oper.operator == BinaryOperation.Operator.SIGN: # Apply SIGN transformation sign_trans.apply(oper) elif oper.operator in [BinaryOperation.Operator.MIN, NaryOperation.Operator.MIN]: # Apply (2-n arg) MIN transformation min_trans.apply(oper) elif oper.operator in [BinaryOperation.Operator.MAX, NaryOperation.Operator.MAX]: # Apply (2-n arg) MAX transformation max_trans.apply(oper) # Remove any loop invariant assignments inside k-loops to make # them perfectly nested. At the moment this transformation # does not perform any dependence analysis validation so could # move code that should not be moved, see issue # #1387. However, it is known that it is safe do apply this # transformation to this particular code # (tra_adv_compute.F90). for loop in schedule.loops(): # outermost only if loop.loop_type == "levels": for child in loop.loop_body[:]: if isinstance(child, Assignment): hoist_trans.apply(child)