This is the mail archive of the gcc@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: [RFC] Tightening up the type system


On Tue, 2004-09-28 at 15:57, Tom Tromey wrote:

> So, I'm in favor of adding the checks, with the caveat that if it
> turns into a big morass it should perhaps be put off until the next
> stage 1.
> 
It's certainly looking that way.  Attached is the WIP patch.  The main
changes are in the gimplifier (as we break down expressions, we need to
adjust the types of the operands) and in some optimizers that were not
emitting operands with the right types (e.g., ivopts).

I then ran into limitations in builtin processing.  We have several
regressions in testsuite/builtins mostly because we are no longer able
to fold memmove to memcpy because we convert

memmove (&a, &b, n)

to

a.1 = (void *) &a;
b.1 = (const void *) &b;
memmove (a.1, b.1, n);

which we then fail to fold into memcpy because we don't recognize that
a.1 and b.1 really are non-overlapping.  Perhaps this optimization
should be moved up into the tree optimizers.  I'm not quite sure where
exactly this happens.

I will keep working on this from time to time, mostly to keep the patch
alive until 4.1 opens.  If anyone is interested in picking it up, let me
know.


Diego.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1404
diff -d -c -p -u -r1.1404 Makefile.in
--- Makefile.in	29 Sep 2004 09:47:41 -0000	1.1404
+++ Makefile.in	30 Sep 2004 16:28:30 -0000
@@ -1719,11 +1719,11 @@ tree-ssa-loop-ivopts.o : tree-ssa-loop-i
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) varray.h $(EXPR_H) \
    output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
    tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
-   cfgloop.h $(PARAMS_H)
+   cfgloop.h $(PARAMS_H) langhooks.h
 tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
    output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
-   tree-pass.h cfglayout.h $(SCEV_H)
+   tree-pass.h cfglayout.h $(SCEV_H) langhooks.h
 tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h $(PARAMS_H)\
    output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.82
diff -d -c -p -u -r2.82 gimplify.c
--- gimplify.c	30 Sep 2004 01:22:05 -0000	2.82
+++ gimplify.c	30 Sep 2004 16:28:31 -0000
@@ -177,6 +177,99 @@ gimple_current_bind_expr (void)
   return gimplify_ctxp->current_bind_expr;
 }
 
