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]

Little infrastructure for IP constant propagation


Hi,
at the moment IPCP is propagating just selected FUNCTION_DECLs constants etc.
This patch adds is_gimple_ip_invariant check that is equivalent to is_gimple_min_invariant
but verify that value is invariant at interprocedural level; in particular that no addresses
of local variables are involved.

Bootstrapped/regtested with IP-CP using this predicate. OK?

Honza

	* tree.c (decl_address_ip_invariant_p): New function.
	* tree.h (decl_address_ip_invariant_p): Declare.
	* gimple.c (strip_invariant_refs): Break out from ...
	(is_gimple_invariant_address): ... here
	(is_gimple_ip_invariant_address): New function.
	(is_gimple_ip_invariant): New function.
	* gimple.h (is_gimple_ip_invariant_address, is_gimple_ip_invariant):
	Declare.
Index: tree.c
===================================================================
*** tree.c	(revision 139391)
--- tree.c	(working copy)
*************** decl_address_invariant_p (const_tree op)
*** 2172,2177 ****
--- 2172,2211 ----
    return false;
  }
  
+ /* Return whether OP is a DECL whose address is interprocedural-invariant.  */
+ 
+ bool
+ decl_address_ip_invariant_p (const_tree op)
+ {
+   /* The conditions below are slightly less strict than the one in
+      staticp.  */
+ 
+   switch (TREE_CODE (op))
+     {
+     case LABEL_DECL:
+     case FUNCTION_DECL:
+     case STRING_CST:
+       return true;
+ 
+     case VAR_DECL:
+       if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
+            && !DECL_DLLIMPORT_P (op))
+           || DECL_THREAD_LOCAL_P (op))
+         return true;
+       break;
+ 
+     case CONST_DECL:
+       if ((TREE_STATIC (op) || DECL_EXTERNAL (op)))
+         return true;
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   return false;
+ }
+ 
  
  /* Return true if T is function-invariant (internal function, does
     not handle arithmetic; that's handled in skip_simple_arithmetic and
Index: tree.h
===================================================================
*** tree.h	(revision 139391)
--- tree.h	(working copy)
*************** extern tree strip_float_extensions (tree
*** 4868,4873 ****
--- 4868,4874 ----
  /* In tree.c */
  extern int really_constant_p (const_tree);
  extern bool decl_address_invariant_p (const_tree);
+ extern bool decl_address_ip_invariant_p (const_tree);
  extern int int_fits_type_p (const_tree, const_tree);
  #ifndef GENERATOR_FILE
  extern void get_type_static_bounds (const_tree, mpz_t, mpz_t);
Index: gimple.c
===================================================================
*** gimple.c	(revision 139391)
--- gimple.c	(working copy)
*************** is_gimple_address (const_tree t)
*** 2730,2746 ****
      }
  }
  
! /* 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))
--- 2730,2741 ----
      }
  }
  
! /* Strip out all handled components that produce invariant
!    offsets.  */
  
! static const_tree
! strip_invariant_refs (const_tree op)
  {
    while (handled_component_p (op))
      {
        switch (TREE_CODE (op))
*************** is_gimple_invariant_address (const_tree 
*** 2750,2761 ****
  	  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:;
--- 2745,2756 ----
  	  if (!is_gimple_constant (TREE_OPERAND (op, 1))
  	      || TREE_OPERAND (op, 2) != NULL_TREE
  	      || TREE_OPERAND (op, 3) != NULL_TREE)
! 	    return NULL;
  	  break;
  
  	case COMPONENT_REF:
  	  if (TREE_OPERAND (op, 2) != NULL_TREE)
! 	    return NULL;
  	  break;
  
  	default:;
*************** is_gimple_invariant_address (const_tree 
*** 2763,2769 ****
        op = TREE_OPERAND (op, 0);
      }
  
!   return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
  }
  
  /* Return true if T is a GIMPLE minimal invariant.  It's a restricted
--- 2758,2795 ----
        op = TREE_OPERAND (op, 0);
      }
  
!   return op;
! }
! 
! /* Return true if T is a gimple invariant address.  */
! 
! bool
! is_gimple_invariant_address (const_tree t)
! {
!   const_tree op;
! 
!   if (TREE_CODE (t) != ADDR_EXPR)
!     return false;
! 
!   op = strip_invariant_refs (TREE_OPERAND (t, 0));
! 
!   return op && (CONSTANT_CLASS_P (op) || decl_address_invariant_p (op));
! }
! 
! /* Return true if T is a gimple invariant address at IPA level
!    (so addresses of variables on stack are not allowed).  */
! 
! bool
! is_gimple_ip_invariant_address (const_tree t)
! {
!   const_tree op;
! 
!   if (TREE_CODE (t) != ADDR_EXPR)
!     return false;
! 
!   op = strip_invariant_refs (TREE_OPERAND (t, 0));
! 
!   return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op));
  }
  
  /* Return true if T is a GIMPLE minimal invariant.  It's a restricted
*************** is_gimple_min_invariant (const_tree t)
*** 2778,2783 ****
--- 2804,2821 ----
    return is_gimple_constant (t);
  }
  
+ /* Return true if T is a GIMPLE interprocedural invariant.  It's a restricted
+    form of gimple minimal invariant.  */
+ 
+ bool
+ is_gimple_ip_invariant (const_tree t)
+ {
+   if (TREE_CODE (t) == ADDR_EXPR)
+     return is_gimple_ip_invariant_address (t);
+ 
+   return is_gimple_constant (t);
+ }
+ 
  /* Return true if T looks like a valid GIMPLE statement.  */
  
  bool
Index: gimple.h
===================================================================
*** gimple.h	(revision 139391)
--- gimple.h	(working copy)
*************** extern bool is_gimple_lvalue (tree);
*** 872,881 ****
--- 872,886 ----
  bool is_gimple_address (const_tree);
  /* Returns true iff T is a GIMPLE invariant address.  */
  bool is_gimple_invariant_address (const_tree);
+ /* Returns true iff T is a GIMPLE invariant address at interprocedural
+    level.  */
+ bool is_gimple_ip_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 restricted interprecodural invariant.  */
+ extern bool is_gimple_ip_invariant (const_tree);
  /* Returns true iff T is a GIMPLE rvalue.  */
  extern bool is_gimple_val (tree);
  /* Returns true iff T is a GIMPLE asm statement input.  */


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