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]

[RFC] Get rid of awkward semantics for subtypes


Hi,

we're almost ready to get rid of the awkward semantics that is implemented in 
the middle-end and the optimizers for subtypes (INTEGER_TYPEs with a non-null 
TREE_TYPE); this should overall simplify things, make the support for invalid 
values in Ada more robust and expose more optimization opportunities.

Patches have already been written and tested (I've attached the non-gigi part 
we currently use, preparatory patches are required for gigi first).  All the 
subtypes are given maximal bounds for their precision, except for TYPE_DOMAIN 
of array types like in C, and thus become first class citizens.  This makes 
it possible to eliminate code in gigi, the gimplifier, the loop optimizer, 
the VRP pass, etc. needed to specifically support their special semantics.

This in turn means that the gimplification will eliminate most of the casts 
between subtypes and base types, making the optimizers more effective.  The 
exception will be the VRP pass, most notably when checks are off in Ada, so 
we'll need to be able to drive VRP differently from gigi.

Comments/suggestions welcome.


	* fold-const.c (fold_truth_not_expr) <CONVERT_EXPR>: Do not strip
	it if the destination type is boolean.
	* tree-chrec.c (avoid_arithmetics_in_type_p): Delete.
	(convert_affine_scev): Remove call to above function.
	(chrec_convert_aggressive): Likewise.
	* tree-scalar-evolution.c (follow_ssa_edge_expr) <PLUS_EXPR>:
	Propagate the type of the first operand.
	(follow_ssa_edge_in_rhs) <GIMPLE_BINARY_RHS>: Likewise
	* tree-ssa.c (useless_type_conversion_p_1): Do not specifically return
	false for conversions involving subtypes.
	* tree-vrp.c (vrp_val_max): Do not get to the base type.
	(vrp_val_min): Likewise.
	(needs_overflow_infinity): Do not special-case subtypes.
	(extract_range_from_unary_expr): Do not use the base types.


-- 
Eric Botcazou
Index: tree-vrp.c
===================================================================
--- tree-vrp.c	(revision 145851)
+++ tree-vrp.c	(working copy)
@@ -121,7 +121,7 @@ DEF_VEC_ALLOC_O(switch_update, heap);
 static VEC (switch_update, heap) *to_update_switch_stmts;
 
 
-/* Return the maximum value for TYPEs base type.  */
+/* Return the maximum value for TYPE.  */
 
 static inline tree
 vrp_val_max (const_tree type)
@@ -129,14 +129,10 @@ vrp_val_max (const_tree type)
   if (!INTEGRAL_TYPE_P (type))
     return NULL_TREE;
 
-  /* For integer sub-types the values for the base type are relevant.  */
-  if (TREE_TYPE (type))
-    type = TREE_TYPE (type);
-
   return TYPE_MAX_VALUE (type);
 }
 
-/* Return the minimum value for TYPEs base type.  */
+/* Return the minimum value for TYPE.  */
 
 static inline tree
 vrp_val_min (const_tree type)
@@ -144,10 +140,6 @@ vrp_val_min (const_tree type)
   if (!INTEGRAL_TYPE_P (type))
     return NULL_TREE;
 
-  /* For integer sub-types the values for the base type are relevant.  */
-  if (TREE_TYPE (type))
-    type = TREE_TYPE (type);
-
   return TYPE_MIN_VALUE (type);
 }
 
