From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 51301 invoked by alias); 22 Mar 2017 15:46:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 50985 invoked by uid 89); 22 Mar 2017 15:46:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.8 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_SOFTFAIL autolearn=ham version=3.3.2 spammy=escaped, Hx-languages-length:4977 X-HELO: eggs.gnu.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (208.118.235.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 22 Mar 2017 15:46:44 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cqiTB-0001NC-Cs for gcc-patches@gcc.gnu.org; Wed, 22 Mar 2017 11:46:44 -0400 Received: from bran.ispras.ru ([83.149.199.196]:41362 helo=smtp.ispras.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cqiTA-0001ML-WA for gcc-patches@gcc.gnu.org; Wed, 22 Mar 2017 11:46:41 -0400 Received: from condor.intra.ispras.ru (condor.intra.ispras.ru [10.10.3.78]) by smtp.ispras.ru (Postfix) with ESMTP id CEF6A61798 for ; Wed, 22 Mar 2017 18:46:35 +0300 (MSK) Received: by condor.intra.ispras.ru (Postfix, from userid 23246) id BAF8D1225DC4; Wed, 22 Mar 2017 18:46:35 +0300 (MSK) From: Alexander Monakov To: gcc-patches@gcc.gnu.org Subject: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3 Date: Wed, 22 Mar 2017 15:46:00 -0000 Message-Id: <1490197595-31938-5-git-send-email-amonakov@ispras.ru> In-Reply-To: <1490197595-31938-1-git-send-email-amonakov@ispras.ru> References: <1490197595-31938-1-git-send-email-amonakov@ispras.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.196 X-IsSubscribed: yes X-SW-Source: 2017-03/txt/msg01179.txt.bz2 This patch implements privatization for SIMT during inlining. We need to discover if the call being inlined belongs to a SIMT region (by looking at simduid of the containing loop), and if so, treat them similar to OpenMP-SIMD privatization: add the "omp simt private" attribute and mention them among arguments of GOMP_SIMT_ENTER. OpenMP-SIMD privatization also adds a clobber at the end of the region; I'm not sure if it's required here: in the example I've looked at, inlined code already contained a clobber. * tree-inline.h (struct copy_body_data): New field dst_simt_vars. * tree-inline.c (expand_call_inline): Handle SIMT privatization. (copy_decl_for_dup_finish): Ditto. --- gcc/tree-inline.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++------- gcc/tree-inline.h | 4 ++++ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6b6d489..56817e4 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4385,6 +4385,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) gcall *call_stmt; unsigned int i; unsigned int prop_mask, src_properties; + struct function *dst_cfun; + tree simduid; + use_operand_p use; + gimple *simtenter_stmt = NULL; + hash_set *simtvars_st = NULL; /* The gimplifier uses input_location in too many places, such as internal_get_tmp_var (). */ @@ -4588,15 +4593,26 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) id->src_cfun = DECL_STRUCT_FUNCTION (fn); id->call_stmt = call_stmt; + /* When inlining into an OpenMP SIMD-on-SIMT loop, arrange for new automatic + variables to be added to IFN_GOMP_SIMT_ENTER argument list. */ + dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn); + if (!(dst_cfun->curr_properties & PROP_gimple_lomp_dev) + && (simduid = bb->loop_father->simduid) != NULL_TREE + && (simduid = ssa_default_def (dst_cfun, simduid)) != NULL_TREE + && single_imm_use (simduid, &use, &simtenter_stmt) + && is_gimple_call (simtenter_stmt) + && gimple_call_internal_p (simtenter_stmt, IFN_GOMP_SIMT_ENTER)) + { + simtvars_st = id->dst_simt_vars; + id->dst_simt_vars = new hash_set; + } + /* If the src function contains an IFN_VA_ARG, then so will the dst function after inlining. Likewise for IFN_GOMP_USE_SIMT. */ prop_mask = PROP_gimple_lva | PROP_gimple_lomp_dev; src_properties = id->src_cfun->curr_properties & prop_mask; if (src_properties != prop_mask) - { - struct function *dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn); - dst_cfun->curr_properties &= src_properties | ~prop_mask; - } + dst_cfun->curr_properties &= src_properties | ~prop_mask; gcc_assert (!id->src_cfun->after_inlining); @@ -4730,6 +4746,25 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) if (cfun->gimple_df) pt_solution_reset (&cfun->gimple_df->escaped); + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ + if (id->dst_simt_vars) + { + size_t nargs = gimple_call_num_args (simtenter_stmt); + hash_set *vars = id->dst_simt_vars; + auto_vec newargs (nargs + vars->elements ()); + for (size_t i = 0; i < nargs; i++) + newargs.quick_push (gimple_call_arg (simtenter_stmt, i)); + for (hash_set::iterator i = vars->begin (); i != vars->end (); ++i) + newargs.quick_push (build1 (ADDR_EXPR, + build_pointer_type (TREE_TYPE (*i)), *i)); + gcall *g = gimple_build_call_internal_vec (IFN_GOMP_SIMT_ENTER, newargs); + gimple_call_set_lhs (g, gimple_call_lhs (simtenter_stmt)); + gimple_stmt_iterator gsi = gsi_for_stmt (simtenter_stmt); + gsi_replace (&gsi, g, false); + delete id->dst_simt_vars; + id->dst_simt_vars = simtvars_st; + } + /* Clean up. */ if (id->debug_map) { @@ -5453,9 +5488,19 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) function. */ ; else - /* Ordinary automatic local variables are now in the scope of the - new function. */ - DECL_CONTEXT (copy) = id->dst_fn; + { + /* Ordinary automatic local variables are now in the scope of the + new function. */ + DECL_CONTEXT (copy) = id->dst_fn; + if (VAR_P (copy) && id->dst_simt_vars && !is_gimple_reg (copy)) + { + if (!lookup_attribute ("omp simt private", DECL_ATTRIBUTES (copy))) + DECL_ATTRIBUTES (copy) + = tree_cons (get_identifier ("omp simt private"), NULL, + DECL_ATTRIBUTES (copy)); + id->dst_simt_vars->add (copy); + } + } return copy; } diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 88b3286..cf46fa5 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -145,6 +145,10 @@ struct copy_body_data equivalents in the function into which it is being inlined. */ hash_map *dependence_map; + /* A set of local variables in the function that is being inlined into + an OpenMP SIMD-on-SIMT loop. */ + hash_set *dst_simt_vars; + /* Cilk keywords currently need to replace some variables that ordinary nested functions do not. */ bool remap_var_for_cilk; -- 1.8.3.1