aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2010-09-21 19:04:09 +0000
committerMikael Morin <mikael@gcc.gnu.org>2010-09-21 19:04:09 +0000
commit0b4f2770ff14ee139b9f5d0aa16c1507eb60cb55 (patch)
treeaa4f4a282ac80b91b29b28096d4af2a6ad0d5e3f /gcc/fortran/trans-expr.c
parent5e68c77aff8d9c984668f8932e54b28d02456bba (diff)
downloadgcc-0b4f2770ff14ee139b9f5d0aa16c1507eb60cb55.zip
gcc-0b4f2770ff14ee139b9f5d0aa16c1507eb60cb55.tar.gz
gcc-0b4f2770ff14ee139b9f5d0aa16c1507eb60cb55.tar.bz2
re PR fortran/45648 (Unnecessary temporary for transpose calls as actual argument.)
2010-09-21 Mikael Morin <mikael@gcc.gnu.org> PR fortran/45648 * trans-array.c (gfc_conv_expr_descriptor): Calculate dim out of n and info->dim. PR fortran/45648 * trans-array.c (gfc_conv_expr_descriptor): Unset full if we are accessing dimensions in reversed order. PR fortran/45648 * trans-array.c (gfc_conv_expr_descriptor): Special case noncopying intrinsic function call. * trans-array.c (gfc_conv_expr_descriptor): Remove ss lookup. Update asserts accordingly. PR fortran/45648 * trans.h (gfc_se): New field force_tmp. * trans-expr.c (gfc_conv_procedure_call): Check for argument alias and set parmse.force_tmp if some alias is found. * trans-array.c (gfc_conv_expr_descriptor): Force a temporary creation if se->force_tmp is set. 2010-09-21 Mikael Morin <mikael@gcc.gnu.org> PR fortran/45648 * gfortran.dg/inline_transpose_1.f90: Update temporary's locations and counts. Add non-elemental function call check. PR fortran/45648 * gfortran.dg/inline_transpose_1.f90: Add function calls with aliasing arguments checks. Update temporary counts. * gfortran.dg/transpose_optimization_1.f90: New. From-SVN: r164494
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 9b24cad..a6837c9 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -2770,7 +2770,7 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
int
gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
- gfc_actual_arglist * arg, gfc_expr * expr,
+ gfc_actual_arglist * args, gfc_expr * expr,
VEC(tree,gc) *append_args)
{
gfc_interface_mapping mapping;
@@ -2789,6 +2789,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
VEC(tree,gc) *stringargs;
tree result = NULL;
gfc_formal_arglist *formal;
+ gfc_actual_arglist *arg;
int has_alternate_specifier = 0;
bool need_interface_mapping;
bool callee_alloc;
@@ -2809,7 +2810,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_clear_ts (&ts);
if (sym->from_intmod == INTMOD_ISO_C_BINDING
- && conv_isocbinding_procedure (se, sym, arg))
+ && conv_isocbinding_procedure (se, sym, args))
return 0;
gfc_is_proc_ptr_comp (expr, &comp);
@@ -2859,7 +2860,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
/* Evaluate the arguments. */
- for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
+ for (arg = args; arg != NULL;
+ arg = arg->next, formal = formal ? formal->next : NULL)
{
e = arg->expr;
fsym = formal ? formal->sym : NULL;
@@ -3040,6 +3042,24 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
f = f || !sym->attr.always_explicit;
+ /* If the argument is a function call that may not create
+ a temporary for the result, we have to check that we
+ can do it, i.e. that there is no alias between this
+ argument and another one. */
+ if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
+ {
+ sym_intent intent;
+
+ if (fsym != NULL)
+ intent = fsym->attr.intent;
+ else
+ intent = INTENT_UNKNOWN;
+
+ if (gfc_check_fncall_dependency (e, intent, sym, args,
+ NOT_ELEMENTAL))
+ parmse.force_tmp = 1;
+ }
+
if (e->expr_type == EXPR_VARIABLE
&& is_subref_array (e))
/* The actual argument is a component reference to an