This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR35607, another revenge of invariant addresses (ivopts)


On Tue, 18 Mar 2008, Richard Guenther wrote:

> On Mon, 17 Mar 2008, Diego Novillo wrote:
> 
> > On 03/17/08 10:46, Richard Guenther wrote:
> > 
> > > Otherwise TREE_INVARIANT is suspiciously
> > > unused and we might be able to get rid of it completely (and maybe
> > > replace it by marking possibly-invariant address DECLs to avoid
> > > the costly checks there).
> > 
> > You mean a caching mechanism for is_gimple_invariant_address?  I guess, but
> > first we'd have to find a significant slowdown with your patch. Caching
> > invariantness is what brought us to this point.
> 
> Yes, I mean caching only of the leaf part, that is
> 
>   if (DECL_P (op)
>       && (staticp (op)
>           || decl_function_context (op) == current_function_decl
>           || (TREE_CODE (op) == VAR_DECL
>               && DECL_THREAD_LOCAL_P (op))))
>     return true;
> 
> but - looking at the implementation of staticp we should better inline it
> (it contains lots of irrelevant code for the case we use it).
> 
> > > 2008-03-17  Richard Guenther  <rguenther@suse.de>
> > > 
> > >  * tree-gimple.h (is_gimple_invariant_address): Declare.
> > >  (is_gimple_constant): Likewise.
> > >  * tree-gimple.c (is_gimple_constant): New function.
> > >  (is_gimple_invariant_address): Likewise.
> > >  (is_gimple_min_invariant): Implement in terms of is_gimple_constant
> > >  and is_gimple_invariant_address.
> > >  * tree-ssa-loop-niter.c (expand_simple_operations): Revert
> > >  previous change.
> > 
> > Looks OK now.
> 
> Bootstrapped and tested ok, I'll inline staticp here and re-do
> the testing.
> 
> Ok if that passes?

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

(gfortran.fortran-torture/execute/der_init.f90 ICEs because we
build an address of an SSA_NAME during data dependency called from
predcom - I have a patch for this, referenced below in the tree-data-ref.c
part but yet untested)

Thanks,
Richard.

2008-03-17  Richard Guenther  <rguenther@suse.de>

	* tree-gimple.h (is_gimple_invariant_address): Declare.
	(is_gimple_constant): Likewise.
	* tree-gimple.c (is_gimple_constant): New function.
	(is_gimple_invariant_address): Likewise.
	(is_gimple_min_invariant): Implement in terms of is_gimple_constant
	and is_gimple_invariant_address.
	* tree-ssa-loop-niter.c (expand_simple_operations): Revert
	previous change.

	* gcc.dg/tree-ssa/loop-19.c: Revert previous change.

Index: gcc/tree-ssa-loop-niter.c
===================================================================
*** gcc/tree-ssa-loop-niter.c	(revision 133290)
--- gcc/tree-ssa-loop-niter.c	(working copy)
*************** expand_simple_operations (tree expr)
*** 1436,1445 ****
      return expr;
  
    e = GIMPLE_STMT_OPERAND (stmt, 1);
-   /* Do not expand random invariants.  */
-   if (TREE_INVARIANT (e)
-       && !is_gimple_min_invariant (e))
-     return expr;
    if (/* Casts are simple.  */
        TREE_CODE (e) != NOP_EXPR
        && TREE_CODE (e) != CONVERT_EXPR
--- 1436,1441 ----
Index: gcc/tree-gimple.h
===================================================================
*** gcc/tree-gimple.h	(revision 133290)
--- gcc/tree-gimple.h	(working copy)
*************** extern bool is_gimple_addressable (tree)
*** 62,67 ****
--- 62,71 ----
  /* Returns true iff T is any valid GIMPLE lvalue.  */
  extern bool is_gimple_lvalue (tree);
  
+ /* Returns true iff T is a GIMPLE invariant address.  */
+ bool is_gimple_invariant_address (const_tree);
+ /* Returns true iff T is a valid GIMPLE constant.  */
+ bool is_gimple_constant (const_tree);
  /* Returns true iff T is a GIMPLE restricted function invariant.  */
  extern bool is_gimple_min_invariant (const_tree);
  /* Returns true iff T is a GIMPLE rvalue.  */
Index: gcc/tree-gimple.c
===================================================================
*** gcc/tree-gimple.c	(revision 133290)
--- gcc/tree-gimple.c	(working copy)
*************** is_gimple_addressable (tree t)
*** 167,183 ****
  	  || INDIRECT_REF_P (t));
  }
  
! /* Return true if T is a GIMPLE minimal invariant.  It's a restricted
!    form of function invariant.  */
  
  bool