@@ -188,11 +180,7 @@ vrp_val_is_min (const_tree val)
 static inline bool
 needs_overflow_infinity (const_tree type)
 {
-  return (INTEGRAL_TYPE_P (type)
-	  && !TYPE_OVERFLOW_WRAPS (type)
-	  /* Integer sub-types never overflow as they are never
-	     operands of arithmetic operators.  */
-	  && !(TREE_TYPE (type) && TREE_TYPE (type) != type));
+  return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
 }
 
 /* Return whether TYPE can support our overflow infinity
@@ -2708,13 +2696,6 @@ extract_range_from_unary_expr (value_ran
       tree inner_type = TREE_TYPE (op0);
       tree outer_type = type;
 
-      /* Always use base-types here.  This is important for the
-	 correct signedness.  */
-      if (TREE_TYPE (inner_type))
-	inner_type = TREE_TYPE (inner_type);
-      if (TREE_TYPE (outer_type))
-	outer_type = TREE_TYPE (outer_type);
-
       /* If VR0 is varying and we increase the type precision, assume
 	 a full range for the following transformation.  */
       if (vr0.type == VR_VARYING
Index: tree-scalar-evolution.c
===================================================================
--- tree-scalar-evolution.c	(revision 145851)
+++ tree-scalar-evolution.c	(working copy)
@@ -1182,6 +1182,7 @@ follow_ssa_edge_expr (struct loop *loop,
       /* This case is under the form "rhs0 +- rhs1".  */
       rhs0 = TREE_OPERAND (expr, 0);
       rhs1 = TREE_OPERAND (expr, 1);
+      type = TREE_TYPE (rhs0);
       STRIP_TYPE_NOPS (rhs0);
       STRIP_TYPE_NOPS (rhs1);
       return follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
@@ -1216,16 +1217,17 @@ static t_bool
 follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt,
 			gimple halting_phi, tree *evolution_of_loop, int limit)
 {
-  tree type = TREE_TYPE (gimple_assign_lhs (stmt));
   enum tree_code code = gimple_assign_rhs_code (stmt);
 
   switch (get_gimple_rhs_class (code))
     {
     case GIMPLE_BINARY_RHS:
-      return follow_ssa_edge_binary (loop, stmt, type,
-				     gimple_assign_rhs1 (stmt), code,
-				     gimple_assign_rhs2 (stmt),
-				     halting_phi, evolution_of_loop, limit);
+      {
+	tree rhs1 = gimple_assign_rhs1 (stmt);
+	return follow_ssa_edge_binary (loop, stmt, TREE_TYPE (rhs1), rhs1,
+				       code, gimple_assign_rhs2 (stmt),
+				       halting_phi, evolution_of_loop, limit);
+      }
     case GIMPLE_SINGLE_RHS:
       return follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
 				   halting_phi, evolution_of_loop, limit);
@@ -1233,6 +1235,7 @@ follow_ssa_edge_in_rhs (struct loop *loo
       if (code == NOP_EXPR)
 	{
 	  /* This assignment is under the form "a_1 = (cast) rhs.  */
+	  tree type = TREE_TYPE (gimple_assign_lhs (stmt));
 	  t_bool res
 	    = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
 				    halting_phi, evolution_of_loop, limit);
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 145851)
+++ fold-const.c	(working copy)
@@ -3732,10 +3732,12 @@ fold_truth_not_expr (tree arg)
       return invert_truthvalue (TREE_OPERAND (arg, 0));
 
     case NOP_EXPR:
+    case CONVERT_EXPR:
       if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
 	return build1 (TRUTH_NOT_EXPR, type, arg);
 
-    case CONVERT_EXPR:
+      /* ... fall through ...  */
+
     case FLOAT_EXPR:
       return build1 (TREE_CODE (arg), type,
 		     invert_truthvalue (TREE_OPERAND (arg, 0)));
Index: tree-chrec.c
===================================================================
--- tree-chrec.c	(revision 145851)
+++ tree-chrec.c	(working copy)
@@ -1100,21 +1100,6 @@ nb_vars_in_chrec (tree chrec)
     }
 }
 
-/* Returns true if TYPE is a type in that we cannot directly perform
-   arithmetics, even though it is a scalar type.  */
-
-static bool
-avoid_arithmetics_in_type_p (const_tree type)
-{
-  /* Ada frontend uses subtypes -- an arithmetic cannot be directly performed
-     in the subtype, but a base type must be used, and the result then can
-     be casted to the subtype.  */
-  if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
-    return true;
-
-  return false;
-}
-
 static tree chrec_convert_1 (tree, tree, gimple, bool);
 
 /* Converts BASE and STEP of affine scev to TYPE.  LOOP is the loop whose iv
@@ -1136,10 +1121,6 @@ convert_affine_scev (struct loop *loop,
   tree new_base, new_step;
   tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
 
-  /* If we cannot perform arithmetic in TYPE, avoid creating an scev.  */
-  if (avoid_arithmetics_in_type_p (type))
-    return false;
-
   /* In general,
      (TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
      but we must check some assumptions.
@@ -1342,10 +1323,6 @@ chrec_convert_aggressive (tree type, tre
   if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
     return NULL_TREE;
 
-  /* If we cannot perform arithmetic in TYPE, avoid creating an scev.  */
-  if (avoid_arithmetics_in_type_p (type))
-    return NULL_TREE;
-
   rtype = POINTER_TYPE_P (type) ? sizetype : type;
 
   left = CHREC_LEFT (chrec);
Index: tree-ssa.c
===================================================================
--- tree-ssa.c	(revision 145851)
+++ tree-ssa.c	(working copy)
@@ -923,19 +923,9 @@ useless_type_conversion_p_1 (tree outer_
 	  || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
 	return false;
 
-      /* Conversions from a non-base to a base type are not useless.
-	 This way we preserve the invariant to do arithmetic in
-	 base types only.  */
-      if (TREE_TYPE (inner_type)
-	  && TREE_TYPE (inner_type) != inner_type
-	  && (TREE_TYPE (outer_type) == outer_type
-	      || TREE_TYPE (outer_type) == NULL_TREE))
-	return false;
-
       /* We don't need to preserve changes in the types minimum or
 	 maximum value in general as these do not generate code
 	 unless the types precisions are different.  */
-
       return true;
     }
 

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