static void *expand_regions (struct tm_region *,
void *(*callback)(struct tm_region *, void *),
- void *);
+ void *, bool);
\f
/* Return the attributes we want to examine for X, or NULL if it's not
region->exit_blocks,
region->irr_blocks,
NULL,
- /*stop_at_irr_p=*/false);
+ /*stop_at_irr_p=*/true);
// We expect expand_region to perform a post-order traversal of the region
// tree. Therefore the last region seen for any bb is the innermost.
// only known instance of this block sharing.
static vec<tm_region_p>
-get_bb_regions_instrumented (void)
+get_bb_regions_instrumented (bool traverse_clones)
{
unsigned n = last_basic_block;
vec<tm_region_p> ret;
ret.create (n);
ret.safe_grow_cleared (n);
- expand_regions (all_tm_regions, collect_bb2reg, &ret);
+ expand_regions (all_tm_regions, collect_bb2reg, &ret, traverse_clones);
return ret;
}
{
pending_edge_inserts_p = false;
- expand_regions (all_tm_regions, generate_tm_state, NULL);
+ expand_regions (all_tm_regions, generate_tm_state, NULL,
+ /*traverse_clones=*/true);
tm_log_init ();
- vec<tm_region_p> bb_regions = get_bb_regions_instrumented ();
+ vec<tm_region_p> bb_regions
+ = get_bb_regions_instrumented (/*traverse_clones=*/true);
struct tm_region *r;
unsigned i;
propagate_tm_flags_out (all_tm_regions);
// Expand GIMPLE_TRANSACTIONs into calls into the runtime.
- expand_regions (all_tm_regions, expand_transaction, NULL);
+ expand_regions (all_tm_regions, expand_transaction, NULL,
+ /*traverse_clones=*/false);
tm_log_emit ();
tm_log_delete ();
static unsigned int
execute_tm_edges (void)
{
- vec<tm_region_p> bb_regions = get_bb_regions_instrumented ();
+ vec<tm_region_p> bb_regions
+ = get_bb_regions_instrumented (/*traverse_clones=*/false);
struct tm_region *r;
unsigned i;
/* 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. */
+ this function will return as well. TRAVERSE_CLONES is true if we
+ should traverse transactional clones. */
static void *
expand_regions_1 (struct tm_region *region,
void *(*callback)(struct tm_region *, void *),
- void *data)
+ void *data,
+ bool traverse_clones)
{
void *retval = NULL;
- if (region->exit_blocks)
+ if (region->exit_blocks
+ || (traverse_clones && decl_is_tm_clone (current_function_decl)))
{
retval = callback (region, data);
if (retval)
}
if (region->inner)
{
- retval = expand_regions (region->inner, callback, data);
+ retval = expand_regions (region->inner, callback, data, traverse_clones);
if (retval)
return retval;
}
/* 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. */
+ function will return as well. TRAVERSE_CLONES is true if we should
+ traverse transactional clones. */
static void *
expand_regions (struct tm_region *region,
void *(*callback)(struct tm_region *, void *),
- void *data)
+ void *data,
+ bool traverse_clones)
{
void *retval = NULL;
while (region)
{
- retval = expand_regions_1 (region, callback, data);
+ retval = expand_regions_1 (region, callback, data, traverse_clones);
if (retval)
return retval;
region = region->next;