From patchwork Tue Nov 6 14:48:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Leoshkevich X-Patchwork-Id: 993733 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-489167-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="LwvqJwt0"; dkim-atps=neutral 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 42qC9r1h9kz9s7W for ; Wed, 7 Nov 2018 01:49:18 +1100 (AEDT) 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:cc:subject:date:mime-version:content-transfer-encoding :message-id; q=dns; s=default; b=dWiHabVNTSebLvwwJv2XHx1K0QP7dTx Y+YkAjCEcgPHi10LegwXwbVS5KmVQpwr1fUrXHakRqic1j4ls/LThtkEQLt8DhIC GFff/JNFlSLrC5ASvmRxnxb1N0imnMB/ln8QgKnmMMirDGmrz/oEkMKcTFWqZgZ2 e9AMsWXEoljg= 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:cc:subject:date:mime-version:content-transfer-encoding :message-id; s=default; bh=DNJ7EZHkVFWjT0qDq/b4PzfWEr0=; b=LwvqJ wt0sC4DRzTEhNazNYMe9hcXjRWHz+DxN3YubQaRA3GqVT6+OQIv4c5CVhGtyID1w CYQkyi3kIlrU1uDENeiRMTpyUpj1UnDv50kQ2EgHyVvjJad6qtBc9xHfbQt4F5y9 3MEXZ8MVt1oRRFVwCObziP+mHeIczevTNyoclQ= Received: (qmail 42043 invoked by alias); 6 Nov 2018 14:49:08 -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 41855 invoked by uid 89); 6 Nov 2018 14:49:01 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, KHOP_DYNAMIC, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=REF, H*Ad:D*de.ibm.com X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 06 Nov 2018 14:48:57 +0000 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id wA6Ej71Q169286 for ; Tue, 6 Nov 2018 09:48:34 -0500 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0b-001b2d01.pphosted.com with ESMTP id 2nk9v18gk9-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 06 Nov 2018 09:48:33 -0500 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 6 Nov 2018 14:48:31 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp05.uk.ibm.com (192.168.101.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 6 Nov 2018 14:48:29 -0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id wA6EmRpg60751896 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 6 Nov 2018 14:48:27 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 52114A4040; Tue, 6 Nov 2018 14:48:27 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 13DEBA4053; Tue, 6 Nov 2018 14:48:27 +0000 (GMT) Received: from white.boeblingen.de.ibm.com (unknown [9.152.99.80]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 6 Nov 2018 14:48:27 +0000 (GMT) From: Ilya Leoshkevich To: gcc-patches@gcc.gnu.org Cc: krebbel@linux.ibm.com, rdapp@linux.ibm.com, uweigand@de.ibm.com, Ilya Leoshkevich Subject: [PATCH v3] S/390: Allow relative addressing of literal pool entries Date: Tue, 6 Nov 2018 15:48:23 +0100 MIME-Version: 1.0 x-cbid: 18110614-0020-0000-0000-000002E106BF X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18110614-0021-0000-0000-000021307CF3 Message-Id: <20181106144823.9541-1-iii@linux.ibm.com> X-IsSubscribed: yes Bootstrapped and regtested on s390x-redhat-linux. r265490 allowed the compiler to choose in a more flexible way whether to use load or load-address-relative-long (LARL) instruction. When it chose LARL for literal pool references, the latter ones were rewritten by pass_s390_early_mach to use UNSPEC_LTREF, which assumes base register usage, which in turn is not compatible with LARL. The end result was an ICE because of unrecognizable insn. UNSPEC_LTREF and friends are necessary in order to communicate the dependency on the base register to pass_sched2. When relative addressing is used, no base register is necessary, so in such cases the rewrite must be avoided. gcc/ChangeLog: 2018-11-05 Ilya Leoshkevich PR target/87762 * config/s390/predicates.md (larl_operand): Use s390_symbol_relative_long_p () to reduce code duplication. * config/s390/s390-protos.h (s390_symbol_relative_long_p): New function. * config/s390/s390.c (s390_safe_relative_long_p): Likewise. (annotate_constant_pool_refs): Skip insns which support relative addressing. (annotate_constant_pool_refs_1): New helper function. (s390_symbol_relative_long_p): New function. (find_constant_pool_ref): Return unannotated constant pool references. (replace_constant_pool_ref): Skip insns which support relative addressing. (replace_constant_pool_ref_1): New helper function. (s390_mainpool_finish): Adjust to the new signature of replace_constant_pool_ref (). (s390_chunkify_finish): Likewise. (pass_s390_early_mach::execute): Likewise. (s390_prologue_plus_offset): Likewise. (s390_emit_prologue): Likewise. (s390_emit_epilogue): Likewise. --- gcc/config/s390/predicates.md | 8 +-- gcc/config/s390/s390-protos.h | 1 + gcc/config/s390/s390.c | 107 ++++++++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index 97f717c558d..bb66c8a6bcb 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -151,9 +151,7 @@ if (GET_CODE (op) == LABEL_REF) return true; if (SYMBOL_REF_P (op)) - return (!SYMBOL_FLAG_NOTALIGN2_P (op) - && SYMBOL_REF_TLS_MODEL (op) == 0 - && s390_rel_address_ok_p (op)); + return s390_symbol_relative_long_p (op); /* Everything else must have a CONST, so strip it. */ if (GET_CODE (op) != CONST) @@ -176,9 +174,7 @@ if (GET_CODE (op) == LABEL_REF) return true; if (SYMBOL_REF_P (op)) - return (!SYMBOL_FLAG_NOTALIGN2_P (op) - && SYMBOL_REF_TLS_MODEL (op) == 0 - && s390_rel_address_ok_p (op)); + return s390_symbol_relative_long_p (op); /* Now we must have a @GOTENT offset or @PLT stub diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 96fa705f879..d3c2cc55e28 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -157,6 +157,7 @@ extern void s390_indirect_branch_via_thunk (unsigned int regno, rtx comparison_operator, enum s390_indirect_branch_type type); extern void s390_indirect_branch_via_inline_thunk (rtx execute_target); +extern bool s390_symbol_relative_long_p (rtx); #endif /* RTX_CODE */ /* s390-c.c routines */ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 1be85727b73..c1318c25004 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2731,6 +2731,17 @@ s390_safe_attr_type (rtx_insn *insn) return TYPE_NONE; } +/* Return attribute relative_long of insn. */ + +static bool +s390_safe_relative_long_p (rtx_insn *insn) +{ + if (recog_memoized (insn) >= 0) + return get_attr_relative_long (insn) == RELATIVE_LONG_YES; + else + return false; +} + /* Return true if DISP is a valid short displacement. */ static bool @@ -8116,11 +8127,8 @@ s390_first_cycle_multipass_dfa_lookahead (void) return 4; } -/* Annotate every literal pool reference in X by an UNSPEC_LTREF expression. - Fix up MEMs as required. */ - static void -annotate_constant_pool_refs (rtx *x) +annotate_constant_pool_refs_1 (rtx *x) { int i, j; const char *fmt; @@ -8199,18 +8207,41 @@ annotate_constant_pool_refs (rtx *x) { if (fmt[i] == 'e') { - annotate_constant_pool_refs (&XEXP (*x, i)); + annotate_constant_pool_refs_1 (&XEXP (*x, i)); } else if (fmt[i] == 'E') { for (j = 0; j < XVECLEN (*x, i); j++) - annotate_constant_pool_refs (&XVECEXP (*x, i, j)); + annotate_constant_pool_refs_1 (&XVECEXP (*x, i, j)); } } } -/* Find an annotated literal pool symbol referenced in RTX X, - and store it at REF. Will abort if X contains references to +/* Annotate every literal pool reference in INSN by an UNSPEC_LTREF expression. + Fix up MEMs as required. + Skip insns which support relative addressing, because they do not use a base + register. */ + +static void +annotate_constant_pool_refs (rtx_insn *insn) +{ + if (s390_safe_relative_long_p (insn)) + return; + annotate_constant_pool_refs_1 (&PATTERN (insn)); +} + +/* Return true iff SYMBOL_REF X can be used with a relative long addressing. */ + +bool +s390_symbol_relative_long_p (rtx x) +{ + return (!SYMBOL_FLAG_NOTALIGN2_P (x) + && SYMBOL_REF_TLS_MODEL (x) == 0 + && s390_rel_address_ok_p (x)); +} + +/* Find a literal pool symbol referenced in INSN, + and store it at REF. Will abort if INSN contains references to more than one such pool symbol; multiple references to the same symbol are allowed, however. @@ -8228,6 +8259,23 @@ find_constant_pool_ref (rtx x, rtx *ref) && XINT (x, 1) == UNSPECV_POOL_ENTRY) return; + /* Return unannotated constant pool references, so that the corresponding + entries are added to the back-end-managed pool. Not doing so would result + in those entries being placed in the middle-end-managed pool, which would + in turn prevent merging them with identical ones in the back-end-managed + pool. */ + if (SYMBOL_REF_P (x) + && CONSTANT_POOL_ADDRESS_P (x) + && s390_symbol_relative_long_p (x)) + { + if (*ref == NULL_RTX) + *ref = x; + else + gcc_assert (*ref == x); + + return; + } + gcc_assert (GET_CODE (x) != SYMBOL_REF || !CONSTANT_POOL_ADDRESS_P (x)); @@ -8260,11 +8308,8 @@ find_constant_pool_ref (rtx x, rtx *ref) } } -/* Replace every reference to the annotated literal pool - symbol REF in X by its base plus OFFSET. */ - static void -replace_constant_pool_ref (rtx *x, rtx ref, rtx offset) +replace_constant_pool_ref_1 (rtx *x, rtx ref, rtx offset) { int i, j; const char *fmt; @@ -8295,16 +8340,29 @@ replace_constant_pool_ref (rtx *x, rtx ref, rtx offset) { if (fmt[i] == 'e') { - replace_constant_pool_ref (&XEXP (*x, i), ref, offset); + replace_constant_pool_ref_1 (&XEXP (*x, i), ref, offset); } else if (fmt[i] == 'E') { for (j = 0; j < XVECLEN (*x, i); j++) - replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset); + replace_constant_pool_ref_1 (&XVECEXP (*x, i, j), ref, offset); } } } +/* Replace every reference to the annotated literal pool + symbol REF in INSN by its base plus OFFSET. + Skip insns which support relative addressing, because they do not use a base + register. */ + +static void +replace_constant_pool_ref (rtx_insn *insn, rtx ref, rtx offset) +{ + if (s390_safe_relative_long_p (insn)) + return; + replace_constant_pool_ref_1 (&PATTERN (insn), ref, offset); +} + /* We keep a list of constants which we have to add to internal constant tables in the middle of large functions. */ @@ -8801,7 +8859,7 @@ s390_mainpool_finish (struct constant_pool *pool) addr = s390_find_constant (pool, get_pool_constant (pool_ref), get_pool_mode (pool_ref)); - replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr); + replace_constant_pool_ref (insn, pool_ref, addr); INSN_CODE (insn) = -1; } } @@ -9002,7 +9060,7 @@ s390_chunkify_finish (struct constant_pool *pool_list) get_pool_constant (pool_ref), get_pool_mode (pool_ref)); - replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr); + replace_constant_pool_ref (insn, pool_ref, addr); INSN_CODE (insn) = -1; } } @@ -10595,7 +10653,7 @@ pass_s390_early_mach::execute (function *fun) for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) { - annotate_constant_pool_refs (&PATTERN (insn)); + annotate_constant_pool_refs (insn); df_insn_rescan (insn); } return 0; @@ -10616,7 +10674,7 @@ make_pass_s390_early_mach (gcc::context *ctxt) static rtx s390_prologue_plus_offset (rtx target, rtx reg, rtx offset, bool frame_related_p) { - rtx insn; + rtx_insn *insn; rtx orig_offset = offset; gcc_assert (REG_P (target)); @@ -10650,7 +10708,7 @@ s390_prologue_plus_offset (rtx target, rtx reg, rtx offset, bool frame_related_p if (!CONST_INT_P (offset)) { - annotate_constant_pool_refs (&PATTERN (insn)); + annotate_constant_pool_refs (insn); if (frame_related_p) add_reg_note (insn, REG_FRAME_RELATED_EXPR, @@ -11090,7 +11148,7 @@ s390_emit_prologue (void) rtx_insn *insns = s390_load_got (); for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn)) - annotate_constant_pool_refs (&PATTERN (insn)); + annotate_constant_pool_refs (insn); emit_insn (insns); } @@ -11154,7 +11212,8 @@ s390_emit_epilogue (bool sibcall) } else { - rtx insn, frame_off, cfa; + rtx_insn *insn; + rtx frame_off, cfa; offset = area_bottom < 0 ? -area_bottom : 0; frame_off = GEN_INT (cfun_frame_layout.frame_size - offset); @@ -11163,9 +11222,7 @@ s390_emit_epilogue (bool sibcall) gen_rtx_PLUS (Pmode, frame_pointer, frame_off)); if (DISP_IN_RANGE (INTVAL (frame_off))) { - insn = gen_rtx_SET (frame_pointer, - gen_rtx_PLUS (Pmode, frame_pointer, frame_off)); - insn = emit_insn (insn); + insn = emit_insn (copy_rtx (cfa)); } else { @@ -11173,7 +11230,7 @@ s390_emit_epilogue (bool sibcall) frame_off = force_const_mem (Pmode, frame_off); insn = emit_insn (gen_add2_insn (frame_pointer, frame_off)); - annotate_constant_pool_refs (&PATTERN (insn)); + annotate_constant_pool_refs (insn); } add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa); RTX_FRAME_RELATED_P (insn) = 1;