Commit 324c9b02 by Olivier Hainque Committed by Olivier Hainque

tree.h (CONSTRUCTOR_BITFIELD_P): True if NODE...

	* tree.h (CONSTRUCTOR_BITFIELD_P): True if NODE, a FIELD_DECL, is
	to be processed as a bitfield for constructor output purposes.
	* output.h (initializer_constant_valid_for_bitfield_p): Declare
	new function.
	* varasm.c (oc_local_state): New type, output_constructor
	local state to support communication with helpers.
	(oc_outer_state): New type, output_constructor outer state of
	relevance in recursive calls.
	(output_constructor_array_range): New output_constructor helper,
	extracted code for an array range element.
	(output_constructor_regular_field): New output_constructor helper,
	extracted code for an element that is not a bitfield.
	(output_constructor_bitfield): New output_constructor helper,
	extracted code for a bitfield element.  Accept an OUTER state
	argument for recursive processing.  Recurse on record or array
	CONSTRUCTOR values, possibly past noop conversions.
	(initializer_constant_valid_for_bitfield_p): New predicate. Whether
	VALUE is a valid constant-valued expression for use in a static
	bit-field initializer.
	(output_constructor): Rework to use helpers. Accept and honor an
	OUTER state argument for recursive calls. Return total size. Be
	prepared for nested constructors initializing bitfields.
	(output_constant): Feed OUTER in calls to output_constructor.

	ada/
	* gcc-interface/utils2.c (gnat_build_constructor): Factor
	out code. Use initializer_constant_valid_for_bitfield_p and
	CONSTRUCTOR_BITFIELD_P for bit-fields.

	testsuite/
	* gnat.dg/oconst[1-6].ad[bs]: New tests. Also support for ...
	* gnat.dg/test_oconst.adb: New test.


Co-Authored-By: Eric Botcazou <ebotcazou@adacore.com>