+/* Adjust the types of operands to binary expression EXPR so that they
+   are compatible with EXPR's type or with each other. This is
+   necessary because as we start breaking appart complex expressions
+   with type casts, the types of the underlying operands may be wrong.
+
+   Consider, for instance the expression
+   
+   (const unsigned char *) (unsigned char *) fde + 8B
+
+   Initially, the FE generates the constant '8' with type 'unsigned
+   char *', but when we take the LHS of '+' and replace it with a
+   temporary of type 'const unsigned char *', we need to change the
+   type of '8' accordingly.
+
+   PRE_P and POST_P are as in gimplify_expr.  */
+
+static void
+adjust_operand_types (tree expr, tree *pre_p, tree *post_p)
+{
+  tree op0, op1, op0_type, op1_type, expr_type, cast_val;
+  enum tree_code code = TREE_CODE (expr);
+
+  gcc_assert (TREE_CODE_LENGTH (code) == 2);
+
+  expr_type = TREE_TYPE (expr);
+
+  op0 = TREE_OPERAND (expr, 0);
+  op0_type = TREE_TYPE (op0);
+
+  op1 = TREE_OPERAND (expr, 1);
+  op1_type = TREE_TYPE (op1);
+
+  if (code == MODIFY_EXPR)
+    {
+      /* If the type of the RHS is not compatible with that of the
+	 LHS, change its type.  */
+      if (!lang_hooks.types_compatible_p (op0_type, op1_type))
+	{
+	  cast_val = fold_convert (op0_type, op1);
+	  op1 = get_initialized_tmp_var (cast_val, pre_p, post_p);
+	  TREE_OPERAND (expr, 1) = op1;
+	}
+    }
+  else if (TREE_CODE_CLASS (code) == tcc_binary)
+    {
+      /* Ignore expressions whose operands may be of different types
+	 and expressions that return a type different from their
+	 operands.  */
+      if (code == LSHIFT_EXPR
+	  || code == RSHIFT_EXPR
+	  || code == LROTATE_EXPR
+	  || code == RROTATE_EXPR
+	  || code == COMPLEX_EXPR)
+	return;
+
+      /* Otherwise, make sure that both operands have a type
+	 compatible with EXPR's type.  */
+      if (!lang_hooks.types_compatible_p (expr_type, op0_type))
+	{
+	  cast_val = fold_convert (expr_type, op0);
+	  op0 = get_initialized_tmp_var (cast_val, pre_p, post_p);
+	  TREE_OPERAND (expr, 0) = op0;
+	}
+
+      if (!lang_hooks.types_compatible_p (expr_type, op1_type))
+	{
+	  cast_val = fold_convert (expr_type, op1);
+	  op1 = get_initialized_tmp_var (cast_val, pre_p, post_p);
+	  TREE_OPERAND (expr, 1) = op1;
+	}
+    }
+  else if (TREE_CODE_CLASS (code) == tcc_comparison
+	   || code == TRUTH_ANDIF_EXPR
+	   || code == TRUTH_ORIF_EXPR
+	   || code == TRUTH_AND_EXPR
+	   || code == TRUTH_OR_EXPR
+	   || code == TRUTH_XOR_EXPR)
+    {
+      /* Make sure the two operands have compatible types.  By
+	 convention, only modify the type for the RHS of the
+	 comparison, if needed.  */
+      if (!lang_hooks.types_compatible_p (op0_type, op1_type))
+	{
+	  cast_val = fold_convert (op0_type, op1);
+	  op1 = get_initialized_tmp_var (cast_val, pre_p, post_p);
+	  TREE_OPERAND (expr, 1) = op1;
+	}
+    }
+  else
+    gcc_unreachable ();
+}
+
+
 /* Returns true iff there is a COND_EXPR between us and the innermost
    CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
 
@@ -2826,6 +2919,10 @@ gimplify_modify_expr (tree *expr_p, tree
   if (ret == GS_ERROR)
     return ret;
 
+  /* Once the LHS and RHS have been gimplified, make sure that their
+     types are compatible.  */
+  adjust_operand_types (*expr_p, pre_p, post_p);
+
   /* Now see if the above changed *from_p to something we handle specially.  */
   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
 				  want_value);
@@ -3902,6 +3999,9 @@ gimplify_expr (tree *expr_p, tree *pre_p
 		r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
 				    post_p, is_gimple_val, fb_rvalue);
 
+		if (r0 != GS_ERROR && r1 != GS_ERROR)
+		  adjust_operand_types (*expr_p, pre_p, post_p);
+
 		ret = MIN (r0, r1);
 		break;
 	      }
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.59
diff -d -c -p -u -r2.59 tree-cfg.c
--- tree-cfg.c	28 Sep 2004 07:59:50 -0000	2.59
+++ tree-cfg.c	30 Sep 2004 16:28:31 -0000
@@ -3062,6 +3062,7 @@ static tree
 verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 {
   tree t = *tp, x;
+  enum tree_code code;
 
   if (TYPE_P (t))
     *walk_subtrees = 0;
@@ -3074,7 +3075,8 @@ verify_expr (tree *tp, int *walk_subtree
          && !is_gimple_val (TREE_OPERAND (t, N)))		\
        { error (MSG); return TREE_OPERAND (t, N); }} while (0)
 
-  switch (TREE_CODE (t))
+  code = TREE_CODE (t);
+  switch (code)
     {
     case SSA_NAME:
       if (SSA_NAME_IN_FREE_LIST (t))
@@ -3092,6 +3094,13 @@ verify_expr (tree *tp, int *walk_subtree
 	  error ("GIMPLE register modified with BIT_FIELD_REF");
 	  return t;
 	}
+
+      if (!lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (t, 0)),
+					  TREE_TYPE (TREE_OPERAND (t, 1))))
+	{
+	  error ("Incompatible types in an assignment");
+	  return t;
+	}
       break;
 
     case ADDR_EXPR:
