From patchwork Mon Nov 10 13:39:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 408935 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 C71CF14012C for ; Tue, 11 Nov 2014 00:40:08 +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 :mime-version:date:message-id:subject:from:to:content-type; q= dns; s=default; b=CWMllTvNNStkPsW55dqrd7ujYPnF6Ls1HKf7TJYIMeNhsc zsgaSxhYOMfjDEpFuNKZZus/cHs5DGjMz52l5Eh2NowlNaHE3+tfALYEAFJgQCw9 pU/yUEdLjbiloxNQ36dqOvOgVE6J5fkjd6vkZ5avymN/mT0DlFxHZBSPisF6Y= 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 :mime-version:date:message-id:subject:from:to:content-type; s= default; bh=87lQyzCp0n4+H1A0jYG8dLT4AW8=; b=IlwkX34RQ0502T+Czm8L KAFr2QF+j8Fq+BRtKd5pM9LRs+j0hmDiNl7hJiqUD7R/0LcmaMXbpE0bGLLwm9cc gs0ffyO644RZ7NrTWwZ8sIMvSBHpiu5lS4IHyFh1xevIqZk8Iea7Wd3UCiERsnpf Yo3S1cmqlnzOhWwmBLSEhIE= Received: (qmail 24994 invoked by alias); 10 Nov 2014 13:40:01 -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 24985 invoked by uid 89); 10 Nov 2014 13:40:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ob0-f181.google.com Received: from mail-ob0-f181.google.com (HELO mail-ob0-f181.google.com) (209.85.214.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 10 Nov 2014 13:39:58 +0000 Received: by mail-ob0-f181.google.com with SMTP id uy5so5616247obc.40 for ; Mon, 10 Nov 2014 05:39:56 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.182.20.76 with SMTP id l12mr1626802obe.63.1415626796068; Mon, 10 Nov 2014 05:39:56 -0800 (PST) Received: by 10.182.199.2 with HTTP; Mon, 10 Nov 2014 05:39:55 -0800 (PST) Date: Mon, 10 Nov 2014 19:09:55 +0530 Message-ID: Subject: [match-and-simplify] operator-lists in expression From: Prathamesh Kulkarni To: Richard Biener , "gcc-patches@gcc.gnu.org" X-IsSubscribed: yes Hi, This patch adds support for operator-lists to be used in expression. I reuse operator-list as the iterator. This is not really valid since user-defined operator-lists cannot be iterator in 'for', but it was convenient to reuse operator-list as a 'for' iterator and lower_for doesn't care about that. eg: (define_operator_list list1 plus minus) (simplify (list1 @x integer_zerop) (non_lvalue @x)) is wrapped into 'for' as: (lower_operator_list): (for list1 (plus minus) (simplify (list1 @x integer_zerop) (non_lvalue @x))) this is not really valid since we reject list1 to be used as iterator if it were written by user. Is this okay or should I introduce an explicit temporary iterator ? so it gets lowered to something like: (for tmp1 (list1) (simplify (tmp1 @x integer_zerop) (non_lvalue @x))) * genmatch.c (fatal_at): New overloaded function. (simplify::oper_lists): New member. (simplify::simplify): Add default argument. (lower_commutative): Adjust call to simplify::simplify. (lower_opt_convert): Likewise. (lower_operator_list): New function. (lower): Call lower_operator_list. (parser::parsing_for_p): New member function. (parser::oper_lists): New member. (parser::parse_operation): Check for operator-list. (parser::parse_c_expr): Likewise. (parser::parse_simplify): Reset parser::oper_lists. Adjust call to simplify::simplify. (parser::parser): Initialize parser::oper_lists. * match-builtin.pd: Adjust patten to use SQRTs and POWs. Thanks, Prathamesh Index: gcc/genmatch.c =================================================================== --- gcc/genmatch.c (revision 217284) +++ gcc/genmatch.c (working copy) @@ -110,6 +110,18 @@ #if GCC_VERSION >= 4001 __attribute__((format (printf, 2, 3))) #endif +fatal_at (source_location loc, const char *msg, ...) +{ + va_list ap; + va_start (ap, msg); + error_cb (NULL, CPP_DL_FATAL, 0, loc, 0, msg, &ap); + va_end (ap); +} + +static void +#if GCC_VERSION >= 4001 +__attribute__((format (printf, 2, 3))) +#endif warning_at (const cpp_token *tk, const char *msg, ...) { va_list ap; @@ -549,11 +561,11 @@ simplify (operand *match_, source_location match_location_, struct operand *result_, source_location result_location_, vec ifexpr_vec_, vec > for_vec_, - cid_map_t *capture_ids_) + cid_map_t *capture_ids_, vec oper_lists_ = vNULL) : match (match_), match_location (match_location_), result (result_), result_location (result_location_), ifexpr_vec (ifexpr_vec_), for_vec (for_vec_), - capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1) {} + capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1), oper_lists (oper_lists_) {} /* The expression that is matched against the GENERIC or GIMPLE IL. */ operand *match; @@ -572,6 +584,8 @@ /* A map of capture identifiers to indexes. */ cid_map_t *capture_ids; int capture_max; + /* collected operator-list used in expression */ + vec oper_lists; }; /* Debugging routines for dumping the AST. */ @@ -721,7 +735,7 @@ { simplify *ns = new simplify (matchers[i], s->match_location, s->result, s->result_location, s->ifexpr_vec, - s->for_vec, s->capture_ids); + s->for_vec, s->capture_ids, s->oper_lists); simplifiers.safe_push (ns); } } @@ -837,7 +851,7 @@ { simplify *ns = new simplify (matchers[i], s->match_location, s->result, s->result_location, s->ifexpr_vec, - s->for_vec, s->capture_ids); + s->for_vec, s->capture_ids, s->oper_lists); simplifiers.safe_push (ns); } } @@ -934,6 +948,38 @@ simplifiers.safe_push (worklist[i]); } +static void +lower_operator_list (simplify *s, vec& simplifiers) +{ + vec oper_lists = s->oper_lists; + if (oper_lists == vNULL) + { + simplifiers.safe_push (s); + return; + } + + unsigned min = oper_lists[0]->substitutes.length (); + for (unsigned i = 1; i < oper_lists.length (); ++i) + if (min > oper_lists[i]->substitutes.length ()) + min = oper_lists[i]->substitutes.length (); + + for (unsigned i = 0; i < oper_lists.length (); ++i) + if (oper_lists[i]->substitutes.length () % min != 0) + fatal_at (s->match_location, "All user-defined identifiers must have a multiple number " + "of operator substittions of the smallest number of substitutions"); + + vec< vec > for_vec = vNULL; + for_vec.safe_push (oper_lists); + + simplify ns (s->match, s->match_location, + s->result, s->result_location, + s->ifexpr_vec, for_vec, + s->capture_ids); + + lower_for (&ns, simplifiers); +} + + /* Lower the AST for everything in SIMPLIFIERS. */ static void @@ -947,14 +993,15 @@ for (unsigned i = 0; i < out_simplifiers0.length (); ++i) lower_commutative (out_simplifiers0[i], out_simplifiers1); + auto_vec out_simplifiers2; + for (unsigned i = 0; i < out_simplifiers1.length (); ++i) + lower_operator_list (out_simplifiers1[i], out_simplifiers2); + simplifiers.truncate (0); - for (unsigned i = 0; i < out_simplifiers1.length (); ++i) - lower_for (out_simplifiers1[i], simplifiers); + for (unsigned i = 0; i < out_simplifiers2.length (); ++i) + lower_for (out_simplifiers2[i], simplifiers); } - - - /* The decision tree built for generating GIMPLE and GENERIC pattern matching code. It represents the 'match' expression of all simplifies and has those as its leafs. */ @@ -2498,10 +2545,13 @@ void parse_if (source_location); void parse_predicates (source_location); void parse_operator_list (source_location); + + bool parsing_for_p () { return active_fors.length () != 0; } cpp_reader *r; vec active_ifs; vec > active_fors; + vec oper_lists; cid_map_t *capture_ids; @@ -2669,8 +2719,11 @@ user_id *p = dyn_cast (op); if (p && p->is_oper_list) - fatal_at (id_tok, "operator-list not allowed in expression"); - + { + if (parsing_for_p ()) + fatal_at (id_tok, "operator-list not allowed in expression enclosed in 'for'"); + oper_lists.safe_push (p); + } return op; } @@ -2807,8 +2860,13 @@ /* If this is possibly a user-defined identifier mark it used. */ if (token->type == CPP_NAME) - get_operator ((const char *)CPP_HASHNODE - (token->val.node.node)->ident.str); + { + id_base *idb = get_operator ((const char *)CPP_HASHNODE + (token->val.node.node)->ident.str); + user_id *p; + if (idb && (p = dyn_cast (idb)) && p->is_oper_list) + oper_lists.safe_push (p); + } /* Record the token. */ code.safe_push (*token); @@ -2893,6 +2951,8 @@ { /* Reset the capture map. */ capture_ids = new cid_map_t; + /* Reset oper_lists */ + oper_lists = vNULL; const cpp_token *loc = peek (); parsing_match_operand = true; @@ -2915,7 +2975,7 @@ simplifiers.safe_push (new simplify (match, match_location, result, token->src_loc, active_ifs.copy (), active_fors.copy (), - capture_ids)); + capture_ids, oper_lists.copy ())); return; } @@ -2941,7 +3001,7 @@ simplifiers.safe_push (new simplify (match, match_location, result, paren_loc, active_ifs.copy (), - active_fors.copy (), capture_ids)); + active_fors.copy (), capture_ids, oper_lists.copy ())); } } else if (peek_ident ("with")) @@ -2960,7 +3020,7 @@ simplifiers.safe_push (new simplify (match, match_location, op, token->src_loc, active_ifs.copy (), - active_fors.copy (), capture_ids)); + active_fors.copy (), capture_ids, oper_lists.copy ())); eat_token (CPP_CLOSE_PAREN); /* A "default" result closes the enclosing scope. */ if (active_ifs.length () > active_ifs_len) @@ -2992,7 +3052,7 @@ (new simplify (match, match_location, matcher ? result : parse_op (), token->src_loc, active_ifs.copy (), - active_fors.copy (), capture_ids)); + active_fors.copy (), capture_ids, oper_lists.copy ())); /* A "default" result closes the enclosing scope. */ if (active_ifs.length () > active_ifs_len) { @@ -3286,6 +3346,7 @@ active_ifs = vNULL; active_fors = vNULL; simplifiers = vNULL; + oper_lists = vNULL; user_predicates = vNULL; parsing_match_operand = false; Index: gcc/match-builtin.pd =================================================================== --- gcc/match-builtin.pd (revision 217284) +++ gcc/match-builtin.pd (working copy) @@ -147,8 +147,6 @@ dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); } (POW @0 { build_real (type, dconstroot); })))) /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */ - (for SQRT (BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL) - POW (BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL) (simplify - (SQRT (POW @0 @1)) - (POW (abs @0) (mult @1 { build_real (TREE_TYPE (@1), dconsthalf); }))))) + (SQRTs (POWs @0 @1)) + (POWs (abs @0) (mult @1 { build_real (TREE_TYPE (@1), dconsthalf); }))))