GCC Middle and Back End API Reference
trans-mem.c File Reference

Data Structures

struct  diagnose_tm
struct  tm_log_entry
struct  log_entry_hasher
struct  tm_new_mem_map
struct  tm_mem_map_hasher
struct  tm_region
struct  bb2reg_stuff
struct  tm_memop
struct  tm_memop_hasher
struct  tm_memopt_bitmaps
struct  tm_ipa_cg_data
struct  create_version_alias_info

Typedefs

typedef struct tm_log_entrytm_log_entry_t
typedef struct tm_new_mem_map tm_new_mem_map_t
typedef struct tm_regiontm_region_p
typedef struct tm_memoptm_memop_t
typedef vec< cgraph_node_ptrcgraph_node_queue

Enumerations

enum  thread_memory_type { mem_non_local = 0, mem_thread_local, mem_transaction_local, mem_max }

Functions

static void * expand_regions (struct tm_region *, void *(*callback)(struct tm_region *, void *), void *, bool)
static tree get_attrs_for ()
bool is_tm_pure ()
static bool is_tm_irrevocable ()
bool is_tm_safe ()
static bool is_tm_pure_call ()
static bool is_tm_callable ()
bool is_tm_may_cancel_outer ()
bool is_tm_ending_fndecl ()
static bool is_tm_load ()
static bool is_tm_simple_load ()
static bool is_tm_store ()
static bool is_tm_simple_store ()
static bool is_tm_abort ()
tree build_tm_abort_call ()
static bool gate_tm ()
void record_tm_replacement ()
static tree find_tm_replacement_function ()
void tm_malloc_replacement ()
static bool volatile_var_p ()
static tree diagnose_tm_1_op (tree *tp, int *walk_subtrees, void *data)
static tree diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *wi)
static unsigned int diagnose_tm_blocks ()
gimple_opt_passmake_pass_diagnose_tm_blocks ()
static void tm_log_init ()
static void tm_log_delete ()
static bool transaction_invariant_address_p ()
static void tm_log_add ()
static tree gimplify_addr ()
static void tm_log_emit_stmt ()
static void tm_log_emit ()
static void tm_log_emit_saves ()
static void tm_log_emit_restores ()
static tree lower_sequence_tm (gimple_stmt_iterator *, bool *, struct walk_stmt_info *)
static tree lower_sequence_no_tm (gimple_stmt_iterator *, bool *, struct walk_stmt_info *)
static enum thread_memory_type thread_private_new_memory ()
static bool requires_barrier ()
static void examine_assign_tm ()
static void examine_call_tm ()
static void lower_transaction ()
static unsigned int execute_lower_tm ()
gimple_opt_passmake_pass_lower_tm ()
static struct tm_regiontm_region_init_0 ()
static struct tm_regiontm_region_init_1 ()
static void tm_region_init ()
static bool gate_tm_init ()
gimple_opt_passmake_pass_tm_init ()
static void transaction_subcode_ior ()
static gimple build_tm_load ()
static gimple build_tm_store ()
static void expand_assign_tm ()
static bool expand_call_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
static void expand_block_tm ()
static vec< basic_blockget_tm_region_blocks (basic_block entry_block, bitmap exit_blocks, bitmap irr_blocks, bitmap all_region_blocks, bool stop_at_irrevocable_p, bool include_uninstrumented_p=true)
static void * collect_bb2reg ()
static vec< tm_region_pget_bb_regions_instrumented (bool traverse_clones, bool include_uninstrumented_p)
void compute_transaction_bits ()
static void * expand_transaction ()
static void * generate_tm_state ()
static void propagate_tm_flags_out ()
static unsigned int execute_tm_mark ()
gimple_opt_passmake_pass_tm_mark ()
static void split_bb_make_tm_edge (gimple stmt, basic_block dest_bb, gimple_stmt_iterator iter, gimple_stmt_iterator *pnext)
static void expand_block_edges ()
static unsigned int execute_tm_edges ()
gimple_opt_passmake_pass_tm_edges ()
static void * expand_regions_1 (struct tm_region *region, void *(*callback)(struct tm_region *, void *), void *data, bool traverse_clones)
static unsigned int tm_memopt_value_number ()
static void tm_memopt_accumulate_memops ()
static void dump_tm_memopt_set ()
static void dump_tm_memopt_sets ()
static void tm_memopt_compute_avin ()
static void tm_memopt_compute_antin ()
static void tm_memopt_compute_available (struct tm_region *region, vec< basic_block > blocks)
static void tm_memopt_compute_antic (struct tm_region *region, vec< basic_block > blocks)
static void dump_tm_memopt_transform ()
static void tm_memopt_transform_stmt (unsigned int offset, gimple stmt, gimple_stmt_iterator *gsi)
static void tm_memopt_transform_blocks ()
static struct tm_memopt_bitmapstm_memopt_init_sets ()
static void tm_memopt_free_sets ()
static void tm_memopt_clear_visited ()
static unsigned int execute_tm_memopt ()
static bool gate_tm_memopt ()
gimple_opt_passmake_pass_tm_memopt ()
static struct tm_ipa_cg_dataget_cg_data ()
static void maybe_push_queue (struct cgraph_node *node, cgraph_node_queue *queue_p, bool *in_queue_p)
static void ipa_uninstrument_transaction (struct tm_region *region, vec< basic_block > queue)
static void ipa_tm_scan_calls_block (cgraph_node_queue *callees_p, basic_block bb, bool for_clone)
static void ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d, cgraph_node_queue *callees_p)
static void ipa_tm_scan_calls_clone (struct cgraph_node *node, cgraph_node_queue *callees_p)
static void ipa_tm_note_irrevocable (struct cgraph_node *node, cgraph_node_queue *worklist_p)
static bool ipa_tm_scan_irr_block ()
static bool ipa_tm_scan_irr_blocks (vec< basic_block > *pqueue, bitmap new_irr, bitmap old_irr, bitmap exit_blocks)
static void ipa_tm_propagate_irr (basic_block entry_block, bitmap new_irr, bitmap old_irr, bitmap exit_blocks)
static void ipa_tm_decrement_clone_counts ()
static bool ipa_tm_scan_irr_function ()
static bool ipa_tm_mayenterirr_function ()
static void ipa_tm_diagnose_tm_safe ()
static void ipa_tm_diagnose_transaction (struct cgraph_node *node, struct tm_region *all_tm_regions)
static tree tm_mangle ()
static void ipa_tm_mark_force_output_node ()
static void ipa_tm_mark_forced_by_abi_node ()
static bool ipa_tm_create_version_alias ()
static void ipa_tm_create_version ()
static void ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region, basic_block bb)
static bool ipa_tm_insert_gettmclone_call (struct cgraph_node *node, struct tm_region *region, gimple_stmt_iterator *gsi, gimple stmt)
static void ipa_tm_transform_calls_redirect (struct cgraph_node *node, struct tm_region *region, gimple_stmt_iterator *gsi, bool *need_ssa_rename_p)
static bool ipa_tm_transform_calls_1 (struct cgraph_node *node, struct tm_region *region, basic_block bb, bitmap irr_blocks)
static bool ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region, basic_block bb, bitmap irr_blocks)
static void ipa_tm_transform_transaction ()
static void ipa_tm_transform_clone ()
static unsigned int ipa_tm_execute ()
simple_ipa_opt_passmake_pass_ipa_tm ()

