GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "memmodel.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "optabs.h"
#include "cgraph.h"
#include "pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "cfganal.h"
#include "internal-fn.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "tree-ssa.h"
#include "splay-tree.h"
#include "cfgloop.h"
#include "omp-general.h"
#include "omp-offload.h"
#include "tree-cfgcleanup.h"
#include "alloc-pool.h"
#include "symbol-summary.h"
#include "gomp-constants.h"
#include "gimple-pretty-print.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-eh.h"
#include "opts.h"
Data Structures | |
struct | omp_region |
struct | oacc_collapse |
Variables | |
static struct omp_region * | root_omp_region |
static bool | omp_any_child_fn_dumped |
|
static |
Change DECL_CONTEXT of CHILD_FNDECL to that of the parent function. Add CHILD_FNDECL to decl chain of the supercontext of the block ENTRY_BLOCK - this is the block which originally contained the code from which CHILD_FNDECL was created. Together, these actions ensure that the debug info for the outlined function will be emitted with the correct lexical scope.
References as_a(), b, BLOCK_SUPERCONTEXT, BLOCK_VARS, current_function_decl, DECL_CHAIN, DECL_CONTEXT, omp_region::entry, gimple_omp_target_child_fn(), gimple_omp_taskreg_child_fn(), last_nondebug_stmt(), NULL_TREE, omp_region::outer, TREE_CODE, and omp_region::type.
Referenced by expand_omp_target(), and expand_omp_taskreg().
|
static |
Scan the CFG and build a tree of OMP regions. Return the root of the OMP region tree.
References build_omp_regions_1(), calculate_dominance_info(), CDI_DOMINATORS, cfun, ENTRY_BLOCK_PTR_FOR_FN, gcc_assert, NULL, and root_omp_region.
Referenced by execute_expand_omp().
|
static |
Helper for build_omp_regions. Scan the dominator tree starting at block BB. PARENT is the region that contains BB. If SINGLE_TREE is true, the function ends once a single tree is built (otherwise, whole forest of OMP constructs may be built).
References build_omp_regions_1(), CDI_DOMINATORS, omp_region::cont, omp_region::exit, first_dom_son(), gcc_assert, gcc_unreachable, GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_ENTER_DATA, GF_OMP_TARGET_KIND_EXIT_DATA, GF_OMP_TARGET_KIND_OACC_DATA, GF_OMP_TARGET_KIND_OACC_DATA_KERNELS, GF_OMP_TARGET_KIND_OACC_DECLARE, GF_OMP_TARGET_KIND_OACC_ENTER_DATA, GF_OMP_TARGET_KIND_OACC_EXIT_DATA, GF_OMP_TARGET_KIND_OACC_HOST_DATA, GF_OMP_TARGET_KIND_OACC_KERNELS, GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE, GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED, GF_OMP_TARGET_KIND_OACC_SERIAL, GF_OMP_TARGET_KIND_OACC_UPDATE, GF_OMP_TARGET_KIND_REGION, GF_OMP_TARGET_KIND_UPDATE, gimple_omp_ordered_standalone_p(), gimple_omp_target_kind(), gimple_omp_task_taskwait_p(), gsi_end_p(), gsi_last_nondebug_bb(), gsi_stmt(), is_gimple_omp(), new_omp_region(), next_dom_son(), NULL, omp_region::outer, and omp_region::type.
Referenced by build_omp_regions(), build_omp_regions_1(), and build_omp_regions_root().
|
static |
Builds the tree of OMP regions rooted at ROOT, storing it to root_omp_region.
References build_omp_regions_1(), gcc_assert, NULL, and root_omp_region.
Referenced by omp_expand_local().
DEBUG_FUNCTION void debug_all_omp_regions | ( | void | ) |
References dump_omp_region(), and root_omp_region.
DEBUG_FUNCTION void debug_omp_region | ( | struct omp_region * | region | ) |
References dump_omp_region().
|
static |
Discover whether REGION is a combined parallel+workshare region.
References omp_region::cont, omp_region::entry, omp_region::exit, get_ws_args_for(), gimple_omp_for_clauses(), gimple_omp_parallel_clauses(), gimple_omp_parallel_combined_p(), gimple_omp_sections_clauses(), omp_region::inner, omp_region::is_combined_parallel, is_in_offload_region(), last_and_only_stmt(), last_nondebug_stmt(), NULL, OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_DECL, OMP_CLAUSE_ORDERED, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_SCHEDULE_KIND, OMP_CLAUSE_SCHEDULE_MASK, OMP_CLAUSE_SCHEDULE_STATIC, omp_find_clause(), POINTER_TYPE_P, single_succ(), TREE_TYPE, omp_region::type, workshare_safe_to_combine_p(), and omp_region::ws_args.
Referenced by expand_omp().
void dump_omp_region | ( | FILE * | file, |
struct omp_region * | region, | ||
int | indent ) |
Debugging dumps for parallel regions.
Dump the parallel region tree rooted at REGION.
References omp_region::cont, dump_omp_region(), omp_region::entry, omp_region::exit, gimple_code_name, basic_block_def::index, omp_region::inner, omp_region::next, and omp_region::type.
Referenced by debug_all_omp_regions(), debug_omp_region(), dump_omp_region(), execute_expand_omp(), and omp_expand_local().
|
static |
Main entry point for expanding OMP-GIMPLE into runtime calls.
References build_omp_regions(), cfun, dump_file, dump_omp_region(), expand_omp(), gimple_in_ssa_p(), omp_free_regions(), remove_exit_barriers(), root_omp_region, TODO_cleanup_cfg, and TODO_update_ssa_only_virtuals.
|
static |
Helper for expand_oacc_for. Determine collapsed loop information. Fill in COUNTS array. Emit any initialization code before GSI. Return the calculated outer loop bound of BOUND_TYPE.
References b, oacc_collapse::base, build_int_cst(), omp_for_data::collapse, create_tmp_var, expr, fold_build1, fold_build2, fold_convert, force_gimple_operand_gsi(), gcc_assert, gimple_build_call_internal(), gimple_call_set_lhs(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, integer_onep(), integer_type_node, integer_zero_node, integer_zerop(), oacc_collapse::iters, omp_for_data::loop, omp_for_data::loops, omp_for_data_loop::n1, NULL, NULL_TREE, oacc_collapse::outer, POINTER_TYPE_P, sizetype, oacc_collapse::step, omp_for_data_loop::step, oacc_collapse::tile, omp_for_data::tiling, TREE_CHAIN, TREE_TYPE, TREE_VALUE, and TYPE_UNSIGNED.
Referenced by expand_oacc_for().
|
static |
Emit initializers for collapsed loop members. INNER is true if this is for the element loop of a TILE. IVAR is the outer loop iteration variable, from which collapsed loop iteration values are calculated. COUNTS array has been initialized by expand_oacc_collapse_inits.
References oacc_collapse::base, omp_for_data::collapse, expr, fold_build2, fold_convert, force_gimple_operand_gsi(), gimple_build_assign(), gsi_insert_before(), GSI_SAME_STMT, oacc_collapse::iters, omp_for_data::loops, NULL_TREE, oacc_collapse::outer, POINTER_TYPE_P, sizetype, oacc_collapse::step, and TREE_TYPE.
Referenced by expand_oacc_for().
|
static |
A subroutine of expand_omp_for. Generate code for an OpenACC partitioned loop. The lowering here is abstracted, in that the loop parameters are passed through internal functions, which are further lowered by oacc_device_lower, once we get to the target compiler. The loop is of the form: for (V = B; V LTGT E; V += S) {BODY} where LTGT is < or >. We may have a specified chunking size, CHUNKING (constant 0 for no chunking) and we will have a GWV partitioning mask, specifying dimensions over which the loop is to be partitioned (see note below). We generate code that looks like (this ignores tiling): <entry_bb> [incoming FALL->body, BRANCH->exit] typedef signedintify (typeof (V)) T; // underlying signed integral type T range = E - B; T chunk_no = 0; T DIR = LTGT == '<' ? +1 : -1; T chunk_max = GOACC_LOOP_CHUNK (dir, range, S, CHUNK_SIZE, GWV); T step = GOACC_LOOP_STEP (dir, range, S, CHUNK_SIZE, GWV); <head_bb> [created by splitting end of entry_bb] T offset = GOACC_LOOP_OFFSET (dir, range, S, CHUNK_SIZE, GWV, chunk_no); T bound = GOACC_LOOP_BOUND (dir, range, S, CHUNK_SIZE, GWV, offset); if (!(offset LTGT bound)) goto bottom_bb; <body_bb> [incoming] V = B + offset; {BODY} <cont_bb> [incoming, may == body_bb FALL->exit_bb, BRANCH->body_bb] offset += step; if (offset LTGT bound) goto body_bb; [*] <bottom_bb> [created by splitting start of exit_bb] insert BRANCH->head_bb chunk_no++; if (chunk < chunk_max) goto head_bb; <exit_bb> [incoming] V = B + ((range -/+ 1) / S +/- 1) * S [*] [*] Needed if V live at end of loop.
References add_loop(), alloc_loop(), as_a(), b, boolean_type_node, BRANCH_EDGE, build2(), build_int_cst(), cfun, omp_for_data::collapse, omp_for_data_loop::cond_code, omp_region::cont, create_tmp_var, current_function_decl, DECL_ATTRIBUTES, EDGE_COUNT, EDGE_SUCC, omp_region::entry, profile_probability::even(), omp_region::exit, expand_oacc_collapse_init(), expand_oacc_collapse_vars(), expr, FALLTHRU_EDGE, basic_block_def::flags, fold_build1, fold_build2, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), gcc_assert, gcc_checking_assert, GF_OMP_FOR_KIND_OACC_LOOP, gimple_build_assign(), gimple_build_call_internal(), gimple_build_cond_empty(), gimple_build_nop(), gimple_call_set_lhs(), gimple_in_ssa_p(), gimple_location(), gimple_omp_continue_control_def(), gimple_omp_continue_control_use(), gimple_omp_for_combined_into_p(), gimple_omp_for_index(), gimple_omp_for_kind(), gimple_set_location(), GSI_CONTINUE_LINKING, gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), profile_probability::guessed(), loop::header, integer_minus_one_node, integer_type_node, integer_zero_node, integer_zerop(), is_oacc_kernels(), last_nondebug_stmt(), loop::latch, profile_probability::likely(), lookup_attribute(), omp_for_data::loop, basic_block_def::loop_father, omp_for_data::loops, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, NULL_TREE, offset, POINTER_TYPE_P, basic_block_def::preds, signed_type_for(), single_pred(), single_succ_edge(), sizetype, split_block(), SSA_VAR_P, oacc_collapse::step, omp_for_data_loop::step, basic_block_def::succs, oacc_collapse::tile, omp_for_data::tiling, TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, profile_probability::unlikely(), and omp_for_data_loop::v.
Referenced by expand_omp_for().
|
static |
Expand the parallel region tree rooted at REGION. Expansion proceeds in depth-first order. Innermost regions are expanded first. This way, parallel regions that require a new function to be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any internal dependencies in their body.
References as_a(), current_function_decl, determine_parallel_type(), dump_file, dump_flags, dump_function_header(), omp_region::entry, expand_omp(), expand_omp_atomic(), expand_omp_for(), expand_omp_sections(), expand_omp_single(), expand_omp_synch(), expand_omp_target(), expand_omp_taskreg(), gcc_assert, gcc_unreachable, gimple_has_location(), gimple_location(), gimple_omp_for_combined_p(), gimple_omp_ordered_standalone_p(), omp_region::inner, input_location, last_nondebug_stmt(), omp_region::next, NULL, omp_any_child_fn_dumped, omp_region::ord_stmt, omp_region::outer, and omp_region::type.
Referenced by execute_expand_omp(), expand_omp(), and omp_expand_local().
|
static |
Expand an GIMPLE_OMP_ATOMIC statement. We try to expand using expand_omp_atomic_fetch_op. If it failed, we try to call expand_omp_atomic_pipeline, and if it fails too, the ultimate fallback is wrapping the operation in a mutex (expand_omp_atomic_mutex). REGION is the atomic region built by build_omp_regions_1().
References as_a(), BITS_PER_WORD, cfun, omp_region::entry, exact_log2(), omp_region::exit, expand_omp_atomic_cas(), expand_omp_atomic_fetch_op(), expand_omp_atomic_load(), expand_omp_atomic_mutex(), expand_omp_atomic_pipeline(), expand_omp_atomic_store(), first_stmt(), GET_MODE_BITSIZE(), gimple_in_ssa_p(), gimple_omp_atomic_load_lhs(), gimple_omp_atomic_load_rhs(), gimple_omp_atomic_store_val(), INTEGRAL_TYPE_P, is_float_mode(), is_int_mode(), last_nondebug_stmt(), POINTER_TYPE_P, single_succ(), tree_to_uhwi(), TREE_TYPE, TYPE_ALIGN_UNIT, TYPE_MAIN_VARIANT, TYPE_MODE, and TYPE_SIZE_UNIT.
Referenced by expand_omp().
|
static |
A subroutine of expand_omp_atomic. Attempt to implement the atomic compare and exchange as an ATOMIC_COMPARE_EXCHANGE internal function. Returns false if the expression is not of the proper form.
References boolean_type_node, build1(), build2(), build_complex_type(), build_int_cst(), build_zero_cst(), builtin_decl_explicit(), can_atomic_load_p(), can_compare_and_swap_p(), create_tmp_reg(), g, gcc_checking_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_location(), gimple_omp_atomic_memory_order(), gimple_omp_atomic_need_value_p(), gimple_omp_atomic_weak_p(), gimple_set_location(), gsi_end_p(), gsi_for_stmt(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_prev_nondebug(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), int_size_in_bytes(), integer_type_node, INTEGRAL_TYPE_P, is_gimple_assign(), last_nondebug_stmt(), NULL, NULL_TREE, omp_memory_order_to_fail_memmodel(), omp_memory_order_to_memmodel(), operand_equal_p(), SCALAR_FLOAT_TYPE_P, single_succ(), TREE_CODE, tree_int_cst_equal(), TREE_OPERAND, TREE_TYPE, TYPE_MAIN_VARIANT, TYPE_MODE, TYPE_SIZE, and useless_type_conversion_p().
Referenced by expand_omp_atomic().
|
static |
A subroutine of expand_omp_atomic. Attempt to implement the atomic operation as a __atomic_fetch_op builtin. INDEX is log2 of the size of the data type, and thus usable to find the index of the builtin decl. Returns false if the expression is not of the proper form.
References build2_loc(), build_call_expr_loc(), build_int_cst(), builtin_decl_explicit(), can_atomic_load_p(), can_compare_and_swap_p(), cfun, commutative_tree_code(), fold_convert_loc(), force_gimple_operand_gsi(), gcc_assert, gcc_checking_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_in_ssa_p(), gimple_location(), gimple_omp_atomic_memory_order(), gimple_omp_atomic_need_value_p(), gsi_after_labels(), gsi_end_p(), gsi_last_nondebug_bb(), gsi_next_nondebug(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), is_gimple_assign(), is_gimple_debug(), last_nondebug_stmt(), NULL, NULL_TREE, omp_memory_order_to_memmodel(), operand_equal_p(), release_defs(), single_succ(), TREE_TYPE, TYPE_MODE, and void_type_node.
Referenced by expand_omp_atomic().
|
static |
A subroutine of expand_omp_atomic. Attempt to implement the atomic operation as a normal volatile load.
References build1(), build_int_cst(), builtin_decl_explicit(), gcc_assert, gimple_build_assign(), gimple_build_call(), gimple_call_set_lhs(), gimple_location(), gimple_omp_atomic_memory_order(), gimple_set_location(), gimple_set_vuse(), gimple_vuse(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, gsi_stmt(), integer_type_node, make_ssa_name(), NULL_TREE, omp_memory_order_to_memmodel(), single_succ(), TREE_TYPE, type(), and useless_type_conversion_p().
Referenced by expand_omp_atomic().
|
static |
A subroutine of expand_omp_atomic. Implement the atomic operation as: GOMP_atomic_start (); *addr = rhs; GOMP_atomic_end (); The result is not globally atomic, but works so long as all parallel references are within #pragma omp atomic directives. According to responses received from omp@openmp.org, appears to be within spec. Which makes sense, since that's how several other compilers handle this situation as well. LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're expanding. STORED_VAL is the operand of the matching GIMPLE_OMP_ATOMIC_STORE. We replace GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with loaded_val = *addr; and replace GIMPLE_OMP_ATOMIC_STORE (stored_val) with *addr = stored_val;
References build_call_expr(), build_pointer_type_for_mode(), build_simple_mem_ref, builtin_decl_explicit(), fold_convert, force_gimple_operand_gsi(), gcc_assert, gimple_build_assign(), gimple_set_vdef(), gimple_set_vuse(), gimple_vdef(), gimple_vuse(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), NULL_TREE, ptr_mode, si, TREE_OPERAND, TREE_TYPE, and unshare_expr().
Referenced by expand_omp_atomic().
|
static |
A subroutine of expand_omp_atomic. Implement the atomic operation as: oldval = *addr; repeat: newval = rhs; // with oldval replacing *addr in rhs oldval = __sync_val_compare_and_swap (addr, oldval, newval); if (oldval != newval) goto repeat; INDEX is log2 of the size of the data type, and thus usable to find the index of the builtin decl.
References add_loop(), alloc_loop(), boolean_type_node, build1(), build2(), build_call_expr(), build_call_expr_internal_loc(), build_complex_type(), build_int_cst(), build_pointer_type_for_mode(), builtin_decl_explicit(), can_atomic_load_p(), can_compare_and_swap_p(), cfun, create_phi_node(), create_tmp_reg(), create_tmp_var, fold_convert, force_gimple_operand_gsi(), gcc_assert, gimple_build_assign(), gimple_build_cond_empty(), gimple_in_ssa_p(), gimple_location(), gimple_omp_atomic_memory_order(), gimple_seq_empty_p(), gimple_seq_first_stmt(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), profile_probability::guessed_always(), profile_probability::guessed_never(), loop::header, int_size_in_bytes(), integer_type_node, INTEGRAL_TYPE_P, loop::latch, basic_block_def::loop_father, make_edge(), make_ssa_name(), MEMMODEL_RELAXED, NULL, NULL_TREE, omp_memory_order_to_fail_memmodel(), omp_memory_order_to_memmodel(), PHI_ARG_DEF_PTR_FROM_EDGE, phi_nodes(), POINTER_TYPE_P, ptr_mode, release_defs(), SET_USE, si, single_succ(), single_succ_edge(), TREE_TYPE, type(), TYPE_MAIN_VARIANT, and TYPE_MODE.
Referenced by expand_omp_atomic().
|
static |
A subroutine of expand_omp_atomic. Attempt to implement the atomic operation as a normal volatile store.
References build1(), build_int_cst(), builtin_decl_explicit(), can_atomic_exchange_p(), fold_build1_loc(), force_gimple_operand_gsi(), gcc_assert, gimple_build_assign(), gimple_build_call(), gimple_call_set_lhs(), gimple_location(), gimple_omp_atomic_memory_order(), gimple_omp_atomic_need_value_p(), gimple_set_location(), gimple_set_vdef(), gimple_set_vuse(), gimple_vdef(), gimple_vuse(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, gsi_stmt(), integer_type_node, make_ssa_name(), NULL_TREE, omp_memory_order_to_memmodel(), single_succ(), TREE_CHAIN, TREE_TYPE, TREE_VALUE, type(), TYPE_ARG_TYPES, TYPE_MODE, and useless_type_conversion_p().
Referenced by expand_omp_atomic().
|
static |
Prepend or append TO = FROM assignment before or after *GSI_P.
References DECL_P, expand_omp_regimplify_p(), force_gimple_operand_gsi(), gimple_build_assign(), gimple_regimplify_operands(), GSI_CONTINUE_LINKING, gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), GSI_SAME_STMT, NULL, NULL_TREE, TREE_ADDRESSABLE, and walk_tree.
Referenced by expand_omp_for_generic(), expand_omp_for_init_counts(), expand_omp_for_init_vars(), expand_omp_for_ordered_loops(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_scantemp_alloc(), expand_omp_sections(), expand_omp_simd(), and expand_parallel_call().
|
static |
Prepend or append LHS CODE RHS condition before or after *GSI_P.
References expand_omp_regimplify_p(), gimple_build_cond(), gimple_cond_lhs_ptr(), gimple_cond_rhs_ptr(), gimple_regimplify_operands(), GSI_CONTINUE_LINKING, gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), GSI_SAME_STMT, NULL, NULL_TREE, and walk_tree.
Referenced by expand_omp_for_init_counts(), expand_omp_for_init_vars(), expand_omp_for_static_chunk(), and expand_omp_for_static_nochunk().
|
static |
Expand the OMP loop defined by REGION.
References as_a(), BRANCH_EDGE, build_int_cstu(), omp_for_data::chunk_size, omp_for_data_loop::cond_code, omp_region::cont, EDGE_COUNT, omp_region::entry, error_at(), expand_oacc_for(), expand_omp_for_generic(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_simd(), expand_omp_taskloop_for_inner(), expand_omp_taskloop_for_outer(), FALLTHRU_EDGE, omp_for_data::first_nonrect, fold_build1, fold_build2, fold_convert, omp_for_data::for_stmt, gcc_assert, gcc_unreachable, GF_OMP_FOR_KIND_FOR, GF_OMP_FOR_KIND_OACC_LOOP, GF_OMP_FOR_KIND_SIMD, GF_OMP_FOR_KIND_TASKLOOP, gimple_location(), gimple_omp_for_collapse(), gimple_omp_for_combined_into_p(), gimple_omp_for_kind(), omp_region::has_lastprivate_conditional, omp_for_data::have_ordered, omp_for_data::have_pointer_condtemp, omp_for_data::have_reductemp, HOST_WIDE_INT_1U, i, integer_nonzerop(), integer_zero_node, omp_for_data::iter_type, last_nondebug_stmt(), omp_for_data::last_nonrect, omp_for_data::lastprivate_conditional, long_integer_type_node, long_long_unsigned_type_node, LOOPS_NEED_FIXUP, loops_state_set(), omp_for_data_loop::m1, omp_for_data_loop::m2, omp_for_data::non_rect, NULL, NULL_TREE, OMP_CLAUSE_SCHEDULE_DYNAMIC, OMP_CLAUSE_SCHEDULE_GUIDED, OMP_CLAUSE_SCHEDULE_MONOTONIC, OMP_CLAUSE_SCHEDULE_NONMONOTONIC, OMP_CLAUSE_SCHEDULE_RUNTIME, OMP_CLAUSE_SCHEDULE_STATIC, omp_extract_for_data(), omp_for_data::ordered, omp_for_data_loop::outer, omp_for_data::sched_kind, omp_region::sched_kind, omp_for_data::sched_modifiers, omp_region::sched_modifiers, omp_for_data_loop::step, basic_block_def::succs, TREE_CODE, TREE_TYPE, TYPE_UNSIGNED, and omp_for_data_loop::v.
Referenced by expand_omp().
|
static |
A subroutine of expand_omp_for. Generate code for a parallel loop with any schedule. Given parameters: for (V = N1; V cond N2; V += STEP) BODY; where COND is "<" or ">", we generate pseudocode more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0); if (more) goto L0; else goto L3; L0: V = istart0; iend = iend0; L1: BODY; V += STEP; if (V cond iend) goto L1; else goto L2; L2: if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3; L3: If this is a combined omp parallel loop, instead of the call to GOMP_loop_foo_start, we call GOMP_loop_foo_next. If this is gimple_omp_for_combined_p loop, then instead of assigning V and iend in L0 we assign the first two _looptemp_ clause decls of the inner GIMPLE_OMP_FOR and V += STEP; and if (V cond iend) goto L1; else goto L2; are removed. For collapsed loops, given parameters: collapse(3) for (V1 = N11; V1 cond1 N12; V1 += STEP1) for (V2 = N21; V2 cond2 N22; V2 += STEP2) for (V3 = N31; V3 cond3 N32; V3 += STEP3) BODY; we generate pseudocode if (__builtin_expect (N32 cond3 N31, 0)) goto Z0; if (cond3 is <) adj = STEP3 - 1; else adj = STEP3 + 1; count3 = (adj + N32 - N31) / STEP3; if (__builtin_expect (N22 cond2 N21, 0)) goto Z0; if (cond2 is <) adj = STEP2 - 1; else adj = STEP2 + 1; count2 = (adj + N22 - N21) / STEP2; if (__builtin_expect (N12 cond1 N11, 0)) goto Z0; if (cond1 is <) adj = STEP1 - 1; else adj = STEP1 + 1; count1 = (adj + N12 - N11) / STEP1; count = count1 * count2 * count3; goto Z1; Z0: count = 0; Z1: more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0); if (more) goto L0; else goto L3; L0: V = istart0; T = V; V3 = N31 + (T % count3) * STEP3; T = T / count3; V2 = N21 + (T % count2) * STEP2; T = T / count2; V1 = N11 + T * STEP1; iend = iend0; L1: BODY; V += 1; if (V < iend) goto L10; else goto L2; L10: V3 += STEP3; if (V3 cond3 N32) goto L1; else goto L11; L11: V3 = N31; V2 += STEP2; if (V2 cond2 N22) goto L1; else goto L12; L12: V2 = N21; V1 += STEP1; goto L1; L2: if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3; L3:
References a, add_bb_to_loop(), add_loop(), add_phi_arg(), alloc_loop(), profile_probability::apply_scale(), as_a(), boolean_type_node, BRANCH_EDGE, build1(), build2(), build4(), build_array_type_nelts(), build_call_expr(), build_clobber(), build_constructor(), build_fold_addr_expr, build_int_cst(), build_simple_mem_ref_loc(), builtin_decl_explicit(), CDI_DOMINATORS, cfun, omp_for_data::chunk_size, omp_for_data::collapse, omp_for_data_loop::cond_code, CONSTRUCTOR_APPEND_ELT, omp_region::cont, copy_ssa_name(), create_empty_bb(), create_phi_node(), create_tmp_var, DECL_INITIAL, DECL_NAMELESS, DECL_P, EDGE_COUNT, omp_region::entry, omp_region::exit, EXIT_BLOCK_PTR_FOR_FN, expand_omp_build_assign(), expand_omp_for_init_counts(), expand_omp_for_init_vars(), expand_omp_for_ordered_loops(), expand_omp_ordered_source_sink(), extract_omp_for_update_vars(), FALLTHRU_EDGE, find_edge(), find_phi_with_arg_on_edge(), fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), g, gcc_assert, get_immediate_dominator(), GF_OMP_FOR_KIND_FOR, GF_OMP_FOR_KIND_SIMD, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_bb(), gimple_build_assign(), gimple_build_call(), gimple_build_cond_empty(), gimple_build_omp_continue(), gimple_call_lhs(), gimple_call_set_lhs(), gimple_in_ssa_p(), gimple_omp_continue_control_def(), gimple_omp_continue_control_use(), gimple_omp_for_clauses(), gimple_omp_for_combined_into_p(), gimple_omp_for_combined_p(), gimple_omp_for_kind(), gimple_omp_return_lhs(), gimple_omp_return_nowait_p(), gimple_phi_arg_location_from_edge(), gimple_phi_result(), gsi_after_labels(), gsi_bb(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_next(), gsi_prev(), gsi_remove(), GSI_SAME_STMT, gsi_start(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), profile_probability::guessed_always(), omp_for_data::have_pointer_condtemp, omp_for_data::have_reductemp, loop::header, i, integer_onep(), profile_probability::invert(), is_combined_parallel(), is_in_offload_region(), omp_for_data::iter_type, omp_for_data::lastprivate_conditional, loop::latch, long_integer_type_node, long_long_unsigned_type_node, omp_for_data::loop, basic_block_def::loop_father, omp_for_data::loops, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, null_pointer_node, NULL_TREE, omp_adjust_chunk_size(), OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_LINEAR, OMP_CLAUSE_LINEAR_NO_COPYIN, OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_LOCATION, omp_find_clause(), omp_privatize_by_reference(), omp_for_data::ordered, gphi_iterator::phi(), PHI_ARG_DEF_FROM_EDGE, PHI_ARG_DEF_PTR_FROM_EDGE, phi_nodes(), phis, POINTER_TYPE_P, recompute_dominator(), release_ssa_name(), remove_bb_from_loops(), remove_edge(), set_immediate_dominator(), SET_USE, signed_type_for(), omp_for_data::simd_schedule, single_succ(), single_succ_edge(), size_int, size_zero_node, sizetype, split_block(), split_edge(), SSA_NAME_DEF_STMT, SSA_VAR_P, omp_for_data_loop::step, basic_block_def::succs, suppress_warning(), TREE_ADDRESSABLE, TREE_CODE, tree_int_cst_sgn(), TREE_STATIC, tree_to_uhwi(), TREE_TYPE, type(), TYPE_MIN_VALUE, TYPE_PRECISION, TYPE_SIZE_UNIT, TYPE_UNSIGNED, UNKNOWN_LOCATION, unshare_expr(), unsigned_type_node, useless_type_conversion_p(), omp_for_data_loop::v, vec_alloc(), virtual_operand_p(), and void_type_node.
Referenced by expand_omp_for().
|
static |
Helper function for expand_omp_{for_*,simd}. If this is the outermost of the combined collapse > 1 loop constructs, generate code like: if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB; if (cond3 is <) adj = STEP3 - 1; else adj = STEP3 + 1; count3 = (adj + N32 - N31) / STEP3; if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB; if (cond2 is <) adj = STEP2 - 1; else adj = STEP2 + 1; count2 = (adj + N22 - N21) / STEP2; if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB; if (cond1 is <) adj = STEP1 - 1; else adj = STEP1 + 1; count1 = (adj + N12 - N11) / STEP1; count = count1 * count2 * count3; Furthermore, if ZERO_ITER_BB is NULL, create a BB which does: count = 0; and set ZERO_ITER_BB to that bb. If this isn't the outermost of the combined loop constructs, just initialize COUNTS array from the _looptemp_ clauses. For loop nests with non-rectangular loops, do this only for the rectangular loops. Then pick the loops which reference outer vars in their bound expressions and the loops which they refer to and for this sub-nest compute number of iterations. For triangular loops use Faulhaber's formula, otherwise as a fallback, compute by iterating the loops. If e.g. the sub-nest is for (I = N11; I COND1 N12; I += STEP1) for (J = M21 * I + N21; J COND2 M22 * I + N22; J += STEP2) for (K = M31 * J + N31; K COND3 M32 * J + N32; K += STEP3) do: COUNT = 0; for (tmpi = N11; tmpi COND1 N12; tmpi += STEP1) for (tmpj = M21 * tmpi + N21; tmpj COND2 M22 * tmpi + N22; tmpj += STEP2) { int tmpk1 = M31 * tmpj + N31; int tmpk2 = M32 * tmpj + N32; if (tmpk1 COND3 tmpk2) { if (COND3 is <) adj = STEP3 - 1; else adj = STEP3 + 1; COUNT += (adj + tmpk2 - tmpk1) / STEP3; } } and finally multiply the counts of the rectangular loops not in the sub-nest with COUNT. Also, as counts[fd->last_nonrect] store number of iterations of the loops from fd->first_nonrect to fd->last_nonrect inclusive, i.e. the above COUNT multiplied by the counts of rectangular loops not referenced in any non-rectangular loops sandwitched in between those.
NOTE: It *could* be better to moosh all of the BBs together, creating one larger BB with all the computation and the unexpected jump at the end. I.e. bool zero3, zero2, zero1, zero; zero3 = N32 c3 N31; count3 = (N32 - N31) /[cl] STEP3; zero2 = N22 c2 N21; count2 = (N22 - N21) /[cl] STEP2; zero1 = N12 c1 N11; count1 = (N12 - N11) /[cl] STEP1; zero = zero3 || zero2 || zero1; count = count1 * count2 * count3; if (__builtin_expect(zero, false)) goto zero_iter_bb; After all, we expect the zero=false, and thus we expect to have to evaluate all of the comparison expressions, so short-circuiting oughtn't be a win. Since the condition isn't protecting a denominator, we're not concerned about divide-by-zero, so we can fully evaluate count even if a numerator turned out to be wrong. It seems like putting this all together would create much better scheduling opportunities, and less pressure on the chip's branch predictor.
References add_bb_to_loop(), omp_for_data::adjn1, boolean_type_node, build_int_cst(), build_one_cst(), build_zero_cst(), CDI_DOMINATORS, cfun, omp_for_data::collapse, omp_for_data_loop::cond_code, create_empty_bb(), create_tmp_reg(), expand_omp_build_assign(), expand_omp_build_cond(), omp_for_data::factor, find_edge(), omp_for_data::first_inner_iterations, omp_for_data::first_nonrect, fold_binary, fold_build1, fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), gcc_assert, gimple_build_assign(), gimple_in_ssa_p(), gimple_omp_for_clauses(), gimple_omp_for_combined_into_p(), gsi_after_labels(), gsi_bb(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_prev(), GSI_SAME_STMT, gsi_stmt(), profile_probability::guessed(), i, integer_one_node, integer_onep(), integer_zerop(), profile_probability::invert(), last, last_nondebug_stmt(), omp_for_data::last_nonrect, profile_probability::likely(), omp_for_data::loop, basic_block_def::loop_father, omp_for_data::loops, omp_for_data_loop::m1, omp_for_data_loop::m2, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, omp_for_data::non_rect, omp_for_data_loop::non_rect_referenced, NULL, NULL_TREE, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, omp_find_clause(), omp_for_data::ordered, omp_for_data_loop::outer, POINTER_TYPE_P, remove_edge(), set_immediate_dominator(), signed_type_for(), split_block(), SSA_VAR_P, omp_for_data_loop::step, TREE_CODE, TREE_TYPE, TYPE_UNSIGNED, profile_probability::unlikely(), unshare_expr(), omp_for_data_loop::v, and profile_probability::very_unlikely().
Referenced by expand_omp_for_generic(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_simd(), expand_omp_taskloop_for_inner(), and expand_omp_taskloop_for_outer().
|
static |
Helper function for expand_omp_{for_*,simd}. Generate code like: T = V; V3 = N31 + (T % count3) * STEP3; T = T / count3; V2 = N21 + (T % count2) * STEP2; T = T / count2; V1 = N11 + T * STEP1; if this loop doesn't have an inner loop construct combined with it. If it does have an inner loop construct combined with it and the iteration count isn't known constant, store values from counts array into its _looptemp_ temporaries instead. For non-rectangular loops (between fd->first_nonrect and fd->last_nonrect inclusive), use the count of all those loops together, and either find quadratic etc. equation roots, or as a fallback, do: COUNT = 0; for (tmpi = N11; tmpi COND1 N12; tmpi += STEP1) for (tmpj = M21 * tmpi + N21; tmpj COND2 M22 * tmpi + N22; tmpj += STEP2) { int tmpk1 = M31 * tmpj + N31; int tmpk2 = M32 * tmpj + N32; if (tmpk1 COND3 tmpk2) { if (COND3 is <) adj = STEP3 - 1; else adj = STEP3 + 1; int temp = (adj + tmpk2 - tmpk1) / STEP3; if (COUNT + temp > T) { V1 = tmpi; V2 = tmpj; V3 = tmpk1 + (T - COUNT) * STEP3; goto done; } else COUNT += temp; } } done:; but for optional innermost or outermost rectangular loops that aren't referenced by other loop expressions keep doing the division/modulo.
References add_bb_to_loop(), omp_for_data::adjn1, boolean_false_node, boolean_true_node, boolean_type_node, build_int_cst(), build_one_cst(), build_real(), build_zero_cst(), CDI_DOMINATORS, cfun, omp_for_data::collapse, omp_for_data_loop::cond_code, count, create_empty_bb(), create_tmp_reg(), create_tmp_var, dconst2, DECL_P, double_type_node, expand_omp_build_assign(), expand_omp_build_cond(), omp_for_data::factor, find_edge(), omp_for_data::first_inner_iterations, omp_for_data::first_nonrect, basic_block_def::flags, fold_build1, fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), gcc_assert, gcc_unreachable, gimple_build_assign(), gimple_build_call_internal(), gimple_build_cond(), gimple_build_nop(), gimple_call_set_lhs(), gimple_omp_for_clauses(), gimple_omp_for_combined_p(), gimple_omp_taskreg_clauses(), gsi_after_labels(), gsi_bb(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), GSI_NEW_STMT, gsi_prev(), GSI_SAME_STMT, gsi_stmt(), profile_probability::guessed(), i, integer_one_node, integer_onep(), integer_zerop(), profile_probability::invert(), last_nondebug_stmt(), omp_for_data::last_nonrect, profile_probability::likely(), long_long_integer_type_node, long_long_unsigned_type_node, omp_for_data::loop, basic_block_def::loop_father, omp_for_data::loops, omp_for_data_loop::m1, omp_for_data_loop::m2, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, omp_for_data::non_rect, omp_for_data_loop::non_rect_referenced, NULL, NULL_TREE, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, omp_find_clause(), operation_could_trap_p(), optab_handler(), omp_for_data_loop::outer, POINTER_TYPE_P, remove_edge(), set_immediate_dominator(), signed_type_for(), split_block(), omp_for_data_loop::step, TREE_ADDRESSABLE, TREE_CODE, TREE_TYPE, TYPE_MODE, TYPE_UNSIGNED, profile_probability::unlikely(), unshare_expr(), omp_for_data_loop::v, profile_probability::very_likely(), and profile_probability::very_unlikely().
Referenced by expand_omp_for_generic(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_simd(), expand_omp_taskloop_for_inner(), and expand_omp_taskloop_for_outer().
|
static |
Wrap the body into fd->ordered - fd->collapse loops that aren't collapsed.
References add_loop(), alloc_loop(), boolean_false_node, boolean_true_node, boolean_type_node, build2(), build4(), build_int_cst(), build_zero_cst(), CDI_DOMINATORS, omp_for_data::collapse, omp_for_data_loop::cond_code, EDGE_COUNT, expand_omp_build_assign(), fold_build2, fold_build_pointer_plus, fold_convert, force_gimple_operand_gsi(), gimple_build_cond_empty(), gsi_after_labels(), gsi_end_p(), gsi_insert_before(), gsi_last_bb(), GSI_NEW_STMT, gsi_prev(), GSI_SAME_STMT, gsi_stmt(), profile_probability::guessed_always(), loop::header, i, integer_onep(), omp_for_data::iter_type, loop::latch, basic_block_def::loop_father, omp_for_data::loops, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, NULL_TREE, omp_for_data::ordered, POINTER_TYPE_P, basic_block_def::preds, remove_edge(), set_immediate_dominator(), size_int, split_block(), omp_for_data_loop::step, TREE_TYPE, and omp_for_data_loop::v.
Referenced by expand_omp_for_generic().
|
static |
A subroutine of expand_omp_for. Generate code for a parallel loop with static schedule and a specified chunk size. Given parameters: for (V = N1; V cond N2; V += STEP) BODY; where COND is "<" or ">", we generate pseudocode if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2; if (cond is <) adj = STEP - 1; else adj = STEP + 1; if ((__typeof (V)) -1 > 0 && cond is >) n = -(adj + N2 - N1) / -STEP; else n = (adj + N2 - N1) / STEP; trip = 0; V = threadid * CHUNK * STEP + N1; -- this extra definition of V is here so that V is defined if the loop is not entered L0: s0 = (trip * nthreads + threadid) * CHUNK; e0 = min (s0 + CHUNK, n); if (s0 < n) goto L1; else goto L4; L1: V = s0 * STEP + N1; e = e0 * STEP + N1; L2: BODY; V += STEP; if (V cond e) goto L2; else goto L3; L3: trip += 1; goto L0; L4:
References a, add_loop(), add_phi_arg(), alloc_loop(), as_a(), boolean_type_node, BRANCH_EDGE, build2(), build_call_expr(), build_fold_addr_expr, build_int_cst(), build_int_cstu(), build_simple_mem_ref_loc(), builtin_decl_explicit(), CDI_DOMINATORS, cfun, omp_for_data::chunk_size, omp_for_data::collapse, omp_for_data_loop::cond_code, omp_region::cont, copy_ssa_name(), create_phi_node(), create_tmp_reg(), create_tmp_var, DECL_P, EDGE_COUNT, omp_region::entry, omp_region::exit, expand_omp_build_assign(), expand_omp_build_cond(), expand_omp_for_init_counts(), expand_omp_for_init_vars(), extract_omp_for_update_vars(), FALLTHRU_EDGE, find_edge(), find_lastprivate_looptemp(), find_phi_with_arg_on_edge(), fold_binary, fold_build1, fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), g, gcc_assert, gcc_unreachable, GF_OMP_FOR_KIND_DISTRIBUTE, GF_OMP_FOR_KIND_FOR, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_build_assign(), gimple_build_call(), gimple_build_cond_empty(), gimple_call_set_lhs(), gimple_in_ssa_p(), gimple_omp_continue_control_def(), gimple_omp_continue_control_use(), gimple_omp_for_clauses(), gimple_omp_for_combined_into_p(), gimple_omp_for_combined_p(), gimple_omp_for_kind(), gimple_omp_parallel_clauses(), gimple_omp_return_lhs(), gimple_omp_return_nowait_p(), gimple_phi_arg_def(), gimple_phi_arg_location_from_edge(), gimple_phi_result(), gsi_after_labels(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_next(), gsi_none(), gsi_prev(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_start_phis(), gsi_stmt(), omp_for_data::have_pointer_condtemp, omp_for_data::have_reductemp, loop::header, HOST_WIDE_INT_1U, i, loop::inner, integer_one_node, integer_onep(), is_in_offload_region(), last_nondebug_stmt(), omp_for_data::lastprivate_conditional, loop::latch, long_integer_type_node, omp_for_data::loop, basic_block_def::loop_father, make_edge(), make_ssa_name(), omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, null_pointer_node, NULL_TREE, omp_adjust_chunk_size(), omp_build_barrier(), OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, OMP_CLAUSE_LINEAR, OMP_CLAUSE_LINEAR_NO_COPYIN, OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_LOCATION, omp_find_clause(), omp_privatize_by_reference(), operand_equal_p(), gphi_iterator::phi(), PHI_ARG_DEF_FROM_EDGE, POINTER_TYPE_P, recompute_dominator(), redirect_edge_and_branch(), redirect_edge_var_map_clear(), redirect_edge_var_map_def(), redirect_edge_var_map_location(), redirect_edge_var_map_result(), redirect_edge_var_map_vector(), release_ssa_name(), remove_edge(), remove_phi_node(), set_immediate_dominator(), signed_type_for(), omp_for_data::simd_schedule, single_pred(), single_pred_p(), single_succ(), single_succ_edge(), sizetype, split_block(), split_edge(), SSA_NAME_DEF_STMT, omp_for_data_loop::step, basic_block_def::succs, TREE_ADDRESSABLE, TREE_CODE, tree_int_cst_equal(), tree_int_cst_sgn(), tree_to_uhwi(), TREE_TYPE, type(), TYPE_PRECISION, TYPE_SIZE_UNIT, TYPE_UNSIGNED, UNKNOWN_LOCATION, unshare_expr(), useless_type_conversion_p(), omp_for_data_loop::v, profile_probability::very_likely(), and profile_probability::very_unlikely().
Referenced by expand_omp_for().
|
static |
A subroutine of expand_omp_for. Generate code for a parallel loop with static schedule and no specified chunk size. Given parameters: for (V = N1; V cond N2; V += STEP) BODY; where COND is "<" or ">", we generate pseudocode if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2; if (cond is <) adj = STEP - 1; else adj = STEP + 1; if ((__typeof (V)) -1 > 0 && cond is >) n = -(adj + N2 - N1) / -STEP; else n = (adj + N2 - N1) / STEP; q = n / nthreads; tt = n % nthreads; if (threadid < tt) goto L3; else goto L4; L3: tt = 0; q = q + 1; L4: s0 = q * threadid + tt; e0 = s0 + q; V = s0 * STEP + N1; if (s0 >= e0) goto L2; else goto L0; L0: e = e0 * STEP + N1; L1: BODY; V += STEP; if (V cond e) goto L1; L2:
References a, add_loop(), add_phi_arg(), alloc_loop(), profile_probability::apply_scale(), as_a(), boolean_false_node, boolean_type_node, BRANCH_EDGE, build2(), build_call_expr(), build_fold_addr_expr, build_int_cst(), build_int_cstu(), build_simple_mem_ref_loc(), builtin_decl_explicit(), builtin_decl_implicit(), CDI_DOMINATORS, cfun, omp_for_data::collapse, omp_for_data_loop::cond_code, omp_region::cont, create_tmp_reg(), create_tmp_var, DECL_P, EDGE_COUNT, omp_region::entry, omp_region::exit, expand_omp_build_assign(), expand_omp_build_cond(), expand_omp_for_init_counts(), expand_omp_for_init_vars(), expand_omp_scantemp_alloc(), extract_omp_for_update_vars(), FALLTHRU_EDGE, find_edge(), find_lastprivate_looptemp(), basic_block_def::flags, fold_binary, fold_build1, fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), g, gcc_assert, gcc_unreachable, GF_OMP_FOR_KIND_DISTRIBUTE, GF_OMP_FOR_KIND_FOR, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_build_assign(), gimple_build_call(), gimple_build_cond(), gimple_build_cond_empty(), gimple_call_set_lhs(), gimple_in_ssa_p(), gimple_omp_continue_control_def(), gimple_omp_continue_control_use(), gimple_omp_for_clauses(), gimple_omp_for_combined_into_p(), gimple_omp_for_combined_p(), gimple_omp_for_kind(), gimple_omp_parallel_clauses(), gimple_omp_return_lhs(), gimple_omp_return_nowait_p(), gimple_phi_arg_def(), gsi_after_labels(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_next(), gsi_none(), gsi_prev(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_start_phis(), gsi_stmt(), profile_probability::guessed_always(), omp_for_data::have_nonctrl_scantemp, omp_for_data::have_pointer_condtemp, omp_for_data::have_reductemp, omp_for_data::have_scantemp, loop::header, HOST_WIDE_INT_1U, integer_one_node, integer_onep(), integer_type_node, omp_for_data::last_nonrect, omp_for_data::lastprivate_conditional, loop::latch, long_integer_type_node, long_long_integer_type_node, omp_for_data::loop, basic_block_def::loop_father, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, omp_for_data::non_rect, NULL, null_pointer_node, NULL_TREE, omp_build_barrier(), OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE__SCANTEMP_, OMP_CLAUSE__SCANTEMP__ALLOC, OMP_CLAUSE__SCANTEMP__CONTROL, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, OMP_CLAUSE_LINEAR, OMP_CLAUSE_LINEAR_NO_COPYIN, OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_LOCATION, omp_find_clause(), omp_privatize_by_reference(), POINTER_TYPE_P, ptr_type_node, recompute_dominator(), redirect_edge_and_branch(), release_ssa_name(), remove_edge(), set_immediate_dominator(), signed_type_for(), single_pred(), single_succ(), size_int, sizetype, split_block(), split_edge(), SSA_NAME_DEF_STMT, omp_for_data_loop::step, basic_block_def::succs, TREE_ADDRESSABLE, TREE_CODE, tree_int_cst_sgn(), tree_to_uhwi(), TREE_TYPE, type(), TYPE_ALIGN, TYPE_ALIGN_UNIT, TYPE_PRECISION, TYPE_SIZE_UNIT, TYPE_UNSIGNED, UNKNOWN_LOCATION, unshare_expr(), useless_type_conversion_p(), omp_for_data_loop::v, profile_probability::very_likely(), and profile_probability::very_unlikely().
Referenced by expand_omp_for().
|
static |
Expand a single depend from #pragma omp ordered depend(sink:...).
References a, boolean_false_node, boolean_true_node, boolean_type_node, build_int_cst(), build_minus_one_cst(), build_zero_cst(), builtin_decl_explicit(), CDI_DOMINATORS, omp_for_data::collapse, omp_for_data_loop::cond_code, create_tmp_var, deps, fold_build1_loc(), fold_build2, fold_build2_loc(), fold_build3_loc(), fold_convert, fold_convert_loc(), force_gimple_operand_gsi(), g, gcc_assert, gimple_build_call_vec(), gimple_build_cond(), gimple_build_cond_empty(), gimple_set_location(), gsi_after_labels(), gsi_bb(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), GSI_NEW_STMT, gsi_prev(), GSI_SAME_STMT, gsi_stmt(), profile_probability::guessed_always(), i, integer_minus_onep(), integer_onep(), integer_zerop(), profile_probability::invert(), omp_for_data::iter_type, long_integer_type_node, omp_for_data::loop, omp_for_data::loops, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, NULL_TREE, OMP_CLAUSE_DECL, OMP_CLAUSE_DOACROSS_DEPEND, OMP_CLAUSE_DOACROSS_SINK_NEGATIVE, omp_for_data::ordered, POINTER_TYPE_P, set_immediate_dominator(), sizetype, split_block(), split_block_after_labels(), omp_for_data_loop::step, TREE_CHAIN, TREE_CODE, tree_int_cst_sgn(), TREE_OPERAND, TREE_PURPOSE, TREE_TYPE, TYPE_UNSIGNED, unshare_expr(), omp_for_data_loop::v, and warning_at().
Referenced by expand_omp_ordered_source_sink().
|
static |
Expand #pragma omp ordered depend(source).
References build_fold_addr_expr, builtin_decl_explicit(), g, gimple_build_call(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, omp_for_data::iter_type, long_integer_type_node, and omp_for_data::ordered.
Referenced by expand_omp_ordered_source_sink().
|
static |
Expand all #pragma omp ordered depend(source) and #pragma omp ordered depend(sink:...) constructs in the current #pragma omp for ordered(n) region.
References build_array_type_nelts(), build_zero_cst(), omp_for_data::collapse, create_tmp_var, expand_omp_ordered_sink(), expand_omp_ordered_source(), gimple_location(), gimple_omp_ordered_clauses(), gsi_for_stmt(), gsi_remove(), i, omp_region::inner, integer_onep(), omp_for_data::iter_type, omp_for_data::loops, omp_region::next, NULL_TREE, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DOACROSS_KIND, OMP_CLAUSE_DOACROSS_SINK, OMP_CLAUSE_DOACROSS_SOURCE, omp_region::ord_stmt, omp_for_data::ordered, POINTER_TYPE_P, omp_for_data_loop::step, TREE_ADDRESSABLE, TREE_TYPE, omp_region::type, and omp_for_data_loop::v.
Referenced by expand_omp_for_generic().
Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be regimplified.
References DECL_HAS_VALUE_EXPR_P, DECL_P, NULL_TREE, recompute_tree_invariant_for_addr_expr(), TREE_CODE, TYPE_P, and VAR_P.
Referenced by expand_omp_build_assign(), expand_omp_build_cond(), expand_omp_simd(), and extract_omp_for_update_vars().
|
static |
Helper function for expand_omp_for_static_nochunk. If PTR is NULL, compute needed allocation size. If !ALLOC of team allocations, if ALLOC of thread allocation. SZ is the initial needed size for other purposes, ALLOC_ALIGN guaranteed alignment of allocation in bytes, CNT number of elements of each array, for !ALLOC this is omp_get_num_threads (), for ALLOC number of iterations handled by the current thread. If PTR is non-NULL, it is the start of the allocation and this routine shall assign to OMP_CLAUSE_DECL (c) of those _scantemp_ clauses pointers to the corresponding arrays.
References build_int_cst(), expand_omp_build_assign(), fold_build2, fold_convert, least_bit_hwi(), MIN, NULL_TREE, OMP_CLAUSE__SCANTEMP_, OMP_CLAUSE__SCANTEMP__ALLOC, OMP_CLAUSE__SCANTEMP__CONTROL, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, pointer_sized_int_node, ptr_type_node, ROUND_UP, size_binop, size_int, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, TYPE_ALIGN_UNIT, and TYPE_SIZE_UNIT.
Referenced by expand_omp_for_static_nochunk().
|
static |
Expand code for an OpenMP sections directive. In pseudo code, we generate v = GOMP_sections_start (n); L0: switch (v) { case 0: goto L2; case 1: section 1; goto L1; case 2: ... case n: ... default: abort (); } L1: v = GOMP_sections_next (); goto L0; L2: reduction; If this is a combined parallel sections, replace the call to GOMP_sections_start with call to GOMP_sections_next.
References add_bb_to_loop(), as_a(), build2(), build_case_label(), build_fold_addr_expr, build_int_cst(), build_one_cst(), builtin_decl_explicit(), CDI_DOMINATORS, omp_region::cont, create_empty_bb(), create_tmp_var, current_loops, EDGE_COUNT, EDGE_SUCC, omp_region::entry, omp_region::exit, expand_omp_build_assign(), FOR_EACH_EDGE, g, gcc_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_block_label(), gimple_build_call(), gimple_build_switch(), gimple_call_set_lhs(), gimple_omp_continue_control_def(), gimple_omp_continue_control_use(), gimple_omp_return_lhs(), gimple_omp_return_nowait_p(), gimple_omp_section_last_p(), gimple_omp_sections_clauses(), gimple_omp_sections_control(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_none(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), i, omp_region::inner, is_combined_parallel(), last_nondebug_stmt(), make_edge(), omp_region::next, NULL, null_pointer_node, NULL_TREE, OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_LASTPRIVATE_CONDITIONAL, omp_find_clause(), basic_block_def::prev_bb, release_ssa_name(), set_immediate_dominator(), si, single_pred(), single_pred_p(), single_succ(), single_succ_edge(), SSA_NAME_DEF_STMT, basic_block_def::succs, TREE_ADDRESSABLE, TREE_CODE, tree_to_uhwi(), TREE_TYPE, omp_region::type, TYPE_SIZE_UNIT, and unsigned_type_node.
Referenced by expand_omp().
|
static |
A subroutine of expand_omp_for. Generate code for a simd non-worksharing loop. Given parameters: for (V = N1; V cond N2; V += STEP) BODY; where COND is "<" or ">", we generate pseudocode V = N1; goto L1; L0: BODY; V += STEP; L1: if (V cond N2) goto L0; else goto L2; L2: For collapsed loops, emit the outer loops as scalar and only try to vectorize the innermost loop.
References add_bb_to_loop(), add_loop(), alloc_loop(), profile_probability::apply_scale(), boolean_type_node, BRANCH_EDGE, build2(), build_call_expr_internal_loc(), build_int_cst(), build_one_cst(), build_zero_cst(), CDI_DOMINATORS, cfun, omp_for_data::collapse, omp_for_data_loop::cond_code, omp_region::cont, create_empty_bb(), create_tmp_var, DECL_P, loop::dont_vectorize, EDGE_COUNT, EDGE_SUCC, omp_region::entry, omp_region::exit, expand_omp_build_assign(), expand_omp_for_init_counts(), expand_omp_for_init_vars(), expand_omp_regimplify_p(), FALLTHRU_EDGE, find_edge(), fold_build1, fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), loop::force_vectorize, g, gcc_assert, gimple_build_assign(), gimple_build_call_internal(), gimple_build_cond(), gimple_build_cond_empty(), gimple_call_set_lhs(), gimple_cond_lhs_ptr(), gimple_cond_rhs_ptr(), gimple_in_ssa_p(), gimple_omp_for_clauses(), gimple_omp_for_combined_into_p(), gimple_regimplify_operands(), gsi_after_labels(), gsi_bb(), GSI_CONTINUE_LINKING, gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), GSI_NEW_STMT, gsi_prev(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), profile_probability::guessed_always(), loop::header, i, INT_MAX, integer_nonzerop(), integer_onep(), integer_zerop(), profile_probability::invert(), last_nondebug_stmt(), omp_for_data::last_nonrect, loop::latch, omp_for_data::loop, basic_block_def::loop_father, omp_for_data::loops, omp_for_data_loop::m1, omp_for_data_loop::m2, make_edge(), MIN, omp_for_data_loop::n1, omp_for_data_loop::n2, omp_for_data::non_rect, NULL, NULL_TREE, offset, OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE__SIMDUID__DECL, OMP_CLAUSE__SIMT_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, OMP_CLAUSE_IF, OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SAFELEN_EXPR, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_SIMDLEN_EXPR, omp_find_clause(), omp_max_simt_vf(), OPTION_SET_P, omp_for_data_loop::outer, POINTER_TYPE_P, poly_int_tree_p(), redirect_edge_succ(), remove_edge(), loop::safelen, set_immediate_dominator(), signed_type_for(), loop::simdlen, loop::simduid, single_succ(), single_succ_edge(), split_block(), split_edge(), omp_for_data_loop::step, basic_block_def::succs, TREE_ADDRESSABLE, TREE_CODE, tree_fits_uhwi_p(), tree_int_cst_sgn(), tree_to_uhwi(), TREE_TYPE, type(), TYPE_UNSIGNED, UNKNOWN_LOCATION, unshare_expr(), unsigned_type_for(), unsigned_type_node, omp_for_data_loop::v, and walk_tree.
Referenced by expand_omp_for().
|
static |
Expand code for an OpenMP single or scope directive. We've already expanded much of the code, here we simply place the GOMP_barrier call.
References omp_region::entry, omp_region::exit, gcc_assert, gimple_omp_return_lhs(), gimple_omp_return_nowait_p(), gsi_insert_after(), gsi_last_nondebug_bb(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), NULL, omp_build_barrier(), si, and single_succ_edge().
Referenced by expand_omp().
|
static |
Generic expansion for OpenMP synchronization directives: master, ordered and critical. All we need to do here is remove the entry and exit markers for REGION.
References as_a(), omp_region::entry, omp_region::exit, expand_omp_taskreg(), gcc_assert, gimple_omp_teams_host(), gsi_last_nondebug_bb(), gsi_remove(), gsi_stmt(), si, and single_succ_edge().
Referenced by expand_omp().
|
static |
Expand the GIMPLE_OMP_TARGET starting at REGION.
References add_bb_to_loop(), cgraph_node::add_new_function(), adjust_context_and_scope(), as_a(), assign_assembler_name_if_needed(), BLOCK_SUPERCONTEXT, BLOCK_VARS, boolean_type_node, build1(), build2(), build_decl(), build_fold_addr_expr, build_int_cst(), build_zero_cst(), builtin_decl_explicit(), cgraph_node::calls_declare_variant_alt, CDI_DOMINATORS, function::cfg, cfun, changed, cleanup_tree_cfg(), clone_function_name(), copy_list(), create_empty_bb(), create_tmp_var, function::curr_properties, current_function_decl, DECL_ARG_TYPE, DECL_ARGUMENTS, DECL_ARTIFICIAL, DECL_ASSEMBLER_NAME_SET_P, DECL_ATTRIBUTES, DECL_CHAIN, DECL_CONTEXT, DECL_EXTERNAL, DECL_FUNCTION_SPECIFIC_OPTIMIZATION, DECL_FUNCTION_SPECIFIC_TARGET, DECL_FUNCTION_VERSIONED, DECL_IGNORED_P, DECL_INITIAL, DECL_NAME, DECL_NAMELESS, DECL_PRESERVE_P, DECL_RESULT, DECL_SAVED_TREE, DECL_SOURCE_LOCATION, DECL_STRUCT_FUNCTION, DECL_UNINLINABLE, dump_file, dump_flags, dump_function_header(), dump_function_to_file(), omp_region::entry, omp_region::exit, varpool_node::finalize_decl(), basic_block_def::flags, fold_build1, fold_convert, fold_convert_loc(), FOR_EACH_BB_FN, force_gimple_operand_gsi(), symtab_node::force_output, g, gcc_assert, gcc_checking_assert, gcc_unreachable, cgraph_node::get(), cgraph_node::get_create(), get_identifier(), get_target_arguments(), GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_ENTER_DATA, GF_OMP_TARGET_KIND_EXIT_DATA, GF_OMP_TARGET_KIND_OACC_DATA, GF_OMP_TARGET_KIND_OACC_DATA_KERNELS, GF_OMP_TARGET_KIND_OACC_DECLARE, GF_OMP_TARGET_KIND_OACC_ENTER_DATA, GF_OMP_TARGET_KIND_OACC_EXIT_DATA, GF_OMP_TARGET_KIND_OACC_HOST_DATA, GF_OMP_TARGET_KIND_OACC_KERNELS, GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE, GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED, GF_OMP_TARGET_KIND_OACC_SERIAL, GF_OMP_TARGET_KIND_OACC_UPDATE, GF_OMP_TARGET_KIND_REGION, GF_OMP_TARGET_KIND_UPDATE, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_block(), gimple_boolify(), gimple_build_assign(), gimple_build_call_internal(), gimple_build_call_vec(), gimple_build_cond_empty(), gimple_build_return(), gimple_in_ssa_p(), gimple_location(), gimple_num_ops(), gimple_omp_target_child_fn(), gimple_omp_target_clauses(), gimple_omp_target_data_arg(), gimple_omp_target_kind(), gimple_purge_dead_eh_edges(), gimple_set_body(), gimple_set_location(), gimplify_function_tree(), gsi_bb(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_next(), gsi_prev(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), function::has_force_vectorize_loops, function::has_simduid_loops, integer_one_node, integer_type_node, integer_zero_node, is_gimple_omp_oacc(), is_gimple_omp_offloaded(), last_nondebug_stmt(), function::local_decls, lookup_attribute(), basic_block_def::loop_father, LOOPS_NEED_FIXUP, loops_state_satisfies_p(), make_edge(), make_node(), mark_loops_in_oacc_kernels_region(), move_sese_region_to_fn(), NULL, NULL_TREE, oacc_launch_pack(), oacc_replace_fn_attrib(), oacc_set_fn_attrib(), offload_funcs, symtab_node::offloadable, omp_any_child_fn_dumped, OMP_CLAUSE_ASYNC, OMP_CLAUSE_ASYNC_EXPR, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, OMP_CLAUSE_DEPEND, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DEVICE_ANCESTOR, OMP_CLAUSE_DEVICE_ID, OMP_CLAUSE_IF, OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_IN_REDUCTION, OMP_CLAUSE_LOCATION, OMP_CLAUSE_NOWAIT, OMP_CLAUSE_SELF, OMP_CLAUSE_SELF_EXPR, OMP_CLAUSE_WAIT, OMP_CLAUSE_WAIT_EXPR, omp_find_clause(), cgraph_node::parallelized_function, pop_cfun(), ptr_type_node, push_cfun(), cgraph_edge::rebuild_edges(), remove_attribute(), remove_edge(), set_immediate_dominator(), single_succ(), single_succ_edge(), size_binop, size_int, size_zero_node, split_block(), split_block_after_labels(), loops::state, wi::to_wide(), TREE_CHAIN, TREE_CODE, tree_cons(), TREE_INT_CST_LOW, TREE_OPERAND, TREE_PUBLIC, TREE_READONLY, TREE_STATIC, TREE_TYPE, TREE_USED, TREE_VEC_ELT, TREE_VEC_LENGTH, TYPE_DOMAIN, TYPE_MAX_VALUE, UNKNOWN_LOCATION, unsigned_type_node, VAR_P, vec2chain(), vec_safe_length(), vec_safe_push(), vec_safe_truncate(), verify_loop_structure(), void_type_node, and function::x_current_loops.
Referenced by expand_omp().
|
static |
Taskloop construct is represented after gimplification with two GIMPLE_OMP_FOR constructs with GIMPLE_OMP_TASK sandwiched in between them. This routine expands the inner GIMPLE_OMP_FOR. GOMP_taskloop{,_ull} function arranges for each task to be given just a single range of iterations.
References add_loop(), alloc_loop(), profile_probability::always(), as_a(), boolean_type_node, BRANCH_EDGE, build2(), CDI_DOMINATORS, omp_for_data::collapse, omp_for_data_loop::cond_code, omp_region::cont, DECL_P, EDGE_COUNT, omp_region::entry, omp_region::exit, expand_omp_for_init_counts(), expand_omp_for_init_vars(), extract_omp_for_update_vars(), FALLTHRU_EDGE, find_edge(), fold_build2, fold_build_pointer_plus, fold_convert, omp_for_data::for_stmt, force_gimple_operand_gsi(), gcc_assert, gimple_build_assign(), gimple_build_cond_empty(), gimple_omp_continue_control_def(), gimple_omp_continue_control_use(), gimple_omp_for_clauses(), gimple_omp_for_combined_p(), gsi_bb(), GSI_CONTINUE_LINKING, gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_last_nondebug_bb(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), loop::header, integer_one_node, omp_for_data::iter_type, omp_for_data::last_nonrect, loop::latch, long_long_unsigned_type_node, omp_for_data::loop, basic_block_def::loop_father, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, omp_for_data::non_rect, NULL, NULL_TREE, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, omp_find_clause(), omp_region::outer, POINTER_TYPE_P, recompute_dominator(), remove_edge(), remove_edge_and_dominated_blocks(), set_immediate_dominator(), signed_type_for(), omp_for_data_loop::step, basic_block_def::succs, TREE_ADDRESSABLE, TREE_CODE, tree_int_cst_sgn(), TREE_TYPE, type(), TYPE_MIN_VALUE, TYPE_UNSIGNED, useless_type_conversion_p(), and omp_for_data_loop::v.
Referenced by expand_omp_for().
|
static |
Taskloop construct is represented after gimplification with two GIMPLE_OMP_FOR constructs with GIMPLE_OMP_TASK sandwiched in between them. This routine expands the outer GIMPLE_OMP_FOR, which should just compute all the needed loop temporaries for GIMPLE_OMP_TASK.
References profile_probability::always(), BRANCH_EDGE, CDI_DOMINATORS, omp_for_data::collapse, omp_for_data_loop::cond_code, omp_region::cont, EDGE_COUNT, omp_region::entry, omp_region::exit, expand_omp_for_init_counts(), expand_omp_for_init_vars(), FALLTHRU_EDGE, find_lastprivate_looptemp(), fold_build2, fold_convert, force_gimple_operand_gsi(), gcc_assert, get_immediate_dominator(), gimple_build_assign(), gimple_omp_task_clauses(), gimple_omp_task_taskloop_p(), GSI_CONTINUE_LINKING, gsi_for_stmt(), gsi_insert_after(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_prev(), gsi_remove(), gsi_stmt(), i, omp_for_data::iter_type, long_long_unsigned_type_node, omp_for_data::loop, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, NULL_TREE, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, omp_find_clause(), POINTER_TYPE_P, recompute_dominator(), remove_edge(), set_immediate_dominator(), signed_type_for(), split_block(), SSA_VAR_P, omp_for_data_loop::step, basic_block_def::succs, suppress_warning(), TREE_CODE, tree_int_cst_sgn(), TREE_TYPE, type(), TYPE_MIN_VALUE, TYPE_PRECISION, TYPE_UNSIGNED, and omp_for_data_loop::v.
Referenced by expand_omp_for().
|
static |
Expand the OpenMP parallel or task directive starting at REGION.
References cgraph_node::add_new_function(), adjust_context_and_scope(), as_a(), assign_assembler_name_if_needed(), BLOCK_VARS, BRANCH_EDGE, CDI_DOMINATORS, function::cfg, cfun, changed, cleanup_tree_cfg(), omp_region::cont, function::curr_properties, current_function_decl, DECL_ARGUMENTS, DECL_ASSEMBLER_NAME_SET_P, DECL_CHAIN, DECL_CONTEXT, DECL_EXTERNAL, DECL_INITIAL, DECL_SAVED_TREE, DECL_STRUCT_FUNCTION, dump_file, dump_flags, dump_function_header(), dump_function_to_file(), omp_region::entry, omp_region::exit, expand_parallel_call(), expand_task_call(), expand_taskwait_call(), expand_teams_call(), FALLTHRU_EDGE, varpool_node::finalize_decl(), basic_block_def::flags, FOR_EACH_BB_FN, gcc_assert, cgraph_node::get_create(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_set_rhs1(), gimple_block(), gimple_build_return(), function::gimple_df, gimple_in_ssa_p(), gimple_num_ops(), gimple_omp_set_subcode(), gimple_omp_task_taskwait_p(), gimple_omp_taskreg_child_fn(), gimple_omp_taskreg_data_arg(), gimple_purge_dead_eh_edges(), gimple_set_body(), gsi_end_p(), gsi_insert_after(), gsi_last_nondebug_bb(), gsi_next(), gsi_remove(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), function::has_force_vectorize_loops, function::has_simduid_loops, gimple_df::in_ssa_p, init_ssa_operands(), init_tree_ssa(), is_combined_parallel(), last_nondebug_stmt(), function::local_decls, LOOPS_NEED_FIXUP, loops_state_satisfies_p(), make_edge(), move_sese_region_to_fn(), NULL, NULL_TREE, omp_any_child_fn_dumped, optimize_omp_library_calls(), cgraph_node::parallelized_function, pop_cfun(), push_cfun(), cgraph_edge::rebuild_edges(), remove_edge(), remove_edge_and_dominated_blocks(), set_immediate_dominator(), single_succ(), single_succ_edge(), single_succ_p(), split_block(), SSA_NAME_VAR, loops::state, TODO_update_ssa, TREE_CODE, TREE_OPERAND, TREE_STATIC, TREE_USED, update_max_bb_count(), update_ssa(), update_stmt(), VAR_P, vec2chain(), vec_safe_length(), vec_safe_truncate(), verify_loop_structure(), omp_region::ws_args, and function::x_current_loops.
Referenced by expand_omp(), and expand_omp_synch().
|
static |
Build the function calls to GOMP_parallel etc to actually generate the parallel operation. REGION is the parallel region being expanded. BB is the block where to insert the code. WS_ARGS will be set if this is a call to a combined parallel+workshare construct, it contains the list of additional arguments needed by the workshare construct.
References add_bb_to_loop(), add_phi_arg(), build2(), build_call_expr_loc_vec(), build_fold_addr_expr, build_int_cst(), builtin_decl_explicit(), CDI_DOMINATORS, cfun, create_empty_bb(), create_phi_node(), create_tmp_var, expand_omp_build_assign(), fold_build2_loc(), fold_convert, fold_convert_loc(), force_gimple_operand_gsi(), gcc_assert, gcc_unreachable, gimple_boolify(), gimple_build_cond_empty(), gimple_in_ssa_p(), gimple_location(), gimple_omp_parallel_child_fn(), gimple_omp_parallel_clauses(), gimple_omp_parallel_data_arg(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_last_nondebug_bb(), gsi_start_bb(), omp_region::has_lastprivate_conditional, omp_region::inner, integer_zerop(), is_combined_parallel(), basic_block_def::loop_father, make_edge(), make_ssa_name(), NULL, null_pointer_node, NULL_TREE, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_DECL, OMP_CLAUSE_IF, OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_LOCATION, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_NUM_THREADS_EXPR, OMP_CLAUSE_PROC_BIND, OMP_CLAUSE_PROC_BIND_KIND, OMP_CLAUSE_SCHEDULE_AUTO, OMP_CLAUSE_SCHEDULE_DYNAMIC, OMP_CLAUSE_SCHEDULE_GUIDED, OMP_CLAUSE_SCHEDULE_MONOTONIC, OMP_CLAUSE_SCHEDULE_NONMONOTONIC, OMP_CLAUSE_SCHEDULE_RUNTIME, omp_find_clause(), pointer_sized_int_node, remove_edge(), omp_region::sched_kind, omp_region::sched_modifiers, set_immediate_dominator(), split_block_after_labels(), TREE_TYPE, omp_region::type, UNKNOWN_LOCATION, unsigned_type_node, vec_alloc(), vec_safe_length(), and omp_region::ws_args.
Referenced by expand_omp_taskreg().
|
static |
Build the function call to GOMP_task to actually generate the task operation. BB is the block where to insert the code.
References as_a(), boolean_true_node, build_call_expr(), build_fold_addr_expr, build_fold_addr_expr_loc(), build_int_cst(), builtin_decl_explicit(), omp_for_data_loop::cond_code, omp_region::entry, fold_build2_loc(), fold_build3_loc(), fold_convert, fold_convert_loc(), force_gimple_operand_gsi(), g, gcc_assert, GF_OMP_FOR_KIND_TASKLOOP, gimple_boolify(), gimple_location(), gimple_omp_for_clauses(), gimple_omp_for_kind(), gimple_omp_task_arg_align(), gimple_omp_task_arg_size(), gimple_omp_task_child_fn(), gimple_omp_task_clauses(), gimple_omp_task_copy_fn(), gimple_omp_task_data_arg(), gimple_omp_task_taskloop_p(), GSI_CONTINUE_LINKING, gsi_last_nondebug_bb(), integer_type_node, integer_zero_node, omp_for_data::iter_type, last_nondebug_stmt(), long_integer_type_node, long_long_unsigned_type_node, omp_for_data::loop, NULL, null_pointer_node, NULL_TREE, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, OMP_CLAUSE_DEPEND, OMP_CLAUSE_DETACH, OMP_CLAUSE_FINAL, OMP_CLAUSE_FINAL_EXPR, OMP_CLAUSE_GRAINSIZE, OMP_CLAUSE_GRAINSIZE_EXPR, OMP_CLAUSE_GRAINSIZE_STRICT, OMP_CLAUSE_IF, OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_MERGEABLE, OMP_CLAUSE_NOGROUP, OMP_CLAUSE_NUM_TASKS, OMP_CLAUSE_NUM_TASKS_EXPR, OMP_CLAUSE_NUM_TASKS_STRICT, OMP_CLAUSE_PRIORITY, OMP_CLAUSE_PRIORITY_EXPR, OMP_CLAUSE_REDUCTION, OMP_CLAUSE_UNTIED, omp_extract_for_data(), omp_find_clause(), omp_region::outer, ptr_type_node, omp_for_data_loop::step, and unsigned_type_node.
Referenced by expand_omp_taskreg().
|
static |
Build the function call to GOMP_taskwait_depend to actually generate the taskwait operation. BB is the block where to insert the code.
References build_call_expr(), builtin_decl_explicit(), force_gimple_operand_gsi(), gimple_omp_task_clauses(), GSI_CONTINUE_LINKING, gsi_last_nondebug_bb(), NULL_TREE, OMP_CLAUSE_DECL, OMP_CLAUSE_DEPEND, OMP_CLAUSE_NOWAIT, and omp_find_clause().
Referenced by expand_omp_taskreg().
|
static |
Build the function call to GOMP_teams_reg to actually generate the host teams operation. REGION is the teams region being expanded. BB is the block where to insert the code.
References build_call_expr_loc_vec(), build_fold_addr_expr, build_int_cst(), build_zero_cst(), builtin_decl_explicit(), fold_convert, force_gimple_operand_gsi(), gimple_omp_teams_child_fn(), gimple_omp_teams_clauses(), gimple_omp_teams_data_arg(), GSI_CONTINUE_LINKING, gsi_last_nondebug_bb(), NULL, null_pointer_node, NULL_TREE, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR, OMP_CLAUSE_THREAD_LIMIT, OMP_CLAUSE_THREAD_LIMIT_EXPR, omp_find_clause(), UNKNOWN_LOCATION, unsigned_type_node, and vec_alloc().
Referenced by expand_omp_taskreg().
|
static |
Helper function for expand_omp_for_*. Generate code like: L10: V3 += STEP3; if (V3 cond3 N32) goto BODY_BB; else goto L11; L11: V3 = N31; V2 += STEP2; if (V2 cond2 N22) goto BODY_BB; else goto L12; L12: V2 = N21; V1 += STEP1; goto BODY_BB; For non-rectangular loops, use temporaries stored in nonrect_bounds for the upper bounds if M?2 multiplier is present. Given e.g. for (V1 = N11; V1 cond1 N12; V1 += STEP1) for (V2 = N21; V2 cond2 N22; V2 += STEP2) for (V3 = N31; V3 cond3 N32; V3 += STEP3) for (V4 = N41 + M41 * V2; V4 cond4 N42 + M42 * V2; V4 += STEP4) do: L10: V4 += STEP4; if (V4 cond4 NONRECT_BOUND4) goto BODY_BB; else goto L11; L11: V4 = N41 + M41 * V2; // This can be left out if the loop // refers to the immediate parent loop V3 += STEP3; if (V3 cond3 N32) goto BODY_BB; else goto L12; L12: V3 = N31; V2 += STEP2; if (V2 cond2 N22) goto L120; else goto L13; L120: V4 = N41 + M41 * V2; NONRECT_BOUND4 = N42 + M42 * V2; if (V4 cond4 NONRECT_BOUND4) goto BODY_BB; else goto L12; L13: V2 = N21; V1 += STEP1; goto L120;
References add_bb_to_loop(), profile_probability::apply_scale(), as_a(), boolean_type_node, CDI_DOMINATORS, omp_for_data::collapse, omp_for_data_loop::cond_code, create_empty_bb(), DECL_P, expand_omp_regimplify_p(), fold_build2, fold_build_pointer_plus, force_gimple_operand_gsi(), gimple_build_assign(), gimple_build_cond(), gimple_build_cond_empty(), gimple_cond_lhs_ptr(), gimple_cond_rhs_ptr(), gimple_regimplify_operands(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_start_bb(), profile_probability::guessed_always(), i, omp_for_data::last_nonrect, basic_block_def::loop_father, omp_for_data::loops, omp_for_data_loop::m1, omp_for_data_loop::m2, make_edge(), omp_for_data_loop::n1, omp_for_data_loop::n2, omp_for_data_loop::non_rect_referenced, NULL, NULL_TREE, omp_for_data_loop::outer, POINTER_TYPE_P, set_immediate_dominator(), omp_for_data_loop::step, TREE_ADDRESSABLE, TREE_TYPE, unshare_expr(), omp_for_data_loop::v, and walk_tree.
Referenced by expand_omp_for_generic(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), and expand_omp_taskloop_for_inner().
|
static |
Return the last _looptemp_ clause if one has been created for lastprivate on distribute parallel for{, simd} or taskloop. FD is the loop data and INNERC should be the second _looptemp_ clause (the one holding the end of the range). This is followed by collapse - 1 _looptemp_ clauses for the counts[1] and up, and for triangular loops followed by 4 further _looptemp_ clauses (one for counts[0], one first_inner_iterations, one factor and one adjn1). After this there is optionally one _looptemp_ clause that this function returns.
References omp_for_data::collapse, count, omp_for_data::first_nonrect, gcc_assert, i, omp_for_data::last_nonrect, omp_for_data::loops, omp_for_data::non_rect, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, omp_find_clause(), TREE_TYPE, TYPE_UNSIGNED, and omp_for_data_loop::v.
Referenced by expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), and expand_omp_taskloop_for_outer().
Return phi in E->DEST with ARG on edge E.
References gsi_end_p(), gsi_next(), gsi_start_phis(), NULL, and PHI_ARG_DEF_FROM_EDGE.
Referenced by expand_omp_for_generic(), and expand_omp_for_static_chunk().
|
static |
Release the memory associated with the region tree rooted at REGION.
References free(), free_omp_region_1(), i, omp_region::inner, and omp_region::next.
Referenced by free_omp_region_1(), and omp_free_regions().
Like above but return it in type that can be directly stored as an element of the argument array.
References fold_convert, get_target_argument_identifier_1(), and ptr_type_node.
Referenced by push_target_argument_according_to_value().
Build target argument identifier from the DEVICE identifier, value identifier ID and whether the element also has a SUBSEQUENT_PARAM.
References build_int_cst(), fold_build2, and integer_type_node.
Referenced by get_target_argument_identifier(), and get_target_argument_value().
|
static |
Return a target argument consisting of DEVICE identifier, value identifier ID, and the actual VALUE.
References build_int_cst(), fold_build2, fold_convert, force_gimple_operand_gsi(), get_target_argument_identifier_1(), GSI_SAME_STMT, integer_type_node, NULL, ptr_type_node, and unsigned_type_node.
Referenced by push_target_argument_according_to_value().
|
static |
Create an array of arguments that is then passed to GOMP_target.
References build4(), build_array_type_nelts(), build_fold_addr_expr, build_int_cst(), create_tmp_var, gimple_build_assign(), gimple_omp_target_clauses(), gsi_insert_before(), GSI_SAME_STMT, i, integer_minus_one_node, integer_type_node, null_pointer_node, NULL_TREE, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR, OMP_CLAUSE_THREAD_LIMIT, OMP_CLAUSE_THREAD_LIMIT_EXPR, omp_find_clause(), ptr_type_node, push_target_argument_according_to_value(), and TREE_ADDRESSABLE.
Referenced by expand_omp_target().
|
static |
Collect additional arguments needed to emit a combined parallel+workshare call. WS_STMT is the workshare directive being expanded.
References build_int_cst(), omp_for_data::chunk_size, dyn_cast(), EDGE_COUNT, fold_convert_loc(), omp_for_data::for_stmt, gcc_assert, gcc_unreachable, gimple_bb(), gimple_location(), gimple_omp_for_combined_into_p(), gimple_omp_parallel_clauses(), long_integer_type_node, omp_for_data::loop, omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, omp_adjust_chunk_size(), OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, omp_extract_for_data(), omp_find_clause(), omp_for_data::simd_schedule, single_succ(), omp_for_data_loop::step, basic_block_def::succs, unsigned_type_node, and vec_alloc().
Referenced by determine_parallel_type().
A convenience function to build an empty GIMPLE_COND with just the condition.
References gimple_build_cond(), gimple_cond_get_ops_from_tree(), and NULL_TREE.
Referenced by expand_oacc_for(), expand_omp_atomic_pipeline(), expand_omp_for_generic(), expand_omp_for_ordered_loops(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_ordered_sink(), expand_omp_simd(), expand_omp_target(), expand_omp_taskloop_for_inner(), expand_parallel_call(), and extract_omp_for_update_vars().
|
inlinestatic |
Return true if REGION is a combined parallel+workshare region.
References omp_region::is_combined_parallel.
Referenced by expand_omp_for_generic(), expand_omp_sections(), expand_omp_taskreg(), and expand_parallel_call().
|
static |
Return true is REGION is or is contained within an offload region.
References current_function_decl, DECL_ATTRIBUTES, omp_region::entry, is_gimple_omp(), is_gimple_omp_offloaded(), is_in_offload_region(), last_nondebug_stmt(), lookup_attribute(), NULL, and omp_region::outer.
Referenced by determine_parallel_type(), expand_omp_for_generic(), expand_omp_for_static_chunk(), and is_in_offload_region().
gimple_opt_pass * make_pass_expand_omp | ( | gcc::context * | ctxt | ) |
gimple_opt_pass * make_pass_expand_omp_ssa | ( | gcc::context * | ctxt | ) |
|
static |
Mark the loops inside the kernels region starting at REGION_ENTRY and ending at REGION_EXIT.
References CDI_DOMINATORS, dominated_by_p(), gcc_assert, loop::header, loop::in_oacc_kernels_region, loop::inner, basic_block_def::loop_father, loop_outer(), loop::next, and NULL.
Referenced by expand_omp_target().
|
static |
Create a new parallel region starting at STMT inside region PARENT.
References omp_region::entry, omp_region::inner, omp_region::next, omp_region::outer, root_omp_region, omp_region::type, and type().
Referenced by build_omp_regions_1(), and omp_make_gimple_edges().
Adjust CHUNK_SIZE from SCHEDULE clause, depending on simd modifier presence (SIMD_SCHEDULE).
References build_call_expr_internal_loc(), build_int_cst(), cfun, omp_for_data::chunk_size, fold_build1, fold_build2, fold_convert, integer_zerop(), known_eq, omp_max_vf(), omp_for_data::simd_schedule, TREE_TYPE, UNKNOWN_LOCATION, and unsigned_type_node.
Referenced by expand_omp_for_generic(), expand_omp_for_static_chunk(), and get_ws_args_for().
void omp_expand_local | ( | basic_block | head | ) |
Expands omp construct (and its subconstructs) starting in HEAD.
References build_omp_regions_root(), dump_file, dump_flags, dump_omp_region(), expand_omp(), omp_free_regions(), remove_exit_barriers(), root_omp_region, and TDF_DETAILS.
void omp_free_regions | ( | void | ) |
Release the memory for the entire omp region tree.
References free_omp_region_1(), omp_region::next, NULL, r, and root_omp_region.
Referenced by execute_expand_omp(), make_edges(), and omp_expand_local().
bool omp_make_gimple_edges | ( | basic_block | bb, |
struct omp_region ** | region, | ||
int * | region_idx ) |
Called from tree-cfg.cc::make_edges to create cfg edges for all relevant GIMPLE_* codes.
References omp_region::cont, omp_region::entry, omp_region::exit, gcc_assert, gcc_unreachable, GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_ENTER_DATA, GF_OMP_TARGET_KIND_EXIT_DATA, GF_OMP_TARGET_KIND_OACC_DATA, GF_OMP_TARGET_KIND_OACC_DATA_KERNELS, GF_OMP_TARGET_KIND_OACC_DECLARE, GF_OMP_TARGET_KIND_OACC_ENTER_DATA, GF_OMP_TARGET_KIND_OACC_EXIT_DATA, GF_OMP_TARGET_KIND_OACC_HOST_DATA, GF_OMP_TARGET_KIND_OACC_KERNELS, GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE, GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED, GF_OMP_TARGET_KIND_OACC_SERIAL, GF_OMP_TARGET_KIND_OACC_UPDATE, GF_OMP_TARGET_KIND_REGION, GF_OMP_TARGET_KIND_UPDATE, gimple_omp_ordered_standalone_p(), gimple_omp_target_kind(), gimple_omp_task_taskwait_p(), i, basic_block_def::index, omp_region::inner, last, last_nondebug_stmt(), make_edge(), new_omp_region(), omp_region::next, basic_block_def::next_bb, omp_region::outer, single_succ(), single_succ_edge(), and omp_region::type.
Referenced by make_edges_bb().
|
static |
Translate enum omp_memory_order to enum memmodel for the embedded fail clause in there.
References gcc_unreachable, MEMMODEL_ACQUIRE, MEMMODEL_RELAXED, MEMMODEL_SEQ_CST, OMP_FAIL_MEMORY_ORDER_ACQUIRE, OMP_FAIL_MEMORY_ORDER_MASK, OMP_FAIL_MEMORY_ORDER_RELAXED, OMP_FAIL_MEMORY_ORDER_SEQ_CST, OMP_FAIL_MEMORY_ORDER_UNSPECIFIED, OMP_MEMORY_ORDER_ACQ_REL, OMP_MEMORY_ORDER_ACQUIRE, OMP_MEMORY_ORDER_MASK, OMP_MEMORY_ORDER_RELAXED, OMP_MEMORY_ORDER_RELEASE, and OMP_MEMORY_ORDER_SEQ_CST.
Referenced by expand_omp_atomic_cas(), expand_omp_atomic_pipeline(), and omp_memory_order_to_memmodel().
|
static |
Translate enum omp_memory_order to enum memmodel. The two enums are using different numbers so that OMP_MEMORY_ORDER_UNSPECIFIED is 0 and omp_memory_order has the fail mode encoded in it too.
References gcc_unreachable, MEMMODEL_ACQ_REL, MEMMODEL_ACQUIRE, MEMMODEL_RELAXED, MEMMODEL_RELEASE, MEMMODEL_SEQ_CST, OMP_FAIL_MEMORY_ORDER_MASK, OMP_FAIL_MEMORY_ORDER_UNSPECIFIED, OMP_MEMORY_ORDER_ACQ_REL, OMP_MEMORY_ORDER_ACQUIRE, OMP_MEMORY_ORDER_MASK, OMP_MEMORY_ORDER_RELAXED, OMP_MEMORY_ORDER_RELEASE, OMP_MEMORY_ORDER_SEQ_CST, and omp_memory_order_to_fail_memmodel().
Referenced by expand_omp_atomic_cas(), expand_omp_atomic_fetch_op(), expand_omp_atomic_load(), expand_omp_atomic_pipeline(), and expand_omp_atomic_store().
|
static |
Optimize omp_get_thread_num () and omp_get_num_threads () calls. These can't be declared as const functions, but within one parallel body they are constant, so they can be transformed there into __builtin_omp_get_{thread_num,num_threads} () which are declared const. Similarly for task body, except that in untied task omp_get_thread_num () can change at any task scheduling point.
References builtin_decl_explicit(), cfun, DECL_ASSEMBLER_NAME, DECL_EXTERNAL, DECL_INITIAL, DECL_NAME, FOR_EACH_BB_FN, gimple_call_fndecl(), gimple_call_num_args(), gimple_call_set_fndecl(), gimple_omp_task_clauses(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_gimple_call(), NULL, OMP_CLAUSE_UNTIED, omp_find_clause(), TREE_CODE, TREE_NOTHROW, TREE_PUBLIC, TREE_TYPE, and types_compatible_p().
Referenced by expand_omp_taskreg().
|
static |
If VALUE is an integer constant greater than -2^15 and smaller than 2^15, push one argument to ARGS with both the DEVICE, ID and VALUE embedded in it, otherwise push an identifier (with DEVICE and ID) and the VALUE in two arguments.
References fold_convert, force_gimple_operand_gsi(), get_target_argument_identifier(), get_target_argument_value(), GSI_SAME_STMT, NULL, ptr_type_node, tree_fits_shwi_p(), and tree_to_shwi().
Referenced by get_target_arguments().
|
static |
Remove barriers in REGION->EXIT's block. Note that this is only valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be removed.
References as_a(), BLOCK_SUPERCONTEXT, BLOCK_VARS, DECL_CHAIN, DECL_STRUCT_FUNCTION, omp_region::entry, omp_region::exit, FOR_EACH_EDGE, FOR_EACH_LOCAL_DECL, gcc_assert, gimple_block(), gimple_omp_parallel_child_fn(), gimple_omp_return_nowait_p(), gimple_omp_return_set_nowait(), gsi_end_p(), gsi_last_nondebug_bb(), gsi_prev_nondebug(), gsi_stmt(), last_nondebug_stmt(), basic_block_def::preds, TREE_ADDRESSABLE, and TREE_CODE.
Referenced by remove_exit_barriers().
|
static |
References omp_region::inner, omp_region::next, remove_exit_barrier(), remove_exit_barriers(), and omp_region::type.
Referenced by execute_expand_omp(), omp_expand_local(), and remove_exit_barriers().
Chain all the DECLs in LIST by their TREE_CHAIN fields.
References DECL_CHAIN, FOR_EACH_VEC_SAFE_ELT_REVERSE, and NULL_TREE.
Referenced by expand_omp_target(), and expand_omp_taskreg().
|
static |
Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB is the immediate dominator of PAR_ENTRY_BB, return true if there are no data dependencies that would prevent expanding the parallel directive at PAR_ENTRY_BB as a combined parallel+workshare region. When expanding a combined parallel+workshare region, the call to the child function may need additional arguments in the case of GIMPLE_OMP_FOR regions. In some cases, these arguments are computed out of variables passed in from the parent to the child via 'struct .omp_data_s'. For instance: #pragma omp parallel for schedule (guided, i * 4) for (j ...) Is lowered into: # BLOCK 2 (PAR_ENTRY_BB) .omp_data_o.i = i; #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598) # BLOCK 3 (WS_ENTRY_BB) .omp_data_i = &.omp_data_o; D.1667 = .omp_data_i->i; D.1598 = D.1667 * 4; #pragma omp for schedule (guided, D.1598) When we outline the parallel region, the call to the child function 'bar.omp_fn.0' will need the value D.1598 in its argument list, but that value is computed *after* the call site. So, in principle we cannot do the transformation. To see whether the code in WS_ENTRY_BB blocks the combined parallel+workshare call, we collect all the variables used in the GIMPLE_OMP_FOR header check whether they appear on the LHS of any statement in WS_ENTRY_BB. If so, then we cannot emit the combined call. FIXME. If we had the SSA form built at this point, we could merely hoist the code in block 3 into block 2 and be done with it. But at this point we don't have dataflow information and though we could hack something up here, it is really not worth the aggravation.
References as_a(), omp_for_data::chunk_size, omp_for_data::collapse, gcc_assert, GF_OMP_FOR_KIND_FOR, gimple_omp_for_kind(), is_gimple_min_invariant(), omp_for_data::iter_type, last_nondebug_stmt(), long_integer_type_node, omp_for_data::loop, omp_for_data_loop::n1, omp_for_data_loop::n2, NULL, omp_extract_for_data(), omp_for_data_loop::step, and TREE_CODE.
Referenced by determine_parallel_type().
|
static |
Referenced by expand_omp(), expand_omp_target(), and expand_omp_taskreg().
|
static |