@@ -3216,8 +3225,21 @@ verify_expr (tree *tp, int *walk_subtree
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
     case BIT_AND_EXPR:
+    case COMPLEX_EXPR:
       CHECK_OP (0, "Invalid operand to binary operator");
       CHECK_OP (1, "Invalid operand to binary operator");
+
+      if (code != LSHIFT_EXPR
+	  && code != RSHIFT_EXPR
+	  && code != LROTATE_EXPR
+	  && code != RROTATE_EXPR
+	  && code != COMPLEX_EXPR
+          && !lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (t, 0)),
+					     TREE_TYPE (TREE_OPERAND (t, 1))))
+	{
+	  error ("Incompatible types in a binary operator");
+	  return t;
+	}
       break;
 
     default:
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.50
diff -d -c -p -u -r2.50 tree-flow.h
--- tree-flow.h	29 Sep 2004 21:23:35 -0000	2.50
+++ tree-flow.h	30 Sep 2004 16:28:32 -0000
@@ -579,7 +579,6 @@ extern void debug_tree_ssa_stats (void);
 extern void ssa_remove_edge (edge);
 extern edge ssa_redirect_edge (edge, basic_block);
 extern bool tree_ssa_useless_type_conversion (tree);
-extern bool tree_ssa_useless_type_conversion_1 (tree, tree);
 extern void verify_ssa (void);
 extern void delete_tree_ssa (void);
 extern void register_new_def (tree, varray_type *);
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.47
diff -d -c -p -u -r2.47 tree-ssa-ccp.c
--- tree-ssa-ccp.c	29 Sep 2004 09:04:17 -0000	2.47
+++ tree-ssa-ccp.c	30 Sep 2004 16:28:32 -0000
@@ -460,6 +460,9 @@ replace_uses_in (tree stmt, bool *replac
       if (val->lattice_val != CONSTANT)
 	continue;
 
+      gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (tuse),
+						 TREE_TYPE (val->const_val)));
+
       if (TREE_CODE (stmt) == ASM_EXPR
 	  && !may_propagate_copy_into_asm (tuse))
 	continue;
