Do not use TYPE_CANONICAL in useless_type_conversion

Jan Hubicka hubicka@ucw.cz
Wed Oct 7 06:00:00 GMT 2015


> > 
> > The patch works for me but I'm not sure about the store_expr_with_bounds
> > change.  Where does the actual copying take place?  adjust_address_nv
> > just adjusts the mode ...
> 
> Yep, the mode was supposed to happen in the later path where we emit block moves,
> but i missed an else there.  I will update the patch.  Thanks for catching this.

Hi,
here is updated patch with temp not being ignored - it will fall into the 
emit_block_move as expected. I tested the pach on x86_64-linux, ppc64-linux
testing in progress, OK?

Honza

	* expr.c (store_expr_with_bounds): Handle aggregate moves from
	BLKmode.
	* gimple-expr.c (useless_type_conversion_p): Do not use TYPE_CANONICAL
	to define gimple type system; compare aggregates only by size.

Index: ../gcc/expr.c
===================================================================
--- ../gcc/expr.c	(revision 228267)
+++ ../gcc/expr.c	(working copy)
@@ -5425,6 +5425,15 @@ store_expr_with_bounds (tree exp, rtx ta
     temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
 			  temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
 
+  /* We allow move between structures of same size but different mode.
+     If source is in memory and the mode differs, simply change the memory.  */
+  if (GET_MODE (temp) == BLKmode && GET_MODE (target) != BLKmode)
+    {
+      gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (exp)));
+      gcc_assert (MEM_P (temp));
+      temp = adjust_address_nv (temp, GET_MODE (target), 0);
+    }
+
   /* If value was not generated in the target, store it there.
      Convert the value to TARGET's type first if necessary and emit the
      pending incrementations that have been queued when expanding EXP.
Index: ../gcc/gimple-expr.c
===================================================================
--- ../gcc/gimple-expr.c	(revision 228267)
+++ ../gcc/gimple-expr.c	(working copy)
@@ -87,11 +87,6 @@ useless_type_conversion_p (tree outer_ty
   if (inner_type == outer_type)
     return true;
 
-  /* If we know the canonical types, compare them.  */
-  if (TYPE_CANONICAL (inner_type)
-      && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type))
-    return true;
-
   /* Changes in machine mode are never useless conversions unless we
      deal with aggregate types in which case we defer to later checks.  */
   if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)
@@ -270,12 +265,23 @@ useless_type_conversion_p (tree outer_ty
       return true;
     }
 
-  /* For aggregates we rely on TYPE_CANONICAL exclusively and require
-     explicit conversions for types involving to be structurally
-     compared types.  */
+  /* For aggregates compare only the size.  Accesses to fields do have
+     a type information by themselves and thus we only care if we can i.e.
+     use the types in move operations.  */
   else if (AGGREGATE_TYPE_P (inner_type)
 	   && TREE_CODE (inner_type) == TREE_CODE (outer_type))
-    return false;
+    return (!TYPE_SIZE (outer_type)
+	    || (TYPE_SIZE (inner_type)
+		&& operand_equal_p (TYPE_SIZE (inner_type),
+				    TYPE_SIZE (outer_type), 0)));
+
+  else if (TREE_CODE (inner_type) == OFFSET_TYPE
+	   && TREE_CODE (inner_type) == TREE_CODE (outer_type))
+    return useless_type_conversion_p (TREE_TYPE (outer_type),
+				      TREE_TYPE (inner_type))
+	   && useless_type_conversion_p
+	        (TYPE_OFFSET_BASETYPE (outer_type),
+		 TYPE_OFFSET_BASETYPE (inner_type));
 
   return false;
 }



More information about the Gcc-patches mailing list