From patchwork Sat Oct 4 11:54:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zamyatin, Igor" X-Patchwork-Id: 396514 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 9196D14016A for ; Sat, 4 Oct 2014 21:55:12 +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:from :to:cc:subject:date:message-id:content-type :content-transfer-encoding:mime-version; q=dns; s=default; b=Cpk /kH+6688y83jqchD/YMxvaXB1dqjRQ5HtvUA3WPgSWN7AxC+MqnxzPvgZq1cCBws kK3LAJxEoepnqEGpUNaeeN3qDuo4GGyuQOO/MqqsgK8usNfnUJv1J6lCy8dqf6mp Cmdv5UtlGjZA5Op/9AQZATIoJSYhYehOTx7L6upQ= 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:message-id:content-type :content-transfer-encoding:mime-version; s=default; bh=P428KZNC2 OBgmjz7xTG5NGG+iGk=; b=Tp0FGR2LfpmRC51rU6+zTWtvjJa6iQIyRGD0uU0BS kqTTme+N9xHiFqZ9fHVpvfcpBmPFGm8aFLyy36tyF6RPist2f+/I31ZLr8K6qcEb Pb7yDCWLeUBxe26SFqBtHH1R7GZphovsErD8UL9HWJHTLM5opR/d16SUqvJO3h34 QE= Received: (qmail 13238 invoked by alias); 4 Oct 2014 11:55:05 -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 13226 invoked by uid 89); 4 Oct 2014 11:55:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga01.intel.com Received: from mga01.intel.com (HELO mga01.intel.com) (192.55.52.88) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 04 Oct 2014 11:55:03 +0000 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP; 04 Oct 2014 04:55:01 -0700 X-ExtLoop1: 1 Received: from irsmsx104.ger.corp.intel.com ([163.33.3.159]) by FMSMGA003.fm.intel.com with ESMTP; 04 Oct 2014 04:48:28 -0700 Received: from irsmsx153.ger.corp.intel.com (163.33.192.75) by IRSMSX104.ger.corp.intel.com (163.33.3.159) with Microsoft SMTP Server (TLS) id 14.3.195.1; Sat, 4 Oct 2014 12:54:59 +0100 Received: from irsmsx101.ger.corp.intel.com ([169.254.1.201]) by IRSMSX153.ger.corp.intel.com ([169.254.9.42]) with mapi id 14.03.0195.001; Sat, 4 Oct 2014 12:54:59 +0100 From: "Zamyatin, Igor" To: "GCC Patches (gcc-patches@gcc.gnu.org)" CC: "Jakub Jelinek (jakub@redhat.com)" Subject: [PATCH, PR63307] Fix generation of new declarations in random order Date: Sat, 4 Oct 2014 11:54:58 +0000 Message-ID: <0EFAB2BDD0F67E4FB6CCC8B9F87D756969BB3310@IRSMSX101.ger.corp.intel.com> MIME-Version: 1.0 X-IsSubscribed: yes Hi! The following patch does fix random order for new decls generation during Cilk_spawn generation. As Jakub suggested in the PR first we deal with vectors, then sort them and only then perform necessary generation of new decls. Bootstrapped and regtested on trunk/4.9. For trunk I couldn't check with COMPARE_DEBUG since building fails somewhere else. For 4.9 COMPARE_DEBUG building is ok. Is it ok for trunk and backport into 4.9? c-family/Changelog: 2014-10-03 Igor Zamyatin PR c/63307 * cilk.c: Include vec.h. (struct cilk_decls): New structure. (wrapper_parm_cb): Split this function to... (fill_decls_vec): ...this... (create_parm_list): ...and this. (compare_decls): New function. (for_local_cb): Remove. (wrapper_local_cb): Ditto. (build_wrapper_type): For now first traverse and fill vector of declarations then sort it and then deal with sorted vector. (cilk_outline): Ditto. (declare_one_free_variable): Ditto. diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c index 20b3432..e7a1c6a 100644 --- a/gcc/c-family/cilk.c +++ b/gcc/c-family/cilk.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "cgraph.h" #include "diagnostic.h" +#include "vec.h" #include "cilk.h" enum add_variable_type { @@ -332,17 +333,36 @@ create_cilk_helper_decl (struct wrapper_data *wd) return fndecl; } -/* A function used by walk tree to find wrapper parms. */ +struct cilk_decls +{ + tree key; + tree *val; +}; + +/* A function used by traversal to fill vector of decls for further work. */ bool -wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd) +fill_decls_vec (tree const &key0, tree *val0, auto_vec *v) +{ + tree t1 = key0; + struct cilk_decls dp; + + dp.key = t1; + dp.val = val0; + v->safe_push (dp); + return true; +} + +/* Function that actually creates necessary parm lists. */ + +static void +create_parm_list (struct wrapper_data *wd, tree *val0, tree arg) { - tree arg = key0; tree val = *val0; tree parm; if (val == error_mark_node || val == arg) - return true; + return; if (TREE_CODE (val) == PAREN_EXPR) { @@ -360,7 +380,7 @@ wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd) } else arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg); - + val = TREE_OPERAND (val, 0); *val0 = val; gcc_assert (TREE_CODE (val) == INDIRECT_REF); @@ -371,9 +391,19 @@ wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd) parm = val; TREE_CHAIN (parm) = wd->parms; wd->parms = parm; - wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes); - wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist); - return true; + wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes); + wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist); +} + +/* Sorting decls in a vector. */ + +static int +compare_decls (const void *a, const void *b) +{ + const struct cilk_decls* t1 = (const struct cilk_decls*) a; + const struct cilk_decls* t2 = (const struct cilk_decls*) b; + + return DECL_UID (t1->key) > DECL_UID (t2->key); } /* This function is used to build a wrapper of a certain type. */ @@ -381,13 +411,21 @@ wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd) static void build_wrapper_type (struct wrapper_data *wd) { + unsigned int j; + struct cilk_decls * c; + auto_vec vd; wd->arglist = NULL_TREE; wd->parms = NULL_TREE; wd->argtypes = void_list_node; - wd->decl_map->traverse (wd); + wd->decl_map->traverse *, fill_decls_vec> (&vd); gcc_assert (wd->type != CILK_BLOCK_FOR); + vd.qsort (compare_decls); + + FOR_EACH_VEC_ELT (vd, j, c) + create_parm_list (wd, c->val, c->key); + /* Now build a function. Its return type is void (all side effects are via explicit parameters). Its parameters are WRAPPER_PARMS with type WRAPPER_TYPES. @@ -448,41 +486,19 @@ copy_decl_for_cilk (tree decl, copy_body_data *id) } } -/* Copy all local variables. */ - -bool -for_local_cb (tree const &k, tree *vp, copy_body_data *id) -{ - tree v = *vp; - - if (v == error_mark_node) - *vp = copy_decl_no_change (k, id); - return true; -} - -/* Copy all local declarations from a _Cilk_spawned function's body. */ - -bool -wrapper_local_cb (tree const &key, tree *vp, copy_body_data *id) -{ - tree val = *vp; - - if (val == error_mark_node) - *vp = copy_decl_for_cilk (key, id); - - return true; -} - /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */ void cilk_outline (tree inner_fn, tree *stmt_p, void *w) { struct wrapper_data *wd = (struct wrapper_data *) w; - const tree outer_fn = wd->context; + const tree outer_fn = wd->context; const bool nested = (wd->type == CILK_BLOCK_FOR); copy_body_data id; bool throws; + auto_vec vd; + unsigned int j; + struct cilk_decls * c; DECL_STATIC_CHAIN (outer_fn) = 1; @@ -508,11 +524,13 @@ cilk_outline (tree inner_fn, tree *stmt_p, void *w) insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn)); + wd->decl_map->traverse *, fill_decls_vec> (&vd); + vd.qsort (compare_decls); /* We don't want the private variables any more. */ - if (nested) - wd->decl_map->traverse (&id); - else - wd->decl_map->traverse (&id); + FOR_EACH_VEC_ELT (vd, j, c) + if (*(c->val) == error_mark_node) + *(c->val) = nested ? copy_decl_no_change (c->key, &id) + : copy_decl_for_cilk (c->key, &id); walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL); @@ -617,7 +635,7 @@ free_wd (struct wrapper_data *wd) */ bool -declare_one_free_variable (tree const &var0, tree *map0, wrapper_data &) +declare_one_free_variable (tree var0, tree *map0) { const_tree var = var0; tree map = *map0; @@ -690,6 +708,9 @@ create_cilk_wrapper (tree exp, tree *args_out) { struct wrapper_data wd; tree fndecl; + unsigned int j; + struct cilk_decls * c; + auto_vec vd; init_wd (&wd, CILK_BLOCK_SPAWN); @@ -710,7 +731,11 @@ create_cilk_wrapper (tree exp, tree *args_out) } else extract_free_variables (exp, &wd, ADD_READ); - wd.decl_map->traverse (wd); + wd.decl_map->traverse *, fill_decls_vec> (&vd); + vd.qsort (compare_decls); + FOR_EACH_VEC_ELT (vd, j, c) + declare_one_free_variable (c->key, c->val); + wd.block = TREE_BLOCK (exp); if (!wd.block) wd.block = DECL_INITIAL (current_function_decl);