From patchwork Thu Aug 22 13:45:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Leoshkevich X-Patchwork-Id: 1151613 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-507517-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="syd2+D+j"; 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 46Dm6W5z7kz9s00 for ; Thu, 22 Aug 2019 23:46:59 +1000 (AEST) 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:in-reply-to:references:mime-version :content-transfer-encoding:message-id; q=dns; s=default; b=Hc2Qn xrR6OGlitOPGVxJiIL5zpQJJcXsEaKiUF7JdZiau0EiS6buVOwNXSnssVALoCoPc 618UHJ8lTMuq/6sJ0m6y8BVwGVkOS3OT0rIz1Laj0GUEUJ/+xUERDJHoJ/kqC97o 2crj2QpiyKXObKYakQPfQyotBX5NFAFKAgXQeU= 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:in-reply-to:references:mime-version :content-transfer-encoding:message-id; s=default; bh=tBsLlvGta7a Agu/CSkJG++y4cys=; b=syd2+D+jRZgcvLGHw2vkIhjQmXmM1FGFRhTT4zoQvpg W4zG9MKv7ARU00i98fL5FSRgobOvEXGlj/4w+jsE/PikWQzvf2H5lThd6AKW/3Na 972ZAbzTl9iP5ADmOld2aRhpRfJoE2gCwMwfM22gQRRBzf+0L9r6mb7uqDjKVOm4 = Received: (qmail 74522 invoked by alias); 22 Aug 2019 13:46:52 -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 74508 invoked by uid 89); 22 Aug 2019 13:46:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.1 spammy=non-signaling, nonsignaling X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 22 Aug 2019 13:46:49 +0000 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x7MDXhEB020088 for ; Thu, 22 Aug 2019 09:46:48 -0400 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0a-001b2d01.pphosted.com with ESMTP id 2uhuestbhk-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 22 Aug 2019 09:46:48 -0400 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 22 Aug 2019 14:46:46 +0100 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) 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) Thu, 22 Aug 2019 14:46:44 +0100 Received: from d06av24.portsmouth.uk.ibm.com (mk.ibm.com [9.149.105.60]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x7MDkhbr44892276 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 22 Aug 2019 13:46:43 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 391614203F; Thu, 22 Aug 2019 13:46:43 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0131C42049; Thu, 22 Aug 2019 13:46:43 +0000 (GMT) Received: from white.boeblingen.de.ibm.com (unknown [9.152.99.241]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 22 Aug 2019 13:46:42 +0000 (GMT) From: Ilya Leoshkevich To: gcc-patches@gcc.gnu.org Cc: richard.sandiford@arm.com, segher@kernel.crashing.org, Ilya Leoshkevich Subject: [PATCH v2 3/9] Introduce can_vector_compare_p function Date: Thu, 22 Aug 2019 15:45:45 +0200 In-Reply-To: <20190822134551.18924-1-iii@linux.ibm.com> References: <20190822134551.18924-1-iii@linux.ibm.com> MIME-Version: 1.0 x-cbid: 19082213-0020-0000-0000-00000362843F X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19082213-0021-0000-0000-000021B7BFC9 Message-Id: <20190822134551.18924-4-iii@linux.ibm.com> X-IsSubscribed: yes z13 supports only non-signaling vector comparisons. This means we cannot vectorize LT, LE, GT, GE and LTGT when compiling for z13. However, we cannot express this restriction today: the code only checks whether vcond$a$b optab exists, which does not contain information about the operation. Introduce a function that checks whether back-end supports vector comparisons with individual rtx codes by matching vcond expander's third argument with a fake comparison with the corresponding rtx code. gcc/ChangeLog: 2019-08-21 Ilya Leoshkevich * Makefile.in (GTFILES): Add optabs.c. * optabs-tree.c (expand_vec_cond_expr_p): Use can_vector_compare_p. * optabs.c (binop_key): Binary operation cache key. (binop_hasher): Binary operation cache hasher. (cached_binops): Binary operation cache. (get_cached_binop): New function that returns a cached binary operation or creates a new one. (can_vector_compare_p): New function. * optabs.h (enum can_vector_compare_purpose): New enum. Not really needed today, but can be used to extend the support to e.g. vec_cmp if need arises. (can_vector_compare_p): New function. --- gcc/Makefile.in | 2 +- gcc/optabs-tree.c | 11 +++++-- gcc/optabs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ gcc/optabs.h | 15 +++++++++ 4 files changed, 104 insertions(+), 3 deletions(-) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 597dc01328b..d2207da5657 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2541,7 +2541,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/function.c $(srcdir)/except.c \ $(srcdir)/ggc-tests.c \ $(srcdir)/gcse.c $(srcdir)/godump.c \ - $(srcdir)/lists.c $(srcdir)/optabs-libfuncs.c \ + $(srcdir)/lists.c $(srcdir)/optabs.c $(srcdir)/optabs-libfuncs.c \ $(srcdir)/profile.c $(srcdir)/mcf.c \ $(srcdir)/reg-stack.c $(srcdir)/cfgrtl.c \ $(srcdir)/stor-layout.c \ diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c index 8157798cc71..e68bb39c021 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -23,7 +23,10 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "target.h" #include "insn-codes.h" +#include "rtl.h" #include "tree.h" +#include "memmodel.h" +#include "optabs.h" #include "optabs-tree.h" #include "stor-layout.h" @@ -347,8 +350,12 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code) || maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode))) return false; - if (get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type), - TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing + bool unsigned_p = TYPE_UNSIGNED (cmp_op_type); + if (((get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type), + unsigned_p) == CODE_FOR_nothing) + || !can_vector_compare_p (get_rtx_code (code, unsigned_p), + TYPE_MODE (value_type), + TYPE_MODE (cmp_op_type), cvcp_vcond)) && ((code != EQ_EXPR && code != NE_EXPR) || get_vcond_eq_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type)) == CODE_FOR_nothing)) diff --git a/gcc/optabs.c b/gcc/optabs.c index 9e54dda6e7f..07b4d824822 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "recog.h" #include "diagnostic-core.h" #include "rtx-vector-builder.h" +#include "hash-table.h" /* Include insn-config.h before expr.h so that HAVE_conditional_move is properly defined. */ @@ -3819,6 +3820,82 @@ can_compare_p (enum rtx_code code, machine_mode mode, return 0; } +/* can_vector_compare_p presents fake rtx binary operations to the the back-end + in order to determine its capabilities. In order to avoid creating fake + operations on each call, values from previous calls are cached in a global + cached_binops hash_table. It contains rtxes, which can be looked up using + binop_keys. */ + +struct binop_key { + enum rtx_code code; /* Operation code. */ + machine_mode value_mode; /* Result mode. */ + machine_mode cmp_op_mode; /* Operand mode. */ +}; + +struct binop_hasher : pointer_hash_mark, ggc_cache_remove { + typedef rtx value_type; + typedef binop_key compare_type; + + static hashval_t + hash (enum rtx_code code, machine_mode value_mode, machine_mode cmp_op_mode) + { + inchash::hash hstate (0); + hstate.add_int (code); + hstate.add_int (value_mode); + hstate.add_int (cmp_op_mode); + return hstate.end (); + } + + static hashval_t + hash (const rtx &ref) + { + return hash (GET_CODE (ref), GET_MODE (ref), GET_MODE (XEXP (ref, 0))); + } + + static bool + equal (const rtx &ref1, const binop_key &ref2) + { + return (GET_CODE (ref1) == ref2.code) + && (GET_MODE (ref1) == ref2.value_mode) + && (GET_MODE (XEXP (ref1, 0)) == ref2.cmp_op_mode); + } +}; + +static GTY ((cache)) hash_table *cached_binops; + +static rtx +get_cached_binop (enum rtx_code code, machine_mode value_mode, + machine_mode cmp_op_mode) +{ + if (!cached_binops) + cached_binops = hash_table::create_ggc (1024); + binop_key key = { code, value_mode, cmp_op_mode }; + hashval_t hash = binop_hasher::hash (code, value_mode, cmp_op_mode); + rtx *slot = cached_binops->find_slot_with_hash (key, hash, INSERT); + if (!*slot) + *slot = gen_rtx_fmt_ee (code, value_mode, gen_reg_rtx (cmp_op_mode), + gen_reg_rtx (cmp_op_mode)); + return *slot; +} + +bool +can_vector_compare_p (enum rtx_code code, machine_mode value_mode, + machine_mode cmp_op_mode, + enum can_vector_compare_purpose purpose) +{ + enum insn_code icode; + bool unsigned_p = (code == LTU || code == LEU || code == GTU || code == GEU); + rtx test = get_cached_binop(code, value_mode, cmp_op_mode); + + if (purpose == cvcp_vcond + && (icode = get_vcond_icode (value_mode, cmp_op_mode, unsigned_p)) + != CODE_FOR_nothing + && insn_operand_matches (icode, 3, test)) + return true; + + return false; +} + /* This function is called when we are going to emit a compare instruction that compares the values found in X and Y, using the rtl operator COMPARISON. @@ -7481,3 +7558,5 @@ expand_jump_insn (enum insn_code icode, unsigned int nops, if (!maybe_expand_jump_insn (icode, nops, ops)) gcc_unreachable (); } + +#include "gt-optabs.h" diff --git a/gcc/optabs.h b/gcc/optabs.h index 897bb5d4443..2b2338a67af 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -242,6 +242,21 @@ enum can_compare_purpose (without splitting it into pieces). */ extern int can_compare_p (enum rtx_code, machine_mode, enum can_compare_purpose); + +/* The various uses that a vector comparison can have; used by + can_vector_compare_p. So far only vcond is defined, vec_cmp is a possible + future extension. */ +enum can_vector_compare_purpose +{ + cvcp_vcond +}; + +/* Return whether back-end can emit a vector comparison insn(s) using a given + CODE, with operands with CMP_OP_MODE, producing a result with VALUE_MODE, + in order to achieve a PURPOSE. */ +extern bool can_vector_compare_p (enum rtx_code, machine_mode, machine_mode, + enum can_vector_compare_purpose); + extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode, machine_mode, int); /* Emit a pair of rtl insns to compare two rtx's and to jump