GCC Middle and Back End API Reference
|
Data Structures | |
struct | reduction_info |
struct | reduction_hasher |
struct | name_to_copy_elt |
struct | name_to_copy_hasher |
struct | lambda_trans_matrix_s |
struct | elv_data |
struct | clsn_data |
Typedefs | |
typedef hash_table < reduction_hasher > | reduction_info_table_type |
typedef hash_table < name_to_copy_hasher > | name_to_copy_table_type |
typedef struct lambda_trans_matrix_s * | lambda_trans_matrix |
Variables | |
static bitmap | parallelized_functions |
typedef struct lambda_trans_matrix_s * lambda_trans_matrix |
A transformation matrix, which is a self-contained ROWSIZE x COLSIZE matrix. Rather than use floats, we simply keep a single DENOMINATOR that represents the denominator for every element in the matrix.
int add_field_for_name | ( | ) |
Callback for htab_traverse. Adds a field corresponding to a ssa name described in SLOT. The type is passed in DATA.
References name_to_copy_elt::field, insert_field_into_struct(), and name_to_copy_elt::version.
Referenced by separate_decls_in_region().
int add_field_for_reduction | ( | ) |
Callback for htab_traverse. Adds a field corresponding to the reduction specified in SLOT. The type is passed in DATA.
References reduction_info::field, gimple_assign_lhs(), gimple_location(), insert_field_into_struct(), and reduction_info::reduc_stmt.
Referenced by separate_decls_in_region().
|
static |
Create a reduction_info struct, initialize it with REDUC_STMT and PHI, insert it to the REDUCTION_LIST.
References dump_file, dump_flags, hash_table< Descriptor, Allocator >::find_slot(), gimple_assign_rhs_code(), gimple_phi_result(), print_gimple_stmt(), reduction_info::reduc_phi, reduction_info::reduc_stmt, reduction_info::reduc_version, and reduction_info::reduction_code.
Referenced by gather_scalar_reductions().
|
static |
Create the atomic operation at the join point of the threads. REDUCTION_LIST describes the reductions in the LOOP. LD_ST_DATA describes the shared data structure where shared data is stored in and loaded from.
References create_call_for_reduction_1(), create_phi_for_local_result(), loop::latch, clsn_data::load_bb, and hash_table< Descriptor, Allocator >::traverse().
Referenced by gen_parallel_loop().
int create_call_for_reduction_1 | ( | ) |
Callback for htab_traverse. Create an atomic instruction for the reduction described in SLOT. DATA annotates the place in memory the atomic operation relates to, and the basic block it needs to be generated in.
References build_addr(), create_tmp_var(), current_function_decl, edge_def::dest, reduction_info::field, force_gimple_operand_gsi(), gimple_build_omp_atomic_load(), gimple_build_omp_atomic_store(), GSI_CONTINUE_LINKING, gsi_insert_after(), GSI_NEW_STMT, gsi_start_bb(), clsn_data::load, clsn_data::load_bb, make_ssa_name(), reduction_info::new_phi, reduction_info::reduc_phi, reduction_info::reduction_code, and split_block().
Referenced by create_call_for_reduction().
|
static |
Load the reduction result that was stored in LD_ST_DATA. REDUCTION_LIST describes the list of reductions that the loads should be generated for.
References create_loads_for_reductions(), gsi_after_labels(), gsi_insert_before(), GSI_NEW_STMT, clsn_data::load, clsn_data::load_bb, clsn_data::store, and hash_table< Descriptor, Allocator >::traverse().
Referenced by separate_decls_in_region().
int create_loads_and_stores_for_name | ( | name_to_copy_elt ** | slot, |
struct clsn_data * | clsn_data | ||
) |
Callback for htab_traverse. Creates loads to a field of LOAD in LOAD_BB and store to a field of STORE in STORE_BB for the ssa name and its duplicate specified in SLOT.
References name_to_copy_elt::field, gsi_insert_after(), gsi_last_bb(), GSI_NEW_STMT, clsn_data::load, clsn_data::load_bb, name_to_copy_elt::new_name, clsn_data::store, clsn_data::store_bb, and name_to_copy_elt::version.
Referenced by separate_decls_in_region().
int create_loads_for_reductions | ( | ) |
Callback for htab_traverse. Loads the final reduction value at the join point of all threads, and inserts it in the right place.
References reduction_info::field, gimple_assign_lhs(), gsi_after_labels(), gsi_end_p(), gsi_insert_after(), GSI_NEW_STMT, gsi_next(), gsi_start_phis(), gsi_stmt(), reduction_info::keep_res, clsn_data::load, clsn_data::load_bb, reduction_info::reduc_stmt, and remove_phi_node().
Referenced by create_final_loads_for_reduction().
|
static |
Creates and returns an empty function that will receive the body of a parallelized loop.
References allocate_struct_function(), bitmap_set_bit(), build_function_type_list(), cfun, clean_symbol_name(), current_function_name(), function::decl, get_identifier(), parallelized_functions, set_cfun(), snprintf(), and type().
Referenced by gen_parallel_loop().
|
static |
Create the parallel constructs for LOOP as described in gen_parallel_loop. LOOP_FN and DATA are the arguments of GIMPLE_OMP_PARALLEL. NEW_DATA is the variable that should be initialized from the argument of LOOP_FN. N_THREADS is the requested number of threads. Returns the basic block containing GIMPLE_OMP_PARALLEL tree.
References add_phi_arg(), build_int_cst(), build_omp_clause(), calculate_dominance_info(), CDI_DOMINATORS, copy_ssa_name(), edge_def::dest, extract_true_false_edges_from_block(), edge_def::flags, free_dominance_info(), GF_OMP_FOR_KIND_FOR, gimple_build_omp_continue(), gimple_build_omp_for(), gimple_build_omp_parallel(), gimple_build_omp_return(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_lhs(), gimple_omp_for_set_cond(), gimple_omp_for_set_final(), gimple_omp_for_set_incr(), gimple_omp_for_set_index(), gimple_omp_for_set_initial(), gimple_phi_arg_location_from_edge(), gimple_set_location(), gsi_after_labels(), gsi_end_p(), gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), GSI_NEW_STMT, gsi_next(), gsi_remove(), GSI_SAME_STMT, gsi_start_phis(), gsi_stmt(), loop::header, last_stmt(), loop::latch, loop_latch_edge(), loop_preheader_edge(), make_edge(), make_ssa_name(), OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_SCHEDULE_STATIC, redirect_edge_and_branch(), single_dom_exit(), single_pred(), single_succ_edge(), split_edge(), split_loop_exit_edge(), edge_def::src, and type().
Referenced by gen_parallel_loop().
int create_phi_for_local_result | ( | ) |
Callback for htab_traverse. A local result is the intermediate result computed by a single thread, or the initial value in case no iteration was executed. This function creates a phi node reflecting these values. The phi's result will be stored in NEW_PHI field of the reduction's data structure.
References add_phi_arg(), copy_ssa_name(), create_phi_node(), gimple_assign_lhs(), gimple_location(), reduction_info::init, loop::latch, reduction_info::new_phi, and reduction_info::reduc_stmt.
Referenced by create_call_for_reduction().
int create_stores_for_reduction | ( | ) |
Callback for htab_traverse. Store the neutral value for the particular reduction's operation, e.g. 0 for PLUS_EXPR, 1 for MULT_EXPR, etc. into the reduction field. The reduction is specified in SLOT. The store information is passed in DATA.
References reduction_info::field, gimple_assign_lhs(), gsi_insert_after(), gsi_last_bb(), GSI_NEW_STMT, reduction_info::initial_value, reduction_info::reduc_stmt, clsn_data::store, and clsn_data::store_bb.
Referenced by separate_decls_in_region().
|
static |
Eliminates the references to local variables from the single entry single exit region between the ENTRY and EXIT edges. This includes: 1) Taking address of a local variable -- these are moved out of the region (and temporary variable is created to hold the address if necessary). 2) Dereferencing a local variable -- these are replaced with indirect references.
References hash_table< Descriptor, Allocator >::create(), elv_data::decl_address, edge_def::dest, hash_table< Descriptor, Allocator >::dispose(), eliminate_local_variables_stmt(), gather_blocks_in_sese_region(), gimple_debug_bind_p(), elv_data::gsi, gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_gimple_debug(), and edge_def::src.
Referenced by gen_parallel_loop().
|
static |
Eliminates references to local variables in *TP out of the single entry single exit region starting at DTA->ENTRY. DECL_ADDRESS contains addresses of the references that had their address taken already. If the expression is changed, CHANGED is set to true. Callback for walk_tree.
References build_pointer_type(), elv_data::changed, elv_data::decl_address, elv_data::entry, get_base_address(), elv_data::gsi, is_gimple_val(), elv_data::reset, take_address_of(), and type().
Referenced by eliminate_local_variables_stmt().
|
static |
Moves the references to local variables in STMT at *GSI out of the single entry single exit region starting at ENTRY. DECL_ADDRESS contains addresses of the references that had their address taken already.
References elv_data::changed, elv_data::decl_address, eliminate_local_variables_1(), elv_data::entry, gimple_build_nop(), gimple_clobber_p(), gimple_debug_bind_get_value_ptr(), gimple_debug_bind_p(), gimple_debug_bind_reset_value(), elv_data::gsi, gsi_replace(), gsi_stmt(), elv_data::info, memset(), elv_data::reset, update_stmt(), and walk_gimple_op().
Referenced by eliminate_local_variables().
|
static |
Returns true if expression EXPR is not defined between ENTRY and EXIT, i.e. if all its operands are defined outside of the region.
References CDI_DOMINATORS, edge_def::dest, dominated_by_p(), gimple_bb(), is_gimple_min_invariant(), and edge_def::src.
Referenced by separate_decls_in_region_stmt().
|
static |
Detect all reductions in the LOOP, insert them into REDUCTION_LIST.
References build_new_reduction(), destroy_loop_vec_info(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), loop::header, reduction_info::reduc_stmt, set_reduc_phi_uids(), simple_iv(), hash_table< Descriptor, Allocator >::traverse(), vect_analyze_loop_form(), vect_force_simple_reduction(), and virtual_operand_p().
Referenced by try_create_reduction_list().
|
static |
Generates code to execute the iterations of LOOP in N_THREADS threads in parallel. NITER describes number of iterations of LOOP. REDUCTION_LIST describes the reductions existent in the LOOP.
References build_int_cst(), cancel_loop_tree(), canonicalize_loop_ivs(), create_call_for_reduction(), create_loop_fn(), create_parallel_loop(), hash_table< Descriptor, Allocator >::elements(), eliminate_local_variables(), force_gimple_operand(), free_numbers_of_iterations_estimates_loop(), free_original_copy_tables(), gimple_location(), gsi_insert_seq_on_edge_immediate(), loop::header, initialize_original_copy_tables(), initialize_reductions(), loop::inner, is_gimple_condexpr(), last_stmt(), loop_preheader_edge(), loop_version(), tree_niter_desc::may_be_zero, tree_niter_desc::niter, omp_expand_local(), prob, scev_reset(), separate_decls_in_region(), single_dom_exit(), single_exit(), transform_to_exit_first_loop(), hash_table< Descriptor, Allocator >::traverse(), type(), unshare_expr(), and update_ssa().
Referenced by parallelize_loops().
int initialize_reductions | ( | ) |
Callback for htab_traverse. Create the initialization statement for reduction described in SLOT, and place it at the preheader of the loop described in DATA.
References build_omp_clause(), create_tmp_var(), gimple_assign_lhs(), gimple_location(), reduction_info::init, reduction_info::initial_value, loop_preheader_edge(), OMP_CLAUSE_REDUCTION, omp_reduction_init(), reduction_info::reduc_phi, reduction_info::reduc_stmt, reduction_info::reduction_code, and type().
Referenced by gen_parallel_loop().
|
static |
Multiply a vector VEC by a matrix MAT. MAT is an M*N matrix, and VEC is a vector with length N. The result is stored in DEST which must be a vector of length M.
References lambda_vector_clear().
Referenced by lambda_transform_legal_p().
|
static |
Allocate a new transformation matrix.
References lambda_matrix_new().
Referenced by loop_parallel_p().
|
static |
Return true if TRANS is a legal transformation matrix that respects the dependence vectors in DISTS and DIRS. The conservative answer is false. "Wolfe proves that a unimodular transformation represented by the matrix T is legal when applied to a loop nest with a set of lexicographically non-negative distance vectors RDG if and only if for each vector d in RDG, (T.d >= 0) is lexicographically positive. i.e.: if and only if it transforms the lexicographically positive distance vectors to lexicographically positive vectors. Note that a unimodular matrix must transform the zero vector (and only it) to the zero vector." S.Muchnick.
References chrec_dont_know, chrec_known, DDR_A, DDR_ARE_DEPENDENT, DDR_B, DDR_DIST_VECT, DDR_NUM_DIST_VECTS, DR_IS_READ, lambda_matrix_vector_mult(), lambda_vector_lexico_pos(), and lambda_vector_new().
Referenced by loop_parallel_p().
|
inlinestatic |
Return true when LOOP contains basic blocks marked with the BB_IRREDUCIBLE_LOOP flag.
References free(), get_loop_body_in_dom_order(), and loop::num_nodes.
Referenced by parallelize_loops().
|
static |
Returns true when LOOP contains vector phi nodes.
References free(), get_loop_body_in_dom_order(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), and loop::num_nodes.
Referenced by parallelize_loops().
|
static |
Data dependency analysis. Returns true if the iterations of LOOP are independent on each other (that is, if we can execute them in parallel).
References compute_data_dependences_for_loop(), dump_data_dependence_relations(), dump_file, dump_flags, free_data_refs(), free_dependence_relations(), loop::inner, lambda_trans_matrix_new(), lambda_transform_legal_p(), data_dependence_relation::loop_nest, and loop::num.
Referenced by parallelize_loops().
bool parallelize_loops | ( | void | ) |
Detect parallel loops and generate parallel code using libgomp primitives. Returns true if some loop was parallelized, false otherwise.
References loop::can_be_parallel, can_duplicate_loop_p(), cfun, changed, hash_table< Descriptor, Allocator >::create(), function::decl, hash_table< Descriptor, Allocator >::dispose(), dump_file, dump_flags, hash_table< Descriptor, Allocator >::empty(), gimple_df::escaped, estimated_stmt_executions_int(), find_loop_location(), edge_def::flags, free_stmt_vec_info_vec(), gen_parallel_loop(), function::gimple_df, function::has_nonlocal_label, loop::header, HOST_WIDE_INT, basic_block_def::index, init_stmt_vec_info_vec(), loop::inner, loop_has_blocks_with_irreducible_flag(), loop_has_vector_phi_nodes(), loop_parallel_p(), loop_preheader_edge(), max_stmt_executions_int(), loop::num, obstack, optimize_loop_nest_for_size_p(), parallelized_function_p(), pt_solution_reset(), single_dom_exit(), try_create_reduction_list(), and try_get_loop_niter().
Referenced by tree_parallelize_loops().
bool parallelized_function_p | ( | ) |
Returns true if FN was created by create_loop_fn.
References bitmap_bit_p().
|
staticread |
|
static |
Moves all the variables used in LOOP and defined outside of it (including the initial values of loop phi nodes, and *PER_THREAD if it is a ssa name) to a structure created for this purpose. The code while (1) { use (a); use (b); } is transformed this way: bb0: old.a = a; old.b = b; bb1: a' = new->a; b' = new->b; while (1) { use (a'); use (b'); } `old' is stored to *ARG_STRUCT and `new' is stored to NEW_ARG_STRUCT. The pointer `new' is intentionally not initialized (the loop will be split to a separate function later, and `new' will be initialized from its arguments). LD_ST_DATA holds information about the shared data structure used to pass information among the threads. It is initialized here, and gen_parallel_loop will pass it to create_call_for_reduction that needs this information. REDUCTION_LIST describes the reductions in LOOP.
References add_field_for_name(), add_field_for_reduction(), build_pointer_type(), hash_table< Descriptor, Allocator >::create(), create_final_loads_for_reduction(), create_loads_and_stores_for_name(), create_stores_for_reduction(), create_tmp_var(), create_tmp_var_name(), edge_def::dest, hash_table< Descriptor, Allocator >::dispose(), hash_table< Descriptor, Allocator >::elements(), gather_blocks_in_sese_region(), gsi_end_p(), gsi_next(), gsi_remove(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), hash_table< Descriptor, Allocator >::is_created(), is_gimple_debug(), layout_type(), clsn_data::load, clsn_data::load_bb, make_ssa_name(), lang_hooks_for_types::make_type, separate_decls_in_region_debug(), separate_decls_in_region_stmt(), single_pred(), single_succ_edge(), split_edge(), clsn_data::store, clsn_data::store_bb, hash_table< Descriptor, Allocator >::traverse(), type(), and lang_hooks::types.
Referenced by gen_parallel_loop().
|
static |
Finds the ssa names used in STMT that are defined outside the region between ENTRY and EXIT and replaces such ssa names with their duplicates. The duplicates are stored to NAME_COPIES. Base decls of all ssa names used in STMT (including those defined in LOOP) are replaced with the new temporary variables; the replacement decls are stored in DECL_COPIES.
References hash_table< Descriptor, Allocator >::find_slot_with_hash(), gimple_debug_bind_get_var(), gimple_debug_bind_p(), gimple_debug_bind_reset_value(), gimple_debug_bind_set_var(), gimple_debug_source_bind_get_var(), gimple_debug_source_bind_p(), gimple_debug_source_bind_set_var(), int_tree_map::uid, update_stmt(), and name_to_copy_elt::version.
Referenced by separate_decls_in_region().
|
static |
If COPY_NAME_P is true, creates and returns a duplicate of NAME. The copies are stored to NAME_COPIES, if NAME was already duplicated, its duplicate stored in NAME_COPIES is returned. Regardless of COPY_NAME_P, the decl used as a base of the ssa name is also duplicated, storing the copies in DECL_COPIES.
References copy(), create_tmp_var(), duplicate_ssa_name(), name_to_copy_elt::field, hash_table< Descriptor, Allocator >::find_slot_with_hash(), get_name(), name_to_copy_elt::new_name, replace_ssa_name_symbol(), int_tree_map::to, int_tree_map::uid, and name_to_copy_elt::version.
Referenced by separate_decls_in_region_stmt().
|
static |
Finds the ssa names used in STMT that are defined outside the region between ENTRY and EXIT and replaces such ssa names with their duplicates. The duplicates are stored to NAME_COPIES. Base decls of all ssa names used in STMT (including those defined in LOOP) are replaced with the new temporary variables; the replacement decls are stored in DECL_COPIES.
References copy(), expr_invariant_in_region_p(), and separate_decls_in_region_name().
Referenced by separate_decls_in_region().
int set_reduc_phi_uids | ( | ) |
Callback for htab_traverse. Sets gimple_uid of reduc_phi stmts.
References gimple_set_uid(), reduction_info::reduc_phi, and reduction_info::reduc_version.
Referenced by gather_scalar_reductions().
|
static |
Assigns the address of OBJ in TYPE to an ssa name, and returns this name. The assignment statement is placed on edge ENTRY. DECL_ADDRESS maps decls to their addresses that can be reused. The address of OBJ is known to be invariant in the whole function. Other needed statements are placed right before GSI.
References build_addr(), current_function_decl, hash_table< Descriptor, Allocator >::find_slot_with_hash(), force_gimple_operand(), get_name(), gimple_seq_empty_p(), gsi_insert_on_edge_immediate(), gsi_insert_seq_before(), GSI_SAME_STMT, handled_component_p(), make_ssa_name(), make_temp_ssa_name(), int_tree_map::to, int_tree_map::uid, unshare_expr(), and useless_type_conversion_p().
Referenced by eliminate_local_variables_1().
|
static |
Moves the exit condition of LOOP to the beginning of its header, and duplicates the part of the last iteration that gets disabled to the exit of the loop. NIT is the number of iterations of the loop (used to initialize the variables in the duplicated part). TODO: the common case is that latch of the loop is empty and immediately follows the loop exit. In this case, it would be better not to copy the body of the loop, but only move the entry of the loop directly before the exit check and increase the number of iterations of the loop by one. This may need some additional preconditioning in case NIT = ~0. REDUCTION_LIST describes the reductions in LOOP.
References add_phi_arg(), copy_ssa_name(), create_phi_node(), hash_table< Descriptor, Allocator >::elements(), force_gimple_operand_gsi(), free(), get_loop_body_in_dom_order(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_lhs(), gimple_duplicate_sese_tail(), gsi_after_labels(), gsi_end_p(), gsi_insert_before(), GSI_NEW_STMT, gsi_next(), GSI_SAME_STMT, gsi_start_phis(), gsi_stmt(), loop::header, reduction_info::keep_res, last_stmt(), reduction_phi(), remove_phi_node(), single_dom_exit(), single_succ(), single_succ_edge(), split_block_after_labels(), edge_def::src, update_stmt(), and virtual_operand_p().
Referenced by gen_parallel_loop().
|
static |
Try to initialize REDUCTION_LIST for code generation part. REDUCTION_LIST describes the reductions.
References edge_def::dest, dump_file, dump_flags, hash_table< Descriptor, Allocator >::elements(), flow_bb_inside_loop_p(), gather_scalar_reductions(), gimple_debug_bind_p(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), loop::header, print_generic_expr(), print_gimple_stmt(), reduction_info::reduc_phi, reduction_info::reduc_stmt, reduction_phi(), simple_iv(), single_dom_exit(), and virtual_operand_p().
Referenced by parallelize_loops().
|
static |
Try to initialize NITER for code generation part.
References dump_file, dump_flags, number_of_iterations_exit(), and single_dom_exit().
Referenced by parallelize_loops().
|
static |
Bitmap containing uids of functions created by parallelization. We cannot allocate it from the default obstack, as it must live across compilation of several functions; we make it gc allocated instead.
Referenced by create_loop_fn().