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]

Re: Do not use TYPE_CANONICAL in useless_type_conversion


> > The type has BLKmode and size 32. DECL_SIZE of the FIELD_DECL is however 24
> > (see it printed as Ada size).
> 
> Yes, no wonder since it's a bitfield, i.e. DECL_BIT_FIELD is set.
> 
> > The DECL_MODE of the FIELD_DECL is VOIDmode (not printed), while the
> > TYPE_MODE of type contained is BLKmode.
> 
> No, the DECL_MODE of a FIELD_DECL cannot be VOIDmode, it's SImode (printed).

Hmm you are right.  The reason is...
> 
> > Because
> > get_inner_reference compute mode based on DECL_MODE:
> >   if (TREE_CODE (exp) == COMPONENT_REF)
> >     {
> >       tree field = TREE_OPERAND (exp, 1);
> >       size_tree = DECL_SIZE (field);
> >       if (flag_strict_volatile_bitfields > 0
> >           && TREE_THIS_VOLATILE (exp)
> >           && DECL_BIT_FIELD_TYPE (field)
> >           && DECL_MODE (field) != BLKmode)
> >         /* Volatile bitfields should be accessed in the mode of the
> >              field's type, not the mode computed based on the bit
> >              size.  */
> >         mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
> >       else if (!DECL_BIT_FIELD (field))
> >         mode = DECL_MODE (field);

... we initialize mode to be non-VOIDmode only if the field is not bitfield. I missed
the flag while looking at the dump.  Indeed the DECL_MODE if FIELD_DECL is SImode,
but it is ignored.

> > Index: expr.c
> > ===================================================================
> > --- expr.c	(revision 228604)
> > +++ expr.c	(working copy)
> > @@ -6703,7 +6704,7 @@ store_field (rtx target, HOST_WIDE_INT b
> >  	  emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
> >  	  temp = temp_target;
> >  	}
> > -      else if (mode == BLKmode)
> > +      else if (GET_MODE (temp) == BLKmode)
> >  	{
> >  	  /* Handle calls that return BLKmode values in registers.  */
> >  	  if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
> 
> This cannot be right, you're short-circuiting the REG_P (temp) test below.

Hmm, it seems that for CALL_EXPR the register is supposed to be non-BLKmode
already.  So I guess only what we need to do is to consider bifields when 
TEMP is blk mode and then we want to convert? what about this?

Honza

Index: expr.c
===================================================================
--- expr.c	(revision 228604)
+++ expr.c	(working copy)
@@ -6703,26 +6703,23 @@ store_field (rtx target, HOST_WIDE_INT b
 	  emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
 	  temp = temp_target;
 	}
-      else if (mode == BLKmode)
+      /* Handle calls that return BLKmode values in registers.  */
+      else if (mode == BLKmode && (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR))
 	{
-	  /* Handle calls that return BLKmode values in registers.  */
-	  if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
-	    {
-	      rtx temp_target = gen_reg_rtx (GET_MODE (temp));
-	      copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
-	      temp = temp_target;
-	    }
-	  else
-	    {
-	      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
-	      rtx temp_target;
-	      mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
-	      temp_target = gen_reg_rtx (mode);
-	      temp_target
-	        = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
-				     temp_target, mode, mode);
-	      temp = temp_target;
-	    }
+	  rtx temp_target = gen_reg_rtx (GET_MODE (temp));
+	  copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
+	  temp = temp_target;
+	}
+      else if (GET_MODE (temp) == BLKmode)
+	{
+	  HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+	  rtx temp_target;
+	  mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
+	  temp_target = gen_reg_rtx (mode);
+	  temp_target
+	    = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
+				 temp_target, mode, mode);
+	  temp = temp_target;
 	}
 
       /* Store the value in the bitfield.  */
> 
> -- 
> Eric Botcazou


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