From patchwork Tue Jun 24 23:32:24 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 363764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 859741400B9 for ; Wed, 25 Jun 2014 09:32:38 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:in-reply-to:subject:references; q=dns; s= default; b=ijyu1+lqlTEK9uGOWILODBRgSm+IDmBep+VaogIe/bFSbAOWQ4DYC krcJhCtFh7U2vrK9hP1QHQRwDo88EfrxZ9NltPyFMVRj0OB5NW4Fspkc3ie6Zpyk oEj0y3pMs6csu4uzJO5TNZVx8kb/yfBAFzFgEW/RwyNBb9qZoKhHyg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:in-reply-to:subject:references; s=default; bh=XfCKjIvdIig9b3akkAu3s+24dEs=; b=quEKKk8XU0hRbYixTHbH70GFluWG fwIc5DfQVi4bWkwBTYcoH7F3LgVqQJ/BS5Vpal+ykNUhdHIysAPQYJgVVmLjFezM RKLLxFMyDu/lL2cY/3vyGA21PZlBD0DmKr6PCtIbgH6fKAeVCLRu3h1WoDrnK370 vILM0gv/bsC8TkI= Received: (qmail 31197 invoked by alias); 24 Jun 2014 23:32:30 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 31178 invoked by uid 89); 24 Jun 2014 23:32:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 24 Jun 2014 23:32:28 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5ONWQXv004363 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 24 Jun 2014 19:32:26 -0400 Received: from greed.delorie.com ([10.3.113.17]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5ONWPLh031796 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 24 Jun 2014 19:32:26 -0400 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.14.4/8.14.4) with ESMTP id s5ONWO2A012837 for ; Tue, 24 Jun 2014 19:32:24 -0400 Received: (from dj@localhost) by greed.delorie.com (8.14.4/8.14.4/Submit) id s5ONWOZn012836; Tue, 24 Jun 2014 19:32:24 -0400 Date: Tue, 24 Jun 2014 19:32:24 -0400 Message-Id: <201406242332.s5ONWOZn012836@greed.delorie.com> From: DJ Delorie To: gcc-patches@gcc.gnu.org In-reply-to: (joseph@codesourcery.com) Subject: Re: [patch 1/4] change specific int128 -> generic intN References: <201404142303.s3EN3ONP009938@greed.delorie.com> <201406211624.s5LGOFC8031566@greed.delorie.com> X-IsSubscribed: yes 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 )) is (sign_extend:M ). (sign_extend:M (zero_extend:N )) is (zero_extend:M ). */ 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 (const_int I)) (const_int I))) is (sign_extend:M (subreg:O )) 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 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,