expr.c (get_inner_reference): Use sbitsizetype for type sizes.

* expr.c (get_inner_reference): Use sbitsizetype for type sizes.
        * fold-const.c (size_int): Replace with
        (size_int_wide).
        (make_bit_field_ref): Use bitsize_int for bit position.
        * stor-layout.c (sizetype): Delete.
        (sizetype_tab, sbitsizetype, ubitsizetype): Declare.
        (layout_record, layout_union, layout_type):
        Use bitsize_int for bit size.
        (set_sizetype): New function.
        (make_signed_type, make_unsigned_type): Use it.
        * c-decl.c (init_decl_processing): Likewise.
        * tree.h (size_int): Don't delcare, #define.
        (size_int_wide, sizetype_tab, sbitsize, ubitsize): Declare.
        (set_sizetype): Declare.
        (bitsize_int, size_int_2, BITS_PER_UNIT_LOG, sizetype, bitsizetype):
        Define.
        * c-typeck.c (c_sizeof, c_sizeof_nowarn, c_size_in_bytes):
        Convert result to sizetype.
        (really_start_incremental_init, push_init_level):
        Set type of constructor_bit_index to sbitsizetype.
        (push_init_level): Use unsigned arithmetic to determine padding.
        (output_init_element): Likewise.

From-SVN: r17577
This commit is contained in:
J"orn Rennecke 1998-02-01 11:47:59 +00:00 committed by Jeff Law
parent f5426d1e9b
commit f8dac6eb3f
8 changed files with 191 additions and 71 deletions

View File

@ -1,3 +1,28 @@
Sun Feb 1 12:39:53 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* expr.c (get_inner_reference): Use sbitsizetype for type sizes.
* fold-const.c (size_int): Replace with
(size_int_wide).
(make_bit_field_ref): Use bitsize_int for bit position.
* stor-layout.c (sizetype): Delete.
(sizetype_tab, sbitsizetype, ubitsizetype): Declare.
(layout_record, layout_union, layout_type):
Use bitsize_int for bit size.
(set_sizetype): New function.
(make_signed_type, make_unsigned_type): Use it.
* c-decl.c (init_decl_processing): Likewise.
* tree.h (size_int): Don't delcare, #define.
(size_int_wide, sizetype_tab, sbitsize, ubitsize): Declare.
(set_sizetype): Declare.
(bitsize_int, size_int_2, BITS_PER_UNIT_LOG, sizetype, bitsizetype):
Define.
* c-typeck.c (c_sizeof, c_sizeof_nowarn, c_size_in_bytes):
Convert result to sizetype.
(really_start_incremental_init, push_init_level):
Set type of constructor_bit_index to sbitsizetype.
(push_init_level): Use unsigned arithmetic to determine padding.
(output_init_element): Likewise.
Sun Feb 1 03:32:07 1998 Jeffrey A Law (law@cygnus.com)
* combine.c (simplify_shift_const): Fix typo in last change.

32
gcc/LANGUAGES Normal file
View File

@ -0,0 +1,32 @@
Right now there is no documentation for the GCC tree -> rtl interfaces
(or more generally the interfaces for adding new languages).
Such documentation would be of great benefit to the project. Until such
time as we can formally start documenting the interface this file will
serve as a repository for information on these interface and any incompatable
changes we've made.
Feb 1, 1998:
GCC used to store structure sizes & offsets to elements as bitsize
quantities. This causes problems because a structure can only be
(target memsize / 8) bytes long (this may effect arrays too). This
is particularly problematical on machines with small address spaces.
So:
All trees that represent sizes in bits should have a TREE_TYPE of
bitsizetype (rather than sizetype).
Accordingly, when such values are computed / initialized, care has to
be takes to use / compute the proper type.
When a size in bits is converted into a size in bytes, which is expressed
in trees, care should be taken to change the tree's type again to sizetype.
We've updated C, C++, Fortran & Objective-C to work with the new
scheme. Other languages will need to be updated accordingly.
Contact amylaar@cygnus.com for additional information.

View File