@@ -486,6 +489,7 @@ replace_vuse_in (tree stmt, bool *replac
   bool replaced = false;
   vuse_optype vuses;
   use_operand_p vuse;
+  tree var;
   value *val;
 
   if (replaced_addresses_p)
@@ -499,13 +503,17 @@ replace_vuse_in (tree stmt, bool *replac
     return false;
 
   vuse = VUSE_OP_PTR (vuses, 0);
+  var = USE_FROM_PTR (vuse);
   val = get_value (USE_FROM_PTR (vuse));
 
   if (val->lattice_val == CONSTANT
       && TREE_CODE (stmt) == MODIFY_EXPR
       && DECL_P (TREE_OPERAND (stmt, 1))
-      && TREE_OPERAND (stmt, 1) == SSA_NAME_VAR (USE_FROM_PTR (vuse)))
+      && TREE_OPERAND (stmt, 1) == SSA_NAME_VAR (var))
     {
+      gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (var),
+						 TREE_TYPE (val->const_val)));
+
       TREE_OPERAND (stmt, 1) = val->const_val;
       replaced = true;
       if (POINTER_TYPE_P (TREE_TYPE (USE_FROM_PTR (vuse))) 
@@ -550,6 +558,10 @@ substitute_and_fold (void)
 	      if (! SSA_VAR_P (orig))
 		break;
 
+	      /* The call to may_propagate_copy is needed to prevent
+		 propagating constants coming from V_MUST_DEFs.  We
+		 will still need the original store to the PHI
+		 argument to properly take this PHI node out of SSA.  */
 	      new_val = get_value (orig);
 	      if (new_val->lattice_val == CONSTANT
 		  && may_propagate_copy (orig, new_val->const_val))
Index: tree-ssa-copy.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-copy.c,v
retrieving revision 2.18
diff -d -c -p -u -r2.18 tree-ssa-copy.c
--- tree-ssa-copy.c	30 Sep 2004 01:22:05 -0000	2.18
+++ tree-ssa-copy.c	30 Sep 2004 16:28:33 -0000
@@ -64,7 +64,7 @@ may_propagate_copy (tree dest, tree orig
   tree type_o = TREE_TYPE (orig);
 
   /* Do not copy between types for which we *do* need a conversion.  */
-  if (!tree_ssa_useless_type_conversion_1 (type_d, type_o))
+  if (!lang_hooks.types_compatible_p (type_d, type_o))
     return false;
 
   /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dom.c,v
retrieving revision 2.57
diff -d -c -p -u -r2.57 tree-ssa-dom.c
--- tree-ssa-dom.c	29 Sep 2004 23:08:32 -0000	2.57
+++ tree-ssa-dom.c	30 Sep 2004 16:28:33 -0000
@@ -2343,6 +2343,9 @@ eliminate_redundant_computations (struct
       && (TREE_CODE (cached_lhs) != SSA_NAME
 	  || may_propagate_copy (*expr_p, cached_lhs)))
     {
+      if (TREE_CODE (cached_lhs) != SSA_NAME)
+	gcc_assert (may_propagate_copy (*expr_p, cached_lhs));
+
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
 	  fprintf (dump_file, "  Replaced redundant expr '");
@@ -2522,8 +2525,6 @@ cprop_operand (tree stmt, use_operand_p 
   val = SSA_NAME_VALUE (op);
   if (val && TREE_CODE (val) != VALUE_HANDLE)
     {
-      tree op_type, val_type;
-
       /* Do not change the base variable in the virtual operand
 	 tables.  That would make it impossible to reconstruct
 	 the renamed virtual operand if we later modify this
@@ -2539,38 +2540,17 @@ cprop_operand (tree stmt, use_operand_p 
 	  && !may_propagate_copy_into_asm (op))
 	return false;
 
-      /* Get the toplevel type of each operand.  */
-      op_type = TREE_TYPE (op);
-      val_type = TREE_TYPE (val);
-
-      /* While both types are pointers, get the type of the object
-	 pointed to.  */
-      while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
-	{
-	  op_type = TREE_TYPE (op_type);
-	  val_type = TREE_TYPE (val_type);
-	}
-
-      /* Make sure underlying types match before propagating a constant by
-	 converting the constant to the proper type.  Note that convert may
-	 return a non-gimple expression, in which case we ignore this
-	 propagation opportunity.  */
-      if (TREE_CODE (val) != SSA_NAME)
-	{
-	  if (!lang_hooks.types_compatible_p (op_type, val_type))
-	    {
-	      val = fold_convert (TREE_TYPE (op), val);
-	      if (!is_gimple_min_invariant (val))
-		return false;
-	    }
-	}
-
       /* Certain operands are not allowed to be copy propagated due
 	 to their interaction with exception handling and some GCC
 	 extensions.  */
       else if (!may_propagate_copy (op, val))
 	return false;
 
+      /* Make sure underlying types match before propagating
+	 the new value.  */
+      gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (op),
+						 TREE_TYPE (val)));
+
       /* Dump details.  */
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
@@ -2879,10 +2859,14 @@ lookup_avail_expr (tree stmt, bool inser
 	  tree t = element->rhs;
 	  free (element);
 
+	  /* Note that the predicate may have a type other than
+	     'bool'.  This happens when this predicate is the return
+	     expression of a function returning 'bool' with an ABI that
+	     widens the return value.  */
 	  if (TREE_CODE (t) == EQ_EXPR)
-	    return boolean_false_node;
+	    return fold_convert (TREE_TYPE (t), boolean_false_node);
 	  else
-	    return boolean_true_node;
+	    return fold_convert (TREE_TYPE (t), boolean_true_node);
 	}
     }
 
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.15
diff -d -c -p -u -r2.15 tree-ssa-loop-ivopts.c
--- tree-ssa-loop-ivopts.c	28 Sep 2004 07:59:52 -0000	2.15
+++ tree-ssa-loop-ivopts.c	30 Sep 2004 16:28:33 -0000
@@ -88,6 +88,7 @@ Software Foundation, 59 Temple Place - S
 #include "tree-scalar-evolution.h"
 #include "cfgloop.h"
 #include "params.h"
+#include "langhooks.h"
 
 /* The infinite cost.  */
 #define INFTY 10000000
@@ -2977,6 +2978,7 @@ may_eliminate_iv (struct loop *loop,
   edge exit;
   struct tree_niter_desc *niter, new_niter;
   tree wider_type, type, base;
+  tree var;
 
   /* For now just very primitive -- we work just for the single exit condition,
      and are quite conservative about the possible overflows.  TODO -- both of
@@ -3023,6 +3025,15 @@ may_eliminate_iv (struct loop *loop,
 			fold_convert (wider_type, new_niter.niter), 0))
     return false;
 
+  /* Adjust *BOUND to the type of the candidate variable.  */
+  var = var_at_stmt (loop, cand, use->stmt);
+  if (!lang_hooks.types_compatible_p (TREE_TYPE (var), TREE_TYPE (*bound)))
+    {
+      *bound = fold_convert (TREE_TYPE (var), *bound);
+      if (!is_gimple_val (*bound))
+	return false;
+    }
+
   return true;
 }
 
@@ -3960,7 +3971,14 @@ rewrite_address_base (block_stmt_iterato
      the variable to a new temporary.  */
   copy = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, with);
   if (name)
-    new_name = duplicate_ssa_name (name, copy);
+    {
+      new_name = duplicate_ssa_name (name, copy);
+
+      /* Make sure that WITH has a compatible type with NEW_NAME.  */
+      if (!lang_hooks.types_compatible_p (TREE_TYPE (new_name),
+					  TREE_TYPE (with)))
+	TREE_OPERAND (copy, 1) = fold_convert (TREE_TYPE (new_name), with);
+    }
   else
     {
       new_var = create_tmp_var (TREE_TYPE (with), "ruatmp");
Index: tree-ssa-loop-manip.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-manip.c,v
retrieving revision 2.9
diff -d -c -p -u -r2.9 tree-ssa-loop-manip.c
--- tree-ssa-loop-manip.c	28 Sep 2004 07:59:52 -0000	2.9
+++ tree-ssa-loop-manip.c	30 Sep 2004 16:28:33 -0000
@@ -36,6 +36,7 @@ Software Foundation, 59 Temple Place - S
 #include "tree-pass.h"
 #include "cfglayout.h"
 #include "tree-scalar-evolution.h"
+#include "langhooks.h"
 
 /* Creates an induction variable with value BASE + STEP * iteration in LOOP.
    It is expected that neither BASE nor STEP are shared with other expressions
@@ -91,6 +92,13 @@ create_iv (tree base, tree step, tree va
 	}
     }
 
+  /* Make sure that STEP is of a type compatible with VB.  */
+  if (!lang_hooks.types_compatible_p (TREE_TYPE (vb), TREE_TYPE (step)))
+    {
+      step = fold_convert (TREE_TYPE (vb), step);
+      gcc_assert (is_gimple_val (step));
+    }
+
   stmt = build2 (MODIFY_EXPR, void_type_node, va,
 		 build2 (incr_op, TREE_TYPE (base),
 			 vb, step));
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.44
diff -d -c -p -u -r2.44 tree-ssa.c
--- tree-ssa.c	30 Sep 2004 01:22:06 -0000	2.44
+++ tree-ssa.c	30 Sep 2004 16:28:34 -0000
@@ -733,7 +733,7 @@ delete_tree_ssa (void)
 /* Return true if EXPR is a useless type conversion, otherwise return
    false.  */
 
-bool
+static bool
 tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
 {
   /* If the inner and outer types are effectively the same, then
@@ -743,51 +743,6 @@ tree_ssa_useless_type_conversion_1 (tree
      || (lang_hooks.types_compatible_p (inner_type, outer_type)))
     return true;
 
-  /* If both types are pointers and the outer type is a (void *), then
-     the conversion is not necessary.  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)
-           && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
-					     TREE_TYPE (outer_type)))
-    return true;
-
-  /* If both the inner and outer types are integral types, then the
-     conversion is not necessary if they have the same mode and
-     signedness and precision, and both or neither are boolean.  Some
-     code assumes an invariant that boolean types stay boolean and do
-     not become 1-bit bit-field types.  Note that types with precision
-     not using all bits of the mode (such as bit-field types in C)
-     mean that testing of precision is necessary.  */
-  else if (INTEGRAL_TYPE_P (inner_type)
-           && INTEGRAL_TYPE_P (outer_type)
-	   && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
-	   && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
-	   && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
-    {
-      bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
-      bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
-      if (first_boolean == second_boolean)
-	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;
 }
 

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