Message ID | 20110615163323.GE30874@virgil.arch.suse.de |
---|---|
State | New |
Headers | show |
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; >
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;