Variables

static htab_t tm_wrap_map
static hash_table
< log_entry_hasher
tm_log
static vec< treetm_log_save_addresses
static hash_table
< tm_mem_map_hasher
tm_new_mem_hash
bool pending_edge_inserts_p
static struct tm_regionall_tm_regions
static bitmap_obstack tm_obstack
static bitmap_obstack tm_memopt_obstack
static unsigned int tm_memopt_value_id
static hash_table
< tm_memop_hasher
tm_memopt_value_numbers

Typedef Documentation

typedef struct tm_log_entry * tm_log_entry_t
Instead of instrumenting thread private memory, we save the
   addresses in a log which we later use to save/restore the addresses
   upon transaction start/restart.

   The log is keyed by address, where each element contains individual
   statements among different code paths that perform the store.

   This log is later used to generate either plain save/restore of the
   addresses upon transaction start/restart, or calls to the ITM_L*
   logging functions.

   So for something like:

       struct large { int x[1000]; };
       struct large lala = { 0 };
       __transaction {
         lala.x[i] = 123;
         ...
       }

   We can either save/restore:

       lala = { 0 };
       trxn = _ITM_startTransaction ();
       if (trxn & a_saveLiveVariables)
         tmp_lala1 = lala.x[i];
       else if (a & a_restoreLiveVariables)
         lala.x[i] = tmp_lala1;

   or use the logging functions:

       lala = { 0 };
       trxn = _ITM_startTransaction ();
       _ITM_LU4 (&lala.x[i]);

   Obviously, if we use _ITM_L* to log, we prefer to call _ITM_L* as
   far up the dominator tree to shadow all of the writes to a given
   location (thus reducing the total number of logging calls), but not
   so high as to be called on a path that does not perform a
   write.   
One individual log entry.  We may have multiple statements for the
   same location if neither dominate each other (on different
   execution paths).   
typedef struct tm_memop * tm_memop_t
A unique TM memory operation.   
typedef struct tm_region* tm_region_p

Enumeration Type Documentation

Enumerator:
mem_non_local 
mem_thread_local 
mem_transaction_local 
mem_max 

Function Documentation

tree build_tm_abort_call ( )
Build a GENERIC tree for a user abort.  This is called by front ends
   while transforming the __tm_abort statement.   

References build_call_expr_loc(), build_int_cst(), and builtin_decl_explicit().

static gimple build_tm_load ( )
static
Construct a memory load in a transactional context.  Return the
   gimple statement performing the load, or NULL if there is no
   TM_LOAD builtin of the appropriate size to do the load.

   LOC is the location to use for the new statement(s).   

References builtin_decl_explicit(), create_tmp_reg(), END_BUILTINS, g, gimple_build_call(), gimple_call_set_lhs(), gimple_set_location(), gimplify_addr(), gsi_insert_before(), GSI_SAME_STMT, host_integerp(), targetm, tree_low_cst(), and useless_type_conversion_p().

Referenced by expand_assign_tm().

void compute_transaction_bits ( void  )
Set the IN_TRANSACTION for all gimple statements that appear in a
   transaction.   

References bitmap_obstack_release(), tm_region::entry_block, tm_region::exit_blocks, basic_block_def::flags, gate_tm_init(), get_tm_region_blocks(), tm_region::irr_blocks, tm_region::next, and queue.

Referenced by tree_ssa_lim_initialize().

static tree diagnose_tm_1_op ( tree tp,
int *  walk_subtrees,
void *  data 
)
static
static void dump_tm_memopt_set ( )
static
Prettily dump one of the memopt sets.  BITS is the bitmap to dump.   

References tm_memop::addr, dump_file, print_generic_expr(), tm_memopt_value_numbers, and tm_memop::value_id.

Referenced by dump_tm_memopt_sets().

static void dump_tm_memopt_sets ( )
static
Prettily dump all of the memopt sets in BLOCKS.   

References dump_file, dump_tm_memopt_set(), and basic_block_def::index.

Referenced by tm_memopt_compute_antic(), and tm_memopt_compute_available().

static void dump_tm_memopt_transform ( )
static
Inform about a load/store optimization.   

References dump_file, and print_gimple_stmt().

Referenced by tm_memopt_transform_stmt().

