diff mbox

[PR,49343] Make SRA cope with some fields with variable offsets

Message ID 20110615163323.GE30874@virgil.arch.suse.de
State New
Headers show

Commit Message

Martin Jambor June 15, 2011, 4:33 p.m. UTC
Hi,

PR 49343 showed that build_ref_for_model in tree-sra.c used a more
primitive technique to determine an offset of a field than
get_ref_base_and_extent, cannot crunch fields with "placeholders" in
their offsets and ICEs on them (while  get_ref_base_and_extent
processed them fine before).

Fixed thusly, code closely follows what is in get_ref_base_and_extent
but is simpler because we know that function has once already accepted
this input.

Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin



2011-06-10  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/49343
	* tree-sra.c (build_ref_for_model): Use component_ref_field_offset to
	calculate offset, provide 2nd operand for the new COMPONENT_REF.

	* testsuite/gnat.dg/discr31.adb: New test.
	* testsuite/gnat.dg/discr31.ads: Likewise.

Comments

Richard Biener June 16, 2011, 7:34 a.m. UTC | #1
On Wed, Jun 15, 2011 at 6:33 PM, Martin Jambor <mjambor@suse.cz> wrote:
> Hi,
>
> PR 49343 showed that build_ref_for_model in tree-sra.c used a more
> primitive technique to determine an offset of a field than
> get_ref_base_and_extent, cannot crunch fields with "placeholders" in
> their offsets and ICEs on them (while  get_ref_base_and_extent
> processed them fine before).
>
> Fixed thusly, code closely follows what is in get_ref_base_and_extent
> but is simpler because we know that function has once already accepted
> this input.
>
> Bootstrapped and tested on x86_64-linux.  OK for trunk?

Ok.

Thanks,
Richard.

> Thanks,
>
> Martin
>
>
>
> 2011-06-10  Martin Jambor  <mjambor@suse.cz>
>
>        PR tree-optimization/49343
>        * tree-sra.c (build_ref_for_model): Use component_ref_field_offset to
>        calculate offset, provide 2nd operand for the new COMPONENT_REF.
>
>        * testsuite/gnat.dg/discr31.adb: New test.
>        * testsuite/gnat.dg/discr31.ads: Likewise.
>
>
> Index: src/gcc/tree-sra.c
> ===================================================================
> --- src.orig/gcc/tree-sra.c
> +++ src/gcc/tree-sra.c
> @@ -1421,12 +1421,16 @@ build_ref_for_model (location_t loc, tre
>  {
>   if (TREE_CODE (model->expr) == COMPONENT_REF)
>     {
> -      tree t, exp_type;
> -      offset -= int_bit_position (TREE_OPERAND (model->expr, 1));
> +      tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
> +      tree cr_offset = component_ref_field_offset (model->expr);
> +
> +      gcc_assert (cr_offset && host_integerp (cr_offset, 1));
> +      offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT;
> +      offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld));
>       exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
>       t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
> -      return fold_build3_loc (loc, COMPONENT_REF, model->type, t,
> -                             TREE_OPERAND (model->expr, 1), NULL_TREE);
> +      return fold_build3_loc (loc, COMPONENT_REF, model->type, t, fld,
> +                             TREE_OPERAND (model->expr, 2));
>     }
>   else
>     return build_ref_for_offset (loc, base, offset, model->type,
> Index: src/gcc/testsuite/gnat.dg/discr31.adb
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gnat.dg/discr31.adb
> @@ -0,0 +1,12 @@
> +-- { dg-do compile }
> +-- { dg-options "-O" }
> +
> +package body Discr31 is
> +
> +   function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type is
> +      None : Log_Item_Type(0);
> +   begin
> +      return None;
> +   end;
> +
> +end Discr31;
> Index: src/gcc/testsuite/gnat.dg/discr31.ads
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gnat.dg/discr31.ads
> @@ -0,0 +1,14 @@
> +package Discr31 is
> +
> +   type Byte_List_Type is array(Positive range <>) of Integer;
> +
> +   type Log_Item_Type(Last : Natural) is record
> +      Data : Byte_List_Type(1 .. Last) := (others => 0);
> +      Link : Natural := 0;
> +   end record;
> +
> +   type Packet_Data_Type is access Log_Item_Type;
> +
> +   function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type;
> +
> +end Discr31;
>
diff mbox

Patch

Index: src/gcc/tree-sra.c
===================================================================
--- src.orig/gcc/tree-sra.c
+++ src/gcc/tree-sra.c
@@ -1421,12 +1421,16 @@  build_ref_for_model (location_t loc, tre
 {
   if (TREE_CODE (model->expr) == COMPONENT_REF)
     {
-      tree t, exp_type;
-      offset -= int_bit_position (TREE_OPERAND (model->expr, 1));
+      tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
+      tree cr_offset = component_ref_field_offset (model->expr);
+
+      gcc_assert (cr_offset && host_integerp (cr_offset, 1));
+      offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT;
+      offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld));
       exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
       t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
-      return fold_build3_loc (loc, COMPONENT_REF, model->type, t,
-			      TREE_OPERAND (model->expr, 1), NULL_TREE);
+      return fold_build3_loc (loc, COMPONENT_REF, model->type, t, fld,
+			      TREE_OPERAND (model->expr, 2));
     }
   else
     return build_ref_for_offset (loc, base, offset, model->type,
Index: src/gcc/testsuite/gnat.dg/discr31.adb
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gnat.dg/discr31.adb
@@ -0,0 +1,12 @@ 
+-- { dg-do compile }
+-- { dg-options "-O" }
+
+package body Discr31 is
+
+   function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type is
+      None : Log_Item_Type(0);
+   begin
+      return None;
+   end;
+
+end Discr31;
Index: src/gcc/testsuite/gnat.dg/discr31.ads
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gnat.dg/discr31.ads
@@ -0,0 +1,14 @@ 
+package Discr31 is
+
+   type Byte_List_Type is array(Positive range <>) of Integer;
+
+   type Log_Item_Type(Last : Natural) is record
+      Data : Byte_List_Type(1 .. Last) := (others => 0);
+      Link : Natural := 0;
+   end record;
+
+   type Packet_Data_Type is access Log_Item_Type;
+
+   function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type;
+
+end Discr31;