This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] tree_ssa_useless_type_conversion_p tweek
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, law at redhat dot com
- Date: Fri, 28 Nov 2003 00:15:10 +0100
- Subject: [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;
}