static void examine_assign_tm ( )
static
Mark the GIMPLE_ASSIGN statement as appropriate for being inside
   a transaction region.   

References gimple_assign_lhs(), gimple_assign_rhs1(), gsi_stmt(), and requires_barrier().

Referenced by lower_sequence_tm().

static void examine_call_tm ( )
static
Mark a GIMPLE_CALL as appropriate for being inside a transaction.   

References gimple_call_fndecl(), gsi_stmt(), is_tm_abort(), and is_tm_pure_call().

Referenced by lower_sequence_tm().

static unsigned int execute_lower_tm ( )
static
Main entry point for flattening GIMPLE_TRANSACTION constructs.  After
   this, GIMPLE_TRANSACTION nodes still exist, but the nested body has
   been moved out, and all the data required for constructing a proper
   CFG has been recorded.   

References current_function_decl, decl_is_tm_clone(), gimple_body(), gimple_set_body(), lower_sequence_no_tm(), memset(), and walk_gimple_seq_mod().

static unsigned int execute_tm_edges ( )
static
Entry point to the final expansion of transactional nodes.  

References bitmap_obstack_release(), CDI_DOMINATORS, expand_block_edges(), free_dominance_info(), and get_bb_regions_instrumented().

static unsigned int execute_tm_mark ( )
static
Entry point to the MARK phase of TM expansion.  Here we replace
   transactional memory statements with calls to builtins, and function
   calls with their transactional clones (if available).  But we don't
   yet lower GIMPLE_TRANSACTION or add the transaction restart back-edges.   

References CDI_DOMINATORS, expand_block_tm(), expand_regions(), expand_transaction(), free_dominance_info(), generate_tm_state(), get_bb_regions_instrumented(), gimple_transaction_subcode(), gsi_commit_edge_inserts(), propagate_tm_flags_out(), tm_log_delete(), tm_log_emit(), tm_log_init(), and tm_region::transaction_stmt.

static void expand_block_edges ( )
static
static void expand_block_tm ( )
static
Expand all statements in BB as appropriate for being inside
   a transaction.   

References expand_assign_tm(), expand_call_tm(), gimple_assign_single_p(), gimple_clobber_p(), gsi_end_p(), gsi_next(), gsi_start_bb(), and gsi_stmt().

Referenced by execute_tm_mark().

static void * expand_regions ( struct tm_region region,
void *(*)(struct tm_region *, void *)  callback,
void *  data,
bool  traverse_clones 
)
static
The representation of a transaction changes several times during the
   lowering process.  In the beginning, in the front-end we have the
   GENERIC tree TRANSACTION_EXPR.  For example,

        __transaction {
          local++;
          if (++global == 10)
            __tm_abort;
        }

  During initial gimplification (gimplify.c) the TRANSACTION_EXPR node is
  trivially replaced with a GIMPLE_TRANSACTION node.

  During pass_lower_tm, we examine the body of transactions looking
  for aborts.  Transactions that do not contain an abort may be
  merged into an outer transaction.  We also add a TRY-FINALLY node
  to arrange for the transaction to be committed on any exit.

  [??? Think about how this arrangement affects throw-with-commit
  and throw-with-abort operations.  In this case we want the TRY to
  handle gotos, but not to catch any exceptions because the transaction
  will already be closed.]

        GIMPLE_TRANSACTION [label=NULL] {
          try {
            local = local + 1;
            t0 = global;
            t1 = t0 + 1;
            global = t1;
            if (t1 == 10)
              __builtin___tm_abort ();
          } finally {
            __builtin___tm_commit ();
          }
        }

  During pass_lower_eh, we create EH regions for the transactions,
  intermixed with the regular EH stuff.  This gives us a nice persistent
  mapping (all the way through rtl) from transactional memory operation
  back to the transaction, which allows us to get the abnormal edges
  correct to model transaction aborts and restarts:

        GIMPLE_TRANSACTION [label=over]
        local = local + 1;
        t0 = global;
        t1 = t0 + 1;
        global = t1;
        if (t1 == 10)
          __builtin___tm_abort ();
        __builtin___tm_commit ();
        over:

  This is the end of all_lowering_passes, and so is what is present
  during the IPA passes, and through all of the optimization passes.

  During pass_ipa_tm, we examine all GIMPLE_TRANSACTION blocks in all
  functions and mark functions for cloning.

  At the end of gimple optimization, before exiting SSA form,
  pass_tm_edges replaces statements that perform transactional
  memory operations with the appropriate TM builtins, and swap
  out function calls with their transactional clones.  At this
  point we introduce the abnormal transaction restart edges and
  complete lowering of the GIMPLE_TRANSACTION node.

        x = __builtin___tm_start (MAY_ABORT);
        eh_label:
        if (x & abort_transaction)
          goto over;
        local = local + 1;
        t0 = __builtin___tm_load (global);
        t1 = t0 + 1;
        __builtin___tm_store (&global, t1);
        if (t1 == 10)
          __builtin___tm_abort ();
        __builtin___tm_commit ();
        over:
Traverse the regions enclosed and including REGION.  Execute
   CALLBACK for each region, passing DATA.  CALLBACK returns NULL to
   continue the traversal, otherwise a non-null value which this
   function will return as well.  TRAVERSE_CLONES is true if we should
   traverse transactional clones.   

References expand_regions_1(), and tm_region::next.

Referenced by execute_tm_mark(), expand_regions_1(), and get_bb_regions_instrumented().

static void* expand_regions_1 ( struct tm_region region,
void *(*)(struct tm_region *, void *)  callback,
void *  data,
bool  traverse_clones 
)
static
Helper function for expand_regions.  Expand REGION and recurse to
   the inner region.  Call CALLBACK on each region.  CALLBACK returns
   NULL to continue the traversal, otherwise a non-null value which
   this function will return as well.  TRAVERSE_CLONES is true if we
   should traverse transactional clones.   

