GCC Middle and Back End API Reference
trans-mem.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.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 "cgraph.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "tree-eh.h"
#include "calls.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-inline.h"
#include "demangle.h"
#include "output.h"
#include "trans-mem.h"
#include "langhooks.h"
#include "cfgloop.h"
#include "tree-ssa-address.h"
#include "stringpool.h"
#include "attribs.h"
#include "alloc-pool.h"
#include "symbol-summary.h"
#include "symtab-thunks.h"
#include "gt-trans-mem.h"
Include dependency graph for trans-mem.cc:

Data Structures

struct  tm_wrapper_hasher
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

Macros

#define A_RUNINSTRUMENTEDCODE   0x0001
#define A_RUNUNINSTRUMENTEDCODE   0x0002
#define A_SAVELIVEVARIABLES   0x0004
#define A_RESTORELIVEVARIABLES   0x0008
#define A_ABORTTRANSACTION   0x0010
#define AR_USERABORT   0x0001
#define AR_USERRETRY   0x0002
#define AR_TMCONFLICT   0x0004
#define AR_EXCEPTIONBLOCKABORT   0x0008
#define AR_OUTERABORT   0x0010
#define MODE_SERIALIRREVOCABLE   0x0000
#define DIAG_TM_OUTER   1
#define DIAG_TM_SAFE   2
#define DIAG_TM_RELAXED   4
#define STORE_AVAIL_IN(BB)
#define STORE_AVAIL_OUT(BB)
#define STORE_ANTIC_IN(BB)
#define STORE_ANTIC_OUT(BB)
#define READ_AVAIL_IN(BB)
#define READ_AVAIL_OUT(BB)
#define READ_LOCAL(BB)
#define STORE_LOCAL(BB)
#define AVAIL_IN_WORKLIST_P(BB)
#define BB_VISITED_P(BB)
#define TRANSFORM_RAR   1
#define TRANSFORM_RAW   2
#define TRANSFORM_RFW   3
#define TRANSFORM_WAR   1
#define TRANSFORM_WAW   2

Typedefs

