PR 35681: Correct handling of "expressions" with ELEMENTAL subroutines

Daniel Kraft d@domob.eu
Tue Oct 21 15:51:00 GMT 2008


Hi all,

I'm investigating PR 35681 at the moment; one of the problems there is 
that a call to an ELEMENTAL subroutine like

CALL copy ((a((/ 2, 1 /))), a)

does not create a temporary value for the "expression" (parentheses!) in 
the first actual argument; see the PR for details.  The problem there is 
that this expression is indeed handled and a temporary created, but this 
all happens in gfc_conv_function_call inside the scalarization loop for 
the ELEMENTAL call and thus only scalar temporaries are created one at a 
time and not one array temporary, as it should be.

My first idea of handling this was to move the expression-evaluation for 
function calls out of gfc_conv_function_call and thus out of the 
ELEMENTAL scalarization; but I believe this would be a very intrusive 
patch and difficult to get right; not to mention it is surely not the 
thing we want for stage 3 and not really worth this trouble at the moment.

Currently there's already logic to handle temporaries (although for the 
INTENT(OUT) arguments) if required for ELEMENTAL calls 
(trans-stmt.c:gfc_conv_elemental_dependencies) and I tried to study the 
code there, but unfortunatelly am not really an expert about trans-time 
scalarization and all those ss/se things.

I also tried a naive patch re-using this logic for the temporaries for 
INTRINSIC_PARENTHESES-expressions but failed because those seem not to 
get an entry into loopse->ss->expr like EXPR_VARIABLE ones seem to do.

So my question is, is it possible (and relatively easy) to 
"gfc_conv_expr" arbitrary expressions (like those not being 
constants/variables or something like this, at the very least 
parentheses expressions but they are probably too few) into array 
temporaries and then modify the ss/se/code->ext.actual in such a way 
that this temporary is used later when calling gfc_conv_function_call 
using the ss and actual argument list of the call-statement instead of 
converting it again?

Something along the lines of:

gfc_expr* e = some_actual_argument_of (code->ext.actual);

temp = create_temporary_array (); /* gfc_conv_create_array_temporary? */
add_modify_to_block (se.pre, temp, gfc_conv_expr (e));
/* Change ss/e somehow to refer to the temporary instead of the original 
expression that would get converted again.  */
gfc_conv_function_call (expr->symtree, code->ext.actual);

I hope I got it somewhat clear...  Any pointer about where I can find 
information on how this scalarization stuff really works and how I can 
achieve this would be very appreciated!

Thanks,

Daniel

-- 
Done:  Arc-Bar-Cav-Rog-Sam-Val-Wiz
To go: Hea-Kni-Mon-Pri-Ran-Tou



More information about the Fortran mailing list