References current_function_decl, decl_is_tm_clone(), tm_region::exit_blocks, expand_regions(), and tm_region::inner.

Referenced by expand_regions().

static bool gate_tm ( )
static
Common gateing function for several of the TM passes.   
static bool gate_tm_init ( )
static
The "gate" function for all transactional memory expansion and optimization
   passes.  We collect region information for each top-level transaction, and
   if we don't find any, we skip all of the TM passes.  Each region will have
   all of the exit blocks recorded, and the originating statement.   

References bitmap_obstack_initialize(), bitmap_obstack_release(), calculate_dominance_info(), CDI_DOMINATORS, current_function_decl, decl_is_tm_clone(), tm_region::entry_block, tm_region::irr_blocks, memset(), bitmap_obstack::obstack, single_succ(), and tm_region_init().

Referenced by compute_transaction_bits().

static bool gate_tm_memopt ( )
static
static void* generate_tm_state ( )
static
Generate the temporary to be used for the return value of
   BUILT_IN_TM_START.   

References builtin_decl_explicit(), create_tmp_reg(), tm_region::exit_blocks, gimple_transaction_set_subcode(), gimple_transaction_subcode(), tm_region::tm_state, and tm_region::transaction_stmt.

Referenced by execute_tm_mark().

static tree get_attrs_for ( )
static
Return the attributes we want to examine for X, or NULL if it's not
   something we examine.  We look at function types, but allow pointers
   to function types and function decls and peek through.   

Referenced by is_tm_callable(), is_tm_irrevocable(), is_tm_may_cancel_outer(), and is_tm_safe().

static vec<tm_region_p> get_bb_regions_instrumented ( bool  traverse_clones,
bool  include_uninstrumented_p 
)
static
static struct tm_ipa_cg_data* get_cg_data ( )
staticread
static vec<basic_block> get_tm_region_blocks ( basic_block  entry_block,
bitmap  exit_blocks,
bitmap  irr_blocks,
bitmap  all_region_blocks,
bool  stop_at_irrevocable_p,
bool  include_uninstrumented_p = true 
)
static
Return the list of basic-blocks in REGION.

   STOP_AT_IRREVOCABLE_P is true if caller is uninterested in blocks
   following a TM_IRREVOCABLE call.

   INCLUDE_UNINSTRUMENTED_P is TRUE if we should include the
   uninstrumented code path blocks in the list of basic blocks
   returned, false otherwise.   

References bitmap_bit_p(), bitmap_ior_into(), bitmap_set_bit(), edge_def::dest, edge_def::flags, basic_block_def::index, basic_block_def::succs, and vNULL.

Referenced by collect_bb2reg(), compute_transaction_bits(), execute_tm_memopt(), ipa_tm_diagnose_transaction(), ipa_tm_propagate_irr(), and ipa_tm_scan_calls_transaction().

static tree gimplify_addr ( )
static
Gimplify the address of a TARGET_MEM_REF.  Return the SSA_NAME
   result, insert the new statements before GSI.   

References build_pointer_type(), force_gimple_operand_gsi(), GSI_SAME_STMT, and tree_mem_ref_addr().

Referenced by build_tm_load(), build_tm_store(), expand_assign_tm(), and tm_log_emit_stmt().

static void ipa_tm_diagnose_tm_safe ( )
static
Diagnose calls from transaction_safe functions to unmarked
   functions that are determined to not be safe.   

References cgraph_edge::call_stmt, cgraph_edge::callee, cgraph_node::callees, symtab_node_base::decl, error_at(), gimple_location(), is_tm_callable(), cgraph_node::local, cgraph_edge::next_callee, cgraph_node::symbol, and cgraph_local_info::tm_may_enter_irr.

Referenced by ipa_tm_execute().

static unsigned int ipa_tm_execute ( )
static
Main entry point for the transactional memory IPA pass.   

References symtab_node_base::alias, cgraph_thunk_info::alias, tm_ipa_cg_data::all_tm_regions, symtab_node_base::analyzed, symtab_node_base::aux, AVAIL_AVAILABLE, AVAIL_NOT_AVAILABLE, AVAIL_OVERWRITABLE, bitmap_obstack_initialize(), bitmap_obstack_release(), calculate_dominance_info(), cgraph_edge::caller, cgraph_node::callers, CDI_DOMINATORS, cgraph(), cgraph_function_body_availability(), cgraph_get_node(), tm_ipa_cg_data::clone, symtab_node_base::cpp_implicit_alias, symtab_node_base::decl, free_original_copy_tables(), get_cg_data(), tm_ipa_cg_data::in_callee_queue, tm_ipa_cg_data::in_worklist, initialize_original_copy_tables(), IPA_REF_ALIAS, ipa_tm_create_version(), ipa_tm_diagnose_tm_safe(), ipa_tm_diagnose_transaction(), ipa_tm_mayenterirr_function(), ipa_tm_note_irrevocable(), ipa_tm_scan_calls_clone(), ipa_tm_scan_calls_transaction(), ipa_tm_scan_irr_function(), ipa_tm_transform_clone(), ipa_tm_transform_transaction(), tm_ipa_cg_data::is_irrevocable, is_tm_callable(), is_tm_irrevocable(), is_tm_pure(), is_tm_safe(), is_tm_safe_or_pure(), cgraph_local_info::local, cgraph_node::local, cgraph_node::lowered, maybe_push_queue(), cgraph_edge::next_caller, pop_cfun(), push_cfun(), record_tm_clone_pair(), symtab_node_base::ref_list, ipa_ref::referring, cgraph_node::symbol, cgraph_node::thunk, tm_ipa_cg_data::tm_callers_clone, tm_ipa_cg_data::tm_callers_normal, cgraph_local_info::tm_may_enter_irr, tm_region_init(), tree_versionable_function_p(), verify_cgraph(), and tm_ipa_cg_data::want_irr_scan_normal.