@ -1,5 +1,5 @@
/* Process declarations and variables for C compiler.
Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -2946,25 +2946,15 @@ init_decl_processing ()
/* `unsigned long' is the standard type for sizeof.
Traditionally, use a signed type.
Note that stddef.h uses `unsigned long',
and this must agree, even of long and int are the same size. */
sizetype
= TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
and this must agree, even if long and int are the same size. */
set_sizetype
(TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
if (flag_traditional && TREE_UNSIGNED (sizetype))
sizetype = signed_type (sizetype);
set_sizetype (signed_type (sizetype));
ptrdiff_type_node
= TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
error_mark_node = make_node (ERROR_MARK);
TREE_TYPE (error_mark_node) = error_mark_node;

View File

@ -852,6 +852,7 @@ c_sizeof (type)
/* Convert in case a char is more than one unit. */
t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
size_int (TYPE_PRECISION (char_type_node)));
t = convert (sizetype, t);
/* size_binop does not put the constant in range, so do it now. */
if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
@ -875,6 +876,7 @@ c_sizeof_nowarn (type)
/* Convert in case a char is more than one unit. */
t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
size_int (TYPE_PRECISION (char_type_node)));
t = convert (sizetype, t);
force_fit_type (t, 0);
return t;
}
@ -903,6 +905,7 @@ c_size_in_bytes (type)
/* Convert in case a char is more than one unit. */
t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
size_int (BITS_PER_UNIT));
t = convert (sizetype, t);
force_fit_type (t, 0);
return t;
}
@ -5347,6 +5350,7 @@ really_start_incremental_init (type)
constructor_fields = TREE_CHAIN (constructor_fields);
constructor_unfilled_fields = constructor_fields;
constructor_bit_index = copy_node (integer_zero_node);
TREE_TYPE (constructor_bit_index) = sbitsizetype;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@ -5426,13 +5430,17 @@ push_init_level (implicit)
if (! tree_int_cst_equal (constructor_bit_index,
DECL_FIELD_BITPOS (constructor_fields)))
{
int next = (TREE_INT_CST_LOW
(DECL_FIELD_BITPOS (constructor_fields))
/ BITS_PER_UNIT);
int here = (TREE_INT_CST_LOW (constructor_bit_index)
/ BITS_PER_UNIT);
/* By using unsigned arithmetic, the result will be correct even
in case of overflows, if BITS_PER_UNIT is a power of two. */
unsigned next = (TREE_INT_CST_LOW
(DECL_FIELD_BITPOS (constructor_fields))
/ (unsigned)BITS_PER_UNIT);
unsigned here = (TREE_INT_CST_LOW (constructor_bit_index)
/ (unsigned)BITS_PER_UNIT);
assemble_zeros (next - here);
assemble_zeros ((next - here)
* (unsigned)BITS_PER_UNIT
/ (unsigned)BITS_PER_UNIT);
}
/* Indicate that we have now filled the structure up to the current
field. */
@ -5524,6 +5532,7 @@ push_init_level (implicit)
constructor_fields = TREE_CHAIN (constructor_fields);
constructor_unfilled_fields = constructor_fields;
constructor_bit_index = copy_node (integer_zero_node);
TREE_TYPE (constructor_bit_index) = sbitsizetype;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@ -6018,12 +6027,19 @@ output_init_element (value, type, field, pending)
if (! tree_int_cst_equal (constructor_bit_index,
DECL_FIELD_BITPOS (field)))
{
int next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
/ BITS_PER_UNIT);
int here = (TREE_INT_CST_LOW (constructor_bit_index)
/ BITS_PER_UNIT);
/* By using unsigned arithmetic, the result will be
correct even in case of overflows, if BITS_PER_UNIT
is a power of two. */
unsigned next = (TREE_INT_CST_LOW
(DECL_FIELD_BITPOS (field))
/ (unsigned)BITS_PER_UNIT);
unsigned here = (TREE_INT_CST_LOW
(constructor_bit_index)
/ (unsigned)BITS_PER_UNIT);
assemble_zeros (next - here);
assemble_zeros ((next - here)
* (unsigned)BITS_PER_UNIT
/ (unsigned)BITS_PER_UNIT);
}
}
output_constant (digest_init (type, value,

View File

@ -4358,8 +4358,14 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
if (! integer_zerop (low_bound))
index = fold (build (MINUS_EXPR, index_type, index, low_bound));
index = fold (build (MULT_EXPR, index_type, index,
convert (index_type,
if (TREE_CODE (index) == INTEGER_CST)
{
index = convert (sbitsizetype, index);
index_type = TREE_TYPE (index);
}
index = fold (build (MULT_EXPR, sbitsizetype, index,
convert (sbitsizetype,
TYPE_SIZE (TREE_TYPE (exp)))));
if (TREE_CODE (index) == INTEGER_CST
@ -4368,9 +4374,9 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
else
{
offset = size_binop (PLUS_EXPR, offset,
size_binop (FLOOR_DIV_EXPR, index,
size_int (BITS_PER_UNIT)));
convert (sizetype,
size_binop (FLOOR_DIV_EXPR, index,
size_int (BITS_PER_UNIT))));
if (contains_placeholder_p (offset))
offset = build (WITH_RECORD_EXPR, sizetype, offset, exp);
}

View File

@ -1,5 +1,5 @@
/* Fold a constant sub-tree into a single node for C-compiler
Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
@@ for cross-compilers. */
/* The entry points in this file are fold, size_int, size_binop
/* The entry points in this file are fold, size_int_wide, size_binop
and force_fit_type.
fold takes a tree as argument and returns a simplified tree.
@ -1422,33 +1422,35 @@ const_binop (code, arg1, arg2, notrunc)
return 0;
}
/* Return an INTEGER_CST with value V and type from `sizetype'. */
/* Return an INTEGER_CST with value V . The type is determined by bit_p:
if it is zero, the type is taken from sizetype; if it is one, the type
is taken from bitsizetype. */
tree
size_int (number)
unsigned HOST_WIDE_INT number;
size_int_wide (number, high, bit_p)
unsigned HOST_WIDE_INT number, high;
{
register tree t;
/* Type-size nodes already made for small sizes. */
static tree size_table[2*HOST_BITS_PER_WIDE_INT + 1];
static tree size_table[2*HOST_BITS_PER_WIDE_INT + 1][2];
if (number < 2*HOST_BITS_PER_WIDE_INT + 1
&& size_table[number] != 0)
return size_table[number];
if (number < 2*HOST_BITS_PER_WIDE_INT + 1)
if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high
&& size_table[number][bit_p] != 0)
return size_table[number][bit_p];
if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high)
{
push_obstacks_nochange ();
/* Make this a permanent node. */
end_temporary_allocation ();
t = build_int_2 (number, 0);
TREE_TYPE (t) = sizetype;
size_table[number] = t;
TREE_TYPE (t) = sizetype_tab[bit_p];
size_table[number][bit_p] = t;
pop_obstacks ();
}
else
{
t = build_int_2 (number, 0);
TREE_TYPE (t) = sizetype;
t = build_int_2 (number, high);
TREE_TYPE (t) = sizetype_tab[bit_p];
TREE_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (t) = force_fit_type (t, 0);
}
return t;
@ -2343,7 +2345,7 @@ make_bit_field_ref (inner, type, bitsize, bitpos, unsignedp)
int unsignedp;
{
tree result = build (BIT_FIELD_REF, type, inner,
size_int (bitsize), size_int (bitpos));
size_int (bitsize), bitsize_int (bitpos, 0L));
TREE_UNSIGNED (result) = unsignedp;

View File

@ -1,5 +1,5 @@
/* C-compiler utilities for types and variables storage layout
Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA. */
It is the first integer type laid out.
In C, this is int. */
tree sizetype;
tree sizetype_tab[2], sbitsizetype, ubitsizetype;
/* An integer constant with value 0 whose type is sizetype. */
@ -419,7 +419,7 @@ layout_record (rec)
{
if (const_size > 0)
var_size = size_binop (PLUS_EXPR, var_size,
size_int (const_size));
bitsize_int (const_size, 0L));
const_size = 0;
var_size = round_up (var_size, desired_align);
var_align = MIN (var_align, desired_align);
@ -483,7 +483,7 @@ layout_record (rec)
if (var_size && const_size)
DECL_FIELD_BITPOS (field)
= size_binop (PLUS_EXPR, var_size, size_int (const_size));
= size_binop (PLUS_EXPR, var_size, bitsize_int (const_size, 0L));
else if (var_size)
DECL_FIELD_BITPOS (field) = var_size;
else
@ -536,7 +536,7 @@ layout_record (rec)
{
if (const_size)
var_size
= size_binop (PLUS_EXPR, var_size, size_int (const_size));
= size_binop (PLUS_EXPR, var_size, bitsize_int (const_size, 0L));
TYPE_SIZE (rec) = var_size;
}
@ -595,7 +595,7 @@ layout_union (rec)
continue;
layout_decl (field, 0);
DECL_FIELD_BITPOS (field) = size_int (0);
DECL_FIELD_BITPOS (field) = bitsize_int (0L, 0L);
/* Union must be at least as aligned as any field requires. */
@ -625,7 +625,7 @@ layout_union (rec)
else if (TREE_CODE (rec) == QUAL_UNION_TYPE)
var_size = fold (build (COND_EXPR, sizetype, DECL_QUALIFIER (field),
DECL_SIZE (field),
var_size ? var_size : integer_zero_node));
var_size ? var_size : bitsize_int (0L, 0L)));
}
if (TREE_CODE (rec) == QUAL_UNION_TYPE)
@ -633,13 +633,13 @@ layout_union (rec)
/* Determine the ultimate size of the union (in bytes). */
if (NULL == var_size)
TYPE_SIZE (rec) = size_int (CEIL (const_size, BITS_PER_UNIT)
* BITS_PER_UNIT);
TYPE_SIZE (rec) = bitsize_int (CEIL (const_size, BITS_PER_UNIT)
* BITS_PER_UNIT, 0L);
else if (const_size == 0)
TYPE_SIZE (rec) = var_size;
else
TYPE_SIZE (rec) = size_binop (MAX_EXPR, var_size,
round_up (size_int (const_size),
round_up (bitsize_int (const_size, 0L),
BITS_PER_UNIT));
/* Determine the desired alignment. */
@ -712,12 +712,12 @@ layout_type (type)
TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
MODE_INT);
TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
break;
case REAL_TYPE:
TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
break;
case COMPLEX_TYPE:
@ -727,7 +727,7 @@ layout_type (type)
(TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
0);
TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
break;
case VOID_TYPE:
@ -737,7 +737,7 @@ layout_type (type)
break;
case OFFSET_TYPE:
TYPE_SIZE (type) = size_int (POINTER_SIZE);
TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
TYPE_MODE (type) = ptr_mode;
break;
@ -750,7 +750,7 @@ layout_type (type)
case POINTER_TYPE:
case REFERENCE_TYPE:
TYPE_MODE (type) = ptr_mode;
TYPE_SIZE (type) = size_int (POINTER_SIZE);
TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
TREE_UNSIGNED (type) = 1;
TYPE_PRECISION (type) = POINTER_SIZE;
break;
@ -798,8 +798,8 @@ layout_type (type)
&& TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
length = size_binop (MAX_EXPR, length, size_zero_node);
TYPE_SIZE (type) = size_binop (MULT_EXPR, length,
TYPE_SIZE (element));
TYPE_SIZE (type) = size_binop (MULT_EXPR, TYPE_SIZE (element),
length);
}
/* Now round the alignment and size,
@ -972,7 +972,7 @@ layout_type (type)
TYPE_MODE (type) = BLKmode;
else
TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
TYPE_SIZE (type) = size_int (rounded_size);
TYPE_SIZE (type) = bitsize_int (rounded_size, 0L);
TYPE_ALIGN (type) = alignment;
TYPE_PRECISION (type) = size_in_bits;
}
@ -1066,9 +1066,7 @@ make_signed_type (precision)
is the type for size values. */
if (sizetype == 0)
{
sizetype = type;
}
set_sizetype (type);
/* Lay out the type: set its alignment, size, etc. */
@ -1092,13 +1090,49 @@ make_unsigned_type (precision)
if (sizetype == 0)
{
sizetype = type;
TREE_UNSIGNED (type) = 1;
set_sizetype (type);
}
fixup_unsigned_type (type);
return type;
}
/* Set sizetype to TYPE, and initialize *bitsizetype accordingly.
Also update the type of any standard type's sizes made so far. */
void
set_sizetype (type)
tree type;
{
int precision = TYPE_PRECISION (type);
sizetype = type;
/* The *bitsizetype types use a precision that avoids overflows when
calculating signed sizes / offsets in bits.
We are allocating bitsizetype once and change it in place when
we decide later that we want to change it. This way, we avoid the
hassle of changing all the TYPE_SIZE (TREE_TYPE (sometype))
individually in each front end. */
if (! bitsizetype)
bitsizetype = make_node (INTEGER_TYPE);
precision += BITS_PER_UNIT_LOG + 1;
/* However, when cross-compiling from a 32 bit to a 64 bit host,
we are limited to 64 bit precision. */
if (precision > 2 * HOST_BITS_PER_WIDE_INT)
precision = 2 * HOST_BITS_PER_WIDE_INT;
TYPE_PRECISION (bitsizetype) = precision;
(TREE_UNSIGNED (type) ? fixup_unsigned_type : fixup_signed_type)
(bitsizetype);
layout_type (bitsizetype);
sbitsizetype = make_signed_type (precision);
ubitsizetype = make_unsigned_type (precision);
}
/* Set the extreme values of TYPE based on its precision in bits,
then lay it out. Used when make_signed_type won't do
because the tree code is not INTEGER_TYPE.

View File

@ -1,5 +1,5 @@
/* Front-end tree definitions for GNU compiler.
Copyright (C) 1989, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
Copyright (C) 1989, 93-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -1295,6 +1295,7 @@ extern tree build_block PROTO((tree, tree, tree, tree, tree));
extern tree make_signed_type PROTO((int));
extern tree make_unsigned_type PROTO((int));
extern void set_sizetype PROTO((tree));
extern tree signed_or_unsigned_type PROTO((int, tree));
extern void fixup_unsigned_type PROTO((tree));
extern tree build_pointer_type PROTO((tree));
@ -1398,14 +1399,28 @@ extern tree convert PROTO((tree, tree));
extern tree size_in_bytes PROTO((tree));
extern int int_size_in_bytes PROTO((tree));
extern tree size_binop PROTO((enum tree_code, tree, tree));
extern tree size_int PROTO((unsigned HOST_WIDE_INT));
extern tree size_int_wide PROTO((unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, int));
#define size_int(L) size_int_2 ((L), 0, 0)
#define bitsize_int(L, H) size_int_2 ((L), (H), 1)
#define size_int_2(L, H, T) \
size_int_wide ((unsigned HOST_WIDE_INT) (L), \
(unsigned HOST_WIDE_INT) (H), (T))
extern tree round_up PROTO((tree, int));
extern tree get_pending_sizes PROTO((void));
extern void put_pending_sizes PROTO((tree));
/* Type for sizes of data-type. */
extern tree sizetype;
#define BITS_PER_UNIT_LOG \
((BITS_PER_UNIT > 1) + (BITS_PER_UNIT > 2) + (BITS_PER_UNIT > 4) \
+ (BITS_PER_UNIT > 8) + (BITS_PER_UNIT > 16) + (BITS_PER_UNIT > 32) \
+ (BITS_PER_UNIT > 64) + (BITS_PER_UNIT > 128) + (BITS_PER_UNIT > 256))
extern tree sizetype_tab[2], sbitsizetype, ubitsizetype;
#define sizetype sizetype_tab[0]
#define bitsizetype sizetype_tab[1]
/* If nonzero, an upper limit on alignment of structure fields, in bits. */
extern int maximum_field_alignment;