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]

[tree-ssa] tree_ssa_useless_type_conversion_p tweek


Hi,
for the type checking work I need to be able to verify that given conversion is
useless when I don't have the NOP anymore.  Does the attached change look fine?
I am not at all sure about nice name of the new function.

I've also included one change in the functionality WRT complex types.  I now allow
complex types to match when their subtypes match.  This is actually needed
because convert call does not introduce any NOP when main variants of subtype match.

Bootstrapped/regtested i686-pc-gnu-linux and x86_64-linux.
Honza

2003-11-28  Jan Hubicka  <jh@suse.cz>
	* tree-flow.h (tree_ssa_useless_type_conversion_1): Declare.
	* tree-flow.c (tree_ssa_useless_type_conversion_1): Break out from
	from...; allow complex types whose subtypes match.
	(tree_ssa_useless_type_conversion): ... here.

Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.160
diff -c -3 -p -r1.1.4.160 tree-flow.h
*** tree-flow.h	25 Nov 2003 05:09:08 -0000	1.1.4.160
--- tree-flow.h	27 Nov 2003 21:06:39 -0000
*************** extern void ssa_remove_edge (edge);
*** 512,517 ****
--- 512,518 ----
  extern edge ssa_redirect_edge (edge, basic_block);
  extern void set_is_used (tree);
  extern bool tree_ssa_useless_type_conversion (tree);
+ extern bool tree_ssa_useless_type_conversion_1 (tree, tree);
  extern void build_dominator_tree (dominance_info);
  extern unsigned int highest_ssa_version;
  
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.166
diff -c -3 -p -r1.1.4.166 tree-ssa.c
*** tree-ssa.c	27 Nov 2003 04:01:02 -0000	1.1.4.166
--- tree-ssa.c	27 Nov 2003 21:06:47 -0000
*************** get_def_blocks_for (tree var)
*** 3111,3116 ****
--- 3111,3166 ----
    dm.var = var;
    return (struct def_blocks_d *) htab_find (def_blocks, &dm);
  }
+ /* Return true if EXPR is a useless type conversion, otherwise return
+    false.  */
+ 
+ bool
+ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
+ {
+   /* If the inner and outer types are effectively the same, then
+      strip the type conversion and enter the equivalence into
+      the table.  */
+   if (inner_type == outer_type
+       || TYPE_MAIN_VARIANT (inner_type) == TYPE_MAIN_VARIANT (outer_type))
+     return true;
+ 
+   /* If the outer type is a (void *), then we can enter the
+      equivalence into the table.  The opposite is not true since
+      that conversion would result in a loss of information if
+      the equivalence was used.  Consider an indirect function call
+      where we need to know the exact type of the function to
+      correctly implement the ABI.  */
+   else if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type)
+ 	   && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
+     return true;
+ 
+   /* Pointers and references are equivalent once we get to GENERIC,
+      so strip conversions that just switch between them.  */
+   else if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type)
+ 	   && (TYPE_MAIN_VARIANT (TREE_TYPE (inner_type))
+ 	       == TYPE_MAIN_VARIANT (TREE_TYPE (outer_type))))
+     return true;
+ 
+   /* If both the inner and outer types are integral types, then
+      we can enter the equivalence if they have the same mode
+      and signedness and precision (The type _Bool can have size of 4
+      (only happens on powerpc-darwin right now but can happen on any 
+      target that defines BOOL_TYPE_SIZE to be INT_TYPE_SIZE) and a
+      precision of 1 while unsigned int is the same expect for a 
+      precision of 4 so testing of precision is nessary).  */
+   else if (INTEGRAL_TYPE_P (inner_type) && INTEGRAL_TYPE_P (outer_type)
+ 	   && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
+ 	   && TREE_UNSIGNED (inner_type) == TREE_UNSIGNED (outer_type)
+ 	   && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
+     return true;
+   /* Recurse for complex types.  */
+   else if (TREE_CODE (inner_type) == COMPLEX_TYPE
+ 	   && TREE_CODE (outer_type) == COMPLEX_TYPE
+ 	   && tree_ssa_useless_type_conversion_1 (TREE_TYPE (outer_type),
+ 						  TREE_TYPE (inner_type)))
+     return true;
+   return false;
+ }
  
  /* Return true if EXPR is a useless type conversion, otherwise return
     false.  */
*************** tree_ssa_useless_type_conversion (tree e
*** 3123,3169 ****
       is "safe", then strip away the type conversion so that we can
       enter LHS = RHS into the const_and_copies table.  */
    if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
!     {
!       tree outer_type = TREE_TYPE (expr);
!       tree inner_type = TREE_TYPE (TREE_OPERAND (expr, 0));
! 
!       /* If the inner and outer types are effectively the same, then
!          strip the type conversion and enter the equivalence into
!          the table.  */
!       if (inner_type == outer_type
! 	  || TYPE_MAIN_VARIANT (inner_type) == TYPE_MAIN_VARIANT (outer_type))
!         return true;
! 
!       /* If the outer type is a (void *), then we can enter the
!          equivalence into the table.  The opposite is not true since
!          that conversion would result in a loss of information if
!          the equivalence was used.  Consider an indirect function call
!          where we need to know the exact type of the function to
!          correctly implement the ABI.  */
!       else if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type)
! 	       && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
! 	return true;
! 
!       /* Pointers and references are equivalent once we get to GENERIC,
! 	 so strip conversions that just switch between them.  */
!       else if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type)
! 	       && (TYPE_MAIN_VARIANT (TREE_TYPE (inner_type))
! 		   == TYPE_MAIN_VARIANT (TREE_TYPE (outer_type))))
! 	return true;
! 
!       /* If both the inner and outer types are integral types, then
!          we can enter the equivalence if they have the same mode
!          and signedness and precision (The type _Bool can have size of 4
!          (only happens on powerpc-darwin right now but can happen on any 
!          target that defines BOOL_TYPE_SIZE to be INT_TYPE_SIZE) and a
!          precision of 1 while unsigned int is the same expect for a 
!          precision of 4 so testing of precision is nessary).  */
!       else if (INTEGRAL_TYPE_P (inner_type) && INTEGRAL_TYPE_P (outer_type)
! 	       && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
! 	       && TREE_UNSIGNED (inner_type) == TREE_UNSIGNED (outer_type)
! 	       && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
! 	return true;
!     }
  
    return false;
  }
--- 3173,3182 ----
       is "safe", then strip away the type conversion so that we can
       enter LHS = RHS into the const_and_copies table.  */
    if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
!     return tree_ssa_useless_type_conversion_1 (TREE_TYPE (expr),
! 					       TREE_TYPE (TREE_OPERAND (expr,
! 									0)));
! 
  
    return false;
  }


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