static void ipa_tm_insert_irr_call ( struct cgraph_node node,
struct tm_region region,
basic_block  bb 
)
static
static void ipa_tm_mark_force_output_node ( )
inlinestatic
static void ipa_tm_mark_forced_by_abi_node ( )
inlinestatic
static void ipa_tm_note_irrevocable ( struct cgraph_node node,
cgraph_node_queue worklist_p 
)
static
static void ipa_tm_propagate_irr ( basic_block  entry_block,
bitmap  new_irr,
bitmap  old_irr,
bitmap  exit_blocks 
)
static
Propagate the irrevocable property both up and down the dominator tree.
   BB is the current block being scanned; EXIT_BLOCKS are the edges of the
   TM regions; OLD_IRR are the results of a previous scan of the dominator
   tree which has been fully propagated; NEW_IRR is the set of new blocks
   which are gaining the irrevocable property during the current scan.   

References bitmap_bit_p(), bitmap_set_bit(), CDI_DOMINATORS, edge_def::dest, first_dom_son(), get_tm_region_blocks(), basic_block_def::index, next_dom_son(), and basic_block_def::succs.

Referenced by ipa_tm_scan_irr_function().

static void ipa_tm_scan_calls_block ( cgraph_node_queue callees_p,
basic_block  bb,
bool  for_clone 
)
static
static void ipa_tm_scan_calls_clone ( struct cgraph_node node,
cgraph_node_queue callees_p 
)
static
Scan all calls in NODE as if this is the transactional clone,
   and push the destinations into the callee queue.   

References symtab_node_base::decl, ipa_tm_scan_calls_block(), and cgraph_node::symbol.

Referenced by ipa_tm_execute().

static void ipa_tm_scan_calls_transaction ( struct tm_ipa_cg_data d,
cgraph_node_queue callees_p 
)
static
static bool ipa_tm_scan_irr_blocks ( vec< basic_block > *  pqueue,
bitmap  new_irr,
bitmap  old_irr,
bitmap  exit_blocks 
)
static
For each of the blocks seeded witin PQUEUE, walk the CFG looking
   for new irrevocable blocks, marking them in NEW_IRR.  Don't bother
   scanning past OLD_IRR or EXIT_BLOCKS.   

References bitmap_bit_p(), bitmap_set_bit(), edge_def::dest, basic_block_def::index, ipa_tm_scan_irr_block(), and basic_block_def::succs.

Referenced by ipa_tm_scan_irr_function().

static bool ipa_tm_scan_irr_function ( )
static
(Re-)Scan the transaction blocks in NODE for calls to irrevocable functions,
   as well as other irrevocable actions such as inline assembly.  Mark all
   such blocks as irrevocable and decrement the number of calls to
   transactional clones.  Return true if, for the transactional clone, the
   entire function is irrevocable.   

References tm_ipa_cg_data::all_tm_regions, bitmap_bit_p(), bitmap_empty_p(), bitmap_ior_into(), calculate_dominance_info(), CDI_DOMINATORS, current_function_decl, symtab_node_base::decl, lang_hooks::decl_printable_name, dump_file, tm_region::entry_block, tm_region::exit_blocks, get_cg_data(), ipa_tm_decrement_clone_counts(), ipa_tm_propagate_irr(), ipa_tm_scan_irr_blocks(), tm_ipa_cg_data::irrevocable_blocks_clone, tm_ipa_cg_data::irrevocable_blocks_normal, tm_region::next, pop_cfun(), push_cfun(), queue, single_succ(), and cgraph_node::symbol.

Referenced by ipa_tm_execute().

static bool ipa_tm_transform_calls ( struct cgraph_node node,
struct tm_region region,
basic_block  bb,
bitmap  irr_blocks 
)
static
Walk the CFG for REGION, beginning at BB.  Install calls to
   tm_irrevocable when IRR_BLOCKS are reached, redirect other calls to
   the generated transactional clone.   

References bitmap_bit_p(), bitmap_set_bit(), edge_def::dest, tm_region::exit_blocks, basic_block_def::index, ipa_tm_transform_calls_1(), queue, basic_block_def::succs, and vNULL.

Referenced by ipa_tm_transform_clone(), and ipa_tm_transform_transaction().

static bool ipa_tm_transform_calls_1 ( struct cgraph_node node,
struct tm_region region,
basic_block  bb,
bitmap  irr_blocks 
)
static
Helper function for ipa_tm_transform_calls.  For a given BB,
   install calls to tm_irrevocable when IRR_BLOCKS are reached,
   redirect other calls to the generated transactional clone.   

References bitmap_bit_p(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), basic_block_def::index, ipa_tm_insert_irr_call(), ipa_tm_transform_calls_redirect(), is_gimple_call(), and is_tm_pure_call().

Referenced by ipa_tm_transform_calls().

static void ipa_tm_transform_calls_redirect ( struct cgraph_node node,
struct tm_region region,
gimple_stmt_iterator gsi,
bool *  need_ssa_rename_p 
)
static
static void ipa_uninstrument_transaction ( struct tm_region region,
vec< basic_block queue 
)
static
Duplicate the basic blocks in QUEUE for use in the uninstrumented
   code path.  QUEUE are the basic blocks inside the transaction
   represented in REGION.

   Later in split_code_paths() we will add the conditional to choose
   between the two alternatives.   

References add_phi_args_after_copy(), copy_bbs(), free(), gimple_bb(), make_edge(), and tm_region::transaction_stmt.

Referenced by ipa_tm_scan_calls_transaction().

static bool is_tm_abort ( )
static
Return true if FNDECL is BUILT_IN_TM_ABORT.   

References BUILT_IN_NORMAL.

