From: Jakub Jelinek Date: Fri, 3 Sep 2021 08:15:17 +0000 (+0200) Subject: openmp: Improve expand_omp_atomic_pipeline X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=afe01c57c1c71a0e26a2676860eb3101281d80b5;p=thirdparty%2Fgcc.git openmp: Improve expand_omp_atomic_pipeline When __atomic_* builtins were introduced, omp-expand.c (omp-low.c at that point) has been adjusted in several spots so that it uses the atomic builtins instead of sync builtins, but expand_omp_atomic_pipeline has not because the __atomic_compare_exchange_* APIs take address of the argument, so it kept using __sync_val_compare_swap_*. That means it always uses seq_cst though. This patch changes it to use the ATOMIC_COMPARE_EXCHANGE ifn which gimple-fold folds __atomic_compare_exchange_* into - that ifn also passes expected directly. 2021-09-03 Jakub Jelinek * omp-expand.c (expand_omp_atomic_pipeline): Use IFN_ATOMIC_COMPARE_EXCHANGE instead of BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_? so that memory order can be provided. (cherry picked from commit 090f0d78f194e3cda23fe904016db77ea36c38fa) --- diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index 59678d62af44..b4231380da4f 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,49 +1,57 @@ +2021-09-03 Tobias Burnus + + 2021-09-03 Jakub Jelinek + + * omp-expand.c (expand_omp_atomic_pipeline): Use + IFN_ATOMIC_COMPARE_EXCHANGE instead of + BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_? so that memory order + can be provided. + 2021-09-02 Marcel Vollweiler Backported from master: 2021-09-02 Marcel Vollweiler - * gfortran.dg/gomp/target-device-ancestor-4.f90: Comment out dg-final to avoid - UNRESOLVED. + * gfortran.dg/gomp/target-device-ancestor-4.f90: Comment out dg-final to avoid + UNRESOLVED. 2021-08-31 Marcel Vollweiler Backported from master: 2021-08-31 Marcel Vollweiler - * c-parser.c (c_parser_omp_clause_device): Parse device-modifiers 'device_num' - and 'ancestor' in 'target device' clauses. - * parser.c (cp_parser_omp_clause_device): Parse device-modifiers 'device_num' - and 'ancestor' in 'target device' clauses. - * semantics.c (finish_omp_clauses): Error handling. Constant device ids must - evaluate to '1' if 'ancestor' is used. - * gfortran.h: Add variable for 'ancestor' in struct gfc_omp_clauses. - * openmp.c (gfc_match_omp_clauses): Parse device-modifiers 'device_num' - and 'ancestor' in 'target device' clauses. - * trans-openmp.c (gfc_trans_omp_clauses): Set OMP_CLAUSE_DEVICE_ANCESTOR. - * gimplify.c (gimplify_scan_omp_clauses): Error handling. 'ancestor' only - allowed on target constructs and only with particular other clauses. - * omp-expand.c (expand_omp_target): Output of 'sorry, not supported' if - 'ancestor' is used. - * omp-low.c (check_omp_nesting_restrictions): Error handling. No nested OpenMP - structs when 'ancestor' is used. - (scan_omp_1_stmt): No usage of OpenMP runtime routines in a target region when - 'ancestor' is used. - * tree-pretty-print.c (dump_omp_clause): Append 'ancestor'. - * tree.h (OMP_CLAUSE_DEVICE_ANCESTOR): Define macro. - * c-c++-common/gomp/target-device-1.c: New test. - * c-c++-common/gomp/target-device-2.c: New test. - * c-c++-common/gomp/target-device-ancestor-1.c: New test. - * c-c++-common/gomp/target-device-ancestor-2.c: New test. - * c-c++-common/gomp/target-device-ancestor-3.c: New test. - * c-c++-common/gomp/target-device-ancestor-4.c: New test. - * gfortran.dg/gomp/target-device-1.f90: New test. - * gfortran.dg/gomp/target-device-2.f90: New test. - * gfortran.dg/gomp/target-device-ancestor-1.f90: New test. - * gfortran.dg/gomp/target-device-ancestor-2.f90: New test. - * gfortran.dg/gomp/target-device-ancestor-3.f90: New test. - * gfortran.dg/gomp/target-device-ancestor-4.f90: New test. - + * c-parser.c (c_parser_omp_clause_device): Parse device-modifiers 'device_num' + and 'ancestor' in 'target device' clauses. + * parser.c (cp_parser_omp_clause_device): Parse device-modifiers 'device_num' + and 'ancestor' in 'target device' clauses. + * semantics.c (finish_omp_clauses): Error handling. Constant device ids must + evaluate to '1' if 'ancestor' is used. + * gfortran.h: Add variable for 'ancestor' in struct gfc_omp_clauses. + * openmp.c (gfc_match_omp_clauses): Parse device-modifiers 'device_num' + and 'ancestor' in 'target device' clauses. + * trans-openmp.c (gfc_trans_omp_clauses): Set OMP_CLAUSE_DEVICE_ANCESTOR. + * gimplify.c (gimplify_scan_omp_clauses): Error handling. 'ancestor' only + allowed on target constructs and only with particular other clauses. + * omp-expand.c (expand_omp_target): Output of 'sorry, not supported' if + 'ancestor' is used. + * omp-low.c (check_omp_nesting_restrictions): Error handling. No nested OpenMP + structs when 'ancestor' is used. + (scan_omp_1_stmt): No usage of OpenMP runtime routines in a target region when + 'ancestor' is used. + * tree-pretty-print.c (dump_omp_clause): Append 'ancestor'. + * tree.h (OMP_CLAUSE_DEVICE_ANCESTOR): Define macro. + * c-c++-common/gomp/target-device-1.c: New test. + * c-c++-common/gomp/target-device-2.c: New test. + * c-c++-common/gomp/target-device-ancestor-1.c: New test. + * c-c++-common/gomp/target-device-ancestor-2.c: New test. + * c-c++-common/gomp/target-device-ancestor-3.c: New test. + * c-c++-common/gomp/target-device-ancestor-4.c: New test. + * gfortran.dg/gomp/target-device-1.f90: New test. + * gfortran.dg/gomp/target-device-2.f90: New test. + * gfortran.dg/gomp/target-device-ancestor-1.f90: New test. + * gfortran.dg/gomp/target-device-ancestor-2.f90: New test. + * gfortran.dg/gomp/target-device-ancestor-3.f90: New test. + * gfortran.dg/gomp/target-device-ancestor-4.f90: New test. 2021-08-23 Tobias Burnus diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 9cd75a91649c..6c538ebfbb12 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -8857,8 +8857,6 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, edge e; enum built_in_function fncode; - /* ??? We need a non-pointer interface to __atomic_compare_exchange in - order to use the RELAXED memory model effectively. */ fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N + index + 1); cmpxchg = builtin_decl_explicit (fncode); @@ -8875,6 +8873,15 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */ si = gsi_last_nondebug_bb (load_bb); gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD); + location_t loc = gimple_location (gsi_stmt (si)); + enum omp_memory_order omo = gimple_omp_atomic_memory_order (gsi_stmt (si)); + enum memmodel imo = omp_memory_order_to_memmodel (omo); + tree mo = build_int_cst (NULL, imo); + if (imo == MEMMODEL_RELEASE) + imo = MEMMODEL_RELAXED; + else if (imo == MEMMODEL_ACQ_REL) + imo = MEMMODEL_ACQUIRE; + tree fmo = build_int_cst (NULL, imo); /* For floating-point values, we'll need to view-convert them to integers so that we can perform the atomic compare and swap. Simplify the @@ -8971,7 +8978,15 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, GSI_SAME_STMT); /* Build the compare&swap statement. */ - new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi); + tree ctype = build_complex_type (itype); + int flag = int_size_in_bytes (itype); + new_storedi = build_call_expr_internal_loc (loc, IFN_ATOMIC_COMPARE_EXCHANGE, + ctype, 6, iaddr, loadedi, + storedi, + build_int_cst (integer_type_node, + flag), + mo, fmo); + new_storedi = build1 (REALPART_EXPR, itype, new_storedi); new_storedi = force_gimple_operand_gsi (&si, fold_convert (TREE_TYPE (loadedi), new_storedi),