From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 109699 invoked by alias); 23 Oct 2017 17:04:16 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 109681 invoked by uid 89); 23 Oct 2017 17:04:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.5 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wr0-f174.google.com Received: from mail-wr0-f174.google.com (HELO mail-wr0-f174.google.com) (209.85.128.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Oct 2017 17:04:08 +0000 Received: by mail-wr0-f174.google.com with SMTP id o44so18097376wrf.11 for ; Mon, 23 Oct 2017 10:04:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=Fv+PSowi2tZX/QsXTvkklHH0QjtrvPSWFbDfpiP9dHw=; b=PinrKcw4O+67jRlwLUG22LfAyCJUK1wtSj9a1CDBSmE9VmdQt34bKgrWkRM/Vsd0yB 2k+hUH1Z9ujNGRW+3Q5TZ6izkmE69R5t2YvBK+2ggDqgTOE26w+EXeKRtTzSxia5JdrM SEJGi7XGXSIfcKqgChLwKbmAQqe16YaaLFfbvkh4UoSpr3VYVGzieCnAvmCA/0yoEGrg ojLE/mBTx4Bsweiu8FPZypm1jZZeiwZatMFkeByz9GDigx80bXEyZ4+DIiu4SFmjLPF8 hgSfWe9N+cP2JG2bw+bNLPDi/AnnAqXLHiNPMv0utHDCWprct2lHtBfWIux/+xkkJ9UD qLiQ== X-Gm-Message-State: AMCzsaU3kdbBLPFzd6NSvGKeGiere+hlSm+sxwmgq192uxVZBhr9uNu6 55gzygB913vxbuE5Y8qV1/swEw5Vtxc= X-Google-Smtp-Source: ABhQp+SN32dxfejm+XAyUm4b88lKtgPWiCcOqlqSwF2/jZZV2gCmfe1tudjErdfwpvtULqBM4XYCLQ== X-Received: by 10.223.184.69 with SMTP id u5mr12239580wrf.33.1508778246029; Mon, 23 Oct 2017 10:04:06 -0700 (PDT) Received: from localhost ([2.26.27.199]) by smtp.gmail.com with ESMTPSA id 65sm4313439wrn.27.2017.10.23.10.04.04 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 10:04:05 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [010/nnn] poly_int: REG_OFFSET References: <871sltvm7r.fsf@linaro.org> Date: Mon, 23 Oct 2017 17:04:00 -0000 In-Reply-To: <871sltvm7r.fsf@linaro.org> (Richard Sandiford's message of "Mon, 23 Oct 2017 17:54:32 +0100") Message-ID: <87o9oxssmz.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2017-10/txt/msg01510.txt.bz2 This patch changes the type of the reg_attrs offset field from HOST_WIDE_INT to poly_int64 and updates uses accordingly. This includes changing reg_attr_hasher::hash to use inchash. (Doing this has no effect on code generation since the only use of the hasher is to avoid creating duplicate objects.) 2017-10-23 Richard Sandiford Alan Hayward David Sherwood gcc/ * rtl.h (reg_attrs::offset): Change from HOST_WIDE_INT to poly_int64. (gen_rtx_REG_offset): Take the offset as a poly_int64. * inchash.h (inchash::hash::add_poly_hwi): New function. * gengtype.c (main): Register poly_int64. * emit-rtl.c (reg_attr_hasher::hash): Use inchash. Treat the offset as a poly_int. (reg_attr_hasher::equal): Use must_eq to compare offsets. (get_reg_attrs, update_reg_offset, gen_rtx_REG_offset): Take the offset as a poly_int64. (set_reg_attrs_from_value): Treat the offset as a poly_int64. * print-rtl.c (print_poly_int): New function. (rtx_writer::print_rtx_operand_code_r): Treat REG_OFFSET as a poly_int. * var-tracking.c (track_offset_p, get_tracked_reg_offset): New functions. (var_reg_set, var_reg_delete_and_set, var_reg_delete): Use them. (same_variable_part_p, track_loc_p): Take the offset as a poly_int64. (vt_get_decl_and_offset): Return the offset as a poly_int64. Enforce track_offset_p for parts of a PARALLEL. (vt_add_function_parameter): Use const_offset for the final offset to track. Use get_tracked_reg_offset for the parts of a PARALLEL. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2017-10-23 17:01:15.119130016 +0100 +++ gcc/rtl.h 2017-10-23 17:01:43.314993320 +0100 @@ -187,7 +187,7 @@ struct GTY(()) mem_attrs struct GTY((for_user)) reg_attrs { tree decl; /* decl corresponding to REG. */ - HOST_WIDE_INT offset; /* Offset from start of DECL. */ + poly_int64 offset; /* Offset from start of DECL. */ }; /* Common union for an element of an rtx. */ @@ -2997,7 +2997,7 @@ subreg_promoted_mode (rtx x) extern rtvec gen_rtvec_v (int, rtx *); extern rtvec gen_rtvec_v (int, rtx_insn **); extern rtx gen_reg_rtx (machine_mode); -extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, int); +extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, poly_int64); extern rtx gen_reg_rtx_offset (rtx, machine_mode, int); extern rtx gen_reg_rtx_and_attrs (rtx); extern rtx_code_label *gen_label_rtx (void); Index: gcc/inchash.h =================================================================== --- gcc/inchash.h 2017-10-23 17:01:29.530765486 +0100 +++ gcc/inchash.h 2017-10-23 17:01:43.314993320 +0100 @@ -63,6 +63,14 @@ hashval_t iterative_hash_hashval_t (hash val = iterative_hash_host_wide_int (v, val); } + /* Add polynomial value V, treating each element as a HOST_WIDE_INT. */ + template + void add_poly_hwi (const poly_int_pod &v) + { + for (unsigned int i = 0; i < N; ++i) + add_hwi (v.coeffs[i]); + } + /* Add wide_int-based value V. */ template void add_wide_int (const generic_wide_int &x) Index: gcc/gengtype.c =================================================================== --- gcc/gengtype.c 2017-10-23 17:01:15.119130016 +0100 +++ gcc/gengtype.c 2017-10-23 17:01:43.313994743 +0100 @@ -5190,6 +5190,7 @@ #define POS_HERE(Call) do { pos.file = t POS_HERE (do_scalar_typedef ("offset_int", &pos)); POS_HERE (do_scalar_typedef ("widest_int", &pos)); POS_HERE (do_scalar_typedef ("int64_t", &pos)); + POS_HERE (do_scalar_typedef ("poly_int64", &pos)); POS_HERE (do_scalar_typedef ("uint64_t", &pos)); POS_HERE (do_scalar_typedef ("uint8", &pos)); POS_HERE (do_scalar_typedef ("uintptr_t", &pos)); Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-10-23 17:01:15.119130016 +0100 +++ gcc/emit-rtl.c 2017-10-23 17:01:43.313994743 +0100 @@ -205,7 +205,6 @@ static rtx lookup_const_wide_int (rtx); #endif static rtx lookup_const_double (rtx); static rtx lookup_const_fixed (rtx); -static reg_attrs *get_reg_attrs (tree, int); static rtx gen_const_vector (machine_mode, int); static void copy_rtx_if_shared_1 (rtx *orig); @@ -424,7 +423,10 @@ reg_attr_hasher::hash (reg_attrs *x) { const reg_attrs *const p = x; - return ((p->offset * 1000) ^ (intptr_t) p->decl); + inchash::hash h; + h.add_ptr (p->decl); + h.add_poly_hwi (p->offset); + return h.end (); } /* Returns nonzero if the value represented by X is the same as that given by @@ -436,19 +438,19 @@ reg_attr_hasher::equal (reg_attrs *x, re const reg_attrs *const p = x; const reg_attrs *const q = y; - return (p->decl == q->decl && p->offset == q->offset); + return (p->decl == q->decl && must_eq (p->offset, q->offset)); } /* Allocate a new reg_attrs structure and insert it into the hash table if one identical to it is not already in the table. We are doing this for MEM of mode MODE. */ static reg_attrs * -get_reg_attrs (tree decl, int offset) +get_reg_attrs (tree decl, poly_int64 offset) { reg_attrs attrs; /* If everything is the default, we can just return zero. */ - if (decl == 0 && offset == 0) + if (decl == 0 && known_zero (offset)) return 0; attrs.decl = decl; @@ -1241,10 +1243,10 @@ reg_is_parm_p (rtx reg) to the REG_OFFSET. */ static void -update_reg_offset (rtx new_rtx, rtx reg, int offset) +update_reg_offset (rtx new_rtx, rtx reg, poly_int64 offset) { REG_ATTRS (new_rtx) = get_reg_attrs (REG_EXPR (reg), - REG_OFFSET (reg) + offset); + REG_OFFSET (reg) + offset); } /* Generate a register with same attributes as REG, but with OFFSET @@ -1252,7 +1254,7 @@ update_reg_offset (rtx new_rtx, rtx reg, rtx gen_rtx_REG_offset (rtx reg, machine_mode mode, unsigned int regno, - int offset) + poly_int64 offset) { rtx new_rtx = gen_rtx_REG (mode, regno); @@ -1288,7 +1290,7 @@ adjust_reg_mode (rtx reg, machine_mode m void set_reg_attrs_from_value (rtx reg, rtx x) { - int offset; + poly_int64 offset; bool can_be_reg_pointer = true; /* Don't call mark_reg_pointer for incompatible pointer sign Index: gcc/print-rtl.c =================================================================== --- gcc/print-rtl.c 2017-10-23 17:01:15.119130016 +0100 +++ gcc/print-rtl.c 2017-10-23 17:01:43.314993320 +0100 @@ -178,6 +178,23 @@ print_mem_expr (FILE *outfile, const_tre fputc (' ', outfile); print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags); } + +/* Print X to FILE. */ + +static void +print_poly_int (FILE *file, poly_int64 x) +{ + HOST_WIDE_INT const_x; + if (x.is_constant (&const_x)) + fprintf (file, HOST_WIDE_INT_PRINT_DEC, const_x); + else + { + fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC, x.coeffs[0]); + for (int i = 1; i < NUM_POLY_INT_COEFFS; ++i) + fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, x.coeffs[i]); + fprintf (file, "]"); + } +} #endif /* Subroutine of print_rtx_operand for handling code '0'. @@ -499,9 +516,11 @@ rtx_writer::print_rtx_operand_code_r (co if (REG_EXPR (in_rtx)) print_mem_expr (m_outfile, REG_EXPR (in_rtx)); - if (REG_OFFSET (in_rtx)) - fprintf (m_outfile, "+" HOST_WIDE_INT_PRINT_DEC, - REG_OFFSET (in_rtx)); + if (maybe_nonzero (REG_OFFSET (in_rtx))) + { + fprintf (m_outfile, "+"); + print_poly_int (m_outfile, REG_OFFSET (in_rtx)); + } fputs (" ]", m_outfile); } if (regno != ORIGINAL_REGNO (in_rtx)) Index: gcc/var-tracking.c =================================================================== --- gcc/var-tracking.c 2017-10-23 17:01:15.119130016 +0100 +++ gcc/var-tracking.c 2017-10-23 17:01:43.315991896 +0100 @@ -673,7 +673,6 @@ static bool dataflow_set_different (data static void dataflow_set_destroy (dataflow_set *); static bool track_expr_p (tree, bool); -static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT); static void add_uses_1 (rtx *, void *); static void add_stores (rtx, const_rtx, void *); static bool compute_bb_dataflow (basic_block); @@ -704,7 +703,6 @@ static void delete_variable_part (datafl static void emit_notes_in_bb (basic_block, dataflow_set *); static void vt_emit_notes (void); -static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *); static void vt_add_function_parameters (void); static bool vt_initialize (void); static void vt_finalize (void); @@ -1850,6 +1848,32 @@ var_reg_decl_set (dataflow_set *set, rtx set_variable_part (set, loc, dv, offset, initialized, set_src, iopt); } +/* Return true if we should track a location that is OFFSET bytes from + a variable. Store the constant offset in *OFFSET_OUT if so. */ + +static bool +track_offset_p (poly_int64 offset, HOST_WIDE_INT *offset_out) +{ + HOST_WIDE_INT const_offset; + if (!offset.is_constant (&const_offset) + || !IN_RANGE (const_offset, 0, MAX_VAR_PARTS - 1)) + return false; + *offset_out = const_offset; + return true; +} + +/* Return the offset of a register that track_offset_p says we + should track. */ + +static HOST_WIDE_INT +get_tracked_reg_offset (rtx loc) +{ + HOST_WIDE_INT offset; + if (!track_offset_p (REG_OFFSET (loc), &offset)) + gcc_unreachable (); + return offset; +} + /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */ static void @@ -1857,7 +1881,7 @@ var_reg_set (dataflow_set *set, rtx loc, rtx set_src) { tree decl = REG_EXPR (loc); - HOST_WIDE_INT offset = REG_OFFSET (loc); + HOST_WIDE_INT offset = get_tracked_reg_offset (loc); var_reg_decl_set (set, loc, initialized, dv_from_decl (decl), offset, set_src, INSERT); @@ -1903,7 +1927,7 @@ var_reg_delete_and_set (dataflow_set *se enum var_init_status initialized, rtx set_src) { tree decl = REG_EXPR (loc); - HOST_WIDE_INT offset = REG_OFFSET (loc); + HOST_WIDE_INT offset = get_tracked_reg_offset (loc); attrs *node, *next; attrs **nextp; @@ -1944,10 +1968,10 @@ var_reg_delete (dataflow_set *set, rtx l attrs **nextp = &set->regs[REGNO (loc)]; attrs *node, *next; - if (clobber) + HOST_WIDE_INT offset; + if (clobber && track_offset_p (REG_OFFSET (loc), &offset)) { tree decl = REG_EXPR (loc); - HOST_WIDE_INT offset = REG_OFFSET (loc); decl = var_debug_decl (decl); @@ -5245,10 +5269,10 @@ track_expr_p (tree expr, bool need_rtl) EXPR+OFFSET. */ static bool -same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset) +same_variable_part_p (rtx loc, tree expr, poly_int64 offset) { tree expr2; - HOST_WIDE_INT offset2; + poly_int64 offset2; if (! DECL_P (expr)) return false; @@ -5272,7 +5296,7 @@ same_variable_part_p (rtx loc, tree expr expr = var_debug_decl (expr); expr2 = var_debug_decl (expr2); - return (expr == expr2 && offset == offset2); + return (expr == expr2 && must_eq (offset, offset2)); } /* LOC is a REG or MEM that we would like to track if possible. @@ -5286,7 +5310,7 @@ same_variable_part_p (rtx loc, tree expr from EXPR in *OFFSET_OUT (if nonnull). */ static bool -track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p, +track_loc_p (rtx loc, tree expr, poly_int64 offset, bool store_reg_p, machine_mode *mode_out, HOST_WIDE_INT *offset_out) { machine_mode mode; @@ -5320,19 +5344,20 @@ track_loc_p (rtx loc, tree expr, HOST_WI || (store_reg_p && !COMPLEX_MODE_P (DECL_MODE (expr)) && hard_regno_nregs (REGNO (loc), DECL_MODE (expr)) == 1)) - && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0) + && known_zero (offset + byte_lowpart_offset (DECL_MODE (expr), mode))) { mode = DECL_MODE (expr); offset = 0; } - if (offset < 0 || offset >= MAX_VAR_PARTS) + HOST_WIDE_INT const_offset; + if (!track_offset_p (offset, &const_offset)) return false; if (mode_out) *mode_out = mode; if (offset_out) - *offset_out = offset; + *offset_out = const_offset; return true; } @@ -9544,7 +9569,7 @@ vt_emit_notes (void) assign declaration to *DECLP and offset to *OFFSETP, and return true. */ static bool -vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp) +vt_get_decl_and_offset (rtx rtl, tree *declp, poly_int64 *offsetp) { if (REG_P (rtl)) { @@ -9570,8 +9595,10 @@ vt_get_decl_and_offset (rtx rtl, tree *d decl = REG_EXPR (reg); if (REG_EXPR (reg) != decl) break; - if (REG_OFFSET (reg) < offset) - offset = REG_OFFSET (reg); + HOST_WIDE_INT this_offset; + if (!track_offset_p (REG_OFFSET (reg), &this_offset)) + break; + offset = MIN (offset, this_offset); } if (i == len) @@ -9615,7 +9642,7 @@ vt_add_function_parameter (tree parm) rtx incoming = DECL_INCOMING_RTL (parm); tree decl; machine_mode mode; - HOST_WIDE_INT offset; + poly_int64 offset; dataflow_set *out; decl_or_value dv; @@ -9738,7 +9765,8 @@ vt_add_function_parameter (tree parm) offset = 0; } - if (!track_loc_p (incoming, parm, offset, false, &mode, &offset)) + HOST_WIDE_INT const_offset; + if (!track_loc_p (incoming, parm, offset, false, &mode, &const_offset)) return; out = &VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out; @@ -9759,7 +9787,7 @@ vt_add_function_parameter (tree parm) arguments passed by invisible reference aren't dealt with above: incoming-rtl will have Pmode rather than the expected mode for the type. */ - if (offset) + if (const_offset) return; lowpart = var_lowpart (mode, incoming); @@ -9774,7 +9802,7 @@ vt_add_function_parameter (tree parm) if (val) { preserve_value (val); - set_variable_part (out, val->val_rtx, dv, offset, + set_variable_part (out, val->val_rtx, dv, const_offset, VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); dv = dv_from_value (val->val_rtx); } @@ -9795,9 +9823,9 @@ vt_add_function_parameter (tree parm) { incoming = var_lowpart (mode, incoming); gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER); - attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset, + attrs_list_insert (&out->regs[REGNO (incoming)], dv, const_offset, incoming); - set_variable_part (out, incoming, dv, offset, + set_variable_part (out, incoming, dv, const_offset, VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); if (dv_is_value_p (dv)) { @@ -9828,17 +9856,19 @@ vt_add_function_parameter (tree parm) for (i = 0; i < XVECLEN (incoming, 0); i++) { rtx reg = XEXP (XVECEXP (incoming, 0, i), 0); - offset = REG_OFFSET (reg); + /* vt_get_decl_and_offset has already checked that the offset + is a valid variable part. */ + const_offset = get_tracked_reg_offset (reg); gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER); - attrs_list_insert (&out->regs[REGNO (reg)], dv, offset, reg); - set_variable_part (out, reg, dv, offset, + attrs_list_insert (&out->regs[REGNO (reg)], dv, const_offset, reg); + set_variable_part (out, reg, dv, const_offset, VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); } } else if (MEM_P (incoming)) { incoming = var_lowpart (mode, incoming); - set_variable_part (out, incoming, dv, offset, + set_variable_part (out, incoming, dv, const_offset, VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); } }