Referenced by examine_call_tm(), and expand_call_tm().

static bool is_tm_callable ( )
static
bool is_tm_ending_fndecl ( )
static bool is_tm_irrevocable ( )
static
Return true if X has been marked TM_IRREVOCABLE.   

References BUILT_IN_NORMAL, get_attrs_for(), and lookup_attribute().

Referenced by diagnose_tm_1(), ipa_tm_execute(), ipa_tm_mayenterirr_function(), and ipa_tm_scan_irr_block().

static bool is_tm_load ( )
static
Return true if STMT is a TM load.   

References BUILT_IN_NORMAL, and gimple_call_fndecl().

Referenced by tm_memopt_accumulate_memops(), and tm_memopt_value_number().

bool is_tm_may_cancel_outer ( )
Return true if X has been marked TRANSACTION_MAY_CANCEL_OUTER.   

References get_attrs_for(), and lookup_attribute().

Referenced by diagnose_tm_1(), and diagnose_tm_blocks().

bool is_tm_pure ( )
Return true if X has been marked TM_PURE.   

References flags_from_decl_or_type().

Referenced by can_inline_edge_p(), ipa_tm_execute(), and is_tm_pure_call().

static bool is_tm_pure_call ( )
static
bool is_tm_safe ( )
static bool is_tm_simple_load ( )
static
Same as above, but for simple TM loads, that is, not the
   after-write, after-read, etc optimized variants.   

References BUILT_IN_NORMAL, and gimple_call_fndecl().

Referenced by tm_memopt_transform_blocks().

static bool is_tm_simple_store ( )
static
Same as above, but for simple TM stores, that is, not the
   after-write, after-read, etc optimized variants.   

References BUILT_IN_NORMAL, and gimple_call_fndecl().

Referenced by tm_memopt_transform_blocks().

static bool is_tm_store ( )
static
Return true if STMT is a TM store.   

References BUILT_IN_NORMAL, and gimple_call_fndecl().

Referenced by tm_memopt_accumulate_memops(), and tm_memopt_value_number().

static tree lower_sequence_no_tm ( gimple_stmt_iterator gsi,
bool *  handled_ops_p,
struct walk_stmt_info wi 
)
static
Iterate through the statements in the sequence, lowering them all
   as appropriate for being outside of a transaction.   

References gimple_has_substatements(), gsi_stmt(), and lower_transaction().

Referenced by execute_lower_tm().

static tree lower_sequence_tm ( gimple_stmt_iterator gsi,
bool *  handled_ops_p,
struct walk_stmt_info wi 
)
static
Iterate through the statements in the sequence, lowering them all
   as appropriate for being in a transaction.   

References examine_assign_tm(), examine_call_tm(), gimple_assign_single_p(), gimple_has_substatements(), gsi_stmt(), walk_stmt_info::info, and lower_transaction().

Referenced by lower_transaction().

gimple_opt_pass* make_pass_diagnose_tm_blocks ( )
simple_ipa_opt_pass* make_pass_ipa_tm ( )
gimple_opt_pass* make_pass_lower_tm ( )
gimple_opt_pass* make_pass_tm_edges ( )
gimple_opt_pass* make_pass_tm_init ( )
gimple_opt_pass* make_pass_tm_mark ( )
gimple_opt_pass* make_pass_tm_memopt ( )
static void maybe_push_queue ( struct cgraph_node node,
cgraph_node_queue queue_p,
bool *  in_queue_p 
)
static
Add NODE to the end of QUEUE, unless IN_QUEUE_P indicates that
   it is already present.   

Referenced by ipa_tm_execute(), ipa_tm_note_irrevocable(), and ipa_tm_scan_calls_block().

void record_tm_replacement ( )
static bool requires_barrier ( )
static
Determine whether X has to be instrumented using a read
   or write barrier.

   ENTRY_BLOCK is the entry block for the region where stmt resides
   in.  NULL if unknown.

   STMT is the statement in which X occurs in.  It is used for thread
   private memory instrumentation.  If no TPM instrumentation is
   desired, STMT should be null.   

References handled_component_p(), is_global_var(), mem_non_local, mem_thread_local, needs_to_live_in_memory(), thread_private_new_memory(), and tm_log_add().

Referenced by examine_assign_tm(), expand_assign_tm(), and expand_call_tm().

static void split_bb_make_tm_edge ( gimple  stmt,
basic_block  dest_bb,
gimple_stmt_iterator  iter,
gimple_stmt_iterator pnext 
)
inlinestatic
Create an abnormal edge from STMT at iter, splitting the block
   as necessary.  Adjust *PNEXT as needed for the split block.   

References cfun, edge_def::dest, ggc_free(), gimple_bb(), gimple_block_label(), function::gimple_df, gsi_one_before_end_p(), gsi_start_bb(), tm_restart_node::label_or_list, make_edge(), split_block(), tm_restart_node::stmt, struct_ptr_eq(), struct_ptr_hash(), and gimple_df::tm_restart.

Referenced by expand_block_edges().

static enum thread_memory_type thread_private_new_memory ( )
static
Evaluate an address X being dereferenced and determine if it
   originally points to a non aliased new chunk of memory (malloc,
   alloca, etc).

   Return MEM_THREAD_LOCAL if it points to a thread-local address.
   Return MEM_TRANSACTION_LOCAL if it points to a transaction-local address.
   Return MEM_NON_LOCAL otherwise.

   ENTRY_BLOCK is the entry block to the transaction containing the
   dereference of X.   

