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]

[PATCH] Fix PR40001


This fixes PR40001, we may not rename volatile or hard registers to
SSA names, even when their variables could be registers according
to DECL_GIMPLE_REG_P.  update_address_taken didn't consider these
restrictions.

As it happens that variables have DECL_GIMPLE_REG_P set even though
they are not is_gimple_reg this patch also reverts moving the
DECL_GIMPLE_REG_P check earlier in is_gimple_reg.  This in turn
uncovers again that we need to be able to build registers of
everything capable during gimplification (the gimplifier previously
avoided this catch-22 with the notion of formal temporaries).  Thus
this patch also removes the priciple restriction that complex
variables can never be registers at -O0.  Instead the gimplifier
avoids rewriting user variables to DECL_GIMPLE_REG_P if not
optimizing.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
trunk.

2009-05-02  Richard Guenther  <rguenther@suse.de>

	PR middle-end/40001
	* tree-ssa.c (execute_update_addresses_taken): Properly check
	if we can mark a variable DECL_GIMPLE_REG_P.
	* gimple.c (is_gimple_reg): Re-order check for DECL_GIMPLE_REG_P
	back to the end of the function.
	(is_gimple_reg_type): Remove complex type special casing.
	* gimplify.c (gimplify_bind_expr): Do not set DECL_GIMPLE_REG_P
	if not optimizing.

	* gcc.target/spu/pr40001.c: New testcase.

Index: gcc/testsuite/gcc.target/spu/pr40001.c
===================================================================
*** gcc/testsuite/gcc.target/spu/pr40001.c	(revision 0)
--- gcc/testsuite/gcc.target/spu/pr40001.c	(revision 0)
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O" } */
+ 
+ void *
+ sbrk (unsigned int increment)
+ {
+   volatile register
+       __attribute__ ((__spu_vector__)) unsigned int sp_r1 __asm__ ("1");
+   unsigned int sps;
+ 
+   sps = __builtin_spu_extract (sp_r1, 0);
+   if (sps - 4096 >= increment)
+     return 0;
+   else
+     return ((void *) -1);
+ }
+ 
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c	(revision 147054)
--- gcc/tree-ssa.c	(working copy)
*************** execute_update_addresses_taken (bool do_
*** 1573,1579 ****
  	if (!DECL_GIMPLE_REG_P (var)
  	    && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
  	    && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
! 		|| TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE))
  	  {
  	    DECL_GIMPLE_REG_P (var) = 1;
  	    mark_sym_for_renaming (var);
--- 1573,1581 ----
  	if (!DECL_GIMPLE_REG_P (var)
  	    && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
  	    && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
! 		|| TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
! 	    && !TREE_THIS_VOLATILE (var)
! 	    && (TREE_CODE (var) != VAR_DECL || !DECL_HARD_REGISTER (var)))
  	  {
  	    DECL_GIMPLE_REG_P (var) = 1;
  	    mark_sym_for_renaming (var);
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c	(revision 147054)
--- gcc/gimple.c	(working copy)
*************** is_gimple_id (tree t)
*** 2805,2817 ****
  bool
  is_gimple_reg_type (tree type)
  {
!   /* In addition to aggregate types, we also exclude complex types if not
!      optimizing because they can be subject to partial stores in GNU C by
!      means of the __real__ and __imag__ operators and we cannot promote
!      them to total stores (see gimplify_modify_expr_complex_part).  */
!   return !(AGGREGATE_TYPE_P (type)
! 	   || (TREE_CODE (type) == COMPLEX_TYPE && !optimize));
! 
  }
  
  /* Return true if T is a non-aggregate register variable.  */
--- 2805,2811 ----
  bool
  is_gimple_reg_type (tree type)
  {
!   return !AGGREGATE_TYPE_P (type);
  }
  
  /* Return true if T is a non-aggregate register variable.  */
*************** is_gimple_reg (tree t)
*** 2825,2836 ****
    if (!is_gimple_variable (t))
      return false;
  
-   /* Complex and vector values must have been put into SSA-like form.
-      That is, no assignments to the individual components.  */
-   if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
-       || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
-     return DECL_GIMPLE_REG_P (t);
- 
    if (!is_gimple_reg_type (TREE_TYPE (t)))
      return false;
  
--- 2819,2824 ----
*************** is_gimple_reg (tree t)
*** 2857,2862 ****
--- 2845,2856 ----
    if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
      return false;
  
+   /* Complex and vector values must have been put into SSA-like form.
+      That is, no assignments to the individual components.  */
+   if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+       || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+     return DECL_GIMPLE_REG_P (t);
+ 
    return true;
  }
  
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 147054)
--- gcc/gimplify.c	(working copy)
*************** gimplify_bind_expr (tree *expr_p, gimple
*** 1218,1226 ****
  
        /* Preliminarily mark non-addressed complex variables as eligible
  	 for promotion to gimple registers.  We'll transform their uses
! 	 as we find them.  */
!       if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
! 	   || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
  	  && !TREE_THIS_VOLATILE (t)
  	  && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
  	  && !needs_to_live_in_memory (t))
--- 1218,1231 ----
  
        /* Preliminarily mark non-addressed complex variables as eligible
  	 for promotion to gimple registers.  We'll transform their uses
! 	 as we find them.
! 	 We exclude complex types if not optimizing because they can be
! 	 subject to partial stores in GNU C by means of the __real__ and
! 	 __imag__ operators and we cannot promote them to total stores
! 	 (see gimplify_modify_expr_complex_part).  */
!       if (optimize
! 	  && (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
! 	      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
  	  && !TREE_THIS_VOLATILE (t)
  	  && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
  	  && !needs_to_live_in_memory (t))


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