re PR fortran/38181 (calls to SIZE not optimized out of loops)
authorJakub Jelinek <jakub@redhat.com>
Thu, 20 Nov 2008 09:42:35 +0000 (10:42 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 20 Nov 2008 09:42:35 +0000 (10:42 +0100)
PR fortran/38181
* trans-intrinsic.c (gfc_conv_intrinsic_size): Inline 2 argument
size if the second argument is not optional and one argument size
for rank 1 arrays.

* gfortran.dg/array_section_2.f90: Adjust pattern to match
the inlined size0 instead of a size0 call.

From-SVN: r142037

gcc/fortran/ChangeLog
gcc/fortran/trans-intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/array_section_2.f90

index 1329354..5659329 100644 (file)
@@ -1,3 +1,10 @@
+2008-11-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR fortran/38181
+       * trans-intrinsic.c (gfc_conv_intrinsic_size): Inline 2 argument
+       size if the second argument is not optional and one argument size
+       for rank 1 arrays.
+
 2008-11-19  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/38171
index b8d9f3e..22e30ab 100644 (file)
@@ -3397,10 +3397,6 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
                          gfc_array_index_type);
       gfc_add_block_to_block (&se->pre, &argse.pre);
 
-      /* Build the call to size1.  */
-      fncall1 = build_call_expr (gfor_fndecl_size1, 2,
-                                arg1, argse.expr);
-
       /* Unusually, for an intrinsic, size does not exclude
         an optional arg2, so we must test for it.  */  
       if (actual->expr->expr_type == EXPR_VARIABLE
@@ -3408,6 +3404,10 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
            && actual->expr->symtree->n.sym->attr.optional)
        {
          tree tmp;
+         /* Build the call to size1.  */
+         fncall1 = build_call_expr (gfor_fndecl_size1, 2,
+                                    arg1, argse.expr);
+
          gfc_init_se (&argse, NULL);
          argse.want_pointer = 1;
          argse.data_not_needed = 1;
@@ -3420,11 +3420,36 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
                                  tmp, fncall1, fncall0);
        }
       else
-       se->expr = fncall1;
+       {
+         se->expr = NULL_TREE;
+         argse.expr = fold_build2 (MINUS_EXPR,
+                                   gfc_array_index_type, argse.expr,
+                                   build_int_cst (gfc_array_index_type, 1));
+       }
+    }
+  else if (expr->value.function.actual->expr->rank == 1)
+    {
+      argse.expr = build_int_cst (gfc_array_index_type, 0);
+      se->expr = NULL_TREE;
     }
   else
     se->expr = fncall0;
 
+  if (se->expr == NULL_TREE)
+    {
+      tree ubound, lbound;
+
+      arg1 = build_fold_indirect_ref (arg1);
+      ubound = gfc_conv_descriptor_ubound (arg1, argse.expr);
+      lbound = gfc_conv_descriptor_lbound (arg1, argse.expr);
+      se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
+                             ubound, lbound);
+      se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
+                             build_int_cst (gfc_array_index_type, 1));
+      se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
+                             build_int_cst (gfc_array_index_type, 0));
+    }
+
   type = gfc_typenode_for_spec (&expr->ts);
   se->expr = convert (type, se->expr);
 }
index 1f0774f..1a543e5 100644 (file)
@@ -1,5 +1,9 @@
 2008-11-20  Jakub Jelinek  <jakub@redhat.com>
 
+       PR fortran/38181
+       * gfortran.dg/array_section_2.f90: Adjust pattern to match
+       the inlined size0 instead of a size0 call.
+
        PR c++/36631
        * g++.dg/template/call5.C: New test.
 
index bfb4c01..ed5208c 100644 (file)
@@ -12,5 +12,5 @@ program test
    allocate(a(n), temp(n))
    temp(1:size(a)) = a
 end program
-! { dg-final { scan-tree-dump-times "size0" 1 "original" } }
+! { dg-final { scan-tree-dump-times "MAX_EXPR\[^\n\t\]+ubound\[^\n\t\]+lbound" 1 "original" } }
 ! { dg-final { cleanup-tree-dump "original" } }