From patchwork Fri Dec 10 17:36:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kwok Cheung Yeung X-Patchwork-Id: 48796 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1EC483857829 for ; Fri, 10 Dec 2021 17:37:32 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id 5D72C385801D for ; Fri, 10 Dec 2021 17:36:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5D72C385801D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com IronPort-SDR: Hj98bOzIokKG9A1fphSgs4HDGdkTZ5vD2YJA6StZHylajMJXRo/vJL5cmXACYQBObM4yj5Z+1Q aVKE/LNwPF2PnHWOTWYyfeBGN4EoK2d9uBPs+/2QJpNzbZmsD7creSohIRd0PBvyjJtOuRmq1W cR8zgD2brZ3B6cK0X14ueUGUjjiitaF3VBCMj1Ron21u5bfyPwEbYiXWEnjF4JJmxXaFlpgA5x ij/GIvz5QqwCBMDHxb5dUMBMKKr5nBo2pM9UpZi+BnC+5kriC4LRo+UsiM59/l2O0WXUxplykb Lb7O+2ceqZqrDel2MBoxQsiw X-IronPort-AV: E=Sophos;i="5.88,196,1635235200"; d="scan'208,223";a="69540032" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 10 Dec 2021 09:36:51 -0800 IronPort-SDR: 8iOBBzkFnH2St0Ohb8o3/EhlbLqkyJBOIFJ9w+2vttcZMbAOZETSQjQGx1jubt1MbSH1UJDvXL F3yiPSUZegEskFBlnan9pKYKjnchPn2Ldcu0SBaZlj1wQrhe/tve97wArjb66h1qLJIw4hOi/I n2XdU4T1s0E4L+2QyXBlpLK0444DZWgkabp0UjJeRw6JCgS6Ln2O14DY7Ao6byYVkb6PY0hw/Z qq/dTnQMiRfLF6F/N9ol3/msamqfDkKuSqOy4rmKoUv/JHfUMVOCUIrfUpnamJI/iTLrOCTHW5 Zag= Message-ID: <0813fb26-b6ec-0a39-11aa-4a4687947531@codesourcery.com> Date: Fri, 10 Dec 2021 17:36:20 +0000 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.4.0 References: Subject: [PATCH 4/7] openmp: Add support for streaming metadirectives and resolving them after LTO To: gcc-patches , Jakub Jelinek From: Kwok Cheung Yeung In-Reply-To: X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-09.mgc.mentorg.com (139.181.222.9) To SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch adds support for streaming the Gimple metadirective representation during LTO. An extra pass (also using omp_get_dynamic_candidates) is also added to resolve metadirectives after LTO, which is required for selectors that need to be resolved on the accel compiler. Kwok From 85826d05e029571fd003dd629aa04ce3e17d9c71 Mon Sep 17 00:00:00 2001 From: Kwok Cheung Yeung Date: Mon, 6 Dec 2021 22:56:07 +0000 Subject: [PATCH 4/7] openmp: Add support for streaming metadirectives and resolving them after LTO This patch adds support for streaming metadirective Gimple statements during LTO, and adds a metadirective expansion pass that runs after LTO. This is required for metadirectives with selectors that can only be resolved from within the accel compiler. 2021-12-10 Kwok Cheung Yeung gcc/ * Makefile.in (OBJS): Add omp-expand-metadirective.o. * gimple-streamer-in.c (input_gimple_stmt): Add case for GIMPLE_OMP_METADIRECTIVE. Handle metadirective labels. * gimple-streamer-out.c (output_gimple_stmt): Likewise. * omp-expand-metadirective.cc: New. * passes.def: Add pass_omp_expand_metadirective. * tree-pass.h (make_pass_omp_expand_metadirective): New prototype. --- gcc/Makefile.in | 1 + gcc/gimple-streamer-in.c | 10 ++ gcc/gimple-streamer-out.c | 6 + gcc/omp-expand-metadirective.cc | 191 ++++++++++++++++++++++++++++++++ gcc/passes.def | 1 + gcc/tree-pass.h | 1 + 6 files changed, 210 insertions(+) create mode 100644 gcc/omp-expand-metadirective.cc diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 2a0be9e66a6..34a17f36922 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1519,6 +1519,7 @@ OBJS = \ omp-oacc-kernels-decompose.o \ omp-oacc-neuter-broadcast.o \ omp-simd-clone.o \ + omp-expand-metadirective.o \ opt-problem.o \ optabs.o \ optabs-libfuncs.o \ diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c index 1c979f438a5..b821aa3ca30 100644 --- a/gcc/gimple-streamer-in.c +++ b/gcc/gimple-streamer-in.c @@ -151,6 +151,7 @@ input_gimple_stmt (class lto_input_block *ib, class data_in *data_in, case GIMPLE_COND: case GIMPLE_GOTO: case GIMPLE_DEBUG: + case GIMPLE_OMP_METADIRECTIVE: for (i = 0; i < num_ops; i++) { tree *opp, op = stream_read_tree (ib, data_in); @@ -188,6 +189,15 @@ input_gimple_stmt (class lto_input_block *ib, class data_in *data_in, else gimple_call_set_fntype (call_stmt, stream_read_tree (ib, data_in)); } + if (gomp_metadirective *metadirective_stmt + = dyn_cast (stmt)) + { + gimple_alloc_omp_metadirective (metadirective_stmt); + for (i = 0; i < num_ops; i++) + gimple_omp_metadirective_set_label (metadirective_stmt, i, + stream_read_tree (ib, + data_in)); + } break; case GIMPLE_NOP: diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c index fcbf92300d4..c19dff74261 100644 --- a/gcc/gimple-streamer-out.c +++ b/gcc/gimple-streamer-out.c @@ -127,6 +127,7 @@ output_gimple_stmt (struct output_block *ob, struct function *fn, gimple *stmt) case GIMPLE_COND: case GIMPLE_GOTO: case GIMPLE_DEBUG: + case GIMPLE_OMP_METADIRECTIVE: for (i = 0; i < gimple_num_ops (stmt); i++) { tree op = gimple_op (stmt, i); @@ -169,6 +170,11 @@ output_gimple_stmt (struct output_block *ob, struct function *fn, gimple *stmt) else stream_write_tree (ob, gimple_call_fntype (stmt), true); } + if (gimple_code (stmt) == GIMPLE_OMP_METADIRECTIVE) + for (i = 0; i < gimple_num_ops (stmt); i++) + stream_write_tree (ob, gimple_omp_metadirective_label (stmt, i), + true); + break; case GIMPLE_NOP: diff --git a/gcc/omp-expand-metadirective.cc b/gcc/omp-expand-metadirective.cc new file mode 100644 index 00000000000..aaf048a699a --- /dev/null +++ b/gcc/omp-expand-metadirective.cc @@ -0,0 +1,191 @@ +/* Expand an OpenMP metadirective. + + Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "target.h" +#include "tree.h" +#include "langhooks.h" +#include "gimple.h" +#include "tree-pass.h" +#include "cgraph.h" +#include "fold-const.h" +#include "gimplify.h" +#include "gimple-iterator.h" +#include "gimple-walk.h" +#include "gomp-constants.h" +#include "omp-general.h" +#include "diagnostic-core.h" +#include "tree-cfg.h" +#include "cfganal.h" +#include "ssa.h" +#include "tree-into-ssa.h" +#include "cfghooks.h" + +static void +omp_expand_metadirective (function *fun, basic_block bb) +{ + gimple *stmt = last_stmt (bb); + vec candidates + = omp_resolve_metadirective (stmt); + + /* This is the last chance for the metadirective to be resolved. */ + if (candidates.is_empty ()) + gcc_unreachable (); + + auto_vec labels; + + for (unsigned int i = 0; i < candidates.length (); i++) + labels.safe_push (candidates[i].directive); + + /* Delete BBs for all variants not in the candidate list. */ + for (unsigned i = 0; i < gimple_num_ops (stmt); i++) + { + tree label = gimple_omp_metadirective_label (stmt, i); + if (!labels.contains (label)) + { + edge e = find_edge (bb, label_to_block (fun, label)); + remove_edge_and_dominated_blocks (e); + } + } + + /* Remove the metadirective statement. */ + gimple_stmt_iterator gsi = gsi_last_bb (bb); + gsi_remove (&gsi, true); + + if (candidates.length () == 1) + { + /* Special case if there is only one selector - there should be one + remaining edge from BB to the selected variant. */ + edge e = find_edge (bb, label_to_block (fun, + candidates.last ().directive)); + e->flags |= EDGE_FALLTHRU; + + return; + } + + basic_block cur_bb = bb; + + /* For each candidate, create a conditional that checks the dynamic + condition, branching to the candidate directive if true, to the + next candidate check if false. */ + for (unsigned i = 0; i < candidates.length () - 1; i++) + { + basic_block next_bb = NULL; + gcond *cond_stmt = gimple_build_cond_from_tree (candidates[i].selector, + NULL_TREE, NULL_TREE); + gsi = gsi_last_bb (cur_bb); + gsi_insert_seq_after (&gsi, cond_stmt, GSI_NEW_STMT); + + if (i < candidates.length () - 2) + { + edge e_false = split_block (cur_bb, cond_stmt); + e_false->flags &= ~EDGE_FALLTHRU; + e_false->flags |= EDGE_FALSE_VALUE; + e_false->probability = profile_probability::uninitialized (); + + next_bb = e_false->dest; + } + + /* Redirect the source of the edge from BB to the candidate directive + to the conditional. Reusing the edge avoids disturbing phi nodes in + the destination BB. */ + edge e = find_edge (bb, label_to_block (fun, candidates[i].directive)); + redirect_edge_pred (e, cur_bb); + e->flags |= EDGE_TRUE_VALUE; + + if (next_bb) + cur_bb = next_bb; + } + + /* The last of the candidates is always static. */ + edge e = find_edge (cur_bb, label_to_block (fun, + candidates.last ().directive)); + e->flags |= EDGE_FALSE_VALUE; +} + +namespace { + +const pass_data pass_data_omp_expand_metadirective = +{ + GIMPLE_PASS, /* type */ + "omp_expand_metadirective", /* name */ + OPTGROUP_OMP, /* optinfo_flags */ + TV_NONE, /* tv_id */ + PROP_gimple_lcf, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_update_ssa | TODO_cleanup_cfg, /* todo_flags_finish */ +}; + +class pass_omp_expand_metadirective : public gimple_opt_pass +{ +public: + pass_omp_expand_metadirective (gcc::context *ctxt) + : gimple_opt_pass (pass_data_omp_expand_metadirective, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + return (flag_openmp); + } + + virtual unsigned int execute (function *fun); +}; // class pass_omp_oacc_kernels_decompose + +unsigned int +pass_omp_expand_metadirective::execute (function *fun) +{ + basic_block bb; + auto_vec metadirective_bbs; + + FOR_EACH_BB_FN (bb, fun) + { + gimple *stmt = last_stmt (bb); + if (stmt && is_a (stmt)) + metadirective_bbs.safe_push (bb); + } + + if (metadirective_bbs.is_empty ()) + return 0; + + calculate_dominance_info (CDI_DOMINATORS); + + for (unsigned i = 0; i < metadirective_bbs.length (); i++) + omp_expand_metadirective (fun, metadirective_bbs[i]); + + free_dominance_info (fun, CDI_DOMINATORS); + mark_virtual_operands_for_renaming (fun); + + return 0; +} + +} // anon namespace + + +gimple_opt_pass * +make_pass_omp_expand_metadirective (gcc::context *ctxt) +{ + return new pass_omp_expand_metadirective (ctxt); +} diff --git a/gcc/passes.def b/gcc/passes.def index 37ea0d318d1..b80a53c4051 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -189,6 +189,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_oacc_device_lower); NEXT_PASS (pass_omp_device_lower); NEXT_PASS (pass_omp_target_link); + NEXT_PASS (pass_omp_expand_metadirective); NEXT_PASS (pass_adjust_alignment); NEXT_PASS (pass_all_optimizations); PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations) diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 3559c3c9f1b..e4315e2fe85 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -422,6 +422,7 @@ extern gimple_opt_pass *make_pass_lower_switch_O0 (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_vector (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_vector_ssa (gcc::context *ctxt); extern gimple_opt_pass *make_pass_omp_oacc_kernels_decompose (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_omp_expand_metadirective (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_omp (gcc::context *ctxt); extern gimple_opt_pass *make_pass_diagnose_omp_blocks (gcc::context *ctxt); extern gimple_opt_pass *make_pass_expand_omp (gcc::context *ctxt);