PSyclone
PSyclone copied to clipboard
Supporting calls in NEMO
At the moment calls are just stored as CodeBlocks, which means they can't be further analysed (e.g. if no information about the calls is available, the variable access API still has to mark those accesses as 'UNKNOWN').
While likely not all Fortran statements will be supported by the PSyIR, it was agreed that calls will need to be supported.
@hiker, I think this can be closed now as we do represent calls as Call
nodes?
@arporter, is there an implementation of reference_accesses
in the Call
class? Or will the arguments be properly marked as 'read-write' (I think that's the best we can do, unless we know more about the subroutine) from one of the base class implementation??
Ah, no, it doesn't have such an implementation. I think it will use the one in Node
which in turn just calls reference_accesses
for each of the child References - these will currently return just 'READ' so that's not correct. I think the simplest solution is to add a reference_accesses
method to Call and, as you say, set them to 'read-write' for the moment. We could do better by attempting to find the source of the routine that is being called but we won't always be able to do that. (e.g. if it's in a library.)
I've just hit this again while doing #1396. I can confirm that we do need to implement Call.reference_accesses
! I'll add an x-failing test in the associated PR.
In fact, getting test coverage was going to be a pain so I decided I'd do this first. It will only be a 'towards' (if the reviewer agrees) as I shan't attempt to resolve the interface of the called routine. However, it should be good enough for most purposes.
I'm guessing the long-term plan for this is to have the call look up the routine symbol and check the intents (if declared) of the arguments to compute the accesses? At the moment PSyclone is conservative and just makes an assumption that the arguments are all ReadWrite, however for example for NemoLite2D we know the arguments, e.g. if I find the routine (using InlineTrans._find_routine for now since its implemented) corresponding to a Call - I can check the symbol_table and see that jj
is Argument(Access.READ)
- the only thing I'm unsure on how to do is check which argument corresponds to which symbol in the symbol_table, but I think by checking the argument vs the symbol_table.argument_list (and then look up the argument_list element in the symbol_table and checking if it has a declared Access?).
This is currently causing false positives for me when attemping to apply a chunk loop trans on a loop containing these kernel calls, as the loop variable is "written to" inside the call, though we know this is not really true.
For GOcean kernels we know more, thanks to the metadata and API rules. However, is the problem that you've lowered the Kernel call to a Call and no longer have that information?
For GOcean kernels we know more, thanks to the metadata and API rules. However, is the problem that you've lowered the Kernel call to a Call and no longer have that information?
I think it might be yeah - but I think in theory we should be able to look at a generic Call and routine in more detail (provided we know the declaration) anyway right?
but I think in theory we should be able to look at a generic Call and routine in more detail (provided we know the declaration) anyway right?
Yes, that's right. We're going to need to do this to resolve calls to polymorphic routines too.