! is_gimple_min_invariant (const_tree t)
  {
    switch (TREE_CODE (t))
      {
-     case ADDR_EXPR:
-       return TREE_INVARIANT (t);
- 
      case INTEGER_CST:
      case REAL_CST:
      case FIXED_CST:
--- 167,179 ----
  	  || INDIRECT_REF_P (t));
  }
  
! /* Return true if T is a valid gimple constant.  */
  
  bool
! is_gimple_constant (const_tree t)
  {
    switch (TREE_CODE (t))
      {
      case INTEGER_CST:
      case REAL_CST:
      case FIXED_CST:
*************** is_gimple_min_invariant (const_tree t)
*** 198,203 ****
--- 194,280 ----
      }
  }
  
+ /* Return true if T is a gimple invariant address.  */
+ 
+ bool
+ is_gimple_invariant_address (const_tree t)
+ {
+   tree op;
+ 
+   if (TREE_CODE (t) != ADDR_EXPR)
+     return false;
+ 
+   op = TREE_OPERAND (t, 0);
+   while (handled_component_p (op))
+     {
+       switch (TREE_CODE (op))
+ 	{
+ 	case ARRAY_REF:
+ 	case ARRAY_RANGE_REF:
+ 	  if (!is_gimple_constant (TREE_OPERAND (op, 1))
+ 	      || TREE_OPERAND (op, 2) != NULL_TREE
+ 	      || TREE_OPERAND (op, 3) != NULL_TREE)
+ 	    return false;
+ 	  break;
+ 
+ 	case COMPONENT_REF:
+ 	  if (TREE_OPERAND (op, 2) != NULL_TREE)
+ 	    return false;
+ 	  break;
+ 
+ 	default:;
+ 	}
+       op = TREE_OPERAND (op, 0);
+     }
+ 
+   if (CONSTANT_CLASS_P (op))
+     return true;
+ 
+   if (INDIRECT_REF_P (op))
+     return false;
+ 
+   switch (TREE_CODE (op))
+     {
+     case PARM_DECL:
+     case RESULT_DECL:
+     case LABEL_DECL:
+     case FUNCTION_DECL:
+       return true;
+ 
+     case VAR_DECL:
+       if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
+ 	   && ! DECL_DLLIMPORT_P (op))
+ 	  || DECL_THREAD_LOCAL_P (op)
+ 	  || DECL_CONTEXT (op) == current_function_decl
+ 	  || decl_function_context (op) == current_function_decl)
+ 	return true;
+       break;
+ 
+     case CONST_DECL:
+       if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
+ 	  || decl_function_context (op) == current_function_decl)
+ 	return true;
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   return false;
+ }
+ 
+ /* Return true if T is a GIMPLE minimal invariant.  It's a restricted
+    form of function invariant.  */
+ 
+ bool
+ is_gimple_min_invariant (const_tree t)
+ {
+   if (TREE_CODE (t) == ADDR_EXPR)
+     return is_gimple_invariant_address (t);
+ 
+   return is_gimple_constant (t);
+ }
+ 
  /* Return true if T looks like a valid GIMPLE statement.  */
  
  bool
Index: gcc/testsuite/gcc.dg/tree-ssa/loop-19.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/loop-19.c	(revision 133290)
--- gcc/testsuite/gcc.dg/tree-ssa/loop-19.c	(working copy)
***************
*** 6,12 ****
  
  /* { dg-do compile { target i?86-*-* x86_64-*-* powerpc*-*-*} } */
  /* { dg-require-effective-target nonpic } */
! /* { dg-options "-O2 -fdump-tree-final_cleanup" } */
  
  # define N      2000000
  static double   a[N],c[N];
--- 6,12 ----
  
  /* { dg-do compile { target i?86-*-* x86_64-*-* powerpc*-*-*} } */
  /* { dg-require-effective-target nonpic } */
! /* { dg-options "-O3 -fdump-tree-final_cleanup" } */
  
  # define N      2000000
  static double   a[N],c[N];


Index: tree-data-ref.c
===================================================================
--- tree-data-ref.c	(revision 133290)
+++ tree-data-ref.c	(working copy)
@@ -3965,11 +3965,14 @@ get_references_in_stmt (tree stmt, VEC (
 
   if (TREE_CODE (stmt) ==  GIMPLE_MODIFY_STMT)
     {
+      tree base;
       op0 = &GIMPLE_STMT_OPERAND (stmt, 0);
       op1 = &GIMPLE_STMT_OPERAND (stmt, 1);
 		
       if (DECL_P (*op1)
-	  || (REFERENCE_CLASS_P (*op1) && get_base_address (*op1)))
+	  || (REFERENCE_CLASS_P (*op1)
+	      && (base = get_base_address (*op1))
+	      && TREE_CODE (base) != SSA_NAME))
 	{
 	  ref = VEC_safe_push (data_ref_loc, heap, *references, NULL);
 	  ref->pos = op1;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]