From-SVN: r148045
parent 0980d7fe
2009-06-01 Olivier Hainque <hainque@adacore.com>
Eric Botcazou <botcazou@adacore.com>
* tree.h (CONSTRUCTOR_BITFIELD_P): True if NODE, a FIELD_DECL, is
to be processed as a bitfield for constructor output purposes.
* output.h (initializer_constant_valid_for_bitfield_p): Declare
new function.
* varasm.c (oc_local_state): New type, output_constructor
local state to support communication with helpers.
(oc_outer_state): New type, output_constructor outer state of
relevance in recursive calls.
(output_constructor_array_range): New output_constructor helper,
extracted code for an array range element.
(output_constructor_regular_field): New output_constructor helper,
extracted code for an element that is not a bitfield.
(output_constructor_bitfield): New output_constructor helper,
extracted code for a bitfield element. Accept an OUTER state
argument for recursive processing. Recurse on record or array
CONSTRUCTOR values, possibly past noop conversions.
(initializer_constant_valid_for_bitfield_p): New predicate. Whether
VALUE is a valid constant-valued expression for use in a static
bit-field initializer.
(output_constructor): Rework to use helpers. Accept and honor an
OUTER state argument for recursive calls. Return total size. Be
prepared for nested constructors initializing bitfields.
(output_constant): Feed OUTER in calls to output_constructor.
2009-06-01 Maxim Kuvyrkov <maxim@codesourcery.com>
* calls.c (emit_library_call_value_1): Don't force_operand for move
......
2009-06-01 Olivier Hainque <hainque@adacore.com>
Eric Botcazou <botcazou@adacore.com>
* gcc-interface/utils2.c (gnat_build_constructor): Factor
out code. Use initializer_constant_valid_for_bitfield_p and
CONSTRUCTOR_BITFIELD_P for bit-fields.
2009-05-26 Ian Lance Taylor <iant@google.com>
* gcc-interface/Makefile.in (COMPILER): Define.
......
......@@ -1623,34 +1623,35 @@ compare_elmt_bitpos (const PTR rt1, const PTR rt2)
tree
gnat_build_constructor (tree type, tree list)
{
tree elmt;
int n_elmts;
bool allconstant = (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST);
bool side_effects = false;
tree result;
tree elmt, result;
int n_elmts;
/* Scan the elements to see if they are all constant or if any has side
effects, to let us set global flags on the resulting constructor. Count
the elements along the way for possible sorting purposes below. */
for (n_elmts = 0, elmt = list; elmt; elmt = TREE_CHAIN (elmt), n_elmts ++)
{
if (!TREE_CONSTANT (TREE_VALUE (elmt))
tree obj = TREE_PURPOSE (elmt);
tree val = TREE_VALUE (elmt);
/* The predicate must be in keeping with output_constructor. */
if (!TREE_CONSTANT (val)
|| (TREE_CODE (type) == RECORD_TYPE
&& DECL_BIT_FIELD (TREE_PURPOSE (elmt))
&& TREE_CODE (TREE_VALUE (elmt)) != INTEGER_CST)
|| !initializer_constant_valid_p (TREE_VALUE (elmt),
TREE_TYPE (TREE_VALUE (elmt))))
&& CONSTRUCTOR_BITFIELD_P (obj)
&& !initializer_constant_valid_for_bitfield_p (val))
|| !initializer_constant_valid_p (val, TREE_TYPE (val)))
allconstant = false;
if (TREE_SIDE_EFFECTS (TREE_VALUE (elmt)))
if (TREE_SIDE_EFFECTS (val))
side_effects = true;
/* Propagate an NULL_EXPR from the size of the type. We won't ever
be executing the code we generate here in that case, but handle it
specially to avoid the compiler blowing up. */
if (TREE_CODE (type) == RECORD_TYPE
&& (0 != (result
= contains_null_expr (DECL_SIZE (TREE_PURPOSE (elmt))))))
&& (result = contains_null_expr (DECL_SIZE (obj))) != NULL_TREE)
return build1 (NULL_EXPR, type, TREE_OPERAND (result, 0));
}
......
......@@ -303,6 +303,11 @@ extern bool constructor_static_from_elts_p (const_tree);
arithmetic-combinations of integers. */
extern tree initializer_constant_valid_p (tree, tree);
/* Return true if VALUE is a valid constant-valued expression
for use in initializing a static bit-field; one that can be
an element of a "constant" initializer. */
extern bool initializer_constant_valid_for_bitfield_p (tree);
/* Output assembler code for constant EXP to FILE, with no label.
This includes the pseudo-op such as ".int" or ".byte", and a newline.
Assumes output_addressed_constants has been done on EXP already.
......
2009-06-01 Olivier Hainque <hainque@adacore.com>
Eric Botcazou <botcazou@adacore.com>
* gnat.dg/oconst[1-6].ad[bs]: New tests. Also support for ...
* gnat.dg/test_oconst.adb: New test.
2009-05-31 Basile Starynkevitch <basile@starynkevitch.net>
......
-- { dg-do compile }
-- { dg-final { scan-assembler-not "elabs" } }
package body OCONST1 is
procedure check (arg : R) is
begin
if arg.u /= 1
or else arg.b.i1 /= 2
or else arg.b.i2 /= 3
or else arg.b.i3 /= 4
then
raise Program_Error;
end if;
end;
end;
package OCONST1 is
type u8 is mod 2**8;
type Base is record
i1 : Integer;
i2 : Integer;
i3 : Integer;
end Record;
type R is record
u : u8;
b : Base;
end record;
for R use record
u at 0 range 0 .. 7;
b at 1 range 0 .. 95; -- BLKmode bitfield
end record;
My_R : constant R := (u=>1, b=>(2, 3, 4));
procedure check (arg : R);
end;
-- { dg-do compile }
-- { dg-final { scan-assembler-not "elabs" } }
package body OCONST2 is
procedure check (arg : R) is
begin
if arg.u /= 1
or else arg.b.i1 /= 2
then
raise Program_Error;
end if;
end;
end;
package OCONST2 is
type u8 is mod 2**8;
type Base is record
i1 : Integer;
end Record;
type R is record
u : u8;
b : Base;
end record;
for R use record
u at 0 range 0 .. 7;
b at 1 range 0 .. 31; -- aligned SImode bitfield
end record;
My_R : constant R := (u=>1, b=>(i1=>2));
procedure check (arg : R);
end;
-- { dg-do compile }
-- { dg-final { scan-assembler-not "elabs" } }
package body OCONST3 is
procedure check (arg : R) is
begin
if arg.u /= 1
or else arg.f /= one
or else arg.b.i1 /= 3
then
raise Program_Error;
end if;
end;
end;
package OCONST3 is
type bit is (zero, one);
type u8 is mod 2**8;
type Base is record
i1 : Integer;
end Record;
type R is record
u : u8;
f : bit;
b : Base;
end record;
for R use record
u at 0 range 0 .. 7;
f at 1 range 0 .. 0;
b at 1 range 1 .. 32; -- unaligned SImode bitfield
end record;
My_R : constant R := (u=>1, f=>one, b=>(i1=>3));
procedure check (arg : R);
end;
-- { dg-do compile }
-- { dg-final { scan-assembler-not "elabs" } }
package body OCONST4 is
procedure check (arg : R) is
begin
if arg.u /= 1
or else arg.d.f1 /= 17
or else arg.d.b.f1 /= one
or else arg.d.b.f2 /= 2
or else arg.d.b.f3 /= 17
or else arg.d.b.f4 /= 42
or else arg.d.f2 /= one
or else arg.d.f3 /= 1
or else arg.d.f4 /= 111
or else arg.d.i1 /= 2
or else arg.d.i2 /= 3
then
raise Program_Error;
end if;
end;
end;
package OCONST4 is
type bit is (zero, one);
type u2 is mod 2**2;
type u5 is mod 2**5;
type u8 is mod 2**8;
type Base is record
f1 : bit;
f2 : u2;
f3 : u5;
f4 : u8;
end record;
for Base use record
f1 at 0 range 0 .. 0;
f2 at 0 range 1 .. 2;
f3 at 0 range 3 .. 7;
f4 at 1 range 0 .. 7;
end record;
type Derived is record
f1 : u5;
b : Base;
f2 : bit;
f3 : u2;
f4 : u8;
i1 : Integer;
i2 : Integer;
end record;
for Derived use record
f1 at 0 range 0 .. 4;
b at 0 range 5 .. 20; -- unaligned HImode bitfield
f2 at 0 range 21 .. 21;
f3 at 0 range 22 .. 23;
f4 at 0 range 24 .. 31;
i1 at 4 range 0 .. 31;
i2 at 8 range 0 .. 31;
end record;
type R is record
u : u8;
d : Derived;
end record;
for R use record
u at 0 range 0 .. 7;
d at 1 range 0 .. 95; -- BLKmode bitfield
end record;
My_R : constant R := (u=>1,
d=>(f1=>17,
b=>(f1=>one,
f2=>2,
f3=>17,
f4=>42),
f2=>one,
f3=>1,
f4=>111,
i1=>2,
i2=>3));
procedure check (arg : R);
end;
-- { dg-do compile }
-- { dg-final { scan-assembler-not "elabs" } }
package body OCONST5 is
procedure Check (Arg : R; Bit : U1) is
begin
if Arg.Bit /= Bit
or else Arg.Agg.A /= 3
or else Arg.Agg.B /= 7
then
raise Program_Error;
end if;
end;
end;
package OCONST5 is
type u1 is mod 2**1;
type u8 is mod 2**8;
type HI_Record is record
A, B : U8;
end record;
pragma Suppress_Initialization (HI_Record);
type R is record
Bit : U1;
Agg : HI_Record;
end record;
pragma Suppress_Initialization (R);
for R use record
Bit at 0 range 0 .. 0;
Agg at 0 range 1 .. 16;
end record;
My_R0 : R := (Bit => 0, Agg => (A => 3, B => 7));
My_R1 : R := (Bit => 1, Agg => (A => 3, B => 7));
procedure Check (Arg : R; Bit : U1);
end;
-- { dg-do compile }
-- { dg-final { scan-assembler-not "elabs" } }
package OCONST6 is
type Sequence is array (1 .. 1) of Natural;
type Message is record
Data : Sequence;
end record;
for Message'Alignment use 1;
pragma PACK (Message);
ACK : Message := (Data => (others => 1));
end;
-- { dg-do run }
with OCONST1, OCONST2, OCONST3, OCONST4, OCONST5;
procedure Test_Oconst is
begin
OCONST1.check (OCONST1.My_R);
OCONST2.check (OCONST2.My_R);
OCONST3.check (OCONST3.My_R);
OCONST4.check (OCONST4.My_R);
OCONST5.check (OCONST5.My_R0, 0);
OCONST5.check (OCONST5.My_R1, 1);
end;
......@@ -1502,6 +1502,11 @@ struct GTY(()) tree_vec {
_ce___->value = VALUE; \
} while (0)
/* True if NODE, a FIELD_DECL, is to be processed as a bitfield for
constructor output purposes. */
#define CONSTRUCTOR_BITFIELD_P(NODE) \
(DECL_BIT_FIELD (FIELD_DECL_CHECK (NODE)) && DECL_MODE (NODE) != BLKmode)
/* A single element of a CONSTRUCTOR. VALUE holds the actual value of the
element. INDEX can optionally design the position of VALUE: in arrays,
it is the index where VALUE has to be placed; in structures, it is the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment