From patchwork Mon Oct 23 17:07:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 116763 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp4874039qgn; Mon, 23 Oct 2017 10:08:32 -0700 (PDT) X-Received: by 10.99.168.76 with SMTP id i12mr12422393pgp.427.1508778511940; Mon, 23 Oct 2017 10:08:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1508778511; cv=none; d=google.com; s=arc-20160816; b=YVs/Bae03GByKjTMLpXWEefYm85QAmy2gLmS3iFmemXGErolhfSbA45AZ9hX3UjhCe 8WeMFBqCvaEUiM5EbbMn2Xl8MlguQyGOKzLgNvhbsSDIAvPTdrN3h8Q3eebi/NUc62bg eZoKF97rQTf2mHjyLnBx8oYxsEe6TeoGvJRU/CXfTz+Rdzof4mC83+e+eqUPQ+TdL6FV ej/EKjCQ8o9OIi01kvf46e7E9F5v9Wd2lA6xdpbQpgnQC3vN/bpq0i8TRTT3LY36kn/A tmwDBRWYgehSa10lN1uJ2xI4pDVHvpLZrpB/jIy5B7CXWpNwaKKzZHfXJqAFAIZk2Xu1 hjqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:in-reply-to:date:references :subject:mail-followup-to:to:from:delivered-to:sender:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=u8Q+r0Pwfd1Vbn6RwDB+d5ghPJwn+q7+2ZKujoeySic=; b=ngGuyuZsgZABYLPkzR6sLTy31zNIzOaKyuzLOYiVE7sRlq/e5dksZxj4PX9oxws26x AhMlW+uM5c/m2bOl9WBM+Rt79B/vPiy0cU46sqnErzrYUPUI4YTn9HQkfIdHWIDOOTU3 lYOwBkp8cNHWkwZQJRKsB+gjRSzvgV2mLcH7+F7oZ/GLCqpdT4hGUcT6VSMZN34zZdO9 DalhdvBbiT1U+g8MyBydZGaP3EcDlGLgYNrqvC3F/4ZKYxMOa2HpGdncNfw/Ai1nDz78 5nt/gu292APc6hCwSJLzrq4wNTOisV9BHim9mGeeq6CbqLvCCvho1V5kOokLxU9f1J8R uy1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=k0RFTR66; spf=pass (google.com: domain of gcc-patches-return-464795-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-464795-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id l6si5155315pgc.205.2017.10.23.10.08.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 23 Oct 2017 10:08:31 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-464795-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=k0RFTR66; spf=pass (google.com: domain of gcc-patches-return-464795-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-464795-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=G4Af1I32h4QqLZ/VzXX5wULKFT7k6 2UxrUHwBAqvasL04n51SUaF4O7SdY4e0BRhY8P60EvJJOu2qchFkJBoJ1YceMOW+ XhxaofNyZINbJrVW4OcS+/4enZjCwhVDZ1FONK7U/JXr0diP9/QjpktCpKDOwJFu xLozL24RrXcZ+0= 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:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=oux4Ico9+FuXV5KLZyMEmCN9mgc=; b=k0R FTR66SuDZvHzRFNojIC1tuJGG4uFiS7KVDf4Od+LG6Jwk0QA7SD/5x5kHr+bv08f StGHWDgh7a9XKsalwr857p5seH7sRFK3ozQJv0ZRZpMb64pOilyAbkD86Aw1dt4R wNvHCd0b+N8OcFDQGbCJqwnazBPbsxn59s+QFiTM= Received: (qmail 126074 invoked by alias); 23 Oct 2017 17:08:03 -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 126028 invoked by uid 89); 23 Oct 2017 17:08:02 -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=20010, presentations X-HELO: mail-wr0-f175.google.com Received: from mail-wr0-f175.google.com (HELO mail-wr0-f175.google.com) (209.85.128.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Oct 2017 17:07:59 +0000 Received: by mail-wr0-f175.google.com with SMTP id j15so5977907wre.8 for ; Mon, 23 Oct 2017 10:07:58 -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=u8Q+r0Pwfd1Vbn6RwDB+d5ghPJwn+q7+2ZKujoeySic=; b=Mqi+891UPCTdF1la3QRSPKvW0tvI1UlpACOSBojftVEwbBUm3xopUNzwh32vLwr0DH iNiohaiw+mL+/xwiL4MxVWLFQ/FVTIc0w7o63Ctq6yAhCMwiSzveRJr4TCE7QDPfGWeQ IzWia6RvxBIJLEU3/tVSUYxHNlHDF8skKN7LA53an5GXZOVDtxsT7jxRR8cxD1TasQUI AX9gtgC/1kaxOXfQMQJtkSMlugovwUv5kO4Mq/22KcJv3kSMurWS5Xa/wy2DNzM8FEIp qSVLKBqRUWQ/jboXW9QEDrFs4O8ilgCcBB0Ix0AnEygosiWjvpiPxMDZPeCalhotGLQU Ak+Q== X-Gm-Message-State: AMCzsaXzGYt7KhsvMHOI3xWfKmVRpGz/nhozgVNHQTPpxwo8z/2YkWaB 0y+UarikNvmEggKyNXT0LWSrvD52lg0= X-Google-Smtp-Source: ABhQp+Q8/IpouoBe8DiVFDzF8q9khGgvO05nKU+fSxlp63SqSHQ/A9juwU3bA+DkWZnxPq1Ga3Xmmw== X-Received: by 10.223.172.3 with SMTP id v3mr12709677wrc.195.1508778476045; Mon, 23 Oct 2017 10:07:56 -0700 (PDT) Received: from localhost ([2.26.27.199]) by smtp.gmail.com with ESMTPSA id u138sm8737958wmd.17.2017.10.23.10.07.54 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 10:07:55 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [019/nnn] poly_int: lra frame offsets References: <871sltvm7r.fsf@linaro.org> Date: Mon, 23 Oct 2017 18:07:54 +0100 In-Reply-To: <871sltvm7r.fsf@linaro.org> (Richard Sandiford's message of "Mon, 23 Oct 2017 17:54:32 +0100") Message-ID: <87lgk1rdw5.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch makes LRA use poly_int64s rather than HOST_WIDE_INTs to store a frame offset (including in things like eliminations). 2017-10-23 Richard Sandiford Alan Hayward David Sherwood gcc/ * lra-int.h (lra_reg): Change offset from int to poly_int64. (lra_insn_recog_data): Change sp_offset from HOST_WIDE_INT to poly_int64. (lra_eliminate_regs_1, eliminate_regs_in_insn): Change update_sp_offset from a HOST_WIDE_INT to a poly_int64. (lra_update_reg_val_offset, lra_reg_val_equal_p): Take the offset as a poly_int64 rather than an int. * lra-assigns.c (find_hard_regno_for_1): Handle poly_int64 offsets. (setup_live_pseudos_and_spill_after_risky_transforms): Likewise. * lra-constraints.c (equiv_address_substitution): Track offsets as poly_int64s. (emit_inc): Check poly_int_rtx_p instead of CONST_INT_P. (curr_insn_transform): Handle the new form of sp_offset. * lra-eliminations.c (lra_elim_table): Change previous_offset and offset from HOST_WIDE_INT to poly_int64. (print_elim_table, update_reg_eliminate): Update accordingly. (self_elim_offsets): Change from HOST_WIDE_INT to poly_int64_pod. (get_elimination): Update accordingly. (form_sum): Check poly_int_rtx_p instead of CONST_INT_P. (lra_eliminate_regs_1, eliminate_regs_in_insn): Change update_sp_offset from a HOST_WIDE_INT to a poly_int64. Handle poly_int64 offsets generally. (curr_sp_change): Change from HOST_WIDE_INT to poly_int64. (mark_not_eliminable, init_elimination): Update accordingly. (remove_reg_equal_offset_note): Return a bool and pass the new offset back by pointer as a poly_int64. * lra-remat.c (change_sp_offset): Take sp_offset as a poly_int64 rather than a HOST_WIDE_INT. (do_remat): Track offsets poly_int64s. * lra.c (lra_update_insn_recog_data, setup_sp_offset): Likewise. Index: gcc/lra-int.h =================================================================== --- gcc/lra-int.h 2017-10-23 16:52:19.836152258 +0100 +++ gcc/lra-int.h 2017-10-23 17:01:59.910337542 +0100 @@ -106,7 +106,7 @@ struct lra_reg they do not conflict. */ int val; /* Offset from relative eliminate register to pesudo reg. */ - int offset; + poly_int64 offset; /* These members are set up in lra-lives.c and updated in lra-coalesce.c. */ /* The biggest size mode in which each pseudo reg is referred in @@ -213,7 +213,7 @@ struct lra_insn_recog_data insn. */ int used_insn_alternative; /* SP offset before the insn relative to one at the func start. */ - HOST_WIDE_INT sp_offset; + poly_int64 sp_offset; /* The insn itself. */ rtx_insn *insn; /* Common data for insns with the same ICODE. Asm insns (their @@ -406,8 +406,8 @@ extern bool lra_remat (void); extern void lra_debug_elim_table (void); extern int lra_get_elimination_hard_regno (int); extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode, - bool, bool, HOST_WIDE_INT, bool); -extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, HOST_WIDE_INT); + bool, bool, poly_int64, bool); +extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64); extern void lra_eliminate (bool, bool); extern void lra_eliminate_reg_if_possible (rtx *); @@ -493,7 +493,7 @@ lra_get_insn_recog_data (rtx_insn *insn) /* Update offset from pseudos with VAL by INCR. */ static inline void -lra_update_reg_val_offset (int val, int incr) +lra_update_reg_val_offset (int val, poly_int64 incr) { int i; @@ -506,10 +506,10 @@ lra_update_reg_val_offset (int val, int /* Return true if register content is equal to VAL with OFFSET. */ static inline bool -lra_reg_val_equal_p (int regno, int val, int offset) +lra_reg_val_equal_p (int regno, int val, poly_int64 offset) { if (lra_reg_info[regno].val == val - && lra_reg_info[regno].offset == offset) + && must_eq (lra_reg_info[regno].offset, offset)) return true; return false; Index: gcc/lra-assigns.c =================================================================== --- gcc/lra-assigns.c 2017-10-23 16:52:19.836152258 +0100 +++ gcc/lra-assigns.c 2017-10-23 17:01:59.909338965 +0100 @@ -485,7 +485,8 @@ find_hard_regno_for_1 (int regno, int *c int hr, conflict_hr, nregs; machine_mode biggest_mode; unsigned int k, conflict_regno; - int offset, val, biggest_nregs, nregs_diff; + poly_int64 offset; + int val, biggest_nregs, nregs_diff; enum reg_class rclass; bitmap_iterator bi; bool *rclass_intersect_p; @@ -1147,7 +1148,8 @@ setup_live_pseudos_and_spill_after_risky { int p, i, j, n, regno, hard_regno; unsigned int k, conflict_regno; - int val, offset; + poly_int64 offset; + int val; HARD_REG_SET conflict_set; machine_mode mode; lra_live_range_t r; Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2017-10-23 16:52:19.836152258 +0100 +++ gcc/lra-constraints.c 2017-10-23 17:01:59.910337542 +0100 @@ -3084,7 +3084,8 @@ can_add_disp_p (struct address_info *ad) equiv_address_substitution (struct address_info *ad) { rtx base_reg, new_base_reg, index_reg, new_index_reg, *base_term, *index_term; - HOST_WIDE_INT disp, scale; + poly_int64 disp; + HOST_WIDE_INT scale; bool change_p; base_term = strip_subreg (ad->base_term); @@ -3115,6 +3116,7 @@ equiv_address_substitution (struct addre } if (base_reg != new_base_reg) { + poly_int64 offset; if (REG_P (new_base_reg)) { *base_term = new_base_reg; @@ -3122,10 +3124,10 @@ equiv_address_substitution (struct addre } else if (GET_CODE (new_base_reg) == PLUS && REG_P (XEXP (new_base_reg, 0)) - && CONST_INT_P (XEXP (new_base_reg, 1)) + && poly_int_rtx_p (XEXP (new_base_reg, 1), &offset) && can_add_disp_p (ad)) { - disp += INTVAL (XEXP (new_base_reg, 1)); + disp += offset; *base_term = XEXP (new_base_reg, 0); change_p = true; } @@ -3134,6 +3136,7 @@ equiv_address_substitution (struct addre } if (index_reg != new_index_reg) { + poly_int64 offset; if (REG_P (new_index_reg)) { *index_term = new_index_reg; @@ -3141,16 +3144,16 @@ equiv_address_substitution (struct addre } else if (GET_CODE (new_index_reg) == PLUS && REG_P (XEXP (new_index_reg, 0)) - && CONST_INT_P (XEXP (new_index_reg, 1)) + && poly_int_rtx_p (XEXP (new_index_reg, 1), &offset) && can_add_disp_p (ad) && (scale = get_index_scale (ad))) { - disp += INTVAL (XEXP (new_index_reg, 1)) * scale; + disp += offset * scale; *index_term = XEXP (new_index_reg, 0); change_p = true; } } - if (disp != 0) + if (maybe_nonzero (disp)) { if (ad->disp != NULL) *ad->disp = plus_constant (GET_MODE (*ad->inner), *ad->disp, disp); @@ -3629,9 +3632,10 @@ emit_inc (enum reg_class new_rclass, rtx register. */ if (plus_p) { - if (CONST_INT_P (inc)) + poly_int64 offset; + if (poly_int_rtx_p (inc, &offset)) emit_insn (gen_add2_insn (result, - gen_int_mode (-INTVAL (inc), + gen_int_mode (-offset, GET_MODE (result)))); else emit_insn (gen_sub2_insn (result, inc)); @@ -3999,10 +4003,13 @@ curr_insn_transform (bool check_only_p) if (INSN_CODE (curr_insn) >= 0 && (p = get_insn_name (INSN_CODE (curr_insn))) != NULL) fprintf (lra_dump_file, " {%s}", p); - if (curr_id->sp_offset != 0) - fprintf (lra_dump_file, " (sp_off=%" HOST_WIDE_INT_PRINT "d)", - curr_id->sp_offset); - fprintf (lra_dump_file, "\n"); + if (maybe_nonzero (curr_id->sp_offset)) + { + fprintf (lra_dump_file, " (sp_off="); + print_dec (curr_id->sp_offset, lra_dump_file); + fprintf (lra_dump_file, ")"); + } + fprintf (lra_dump_file, "\n"); } /* Right now, for any pair of operands I and J that are required to Index: gcc/lra-eliminations.c =================================================================== --- gcc/lra-eliminations.c 2017-10-23 16:52:19.836152258 +0100 +++ gcc/lra-eliminations.c 2017-10-23 17:01:59.910337542 +0100 @@ -79,9 +79,9 @@ struct lra_elim_table int to; /* Difference between values of the two hard registers above on previous iteration. */ - HOST_WIDE_INT previous_offset; + poly_int64 previous_offset; /* Difference between the values on the current iteration. */ - HOST_WIDE_INT offset; + poly_int64 offset; /* Nonzero if this elimination can be done. */ bool can_eliminate; /* CAN_ELIMINATE since the last check. */ @@ -120,10 +120,14 @@ print_elim_table (FILE *f) struct lra_elim_table *ep; for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) - fprintf (f, "%s eliminate %d to %d (offset=" HOST_WIDE_INT_PRINT_DEC - ", prev_offset=" HOST_WIDE_INT_PRINT_DEC ")\n", - ep->can_eliminate ? "Can" : "Can't", - ep->from, ep->to, ep->offset, ep->previous_offset); + { + fprintf (f, "%s eliminate %d to %d (offset=", + ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to); + print_dec (ep->offset, f); + fprintf (f, ", prev_offset="); + print_dec (ep->previous_offset, f); + fprintf (f, ")\n"); + } } /* Print info about elimination table to stderr. */ @@ -161,7 +165,7 @@ setup_can_eliminate (struct lra_elim_tab /* Offsets should be used to restore original offsets for eliminable hard register which just became not eliminable. Zero, otherwise. */ -static HOST_WIDE_INT self_elim_offsets[FIRST_PSEUDO_REGISTER]; +static poly_int64_pod self_elim_offsets[FIRST_PSEUDO_REGISTER]; /* Map: hard regno -> RTL presentation. RTL presentations of all potentially eliminable hard registers are stored in the map. */ @@ -193,6 +197,7 @@ setup_elimination_map (void) form_sum (rtx x, rtx y) { machine_mode mode = GET_MODE (x); + poly_int64 offset; if (mode == VOIDmode) mode = GET_MODE (y); @@ -200,10 +205,10 @@ form_sum (rtx x, rtx y) if (mode == VOIDmode) mode = Pmode; - if (CONST_INT_P (x)) - return plus_constant (mode, y, INTVAL (x)); - else if (CONST_INT_P (y)) - return plus_constant (mode, x, INTVAL (y)); + if (poly_int_rtx_p (x, &offset)) + return plus_constant (mode, y, offset); + else if (poly_int_rtx_p (y, &offset)) + return plus_constant (mode, x, offset); else if (CONSTANT_P (x)) std::swap (x, y); @@ -252,14 +257,14 @@ get_elimination (rtx reg) { int hard_regno; struct lra_elim_table *ep; - HOST_WIDE_INT offset; lra_assert (REG_P (reg)); if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) return NULL; if ((ep = elimination_map[hard_regno]) != NULL) return ep->from_rtx != reg ? NULL : ep; - if ((offset = self_elim_offsets[hard_regno]) == 0) + poly_int64 offset = self_elim_offsets[hard_regno]; + if (known_zero (offset)) return NULL; /* This is an iteration to restore offsets just after HARD_REGNO stopped to be eliminable. */ @@ -325,7 +330,7 @@ move_plus_up (rtx x) rtx lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, bool subst_p, bool update_p, - HOST_WIDE_INT update_sp_offset, bool full_p) + poly_int64 update_sp_offset, bool full_p) { enum rtx_code code = GET_CODE (x); struct lra_elim_table *ep; @@ -335,7 +340,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt int copied = 0; lra_assert (!update_p || !full_p); - lra_assert (update_sp_offset == 0 || (!subst_p && update_p && !full_p)); + lra_assert (known_zero (update_sp_offset) + || (!subst_p && update_p && !full_p)); if (! current_function_decl) return x; @@ -360,7 +366,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; - if (update_sp_offset != 0) + if (maybe_nonzero (update_sp_offset)) { if (ep->to_rtx == stack_pointer_rtx) return plus_constant (Pmode, to, update_sp_offset); @@ -387,20 +393,21 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt { if ((ep = get_elimination (XEXP (x, 0))) != NULL) { - HOST_WIDE_INT offset; + poly_int64 offset, curr_offset; rtx to = subst_p ? ep->to_rtx : ep->from_rtx; if (! update_p && ! full_p) return gen_rtx_PLUS (Pmode, to, XEXP (x, 1)); - if (update_sp_offset != 0) + if (maybe_nonzero (update_sp_offset)) offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0; else offset = (update_p ? ep->offset - ep->previous_offset : ep->offset); if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) offset -= lra_get_insn_recog_data (insn)->sp_offset; - if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == -offset) + if (poly_int_rtx_p (XEXP (x, 1), &curr_offset) + && must_eq (curr_offset, -offset)) return to; else return gen_rtx_PLUS (Pmode, to, @@ -449,7 +456,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; - if (update_sp_offset != 0) + if (maybe_nonzero (update_sp_offset)) { if (ep->to_rtx == stack_pointer_rtx) return plus_constant (Pmode, @@ -464,7 +471,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt * INTVAL (XEXP (x, 1))); else if (full_p) { - HOST_WIDE_INT offset = ep->offset; + poly_int64 offset = ep->offset; if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) offset -= lra_get_insn_recog_data (insn)->sp_offset; @@ -711,7 +718,7 @@ lra_eliminate_regs (rtx x, machine_mode /* Stack pointer offset before the current insn relative to one at the func start. RTL insns can change SP explicitly. We keep the changes from one insn to another through this variable. */ -static HOST_WIDE_INT curr_sp_change; +static poly_int64 curr_sp_change; /* Scan rtx X for references to elimination source or target registers in contexts that would prevent the elimination from happening. @@ -725,6 +732,7 @@ mark_not_eliminable (rtx x, machine_mode struct lra_elim_table *ep; int i, j; const char *fmt; + poly_int64 offset = 0; switch (code) { @@ -738,7 +746,7 @@ mark_not_eliminable (rtx x, machine_mode && ((code != PRE_MODIFY && code != POST_MODIFY) || (GET_CODE (XEXP (x, 1)) == PLUS && XEXP (x, 0) == XEXP (XEXP (x, 1), 0) - && CONST_INT_P (XEXP (XEXP (x, 1), 1))))) + && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset)))) { int size = GET_MODE_SIZE (mem_mode); @@ -752,7 +760,7 @@ mark_not_eliminable (rtx x, machine_mode else if (code == PRE_INC || code == POST_INC) curr_sp_change += size; else if (code == PRE_MODIFY || code == POST_MODIFY) - curr_sp_change += INTVAL (XEXP (XEXP (x, 1), 1)); + curr_sp_change += offset; } else if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER) @@ -802,9 +810,9 @@ mark_not_eliminable (rtx x, machine_mode if (SET_DEST (x) == stack_pointer_rtx && GET_CODE (SET_SRC (x)) == PLUS && XEXP (SET_SRC (x), 0) == SET_DEST (x) - && CONST_INT_P (XEXP (SET_SRC (x), 1))) + && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset)) { - curr_sp_change += INTVAL (XEXP (SET_SRC (x), 1)); + curr_sp_change += offset; return; } if (! REG_P (SET_DEST (x)) @@ -859,11 +867,11 @@ mark_not_eliminable (rtx x, machine_mode #ifdef HARD_FRAME_POINTER_REGNUM -/* Find offset equivalence note for reg WHAT in INSN and return the - found elmination offset. If the note is not found, return NULL. - Remove the found note. */ -static rtx -remove_reg_equal_offset_note (rtx_insn *insn, rtx what) +/* Search INSN's reg notes to see whether the destination is equal to + WHAT + C for some constant C. Return true if so, storing C in + *OFFSET_OUT and removing the reg note. */ +static bool +remove_reg_equal_offset_note (rtx_insn *insn, rtx what, poly_int64 *offset_out) { rtx link, *link_loc; @@ -873,12 +881,12 @@ remove_reg_equal_offset_note (rtx_insn * if (REG_NOTE_KIND (link) == REG_EQUAL && GET_CODE (XEXP (link, 0)) == PLUS && XEXP (XEXP (link, 0), 0) == what - && CONST_INT_P (XEXP (XEXP (link, 0), 1))) + && poly_int_rtx_p (XEXP (XEXP (link, 0), 1), offset_out)) { *link_loc = XEXP (link, 1); - return XEXP (XEXP (link, 0), 1); + return true; } - return NULL_RTX; + return false; } #endif @@ -899,7 +907,7 @@ remove_reg_equal_offset_note (rtx_insn * void eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, - HOST_WIDE_INT update_sp_offset) + poly_int64 update_sp_offset) { int icode = recog_memoized (insn); rtx old_set = single_set (insn); @@ -940,28 +948,21 @@ eliminate_regs_in_insn (rtx_insn *insn, nonlocal goto. */ { rtx src = SET_SRC (old_set); - rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx); - + poly_int64 offset = 0; + /* We should never process such insn with non-zero UPDATE_SP_OFFSET. */ - lra_assert (update_sp_offset == 0); + lra_assert (known_zero (update_sp_offset)); - if (off != NULL_RTX - || src == ep->to_rtx - || (GET_CODE (src) == PLUS - && XEXP (src, 0) == ep->to_rtx - && CONST_INT_P (XEXP (src, 1)))) + if (remove_reg_equal_offset_note (insn, ep->to_rtx, &offset) + || strip_offset (src, &offset) == ep->to_rtx) { - HOST_WIDE_INT offset; - if (replace_p) { SET_DEST (old_set) = ep->to_rtx; lra_update_insn_recog_data (insn); return; } - offset = (off != NULL_RTX ? INTVAL (off) - : src == ep->to_rtx ? 0 : INTVAL (XEXP (src, 1))); offset -= (ep->offset - ep->previous_offset); src = plus_constant (Pmode, ep->to_rtx, offset); @@ -997,13 +998,13 @@ eliminate_regs_in_insn (rtx_insn *insn, currently support: a single set with the source or a REG_EQUAL note being a PLUS of an eliminable register and a constant. */ plus_src = plus_cst_src = 0; + poly_int64 offset = 0; if (old_set && REG_P (SET_DEST (old_set))) { if (GET_CODE (SET_SRC (old_set)) == PLUS) plus_src = SET_SRC (old_set); /* First see if the source is of the form (plus (...) CST). */ - if (plus_src - && CONST_INT_P (XEXP (plus_src, 1))) + if (plus_src && poly_int_rtx_p (XEXP (plus_src, 1), &offset)) plus_cst_src = plus_src; /* Check that the first operand of the PLUS is a hard reg or the lowpart subreg of one. */ @@ -1021,7 +1022,6 @@ eliminate_regs_in_insn (rtx_insn *insn, if (plus_cst_src) { rtx reg = XEXP (plus_cst_src, 0); - HOST_WIDE_INT offset = INTVAL (XEXP (plus_cst_src, 1)); if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); @@ -1032,7 +1032,7 @@ eliminate_regs_in_insn (rtx_insn *insn, if (! replace_p) { - if (update_sp_offset == 0) + if (known_zero (update_sp_offset)) offset += (ep->offset - ep->previous_offset); if (ep->to_rtx == stack_pointer_rtx) { @@ -1051,7 +1051,7 @@ eliminate_regs_in_insn (rtx_insn *insn, the cost of the insn by replacing a simple REG with (plus (reg sp) CST). So try only when we already had a PLUS before. */ - if (offset == 0 || plus_src) + if (known_zero (offset) || plus_src) { rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset); @@ -1239,7 +1239,7 @@ update_reg_eliminate (bitmap insns_with_ if (lra_dump_file != NULL) fprintf (lra_dump_file, " Using elimination %d to %d now\n", ep1->from, ep1->to); - lra_assert (ep1->previous_offset == 0); + lra_assert (known_zero (ep1->previous_offset)); ep1->previous_offset = ep->offset; } else @@ -1251,7 +1251,7 @@ update_reg_eliminate (bitmap insns_with_ fprintf (lra_dump_file, " %d is not eliminable at all\n", ep->from); self_elim_offsets[ep->from] = -ep->offset; - if (ep->offset != 0) + if (maybe_nonzero (ep->offset)) bitmap_ior_into (insns_with_changed_offsets, &lra_reg_info[ep->from].insn_bitmap); } @@ -1271,7 +1271,7 @@ update_reg_eliminate (bitmap insns_with_ the usage for pseudos. */ if (ep->from != ep->to) SET_HARD_REG_BIT (temp_hard_reg_set, ep->to); - if (ep->previous_offset != ep->offset) + if (may_ne (ep->previous_offset, ep->offset)) { bitmap_ior_into (insns_with_changed_offsets, &lra_reg_info[ep->from].insn_bitmap); @@ -1357,13 +1357,13 @@ init_elimination (void) if (NONDEBUG_INSN_P (insn)) { mark_not_eliminable (PATTERN (insn), VOIDmode); - if (curr_sp_change != 0 + if (maybe_nonzero (curr_sp_change) && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX)) stop_to_sp_elimination_p = true; } } if (! frame_pointer_needed - && (curr_sp_change != 0 || stop_to_sp_elimination_p) + && (maybe_nonzero (curr_sp_change) || stop_to_sp_elimination_p) && bb->succs && bb->succs->length () != 0) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) if (ep->to == STACK_POINTER_REGNUM) Index: gcc/lra-remat.c =================================================================== --- gcc/lra-remat.c 2017-10-23 16:52:19.836152258 +0100 +++ gcc/lra-remat.c 2017-10-23 17:01:59.910337542 +0100 @@ -994,7 +994,7 @@ calculate_global_remat_bb_data (void) /* Setup sp offset attribute to SP_OFFSET for all INSNS. */ static void -change_sp_offset (rtx_insn *insns, HOST_WIDE_INT sp_offset) +change_sp_offset (rtx_insn *insns, poly_int64 sp_offset) { for (rtx_insn *insn = insns; insn != NULL; insn = NEXT_INSN (insn)) eliminate_regs_in_insn (insn, false, false, sp_offset); @@ -1118,7 +1118,7 @@ do_remat (void) int i, hard_regno, nregs; int dst_hard_regno, dst_nregs; rtx_insn *remat_insn = NULL; - HOST_WIDE_INT cand_sp_offset = 0; + poly_int64 cand_sp_offset = 0; if (cand != NULL) { lra_insn_recog_data_t cand_id @@ -1241,8 +1241,8 @@ do_remat (void) if (remat_insn != NULL) { - HOST_WIDE_INT sp_offset_change = cand_sp_offset - id->sp_offset; - if (sp_offset_change != 0) + poly_int64 sp_offset_change = cand_sp_offset - id->sp_offset; + if (maybe_nonzero (sp_offset_change)) change_sp_offset (remat_insn, sp_offset_change); update_scratch_ops (remat_insn); lra_process_new_insns (insn, remat_insn, NULL, Index: gcc/lra.c =================================================================== --- gcc/lra.c 2017-10-23 16:52:19.836152258 +0100 +++ gcc/lra.c 2017-10-23 17:01:59.911336118 +0100 @@ -1163,7 +1163,7 @@ lra_update_insn_recog_data (rtx_insn *in int n; unsigned int uid = INSN_UID (insn); struct lra_static_insn_data *insn_static_data; - HOST_WIDE_INT sp_offset = 0; + poly_int64 sp_offset = 0; check_and_expand_insn_recog_data (uid); if ((data = lra_insn_recog_data[uid]) != NULL @@ -1805,8 +1805,8 @@ push_insns (rtx_insn *from, rtx_insn *to setup_sp_offset (rtx_insn *from, rtx_insn *last) { rtx_insn *before = next_nonnote_insn_bb (last); - HOST_WIDE_INT offset = (before == NULL_RTX || ! INSN_P (before) - ? 0 : lra_get_insn_recog_data (before)->sp_offset); + poly_int64 offset = (before == NULL_RTX || ! INSN_P (before) + ? 0 : lra_get_insn_recog_data (before)->sp_offset); for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn)) lra_get_insn_recog_data (insn)->sp_offset = offset;