From patchwork Tue Sep 16 09:10:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 390017 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 88FCF14009A for ; Tue, 16 Sep 2014 19:13:57 +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 :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=F3IveiJT/XNSVNAlyrSvbkMQTa4RaZVZyxEP0LwTNJL9cVJyk985V XGo9btqiT06PhtyNwKQlPtI9tw20wwCcjOYKRLUdZsIypIqT5V43v715asDcZF27 9d0mvCgzulrgo7ikzAx5DvXadwqtCoGvPdzvUvfZQGturhAwzz6g4M= 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 :from:to:subject:message-id:mime-version:content-type; s= default; bh=eo3cc6RKb4E/1JwLa8m/IlLVE+o=; b=xh9+7+CflWyWCMWS3Wft RuTZaWGNNxY+gWI77jlDHGCvASZjoXyJ+gGqL/h6TzHRcBqaGzI//daKmFoUPvnV m++s3x4Lv3MUA+qMRAK5GSWQ73A1b9FiHuaMLX/BEKe7icLdzyIZUYu8f7UG9koG ds5NUQo1HGYtpl3vAaOf8sA= Received: (qmail 29270 invoked by alias); 16 Sep 2014 09:13:47 -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 29260 invoked by uid 89); 16 Sep 2014 09:13:46 -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, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 16 Sep 2014 09:13:45 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 33966AB08 for ; Tue, 16 Sep 2014 09:13:42 +0000 (UTC) Date: Tue, 16 Sep 2014 11:10:06 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH][match-and-simplify] Fix comparison operator type handling Message-ID: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2014-09-16 Richard Biener * genmatch.c (operator_id): Add tcc member. (get_operand_type): New function, split out from ... (expr::gen_transform): ... here. Treat comparisons properly. (dt_simplify::gen): Use get_operand_type. Index: gcc/genmatch.c =================================================================== --- gcc/genmatch.c (revision 215264) +++ gcc/genmatch.c (working copy) @@ -171,12 +171,14 @@ id_base::id_base (id_kind kind_, const c struct operator_id : public id_base { - operator_id (enum tree_code code_, const char *id_, unsigned nargs_) + operator_id (enum tree_code code_, const char *id_, unsigned nargs_, + const char *tcc_) : id_base (id_base::CODE, id_), - code (code_), nargs (nargs_) {} + code (code_), nargs (nargs_), tcc (tcc_) {} unsigned get_required_nargs () const { return nargs; } enum tree_code code; unsigned nargs; + const char *tcc; }; struct fn_id : public id_base @@ -215,7 +217,7 @@ add_operator (enum tree_code code, const /* To have INTEGER_CST and friends as "predicate operators". */ && strcmp (tcc, "tcc_constant") != 0) return; - operator_id *op = new operator_id (code, id, nargs); + operator_id *op = new operator_id (code, id, nargs, tcc); id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT); if (*slot) fatal ("duplicate id definition"); @@ -890,6 +892,38 @@ is_conversion (id_base *op) || *op == VIEW_CONVERT_EXPR); } +/* Get the type to be used for generating operands of OP from the + various sources. */ + +static const char * +get_operand_type (id_base *op, const char *in_type, + const char *expr_type, + const char *other_oprnd_type) +{ + /* Generally operands whose type does not match the type of the + expression generated need to know their types but match and + thus can fall back to 'other_oprnd_type'. */ + if (is_conversion (op)) + return other_oprnd_type; + else if (*op == REALPART_EXPR + || *op == IMAGPART_EXPR) + return other_oprnd_type; + else if (is_a (op) + && strcmp (as_a (op)->tcc, "tcc_comparison") == 0) + return other_oprnd_type; + else + { + /* Otherwise all types should match - choose one in order of + preference. */ + if (expr_type) + return expr_type; + else if (in_type) + return in_type; + else + return other_oprnd_type; + } +} + /* Code gen off the AST. */ void @@ -912,8 +946,14 @@ expr::gen_transform (FILE *f, const char /* __real and __imag use the component type of its operand. */ sprintf (optype, "TREE_TYPE (TREE_TYPE (ops%d[0]))", depth); type = optype; - /* Avoid passing in_type / type to operand creation. */ - conversion_p = true; + } + else if (is_a (operation->op) + && strcmp (as_a (operation->op)->tcc, "tcc_comparison") == 0) + { + /* comparisons use boolean_type_node (or what gets in), but + their operands need to figure out the types themselves. */ + sprintf (optype, "boolean_type_node"); + type = optype; } else { @@ -926,26 +966,16 @@ expr::gen_transform (FILE *f, const char fprintf (f, "{\n"); fprintf (f, " tree ops%d[%u], res;\n", depth, ops.length ()); + char op0type[64]; + snprintf (op0type, 64, "TREE_TYPE (ops%d[0])", depth); for (unsigned i = 0; i < ops.length (); ++i) { char dest[32]; snprintf (dest, 32, " ops%d[%u]", depth, i); - ops[i]->gen_transform (f, dest, gimple, depth + 1, - conversion_p - /* If this op is a conversion its single - operand has to know its type itself. */ - ? NULL - /* For other ops the type is the type - we got passed in, or if that is from - a conversion we can at most use the - first operand type for all further - operands. So (convert (plus @1 (convert @2)) - is possible while - (convert (plus (convert @1) @2)) - is not unless we somehow discover what - operand we can generate first and do it - in the appropriate order. */ - : (i == 0 ? in_type : type)); + const char *optype + = get_operand_type (operation->op, in_type, expr_type, + i == 0 ? NULL : op0type); + ops[i]->gen_transform (f, dest, gimple, depth + 1, optype); } if (gimple) @@ -1804,9 +1834,12 @@ dt_simplify::gen (FILE *f, bool gimple) { char dest[32]; snprintf (dest, 32, " res_ops[%d]", j); - e->ops[j]->gen_transform (f, dest, true, 1, - is_conversion (e->operation->op) - ? NULL : "type"); + const char *optype + = get_operand_type (e->operation->op, + "type", e->expr_type, + j == 0 + ? NULL : "TREE_TYPE (res_ops[0])"); + e->ops[j]->gen_transform (f, dest, true, 1, optype); } /* Re-fold the toplevel result. It's basically an embedded gimple_build w/o actually building the stmt. */ @@ -1833,9 +1866,12 @@ dt_simplify::gen (FILE *f, bool gimple) fprintf (f, " tree res_op%d;\n", j); char dest[32]; snprintf (dest, 32, " res_op%d", j); - e->ops[j]->gen_transform (f, dest, false, 1, - is_conversion (e->operation->op) - ? NULL : "type"); + const char *optype + = get_operand_type (e->operation->op, + "type", e->expr_type, + j == 0 + ? NULL : "TREE_TYPE (res_op0)"); + e->ops[j]->gen_transform (f, dest, false, 1, optype); } /* Re-fold the toplevel result. */ if (e->operation->op->kind == id_base::CODE)