References CDI_DOMINATORS, dominated_by_p(), hash_table< Descriptor, Allocator >::find_slot(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_call_flags(), gimple_phi_num_args(), gimple_phi_result(), is_gimple_assign(), is_gimple_call(), tm_new_mem_map::local_new_memory, mem_max, mem_non_local, mem_thread_local, mem_transaction_local, ptr_deref_may_alias_global_p(), and tm_new_mem_map::val.

Referenced by requires_barrier().

static void tm_log_add ( )
static
Given an address ADDR in STMT, find it in the memory log or add it,
   making sure to keep only the addresses highest in the dominator
   tree.

   ENTRY_BLOCK is the entry_block for the transaction.

   If we find the address in the log, make sure it's either the same
   address, or an equivalent one that dominates ADDR.

   If we find the address, but neither ADDR dominates the found
   address, nor the found one dominates ADDR, we're on different
   execution paths.  Add it.

   If known, ENTRY_BLOCK is the entry block for the region, otherwise
   NULL.   

References tm_log_entry::addr, CDI_DOMINATORS, create_tmp_reg(), dominated_by_p(), tm_log_entry::entry_block, hash_table< Descriptor, Allocator >::find_slot(), host_integerp(), tm_log_entry::save_var, tm_log_entry::stmts, transaction_invariant_address_p(), and tree_low_cst().

Referenced by requires_barrier().

static void tm_log_delete ( )
static
Free logging data structures.   

References hash_table< Descriptor, Allocator >::dispose().

Referenced by execute_tm_mark().

static void tm_log_emit ( )
static
Go through the log and instrument address that must be instrumented
   with the logging functions.  Leave the save/restore addresses for
   later.   

References tm_log_entry::addr, dump_file, print_generic_expr(), tm_log_entry::save_var, tm_log_entry::stmts, and tm_log_emit_stmt().

Referenced by execute_tm_mark().

static void tm_log_emit_restores ( )
static
Emit the restore sequence for the corresponding addresses in the log.
   ENTRY_BLOCK is the entry block for the transaction.
   BB is the basic block to insert the code in.   

References tm_log_entry::addr, tm_log_entry::entry_block, hash_table< Descriptor, Allocator >::find_slot(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_start_bb(), tm_log_entry::save_var, and unshare_expr().

Referenced by expand_transaction().

static void tm_log_emit_saves ( )
static
Emit the save sequence for the corresponding addresses in the log.
   ENTRY_BLOCK is the entry block for the transaction.
   BB is the basic block to insert the code in.   

References tm_log_entry::addr, tm_log_entry::entry_block, hash_table< Descriptor, Allocator >::find_slot(), gimple_assign_set_lhs(), gsi_insert_before(), gsi_last_bb(), GSI_SAME_STMT, is_gimple_reg_type(), make_ssa_name(), tm_log_entry::save_var, and unshare_expr().

Referenced by expand_transaction().

static void tm_log_emit_stmt ( )
static
Instrument one address with the logging functions.
   ADDR is the address to save.
   STMT is the statement before which to place it.   

References builtin_decl_explicit(), gimple_build_call(), gimplify_addr(), gsi_for_stmt(), gsi_insert_before(), GSI_SAME_STMT, host_integerp(), log(), and tree_low_cst().

Referenced by tm_log_emit().

static void tm_log_init ( )
static
Initialize logging data structures.   

References hash_table< Descriptor, Allocator >::create().

Referenced by execute_tm_mark().

void tm_malloc_replacement ( )
When appropriate, record TM replacement for memory allocation functions.

   FROM is the FNDECL to wrap.   

References builtin_decl_explicit(), find_tm_replacement_function(), record_tm_replacement(), and tree_map::to.

static tree tm_mangle ( )
static
Return a transactional mangled name for the DECL_ASSEMBLER_NAME in
   OLD_DECL.  The returned value is a freshly malloced pointer that
   should be freed by the caller.   

References free(), and get_identifier().

Referenced by ipa_tm_create_version(), and ipa_tm_create_version_alias().

static void tm_memopt_accumulate_memops ( )
static
Accumulate TM memory operations in BB into STORE_LOCAL and READ_LOCAL.   

References bitmap_set_bit(), dump_file, gimple_call_arg(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_tm_load(), is_tm_store(), print_generic_expr(), and tm_memopt_value_number().

Referenced by execute_tm_memopt().

static void tm_memopt_clear_visited ( )
static
Clear the visited bit for every basic block in BLOCKS.   

Referenced by execute_tm_memopt().

static void tm_memopt_compute_antic ( struct tm_region region,
vec< basic_block blocks 
)
static
Compute ANTIC sets for every basic block in BLOCKS.

   We compute STORE_ANTIC_OUT as follows:

        STORE_ANTIC_OUT[bb] = union(STORE_ANTIC_IN[bb], STORE_LOCAL[bb])
        STORE_ANTIC_IN[bb]  = intersect(STORE_ANTIC_OUT[successors])

   REGION is the TM region.
   BLOCKS are the basic blocks in the region.   

References bitmap_bit_p(), bitmap_ior_into(), dump_file, dump_tm_memopt_sets(), tm_region::entry_block, tm_region::exit_blocks, free(), basic_block_def::index, basic_block_def::preds, edge_def::src, tm_memopt_compute_antin(), and worklist.

Referenced by execute_tm_memopt().

static void tm_memopt_compute_antin ( )
static
Compute the STORE_ANTIC_IN for the basic block BB.   

References bitmap_and_into(), bitmap_copy(), edge_def::dest, and basic_block_def::succs.

Referenced by tm_memopt_compute_antic().

static void tm_memopt_compute_available ( struct tm_region region,
vec< basic_block blocks 
)
static
Compute the AVAIL sets for every basic block in BLOCKS.

   We compute {STORE,READ}_AVAIL_{OUT,IN} as follows:

     AVAIL_OUT[bb] = union (AVAIL_IN[bb], LOCAL[bb])
     AVAIL_IN[bb]  = intersect (AVAIL_OUT[predecessors])

   This is basically what we do in lcm's compute_available(), but here
   we calculate two sets of sets (one for STOREs and one for READs),
   and we work on a region instead of the entire CFG.

   REGION is the TM region.
   BLOCKS are the basic blocks in the region.   

References bitmap_bit_p(), bitmap_ior_into(), changed, edge_def::dest, dump_file, dump_tm_memopt_sets(), tm_region::entry_block, tm_region::exit_blocks, free(), basic_block_def::index, basic_block_def::succs, tm_memopt_compute_avin(), and worklist.

Referenced by execute_tm_memopt().

static void tm_memopt_compute_avin ( )
static
Compute {STORE,READ}_AVAIL_IN for the basic block BB.   

References basic_block_def::aux, bitmap_and_into(), bitmap_copy(), basic_block_def::preds, and edge_def::src.

Referenced by tm_memopt_compute_available().

static void tm_memopt_free_sets ( )
static
Free sets computed for each BB.   

References basic_block_def::aux.

Referenced by execute_tm_memopt().

static void tm_memopt_transform_blocks ( )
static
Perform the actual TM memory optimization transformations in the
   basic blocks in BLOCKS.   

References bitmap_bit_p(), bitmap_set_bit(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_tm_simple_load(), is_tm_simple_store(), tm_memopt_transform_stmt(), and tm_memopt_value_number().

Referenced by execute_tm_memopt().

static void tm_memopt_transform_stmt ( unsigned int  offset,
gimple  stmt,
gimple_stmt_iterator gsi 
)
static
Perform a read/write optimization.  Replaces the TM builtin in STMT
   by a builtin that is OFFSET entries down in the builtins table in
   gtm-builtins.def.   

References builtin_decl_explicit(), dump_tm_memopt_transform(), gimple_call_fn(), gimple_call_set_fn(), and gsi_replace().

Referenced by tm_memopt_transform_blocks().

static unsigned int tm_memopt_value_number ( )
static
Given a TM load/store in STMT, return the value number for the address
   it accesses.   

References tm_memop::addr, gimple_call_arg(), is_tm_load(), is_tm_store(), tm_memopt_value_id, tm_memopt_value_numbers, and tm_memop::value_id.

Referenced by tm_memopt_accumulate_memops(), and tm_memopt_transform_blocks().

static void tm_region_init ( )
static
Collect all of the transaction regions within the current function
   and record them in ALL_TM_REGIONS.  The REGION parameter may specify
   an "outermost" region for use by tm clones.   

References bitmap_bit_p(), bitmap_set_bit(), edge_def::dest, tm_region::entry_block, g, basic_block_def::index, last_stmt(), queue, single_succ(), basic_block_def::succs, tm_region_init_0(), tm_region_init_1(), and vNULL.

Referenced by gate_tm_init(), and ipa_tm_execute().

static struct tm_region* tm_region_init_0 ( )
staticread
A subroutine of tm_region_init.  Record the existence of the
   GIMPLE_TRANSACTION statement in a tree of tm_region elements.   

References all_tm_regions, tm_region::entry_block, tm_region::exit_blocks, tm_region::inner, tm_region::irr_blocks, tm_region::next, bitmap_obstack::obstack, tm_region::original_transaction_was_outer, tm_region::outer, tm_region::tm_state, and tm_region::transaction_stmt.

Referenced by tm_region_init().

static struct tm_region* tm_region_init_1 ( )
staticread
A subroutine of tm_region_init.  Record all the exit and
   irrevocable blocks in BB into the region's exit_blocks and
   irr_blocks bitmaps.  Returns the new region being scanned.   

References bitmap_set_bit(), BUILT_IN_NORMAL, tm_region::exit_blocks, g, gimple_call_fndecl(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_stmt(), basic_block_def::index, tm_region::irr_blocks, and tm_region::outer.

Referenced by tm_region_init().

static bool transaction_invariant_address_p ( )
static
Return true if MEM is a transaction invariant memory for the TM
   region starting at REGION_ENTRY_BLOCK.   

References CDI_DOMINATORS, decl_address_invariant_p(), dominated_by_p(), gimple_bb(), and strip_invariant_refs().

Referenced by tm_log_add().

static void transaction_subcode_ior ( )
inlinestatic
Add FLAGS to the GIMPLE_TRANSACTION subcode for the transaction region
   represented by STATE.   

References gimple_transaction_set_subcode(), gimple_transaction_subcode(), and tm_region::transaction_stmt.

Referenced by expand_assign_tm(), expand_call_tm(), ipa_tm_insert_gettmclone_call(), ipa_tm_insert_irr_call(), and ipa_tm_transform_transaction().

static bool volatile_var_p ( )
static
Return true if T is a volatile variable of some kind.   

Referenced by diagnose_tm_1_op(), and ipa_tm_scan_irr_block().


Variable Documentation

struct tm_region* all_tm_regions
static
bool pending_edge_inserts_p
True if there are pending edge statements to be committed for the
   current function being scanned in the tmmark pass.   
hash_table<log_entry_hasher> tm_log
static
The actual log.   
vec<tree> tm_log_save_addresses
static
Addresses to log with a save/restore sequence.  These should be in
   dominator order.   
bitmap_obstack tm_memopt_obstack
static
unsigned int tm_memopt_value_id
static
Unique counter for TM loads and stores. Loads and stores of the
   same address get the same ID.   

Referenced by execute_tm_memopt(), and tm_memopt_value_number().

hash_table<tm_memop_hasher> tm_memopt_value_numbers
static
hash_table<tm_mem_map_hasher> tm_new_mem_hash
static
Map for an SSA_NAME originally pointing to a non aliased new piece
   of memory (malloc, alloc, etc).   
bitmap_obstack tm_obstack
static
htab_t tm_wrap_map
static
Map for aribtrary function replacement under TM, as created
   by the tm_wrap attribute.   

Referenced by find_tm_replacement_function().