GCC Middle and Back End API Reference
tree-parloops.c File 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

Functions

static struct reduction_inforeduction_phi ()
static lambda_trans_matrix lambda_trans_matrix_new (int colsize, int rowsize, struct obstack *lambda_obstack)
static void lambda_matrix_vector_mult (lambda_matrix matrix, int m, int n, lambda_vector vec, lambda_vector dest)
static bool lambda_transform_legal_p (lambda_trans_matrix trans, int nb_loops, vec< ddr_p > dependence_relations)
static bool loop_parallel_p ()
static bool loop_has_blocks_with_irreducible_flag ()
static tree take_address_of (tree obj, tree type, edge entry, int_tree_htab_type decl_address, gimple_stmt_iterator *gsi)
int initialize_reductions ()
static tree eliminate_local_variables_1 ()
static void eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi, int_tree_htab_type decl_address)
static void eliminate_local_variables ()
static bool expr_invariant_in_region_p ()
static tree separate_decls_in_region_name (tree name, name_to_copy_table_type name_copies, int_tree_htab_type decl_copies, bool copy_name_p)
static void separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt, name_to_copy_table_type name_copies, int_tree_htab_type decl_copies)
static bool separate_decls_in_region_debug (gimple stmt, name_to_copy_table_type name_copies, int_tree_htab_type decl_copies)
int add_field_for_reduction ()
int add_field_for_name ()
int create_phi_for_local_result ()
int create_call_for_reduction_1 ()
static void create_call_for_reduction (struct loop *loop, reduction_info_table_type reduction_list, struct clsn_data *ld_st_data)
int create_loads_for_reductions ()
static void create_final_loads_for_reduction (reduction_info_table_type reduction_list, struct clsn_data *ld_st_data)
int create_stores_for_reduction ()
int create_loads_and_stores_for_name (name_to_copy_elt **slot, struct clsn_data *clsn_data)
static void separate_decls_in_region (edge entry, edge exit, reduction_info_table_type reduction_list, tree *arg_struct, tree *new_arg_struct, struct clsn_data *ld_st_data)
bool parallelized_function_p ()
static tree create_loop_fn ()
static void transform_to_exit_first_loop (struct loop *loop, reduction_info_table_type reduction_list, tree nit)
static basic_block create_parallel_loop (struct loop *loop, tree loop_fn, tree data, tree new_data, unsigned n_threads, location_t loc)
static void gen_parallel_loop (struct loop *loop, reduction_info_table_type reduction_list, unsigned n_threads, struct tree_niter_desc *niter)
static bool loop_has_vector_phi_nodes ()
static void build_new_reduction (reduction_info_table_type reduction_list, gimple reduc_stmt, gimple phi)
int set_reduc_phi_uids ()
static void gather_scalar_reductions ()
static bool try_get_loop_niter ()
static bool try_create_reduction_list (loop_p loop, reduction_info_table_type reduction_list)
bool parallelize_loops ()

Variables

static bitmap parallelized_functions

Typedef Documentation

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.   

Function Documentation

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 void build_new_reduction ( reduction_info_table_type  reduction_list,
gimple  reduc_stmt,
gimple  phi 
)
static
static void create_call_for_reduction ( struct loop loop,
reduction_info_table_type  reduction_list,
struct clsn_data ld_st_data 
)
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 void create_final_loads_for_reduction ( reduction_info_table_type  reduction_list,
struct clsn_data ld_st_data 
)
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 tree create_loop_fn ( )
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 basic_block create_parallel_loop ( struct loop loop,
tree  loop_fn,
tree  data,
tree  new_data,
unsigned  n_threads,
location_t  loc 
)
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 void eliminate_local_variables ( )
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 tree eliminate_local_variables_1 ( )
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 void eliminate_local_variables_stmt ( edge  entry,
gimple_stmt_iterator gsi,
int_tree_htab_type  decl_address 
)
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 bool expr_invariant_in_region_p ( )
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().

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 void lambda_matrix_vector_mult ( lambda_matrix  matrix,
int  m,
int  n,
lambda_vector  vec,
lambda_vector  dest 
)
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 lambda_trans_matrix lambda_trans_matrix_new ( int  colsize,
int  rowsize,
struct obstack lambda_obstack 
)
static
Allocate a new transformation matrix.   

References lambda_matrix_new().

Referenced by loop_parallel_p().

static bool lambda_transform_legal_p ( lambda_trans_matrix  trans,
int  nb_loops,
vec< ddr_p dependence_relations 
)
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().

static bool loop_has_blocks_with_irreducible_flag ( )
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 bool loop_has_vector_phi_nodes ( )
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 bool loop_parallel_p ( )
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 parallelized_function_p ( )
Returns true if FN was created by create_loop_fn.   

References bitmap_bit_p().

static void separate_decls_in_region ( edge  entry,
edge  exit,
reduction_info_table_type  reduction_list,
tree arg_struct,
tree new_arg_struct,
struct clsn_data ld_st_data 
)
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 bool separate_decls_in_region_debug ( gimple  stmt,
name_to_copy_table_type  name_copies,
int_tree_htab_type  decl_copies 
)
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 tree separate_decls_in_region_name ( tree  name,
name_to_copy_table_type  name_copies,
int_tree_htab_type  decl_copies,
bool  copy_name_p 
)
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 void separate_decls_in_region_stmt ( edge  entry,
edge  exit,
gimple  stmt,
name_to_copy_table_type  name_copies,
int_tree_htab_type  decl_copies 
)
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 tree take_address_of ( tree  obj,
tree  type,
edge  entry,
int_tree_htab_type  decl_address,
gimple_stmt_iterator gsi 
)
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 void transform_to_exit_first_loop ( struct loop loop,
reduction_info_table_type  reduction_list,
tree  nit 
)
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 bool try_get_loop_niter ( )
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().


Variable Documentation

bitmap parallelized_functions
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().