typedef vec< cgraph_node * > cgraph_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 (const_tree x)
bool is_tm_pure (const_tree x)
static bool is_tm_irrevocable (tree x)
bool is_tm_safe (const_tree x)
static bool is_tm_pure_call (gimple *call)
static bool is_tm_callable (tree x)
bool is_tm_may_cancel_outer (tree x)
bool is_tm_ending_fndecl (tree fndecl)
bool is_tm_ending (gimple *stmt)
static bool is_tm_load (gimple *stmt)
static bool is_tm_simple_load (gimple *stmt)
static bool is_tm_store (gimple *stmt)
static bool is_tm_simple_store (gimple *stmt)
static bool is_tm_abort (tree fndecl)
tree build_tm_abort_call (location_t loc, bool is_outer)
void record_tm_replacement (tree from, tree to)
static tree find_tm_replacement_function (tree fndecl)
void tm_malloc_replacement (tree from)
static bool volatile_lvalue_p (tree t)
static tree diagnose_tm_1_op (tree *tp, int *walk_subtrees, void *data)
static bool is_tm_safe_or_pure (const_tree x)
static tree diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *wi)
static unsigned int diagnose_tm_blocks (void)
gimple_opt_pass * make_pass_diagnose_tm_blocks (gcc::context *ctxt)
static void tm_log_init (void)
static void tm_log_delete (void)
static bool transaction_invariant_address_p (const_tree mem, basic_block region_entry_block)
static void tm_log_add (basic_block entry_block, tree addr, gimple *stmt)
static tree gimplify_addr (gimple_stmt_iterator *gsi, tree x)
static void tm_log_emit_stmt (tree addr, gimple *stmt)
static void tm_log_emit (void)
static void tm_log_emit_saves (basic_block entry_block, basic_block bb)
static void tm_log_emit_restores (basic_block entry_block, basic_block bb)
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 (basic_block entry_block, tree x)
static bool requires_barrier (basic_block entry_block, tree x, gimple *stmt)
static void examine_assign_tm (unsigned *state, gimple_stmt_iterator *gsi)
static void examine_call_tm (unsigned *state, gimple_stmt_iterator *gsi)
static tree make_tm_uninst (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *)
static void lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi)
static unsigned int execute_lower_tm (void)
gimple_opt_pass * make_pass_lower_tm (gcc::context *ctxt)
static struct tm_region * tm_region_init_0 (struct tm_region *outer, basic_block bb, gtransaction *stmt)
static struct tm_region * tm_region_init_1 (struct tm_region *region, basic_block bb)
static void tm_region_init (struct tm_region *region)
static bool gate_tm_init (void)
gimple_opt_pass * make_pass_tm_init (gcc::context *ctxt)
static void transaction_subcode_ior (struct tm_region *region, unsigned flags)
static gcall * build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
static gcall * build_tm_store (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
static void expand_assign_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
static bool expand_call_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
static void expand_block_tm (struct tm_region *region, basic_block bb)
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 void * collect_bb2reg (struct tm_region *region, void *data)
static vec< tm_region * > get_bb_regions_instrumented (bool traverse_clones, bool include_uninstrumented_p)
void compute_transaction_bits (void)
static void * expand_transaction (struct tm_region *region, void *data)
static void * generate_tm_state (struct tm_region *region, void *data)
static void propagate_tm_flags_out (struct tm_region *region)
static unsigned int execute_tm_mark (void)
gimple_opt_pass * make_pass_tm_mark (gcc::context *ctxt)
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 (struct tm_region *const region, basic_block bb)
gimple_opt_pass * make_pass_tm_edges (gcc::context *ctxt)
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 (gimple *stmt, enum insert_option op)
static void tm_memopt_accumulate_memops (basic_block bb)
static void dump_tm_memopt_set (const char *set_name, bitmap bits)
static void dump_tm_memopt_sets (vec< basic_block > blocks)
static void tm_memopt_compute_avin (basic_block bb)
static void tm_memopt_compute_antin (basic_block bb)
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 (gimple *stmt)
static void tm_memopt_transform_stmt (unsigned int offset, gcall *stmt, gimple_stmt_iterator *gsi)
static void tm_memopt_transform_blocks (vec< basic_block > blocks)
static struct tm_memopt_bitmaps * tm_memopt_init_sets (void)
static void tm_memopt_free_sets (vec< basic_block > blocks)
static void tm_memopt_clear_visited (vec< basic_block > blocks)
static unsigned int execute_tm_memopt (void)
gimple_opt_pass * make_pass_tm_memopt (gcc::context *ctxt)
static struct tm_ipa_cg_data * get_cg_data (struct cgraph_node **node, bool traverse_aliases)
static void maybe_push_queue (struct cgraph_node *node, cgraph_node_queue *queue_p, bool *in_queue_p)
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 (basic_block bb)
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 (basic_block bb, bool for_clone)
static bool ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
static bool ipa_tm_mayenterirr_function (struct cgraph_node *node)
static void ipa_tm_diagnose_tm_safe (struct cgraph_node *node)
static void ipa_tm_diagnose_transaction (struct cgraph_node *node, struct tm_region *all_tm_regions)
static tree tm_mangle (tree old_asm_id)
static void ipa_tm_mark_force_output_node (struct cgraph_node *node)
static void ipa_tm_mark_forced_by_abi_node (struct cgraph_node *node)
static bool ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
static void ipa_tm_create_version (struct cgraph_node *old_node)
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, gcall *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 (struct cgraph_node *node)
static void ipa_tm_transform_clone (struct cgraph_node *node)
static unsigned int ipa_tm_execute (void)
simple_ipa_opt_pass * make_pass_ipa_tm (gcc::context *ctxt)

Variables

static hash_table< tm_wrapper_hasher > * tm_wrap_map
static hash_table< log_entry_hasher > * tm_log
static vec< tree > tm_log_save_addresses
static hash_table< tm_mem_map_hasher > * tm_new_mem_hash
bool pending_edge_inserts_p
static struct tm_region * all_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

Macro Definition Documentation

◆ A_ABORTTRANSACTION

#define A_ABORTTRANSACTION   0x0010

Referenced by expand_transaction().

◆ A_RESTORELIVEVARIABLES

#define A_RESTORELIVEVARIABLES   0x0008

Referenced by expand_transaction().

◆ A_RUNINSTRUMENTEDCODE

#define A_RUNINSTRUMENTEDCODE   0x0001
Passes for transactional memory support.
Copyright (C) 2008-2026 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>
and Aldy Hernandez <aldyh@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   

◆ A_RUNUNINSTRUMENTEDCODE

#define A_RUNUNINSTRUMENTEDCODE   0x0002

Referenced by expand_transaction().

◆ A_SAVELIVEVARIABLES

#define A_SAVELIVEVARIABLES   0x0004

◆ AR_EXCEPTIONBLOCKABORT

#define AR_EXCEPTIONBLOCKABORT   0x0008

◆ AR_OUTERABORT

#define AR_OUTERABORT   0x0010

◆ AR_TMCONFLICT

#define AR_TMCONFLICT   0x0004

◆ AR_USERABORT

#define AR_USERABORT   0x0001

Referenced by build_tm_abort_call().

◆ AR_USERRETRY

#define AR_USERRETRY   0x0002

◆ AVAIL_IN_WORKLIST_P

#define AVAIL_IN_WORKLIST_P ( BB)
Value:
((struct tm_memopt_bitmaps *) ((BB)->aux))->avail_in_worklist_p
Definition trans-mem.cc:3476

Referenced by tm_memopt_compute_antic(), and tm_memopt_compute_available().

◆ BB_VISITED_P

#define BB_VISITED_P ( BB)

◆ DIAG_TM_OUTER

#define DIAG_TM_OUTER   1
Diagnostics for tm_safe functions/regions.  Called by the front end
once we've lowered the function to high-gimple.   
Subroutine of diagnose_tm_safe_errors, called through walk_gimple_seq.
Process exactly one statement.  WI->INFO is set to non-null when in
the context of a tm_safe function, and null for a __transaction block.   

Referenced by diagnose_tm_1(), and diagnose_tm_blocks().

◆ DIAG_TM_RELAXED

#define DIAG_TM_RELAXED   4

Referenced by diagnose_tm_1().

◆ DIAG_TM_SAFE

#define DIAG_TM_SAFE   2

◆ MODE_SERIALIRREVOCABLE

#define MODE_SERIALIRREVOCABLE   0x0000

Referenced by ipa_tm_insert_irr_call().

◆ READ_AVAIL_IN

#define READ_AVAIL_IN ( BB)

◆ READ_AVAIL_OUT

#define READ_AVAIL_OUT ( BB)
Value:
((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_out

Referenced by dump_tm_memopt_sets(), tm_memopt_compute_available(), and tm_memopt_compute_avin().

◆ READ_LOCAL

#define READ_LOCAL ( BB)
Value:
((struct tm_memopt_bitmaps *) ((BB)->aux))->read_local

Referenced by dump_tm_memopt_sets(), tm_memopt_accumulate_memops(), and tm_memopt_compute_available().

◆ STORE_ANTIC_IN

#define STORE_ANTIC_IN ( BB)
Value:
((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_in

Referenced by tm_memopt_compute_antic(), and tm_memopt_compute_antin().

◆ STORE_ANTIC_OUT

#define STORE_ANTIC_OUT ( BB)
Value:
((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_out

Referenced by tm_memopt_compute_antic(), tm_memopt_compute_antin(), and tm_memopt_transform_blocks().

◆ STORE_AVAIL_IN

#define STORE_AVAIL_IN ( BB)

◆ STORE_AVAIL_OUT

#define STORE_AVAIL_OUT ( BB)
Value:
((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_out

Referenced by dump_tm_memopt_sets(), tm_memopt_compute_available(), and tm_memopt_compute_avin().

◆ STORE_LOCAL

#define STORE_LOCAL ( BB)

◆ TRANSFORM_RAR

#define TRANSFORM_RAR   1
Offsets of load variants from TM_LOAD.  For example,
BUILT_IN_TM_LOAD_RAR* is an offset of 1 from BUILT_IN_TM_LOAD*.
See gtm-builtins.def.   

Referenced by tm_memopt_transform_blocks().

◆ TRANSFORM_RAW

#define TRANSFORM_RAW   2

◆ TRANSFORM_RFW

#define TRANSFORM_RFW   3

◆ TRANSFORM_WAR

#define TRANSFORM_WAR   1
Offsets of store variants from TM_STORE.   

Referenced by tm_memopt_transform_blocks().

◆ TRANSFORM_WAW

#define TRANSFORM_WAW   2

Typedef Documentation

◆ cgraph_node_queue

Enumeration Type Documentation

◆ thread_memory_type

Enumerator
mem_non_local 
mem_thread_local 
mem_transaction_local 
mem_max 

Function Documentation

◆ build_tm_abort_call()

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

References AR_OUTERABORT, AR_USERABORT, build_call_expr_loc(), build_int_cst(), build_tm_abort_call(), builtin_decl_explicit(), and integer_type_node.

Referenced by build_tm_abort_call().

◆ build_tm_load()

gcall * build_tm_load ( location_t loc,
tree lhs,
tree rhs,
gimple_stmt_iterator * gsi )
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 build_tm_load(), builtin_decl_explicit(), builtin_decl_explicit_p(), create_tmp_reg(), double_type_node, float_type_node, fold_build1, g, gcc_assert, gimple_build_assign(), gimple_build_call(), gimple_call_set_lhs(), gimple_set_location(), gimplify_addr(), gsi_insert_before(), GSI_SAME_STMT, long_double_type_node, NULL, TREE_CODE, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, TYPE_SIZE, and useless_type_conversion_p().

Referenced by build_tm_load(), and expand_assign_tm().

◆ build_tm_store()

◆ collect_bb2reg()

◆ compute_transaction_bits()

◆ diagnose_tm_1()

◆ diagnose_tm_1_op()

tree diagnose_tm_1_op ( tree * tp,
int * walk_subtrees,
void * data )
static

◆ diagnose_tm_blocks()

◆ dump_tm_memopt_set()

void dump_tm_memopt_set ( const char * set_name,
bitmap bits )
static

◆ dump_tm_memopt_sets()

◆ dump_tm_memopt_transform()

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

References dump_file, dump_tm_memopt_transform(), and print_gimple_stmt().

Referenced by dump_tm_memopt_transform(), and tm_memopt_transform_stmt().

◆ examine_assign_tm()

void examine_assign_tm ( unsigned * state,
gimple_stmt_iterator * gsi )
static
Mark the GIMPLE_ASSIGN statement as appropriate for being inside
a transaction region.   

References examine_assign_tm(), gimple_assign_lhs(), gimple_assign_rhs1(), gsi_stmt(), GTMA_HAVE_LOAD, GTMA_HAVE_STORE, NULL, and requires_barrier().

Referenced by examine_assign_tm(), and lower_sequence_tm().

◆ examine_call_tm()

void examine_call_tm ( unsigned * state,
gimple_stmt_iterator * gsi )
static
Mark a GIMPLE_CALL as appropriate for being inside a transaction.   

References examine_call_tm(), gimple_call_fndecl(), gsi_stmt(), GTMA_HAVE_ABORT, GTMA_HAVE_LOAD, GTMA_HAVE_STORE, is_tm_abort(), and is_tm_pure_call().

Referenced by examine_call_tm(), and lower_sequence_tm().

◆ execute_lower_tm()

unsigned int execute_lower_tm ( void )
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(), execute_lower_tm(), gcc_assert, gimple_body(), gimple_set_body(), lower_sequence_no_tm(), NULL, and walk_gimple_seq_mod().

Referenced by execute_lower_tm().

◆ execute_tm_mark()

unsigned int execute_tm_mark ( void )
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 all_tm_regions, BASIC_BLOCK_FOR_FN, CDI_DOMINATORS, cfun, execute_tm_mark(), expand_block_tm(), expand_regions(), expand_transaction(), FOR_EACH_VEC_ELT, free_dominance_info(), generate_tm_state(), get_bb_regions_instrumented(), gimple_transaction_subcode(), gsi_commit_edge_inserts(), GTMA_DOES_GO_IRREVOCABLE, GTMA_MAY_ENTER_IRREVOCABLE, i, NULL, pending_edge_inserts_p, propagate_tm_flags_out(), r, tm_log_delete(), tm_log_emit(), and tm_log_init().

Referenced by execute_tm_mark().

◆ execute_tm_memopt()

◆ expand_assign_tm()

◆ expand_block_edges()

◆ expand_block_tm()

void expand_block_tm ( struct tm_region * region,
basic_block bb )
static
Expand all statements in BB as appropriate for being inside
a transaction.   

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

Referenced by execute_tm_mark(), and expand_block_tm().

◆ expand_call_tm()

◆ expand_regions()

void * expand_regions ( struct tm_region * region,
void * callback (*)(struct tm_region *, void *),
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.cc) 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(), expand_regions_1(), tm_region::next, and NULL.

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

◆ expand_regions_1()

void * expand_regions_1 ( struct tm_region * region,
void * callback (*)(struct tm_region *, void *),
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(), expand_regions_1(), tm_region::inner, and NULL.

Referenced by expand_regions(), and expand_regions_1().

◆ expand_transaction()

void * expand_transaction ( struct tm_region * region,
void * data )
static
Replace the GIMPLE_TRANSACTION in this region with the corresponding
call to BUILT_IN_TM_START.   

References A_ABORTTRANSACTION, A_RESTORELIVEVARIABLES, A_RUNUNINSTRUMENTEDCODE, add_bb_to_loop(), profile_probability::always(), build_int_cst(), builtin_decl_explicit(), basic_block_def::count, create_empty_bb(), create_tmp_reg(), tm_region::entry_block, profile_probability::even(), expand_transaction(), basic_block_def::flags, FOR_EACH_EDGE, gcc_assert, tm_region::get_transaction_stmt(), gimple_bb(), gimple_build_assign(), gimple_build_call(), gimple_build_cond(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), gimple_transaction_subcode(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_insert_before(), gsi_last_bb(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), GTMA_DOES_GO_IRREVOCABLE, GTMA_HAS_NO_INSTRUMENTATION, GTMA_HAVE_ABORT, GTMA_HAVE_STORE, GTMA_IS_OUTER, GTMA_MAY_ENTER_IRREVOCABLE, i, profile_probability::likely(), basic_block_def::loop_father, make_edge(), NULL, tm_region::original_transaction_was_outer, phi_nodes(), PR_DOESGOIRREVOCABLE, PR_HASNOABORT, PR_HASNOIRREVOCABLE, PR_INSTRUMENTEDCODE, PR_READONLY, PR_UNINSTRUMENTEDCODE, redirect_edge_pred(), tm_region::restart_block, basic_block_def::succs, tm_log_emit_restores(), tm_log_emit_saves(), tm_log_save_addresses, tm_region::tm_state, tm_region::transaction_stmt, TREE_TYPE, profile_probability::unlikely(), and profile_probability::very_likely().

Referenced by execute_tm_mark(), and expand_transaction().

◆ find_tm_replacement_function()

◆ gate_tm_init()

bool gate_tm_init ( void )
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 all_tm_regions, BITMAP_ALLOC, bitmap_obstack_initialize(), bitmap_obstack_release(), calculate_dominance_info(), CDI_DOMINATORS, cfun, current_function_decl, decl_is_tm_clone(), tm_region::entry_block, ENTRY_BLOCK_PTR_FOR_FN, gate_tm_init(), tm_region::irr_blocks, NULL, bitmap_obstack::obstack, single_succ(), tm_obstack, and tm_region_init().

Referenced by compute_transaction_bits(), and gate_tm_init().

◆ generate_tm_state()

◆ get_attrs_for()

tree get_attrs_for ( const_tree x)
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.   

References get_attrs_for(), NULL_TREE, TREE_CODE, TREE_TYPE, TYPE_ATTRIBUTES, and TYPE_P.

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

◆ get_bb_regions_instrumented()

◆ get_cg_data()

struct tm_ipa_cg_data * get_cg_data ( struct cgraph_node ** node,
bool traverse_aliases )
static

◆ get_tm_region_blocks()

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_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_ior_into(), bitmap_set_bit, FOR_EACH_EDGE, get_tm_region_blocks(), i, basic_block_def::index, NULL, basic_block_def::succs, and vNULL.

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

◆ gimplify_addr()

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

References build_fold_addr_expr, build_pointer_type(), force_gimple_operand_gsi(), gimplify_addr(), GSI_SAME_STMT, NULL, TREE_CODE, tree_mem_ref_addr(), and TREE_TYPE.

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

◆ ipa_tm_create_version()

◆ ipa_tm_create_version_alias()

◆ ipa_tm_decrement_clone_counts()

◆ ipa_tm_diagnose_tm_safe()

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

References error_at(), gimple_location(), ipa_tm_diagnose_tm_safe(), and is_tm_callable().

Referenced by ipa_tm_diagnose_tm_safe(), and ipa_tm_execute().

◆ ipa_tm_diagnose_transaction()

◆ ipa_tm_execute()

◆ ipa_tm_insert_gettmclone_call()

◆ ipa_tm_insert_irr_call()

◆ ipa_tm_mark_force_output_node()

void ipa_tm_mark_force_output_node ( struct cgraph_node * node)
inlinestatic

◆ ipa_tm_mark_forced_by_abi_node()

void ipa_tm_mark_forced_by_abi_node ( struct cgraph_node * node)
inlinestatic

◆ ipa_tm_mayenterirr_function()

◆ ipa_tm_note_irrevocable()

void ipa_tm_note_irrevocable ( struct cgraph_node * node,
cgraph_node_queue * worklist_p )
static

◆ ipa_tm_propagate_irr()

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_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, CDI_DOMINATORS, first_dom_son(), FOR_EACH_EDGE, get_tm_region_blocks(), basic_block_def::index, ipa_tm_propagate_irr(), next_dom_son(), NULL, basic_block_def::succs, and tm_obstack.

Referenced by ipa_tm_propagate_irr(), and ipa_tm_scan_irr_function().

◆ ipa_tm_scan_calls_block()

◆ ipa_tm_scan_calls_clone()

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 DECL_STRUCT_FUNCTION, FOR_EACH_BB_FN, ipa_tm_scan_calls_block(), and ipa_tm_scan_calls_clone().

Referenced by ipa_tm_execute(), and ipa_tm_scan_calls_clone().

◆ ipa_tm_scan_calls_transaction()

void ipa_tm_scan_calls_transaction ( struct tm_ipa_cg_data * d,
cgraph_node_queue * callees_p )
static
Scan all calls in NODE that are within a transaction region,
and push the resulting nodes into the callee queue.   

References all_tm_regions, tm_ipa_cg_data::all_tm_regions, BITMAP_ALLOC, FOR_EACH_VEC_ELT, get_tm_region_blocks(), i, ipa_tm_scan_calls_block(), ipa_tm_scan_calls_transaction(), NULL, r, tm_obstack, and tm_ipa_cg_data::transaction_blocks_normal.

Referenced by ipa_tm_execute(), and ipa_tm_scan_calls_transaction().

◆ ipa_tm_scan_irr_block()

◆ ipa_tm_scan_irr_blocks()

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 within 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_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, FOR_EACH_EDGE, basic_block_def::index, ipa_tm_scan_irr_block(), ipa_tm_scan_irr_blocks(), NULL, and basic_block_def::succs.

Referenced by ipa_tm_scan_irr_blocks(), and ipa_tm_scan_irr_function().

◆ ipa_tm_scan_irr_function()

bool ipa_tm_scan_irr_function ( struct cgraph_node * node,
bool for_clone )
static

◆ ipa_tm_transform_calls()

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_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, tm_region::exit_blocks, FOR_EACH_EDGE, basic_block_def::index, ipa_tm_transform_calls(), ipa_tm_transform_calls_1(), NULL, and basic_block_def::succs.

Referenced by ipa_tm_transform_calls(), ipa_tm_transform_clone(), and ipa_tm_transform_transaction().

◆ ipa_tm_transform_calls_1()

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_1(), ipa_tm_transform_calls_redirect(), is_gimple_call(), and is_tm_pure_call().

Referenced by ipa_tm_transform_calls(), and ipa_tm_transform_calls_1().

◆ ipa_tm_transform_calls_redirect()

void ipa_tm_transform_calls_redirect ( struct cgraph_node * node,
struct tm_region * region,
gimple_stmt_iterator * gsi,
bool * need_ssa_rename_p )
static

◆ ipa_tm_transform_clone()

◆ ipa_tm_transform_transaction()

◆ is_tm_abort()

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

References fndecl_built_in_p(), and is_tm_abort().

Referenced by examine_call_tm(), expand_call_tm(), and is_tm_abort().

◆ is_tm_callable()

bool is_tm_callable ( tree x)
static

◆ is_tm_ending()

bool is_tm_ending ( gimple * stmt)
Return true if STMT is a built in function call that "ends" a
transaction.   

References gimple_call_fndecl(), is_tm_ending(), is_tm_ending_fndecl(), and NULL_TREE.

Referenced by is_tm_ending(), and merge_stmts_p().

◆ is_tm_ending_fndecl()

◆ is_tm_irrevocable()

bool is_tm_irrevocable ( tree x)
static

◆ is_tm_load()

◆ is_tm_may_cancel_outer()

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

References get_attrs_for(), is_tm_may_cancel_outer(), lookup_attribute(), and NULL.

Referenced by diagnose_tm_1(), diagnose_tm_blocks(), and is_tm_may_cancel_outer().

◆ is_tm_pure()

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

References ECF_TM_PURE, flags_from_decl_or_type(), is_tm_pure(), TREE_CODE, TREE_TYPE, and TYPE_P.

Referenced by can_inline_edge_p(), ipa_tm_execute(), is_tm_pure(), and is_tm_safe_or_pure().

◆ is_tm_pure_call()

◆ is_tm_safe()

◆ is_tm_safe_or_pure()

◆ is_tm_simple_load()

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

References BUILT_IN_NORMAL, DECL_FUNCTION_CODE(), fndecl_built_in_p(), gimple_call_fndecl(), and is_tm_simple_load().

Referenced by is_tm_simple_load(), and tm_memopt_transform_blocks().

◆ is_tm_simple_store()

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

References BUILT_IN_NORMAL, DECL_FUNCTION_CODE(), fndecl_built_in_p(), gimple_call_fndecl(), and is_tm_simple_store().

Referenced by is_tm_simple_store(), and tm_memopt_transform_blocks().

◆ is_tm_store()

◆ lower_sequence_no_tm()

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(), walk_stmt_info::gsi, gsi_stmt(), lower_sequence_no_tm(), lower_transaction(), NULL_TREE, and walk_stmt_info::stmt.

Referenced by execute_lower_tm(), and lower_sequence_no_tm().

◆ lower_sequence_tm()

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(), walk_stmt_info::gsi, gsi_stmt(), GTMA_MAY_ENTER_IRREVOCABLE, lower_sequence_tm(), lower_transaction(), NULL_TREE, and walk_stmt_info::stmt.

Referenced by lower_sequence_tm(), and lower_transaction().

◆ lower_transaction()

◆ make_pass_diagnose_tm_blocks()

gimple_opt_pass * make_pass_diagnose_tm_blocks ( gcc::context * ctxt)

◆ make_pass_ipa_tm()

simple_ipa_opt_pass * make_pass_ipa_tm ( gcc::context * ctxt)

◆ make_pass_lower_tm()

gimple_opt_pass * make_pass_lower_tm ( gcc::context * ctxt)

◆ make_pass_tm_edges()

gimple_opt_pass * make_pass_tm_edges ( gcc::context * ctxt)

◆ make_pass_tm_init()

gimple_opt_pass * make_pass_tm_init ( gcc::context * ctxt)

◆ make_pass_tm_mark()

gimple_opt_pass * make_pass_tm_mark ( gcc::context * ctxt)

◆ make_pass_tm_memopt()

gimple_opt_pass * make_pass_tm_memopt ( gcc::context * ctxt)

◆ make_tm_uninst()

tree make_tm_uninst ( gimple_stmt_iterator * gsi,
bool * handled_ops_p,
struct walk_stmt_info *  )
static
Iterate through the statements in the sequence, moving labels
(and thus edges) of transactions from "label_norm" to "label_uninst".   

References dyn_cast(), gimple_has_substatements(), gsi_stmt(), make_tm_uninst(), NULL, and NULL_TREE.

Referenced by lower_transaction(), and make_tm_uninst().

◆ maybe_push_queue()

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.   

References maybe_push_queue().

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

◆ propagate_tm_flags_out()

◆ record_tm_replacement()

◆ requires_barrier()

bool requires_barrier ( basic_block entry_block,
tree x,
gimple * stmt )
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 DECL_BY_REFERENCE, tm_log_entry::entry_block, gcc_assert, handled_component_p(), is_global_var(), mem_non_local, mem_thread_local, needs_to_live_in_memory(), requires_barrier(), thread_private_new_memory(), tm_log_add(), TMR_BASE, TREE_CODE, TREE_OPERAND, TREE_READONLY, and VAR_P.

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

◆ split_bb_make_tm_edge()

void split_bb_make_tm_edge ( gimple * stmt,
basic_block dest_bb,
gimple_stmt_iterator iter,
gimple_stmt_iterator * pnext )
inlinestatic

◆ thread_private_new_memory()

enum thread_memory_type thread_private_new_memory ( basic_block entry_block,
tree x )
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, CONVERT_EXPR_CODE_P, dominated_by_p(), ECF_MALLOC, tm_log_entry::entry_block, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_bb(), gimple_call_flags(), gimple_phi_num_args(), gimple_phi_result(), i, is_gimple_assign(), is_gimple_call(), tm_new_mem_map::local_new_memory, mem_max, mem_non_local, mem_thread_local, mem_transaction_local, MIN, NULL, PHI_ARG_DEF, ptr_deref_may_alias_global_p(), SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, thread_private_new_memory(), tm_new_mem_hash, TREE_CODE, and tm_new_mem_map::val.

Referenced by requires_barrier(), and thread_private_new_memory().

◆ tm_log_add()

void tm_log_add ( basic_block entry_block,
tree addr,
gimple * stmt )
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, gcc_assert, gimple_bb(), i, NULL, tm_log_entry::save_var, tm_log_entry::stmts, tm_log, tm_log_add(), tm_log_save_addresses, transaction_invariant_address_p(), TREE_ADDRESSABLE, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, and TYPE_SIZE_UNIT.

Referenced by requires_barrier(), and tm_log_add().

◆ tm_log_delete()

void tm_log_delete ( void )
static
Free logging data structures.   

References NULL, tm_log, tm_log_delete(), tm_log_save_addresses, and tm_new_mem_hash.

Referenced by execute_tm_mark(), and tm_log_delete().

◆ tm_log_emit()

void tm_log_emit ( void )
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, FOR_EACH_HASH_TABLE_ELEMENT, i, print_generic_expr(), tm_log_entry::save_var, tm_log_entry::stmts, tm_log, tm_log_emit(), and tm_log_emit_stmt().

Referenced by execute_tm_mark(), and tm_log_emit().

◆ tm_log_emit_restores()

void tm_log_emit_restores ( basic_block entry_block,
basic_block bb )
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, gcc_assert, gimple_build_assign(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_start_bb(), i, NULL, tm_log_entry::save_var, tm_log, tm_log_emit_restores(), tm_log_save_addresses, and unshare_expr().

Referenced by expand_transaction(), and tm_log_emit_restores().

◆ tm_log_emit_saves()

void tm_log_emit_saves ( basic_block entry_block,
basic_block bb )
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, gcc_assert, gimple_assign_set_lhs(), gimple_build_assign(), gsi_insert_before(), gsi_last_bb(), GSI_SAME_STMT, i, is_gimple_reg_type(), make_ssa_name(), NULL, tm_log_entry::save_var, tm_log, tm_log_emit_saves(), tm_log_save_addresses, TREE_TYPE, and unshare_expr().

Referenced by expand_transaction(), and tm_log_emit_saves().

◆ tm_log_emit_stmt()

void tm_log_emit_stmt ( tree addr,
gimple * stmt )
static

◆ tm_log_init()

void tm_log_init ( void )
static

◆ tm_malloc_replacement()

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

FROM is the FNDECL to wrap.   

References builtin_decl_explicit(), DECL_NAME, find_tm_replacement_function(), IDENTIFIER_POINTER, record_tm_replacement(), tm_malloc_replacement(), TREE_CODE, and TREE_NOTHROW.

Referenced by tm_malloc_replacement().

◆ tm_mangle()

tree tm_mangle ( tree old_asm_id)
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(), get_identifier(), IDENTIFIER_LENGTH, IDENTIFIER_POINTER, NULL, and tm_mangle().

Referenced by ipa_tm_create_version(), ipa_tm_create_version_alias(), and tm_mangle().

◆ tm_memopt_accumulate_memops()

void tm_memopt_accumulate_memops ( basic_block bb)
static

◆ tm_memopt_clear_visited()

void tm_memopt_clear_visited ( vec< basic_block > blocks)
static
Clear the visited bit for every basic block in BLOCKS.   

References BB_VISITED_P, i, and tm_memopt_clear_visited().

Referenced by execute_tm_memopt(), and tm_memopt_clear_visited().

◆ tm_memopt_compute_antic()

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 AVAIL_IN_WORKLIST_P, BASIC_BLOCK_FOR_FN, BB_VISITED_P, bitmap_bit_p, bitmap_ior_into(), cfun, dump_file, dump_tm_memopt_sets(), tm_region::entry_block, EXECUTE_IF_SET_IN_BITMAP, tm_region::exit_blocks, FOR_EACH_EDGE, free(), i, basic_block_def::index, basic_block_def::preds, STORE_ANTIC_IN, STORE_ANTIC_OUT, STORE_LOCAL, tm_memopt_compute_antic(), and tm_memopt_compute_antin().

Referenced by execute_tm_memopt(), and tm_memopt_compute_antic().

◆ tm_memopt_compute_antin()

void tm_memopt_compute_antin ( basic_block bb)
static

◆ tm_memopt_compute_available()

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 AVAIL_IN_WORKLIST_P, BB_VISITED_P, bitmap_bit_p, bitmap_ior_into(), cfun, dump_file, dump_tm_memopt_sets(), tm_region::entry_block, EXIT_BLOCK_PTR_FOR_FN, tm_region::exit_blocks, FOR_EACH_EDGE, free(), gcc_assert, i, basic_block_def::index, NULL, READ_AVAIL_IN, READ_AVAIL_OUT, READ_LOCAL, STORE_AVAIL_IN, STORE_AVAIL_OUT, STORE_LOCAL, basic_block_def::succs, tm_memopt_compute_available(), and tm_memopt_compute_avin().

Referenced by execute_tm_memopt(), and tm_memopt_compute_available().

◆ tm_memopt_compute_avin()

void tm_memopt_compute_avin ( basic_block bb)
static

◆ tm_memopt_free_sets()

void tm_memopt_free_sets ( vec< basic_block > blocks)
static
Free sets computed for each BB.   

References basic_block_def::aux, i, NULL, and tm_memopt_free_sets().

Referenced by execute_tm_memopt(), and tm_memopt_free_sets().

◆ tm_memopt_init_sets()

struct tm_memopt_bitmaps * tm_memopt_init_sets ( void )
static
Return a new set of bitmaps for a BB.   

References b, BITMAP_ALLOC, bitmap_obstack::obstack, tm_memopt_init_sets(), and tm_memopt_obstack.

Referenced by execute_tm_memopt(), and tm_memopt_init_sets().

◆ tm_memopt_transform_blocks()

◆ tm_memopt_transform_stmt()

void tm_memopt_transform_stmt ( unsigned int offset,
gcall * 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(), DECL_FUNCTION_CODE(), dump_tm_memopt_transform(), gcc_assert, gimple_call_fn(), gimple_call_set_fn(), gsi_replace(), tm_memopt_transform_stmt(), TREE_CODE, and TREE_OPERAND.

Referenced by tm_memopt_transform_blocks(), and tm_memopt_transform_stmt().

◆ tm_memopt_value_number()

unsigned int tm_memopt_value_number ( gimple * stmt,
enum insert_option op )
static

◆ tm_region_init()

void tm_region_init ( struct tm_region * region)
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 all_tm_regions, BITMAP_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, cfun, dyn_cast(), tm_region::entry_block, ENTRY_BLOCK_PTR_FOR_FN, FOR_EACH_EDGE, g, basic_block_def::index, last_basic_block_for_fn, last_nondebug_stmt(), NULL, single_succ(), basic_block_def::succs, tm_region_init(), tm_region_init_0(), and tm_region_init_1().

Referenced by gate_tm_init(), ipa_tm_execute(), and tm_region_init().

◆ tm_region_init_0()

struct tm_region * tm_region_init_0 ( struct tm_region * outer,
basic_block bb,
gtransaction * stmt )
static

◆ tm_region_init_1()

struct tm_region * tm_region_init_1 ( struct tm_region * region,
basic_block bb )
static
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, DECL_FUNCTION_CODE(), tm_region::exit_blocks, fndecl_built_in_p(), g, gimple_call_fndecl(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_stmt(), basic_block_def::index, tm_region::irr_blocks, tm_region::outer, and tm_region_init_1().

Referenced by tm_region_init(), and tm_region_init_1().

◆ transaction_invariant_address_p()

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

References CDI_DOMINATORS, CONSTANT_CLASS_P, decl_address_invariant_p(), dominated_by_p(), gimple_bb(), INDIRECT_REF_P, SSA_NAME_DEF_STMT, strip_invariant_refs(), transaction_invariant_address_p(), TREE_CODE, and TREE_OPERAND.

Referenced by tm_log_add(), and transaction_invariant_address_p().

◆ transaction_subcode_ior()

void transaction_subcode_ior ( struct tm_region * region,
unsigned flags )
inlinestatic

◆ volatile_lvalue_p()

bool volatile_lvalue_p ( tree t)
static
Return true if T is a volatile lvalue of some kind.   

References REFERENCE_CLASS_P, SSA_VAR_P, TREE_THIS_VOLATILE, TREE_TYPE, and volatile_lvalue_p().

Referenced by diagnose_tm_1_op(), ipa_tm_scan_irr_block(), and volatile_lvalue_p().

Variable Documentation

◆ all_tm_regions

◆ pending_edge_inserts_p

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.   

Referenced by execute_tm_mark(), and expand_call_tm().

◆ tm_log

◆ tm_log_save_addresses

vec<tree> tm_log_save_addresses
static
Addresses to log with a save/restore sequence.  These should be in
dominator order.   

Referenced by expand_transaction(), tm_log_add(), tm_log_delete(), tm_log_emit_restores(), tm_log_emit_saves(), and tm_log_init().

◆ tm_memopt_obstack

bitmap_obstack tm_memopt_obstack
static

◆ tm_memopt_value_id

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

◆ tm_memopt_value_numbers

hash_table<tm_memop_hasher>* tm_memopt_value_numbers
static

◆ tm_new_mem_hash

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).   

Referenced by thread_private_new_memory(), tm_log_delete(), and tm_log_init().

◆ tm_obstack

◆ tm_wrap_map