This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch 1/4] change specific int128 -> generic intN
- From: DJ Delorie <dj at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 24 Jun 2014 19:32:24 -0400
- Subject: Re: [patch 1/4] change specific int128 -> generic intN
- Authentication-results: sourceware.org; auth=none
- References: <201404142303 dot s3EN3ONP009938 at greed dot delorie dot com> <201406211624 dot s5LGOFC8031566 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1406212014500 dot 29257 at digraph dot polyomino dot org dot uk>
Part 1 of 4, split from the full patch. The purpose of this set of
changes is to remove assumptions in GCC about type sizes. Previous to
this patch, GCC assumed that all types were powers-of-two in size, and
used naive math accordingly.
Old:
POINTER_SIZE / BITS_PER_UNIT
TYPE_SIZE
GET_MODE_BITSIZE
New:
POINTER_SIZE_UNITS (ceil, not floor)
TYPE_PRECISION
GET_MODE_PRECISION
gcc/
* cppbuiltin.c (define_builtin_macros_for_type_sizes): Round
pointer size up to a power of two.
* defaults.h (DWARF2_ADDR_SIZE): Round up.
(POINTER_SIZE_UNITS): New, rounded up value.
* dwarf2asm.c (size_of_encoded_value): Use it.
(dw2_output_indirect_constant_1): Likewise.
* expmed.c (init_expmed_one_conv): We now know the sizes of
partial int modes.
* loop-iv.c (iv_number_of_iterations): Use precision, not size.
* optabs.c (expand_float): Use precision, not size.
(expand_fix): Likewise.
* simplify-rtx (simplify_unary_operation_1): Likewise.
* tree-dfa.c (get_ref_base_and_extent): Likewise.
* varasm.c (assemble_addr_to_section): Round up pointer sizes.
(default_assemble_integer) Likewise.
(dump_tm_clone_pairs): Likewise.
* tree-core.c: Adjust comment.
gcc/lto/
* lto-object.c (lto_obj_begin_section): Do not assume pointers are
powers-of-two in size.
gcc/c-family/
* c-cppbuiltin.c (cpp_atomic_builtins): Round pointer sizes up.
(type_suffix): Use type precision, not specific types.
Index: gcc/dwarf2asm.c
===================================================================
--- gcc/dwarf2asm.c (revision 211858)
+++ gcc/dwarf2asm.c (working copy)
@@ -387,13 +387,13 @@ size_of_encoded_value (int encoding)
if (encoding == DW_EH_PE_omit)
return 0;
switch (encoding & 0x07)
{
case DW_EH_PE_absptr:
- return POINTER_SIZE / BITS_PER_UNIT;
+ return POINTER_SIZE_UNITS;
case DW_EH_PE_udata2:
return 2;
case DW_EH_PE_udata4:
return 4;
case DW_EH_PE_udata8:
return 8;
@@ -917,13 +917,13 @@ dw2_output_indirect_constant_1 (splay_tr
if (USE_LINKONCE_INDIRECT)
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
}
sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
assemble_variable (decl, 1, 1, 1);
- assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+ assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
return 0;
}
/* Emit the constants queued through dw2_force_const_mem. */
Index: gcc/cppbuiltin.c
===================================================================
--- gcc/cppbuiltin.c (revision 211858)
+++ gcc/cppbuiltin.c (working copy)
@@ -172,13 +172,13 @@ define_builtin_macros_for_type_sizes (cp
? "__ORDER_BIG_ENDIAN__"
: "__ORDER_LITTLE_ENDIAN__"));
/* ptr_type_node can't be used here since ptr_mode is only set when
toplev calls backend_init which is not done with -E switch. */
cpp_define_formatted (pfile, "__SIZEOF_POINTER__=%d",
- POINTER_SIZE / BITS_PER_UNIT);
+ 1 << ceil_log2 ((POINTER_SIZE + BITS_PER_UNIT - 1) / BITS_PER_UNIT));
}
/* Define macros builtins common to all language performing CPP
preprocessing. */
void
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c (revision 211858)
+++ gcc/c-family/c-cppbuiltin.c (working copy)
@@ -675,13 +675,13 @@ cpp_atomic_builtins (cpp_reader *pfile)
to a boolean truth value, let the library work around that. */
builtin_define_with_int_value ("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL",
targetm.atomic_test_and_set_trueval);
/* ptr_type_node can't be used here since ptr_mode is only set when
toplev calls backend_init which is not done with -E or pch. */
- psize = POINTER_SIZE / BITS_PER_UNIT;
+ psize = POINTER_SIZE_UNITS;
if (psize >= SWAP_LIMIT)
psize = 0;
builtin_define_with_int_value ("__GCC_ATOMIC_POINTER_LOCK_FREE",
(have_swap[psize]? 2 : 1));
}
@@ -1227,18 +1269,21 @@ builtin_define_with_hex_fp_value (const
static const char *
type_suffix (tree type)
{
static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
int unsigned_suffix;
int is_long;
+ int tp = TYPE_PRECISION (type);
if (type == long_long_integer_type_node
- || type == long_long_unsigned_type_node)
+ || type == long_long_unsigned_type_node
+ || tp > TYPE_PRECISION (long_integer_type_node))
is_long = 2;
else if (type == long_integer_type_node
- || type == long_unsigned_type_node)
+ || type == long_unsigned_type_node
+ || tp > TYPE_PRECISION (integer_type_node))
is_long = 1;
else if (type == integer_type_node
|| type == unsigned_type_node
|| type == short_integer_type_node
|| type == short_unsigned_type_node
|| type == signed_char_type_node
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c (revision 211858)
+++ gcc/optabs.c (working copy)
@@ -5178,13 +5178,13 @@ expand_float (rtx to, rtx from, int unsi
{
rtx libfunc;
rtx insns;
rtx value;
convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
- if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
+ if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_PRECISION (SImode))
from = convert_to_mode (SImode, from, unsignedp);
libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
gcc_assert (libfunc);
start_sequence ();
@@ -5354,13 +5354,13 @@ expand_fix (rtx to, rtx from, int unsign
}
/* We can't do it with an insn, so use a library call. But first ensure
that the mode of TO is at least as wide as SImode, since those are the
only library calls we know about. */
- if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
+ if (GET_MODE_PRECISION (GET_MODE (to)) < GET_MODE_PRECISION (SImode))
{
target = gen_reg_rtx (SImode);
expand_fix (target, from, unsignedp);
}
else
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h (revision 211858)
+++ gcc/defaults.h (working copy)
@@ -448,13 +448,13 @@ see the files COPYING3 and COPYING.RUNTI
/* The size of addresses as they appear in the Dwarf 2 data.
Some architectures use word addresses to refer to code locations,
but Dwarf 2 info always uses byte addresses. On such machines,
Dwarf 2 addresses need to be larger than the architecture's
pointers. */
#ifndef DWARF2_ADDR_SIZE
-#define DWARF2_ADDR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
+#define DWARF2_ADDR_SIZE ((POINTER_SIZE + BITS_PER_UNIT - 1) / BITS_PER_UNIT)
#endif
/* The size in bytes of a DWARF field indicating an offset or length
relative to a debug info section, specified to be 4 bytes in the
DWARF-2 specification. The SGI/MIPS ABI defines it to be the same
as PTR_SIZE. */
@@ -748,12 +748,16 @@ see the files COPYING3 and COPYING.RUNTI
#endif
/* Width in bits of a pointer. Mind the value of the macro `Pmode'. */
#ifndef POINTER_SIZE
#define POINTER_SIZE BITS_PER_WORD
#endif
+#ifndef POINTER_SIZE_UNITS
+#define POINTER_SIZE_UNITS ((POINTER_SIZE + BITS_PER_UNIT - 1) / BITS_PER_UNIT)
+#endif
+
#ifndef PIC_OFFSET_TABLE_REGNUM
#define PIC_OFFSET_TABLE_REGNUM INVALID_REGNUM
#endif
#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c (revision 211858)
+++ gcc/stor-layout.c (working copy)
@@ -2123,13 +2142,13 @@ layout_type (tree type)
case BOOLEAN_TYPE:
case INTEGER_TYPE:
case ENUMERAL_TYPE:
SET_TYPE_MODE (type,
smallest_mode_for_size (TYPE_PRECISION (type), MODE_INT));
- TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+ TYPE_SIZE (type) = bitsize_int (GET_MODE_PRECISION (TYPE_MODE (type)));
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
case REAL_TYPE:
SET_TYPE_MODE (type,
mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0));
@@ -2194,13 +2213,13 @@ layout_type (tree type)
TYPE_USER_ALIGN (type) = 0;
SET_TYPE_MODE (type, VOIDmode);
break;
case OFFSET_TYPE:
TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
- TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
+ TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE_UNITS);
/* A pointer might be MODE_PARTIAL_INT,
but ptrdiff_t must be integral. */
SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
TYPE_PRECISION (type) = POINTER_SIZE;
break;
@@ -2224,13 +2243,13 @@ layout_type (tree type)
mode = targetm.addr_space.address_mode (as);
}
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
TYPE_UNSIGNED (type) = 1;
- TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
+ TYPE_PRECISION (type) = GET_MODE_PRECISION (mode);
}
break;
case ARRAY_TYPE:
{
tree index = TYPE_DOMAIN (type);
@@ -2516,16 +2535,33 @@ initialize_sizetypes (void)
precision = LONG_TYPE_SIZE;
else if (strcmp (SIZETYPE, "long long unsigned int") == 0)
precision = LONG_LONG_TYPE_SIZE;
else if (strcmp (SIZETYPE, "short unsigned int") == 0)
precision = SHORT_TYPE_SIZE;
else
gcc_unreachable ();
bprecision
- = MIN (precision + BITS_PER_UNIT_LOG + 1, MAX_FIXED_MODE_SIZE);
+ = MIN (precision, MAX_FIXED_MODE_SIZE);
bprecision
= GET_MODE_PRECISION (smallest_mode_for_size (bprecision, MODE_INT));
if (bprecision > HOST_BITS_PER_DOUBLE_INT)
bprecision = HOST_BITS_PER_DOUBLE_INT;
/* Create stubs for sizetype and bitsizetype so we can create constants. */
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c (revision 211858)
+++ gcc/expmed.c (working copy)
@@ -115,19 +115,25 @@ static void
init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode,
enum machine_mode from_mode, bool speed)
{
int to_size, from_size;
rtx which;
- /* We're given no information about the true size of a partial integer,
- only the size of the "full" integer it requires for storage. For
- comparison purposes here, reduce the bit size by one in that case. */
- to_size = (GET_MODE_BITSIZE (to_mode)
- - (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT));
- from_size = (GET_MODE_BITSIZE (from_mode)
- - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT));
+ to_size = GET_MODE_PRECISION (to_mode);
+ from_size = GET_MODE_PRECISION (from_mode);
+
+ /* Most partial integers have a precision less than the "full"
+ integer it requires for storage. In case one doesn't, for
+ comparison purposes here, reduce the bit size by one in that
+ case. */
+ if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT
+ && exact_log2 (to_size) != -1)
+ to_size --;
+ if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT
+ && exact_log2 (from_size) != -1)
+ from_size --;
/* Assume cost of zero-extend and sign-extend is the same. */
which = (to_size < from_size ? &all->trunc : &all->zext);
PUT_MODE (&all->reg, from_mode);
set_convert_cost (to_mode, from_mode, speed, set_src_cost (which, speed));
Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c (revision 211858)
+++ gcc/tree-dfa.c (working copy)
@@ -404,13 +404,13 @@ get_ref_base_and_extent (tree exp, HOST_
else if (!VOID_TYPE_P (TREE_TYPE (exp)))
{
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
if (mode == BLKmode)
size_tree = TYPE_SIZE (TREE_TYPE (exp));
else
- bitsize = int (GET_MODE_BITSIZE (mode));
+ bitsize = int (GET_MODE_PRECISION (mode));
}
if (size_tree != NULL_TREE
&& TREE_CODE (size_tree) == INTEGER_CST)
bitsize = wi::to_offset (size_tree);
/* Initially, maxsize is the same as the accessed element size.
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c (revision 211858)
+++ gcc/simplify-rtx.c (working copy)
@@ -1361,14 +1361,14 @@ simplify_unary_operation_1 (enum rtx_cod
}
/* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
(sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
{
- gcc_assert (GET_MODE_BITSIZE (mode)
- > GET_MODE_BITSIZE (GET_MODE (op)));
+ gcc_assert (GET_MODE_PRECISION (mode)
+ > GET_MODE_PRECISION (GET_MODE (op)));
return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
GET_MODE (XEXP (op, 0)));
}
/* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
is (sign_extend:M (subreg:O <X>)) if there is mode with
Index: gcc/lto/lto-object.c
===================================================================
--- gcc/lto/lto-object.c (revision 211858)
+++ gcc/lto/lto-object.c (working copy)
@@ -335,13 +335,13 @@ lto_obj_begin_section (const char *name)
lo = (struct lto_simple_object *) current_out_file;
gcc_assert (lo != NULL
&& lo->sobj_r == NULL
&& lo->sobj_w != NULL
&& lo->section == NULL);
- align = exact_log2 (POINTER_SIZE / BITS_PER_UNIT);
+ align = ceil_log2 (POINTER_SIZE_UNITS);
lo->section = simple_object_write_create_section (lo->sobj_w, name, align,
&errmsg, &err);
if (lo->section == NULL)
{
if (err == 0)
fatal_error ("%s", errmsg);
Index: gcc/loop-iv.c
===================================================================
--- gcc/loop-iv.c (revision 211858)
+++ gcc/loop-iv.c (working copy)
@@ -2409,13 +2409,13 @@ iv_number_of_iterations (struct loop *lo
if (!canonicalize_iv_subregs (&iv0, &iv1, cond, desc))
goto fail;
comp_mode = iv0.extend_mode;
mode = iv0.mode;
- size = GET_MODE_BITSIZE (mode);
+ size = GET_MODE_PRECISION (mode);
get_mode_bounds (mode, (cond == LE || cond == LT), comp_mode, &mmin, &mmax);
mode_mmin = lowpart_subreg (mode, mmin, comp_mode);
mode_mmax = lowpart_subreg (mode, mmax, comp_mode);
if (!CONST_INT_P (iv0.step) || !CONST_INT_P (iv1.step))
goto fail;
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c (revision 211858)
+++ gcc/varasm.c (working copy)
@@ -1466,13 +1466,13 @@ assemble_asm (tree string)
/* Write the address of the entity given by SYMBOL to SEC. */
void
assemble_addr_to_section (rtx symbol, section *sec)
{
switch_to_section (sec);
assemble_align (POINTER_SIZE);
- assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+ assemble_integer (symbol, (POINTER_SIZE + BITS_PER_UNIT - 1) / BITS_PER_UNIT, POINTER_SIZE, 1);
}
/* Return the numbered .ctors.N (if CONSTRUCTOR_P) or .dtors.N (if
not) section for PRIORITY. */
section *
get_cdtor_priority_section (int priority, bool constructor_p)
@@ -2619,13 +2619,13 @@ default_assemble_integer (rtx x ATTRIBUT
unsigned int size ATTRIBUTE_UNUSED,
int aligned_p ATTRIBUTE_UNUSED)
{
const char *op = integer_asm_op (size, aligned_p);
/* Avoid GAS bugs for large values. Specifically negative values whose
absolute value fits in a bfd_vma, but not in a bfd_signed_vma. */
- if (size > UNITS_PER_WORD && size > POINTER_SIZE / BITS_PER_UNIT)
+ if (size > UNITS_PER_WORD && size > POINTER_SIZE_UNITS)
return false;
return op && (assemble_integer_with_op (op, x), true);
}
/* Assemble the integer constant X into an object of SIZE bytes. ALIGN is
the alignment of the integer in bits. Return 1 if we were able to output
@@ -5750,15 +5750,15 @@ dump_tm_clone_pairs (vec<tm_alias_pair>
switch_to_section (targetm.asm_out.tm_clone_table_section ());
assemble_align (POINTER_SIZE);
switched = true;
}
assemble_integer (XEXP (DECL_RTL (src), 0),
- POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+ POINTER_SIZE_UNITS, POINTER_SIZE, 1);
assemble_integer (XEXP (DECL_RTL (dst), 0),
- POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+ POINTER_SIZE_UNITS, POINTER_SIZE, 1);
}
}
/* Provide a default for the tm_clone_table section. */
section *
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h (revision 211858)
+++ gcc/tree-core.h (working copy)
@@ -1147,13 +1155,13 @@ enum omp_clause_map_kind
OMP_CLAUSE_MAP_ALLOC,
OMP_CLAUSE_MAP_TO,
OMP_CLAUSE_MAP_FROM,
OMP_CLAUSE_MAP_TOFROM,
/* The following kind is an internal only map kind, used for pointer based
array sections. OMP_CLAUSE_SIZE for these is not the pointer size,
- which is implicitly POINTER_SIZE / BITS_PER_UNIT, but the bias. */
+ which is implicitly POINTER_SIZE_UNITS, but the bias. */
OMP_CLAUSE_MAP_POINTER,
/* Also internal, behaves like OMP_CLAUS_MAP_TO, but additionally any
OMP_CLAUSE_MAP_POINTER records consecutive after it which have addresses
falling into that range will not be ignored if OMP_CLAUSE_MAP_TO_PSET
wasn't mapped already. */
OMP_CLAUSE_MAP_TO_PSET,