re PR ipa/67811 ([TM] ICE with try-block in transaction)
PR ipa/67811 * gimple.h (struct gtransaction): Add label_norm, label_uninst; replace label with label_over. (gimple_build_transaction): Remove label parameter. (gimple_transaction_label_norm): New. (gimple_transaction_label_uninst): New. (gimple_transaction_label_over): Rename from gimple_transaction_label. (gimple_transaction_label_norm_ptr): New. (gimple_transaction_label_uninst_ptr): New. (gimple_transaction_label_over_ptr): Rename from gimple_transaction_label_ptr. (gimple_transaction_set_label_norm): New. (gimple_transaction_set_label_uninst): New. (gimple_transaction_set_label_over): Rename from gimple_transaction_set_label. * gimple-pretty-print.c (dump_gimple_transaction): Update. * gimple-streamer-in.c (input_gimple_stmt) [GIMPLE_TRANSACTION]: Same. * gimple-streamer-out.c (output_gimple_stmt) [GIMPLE_TRANSACTION]: Same. * gimple-walk.c (walk_gimple_op) [GIMPLE_TRANSACTION]: Same. * tree-cfg.c (make_edges_bb) [GIMPLE_TRANSACTION]: Same. (cleanup_dead_labels) [GIMPLE_TRANSACTION]: Same. (verify_gimple_transaction): Same. (gimple_redirect_edge_and_branch) [GIMPLE_TRANSACTION]: Same. * tree-inline.c (remap_gimple_stmt) [GIMPLE_TRANSACTION]: Same. * gimple.c (gimple_build_transaction): Remove label parameter; initialize all three label memebers. * gimplify.c (gimplify_transaction): Update call to gimple_build_transaction. * trans-mem.c (make_tm_uninst): New. (lower_transaction): Create uninstrumented code path here... (ipa_tm_scan_calls_transaction): ... not here. (ipa_uninstrument_transaction): Remove. testsuite/ * g++.dg/tm/noexcept-1.C: Update expected must_not_throw count. * g++.dg/tm/noexcept-4.C: Likewise. * g++.dg/tm/noexcept-5.C: Likewise. * g++.dg/tm/pr67811.C: New. From-SVN: r231907
This commit is contained in:
parent
ebe9921f0c
commit
7c11b0fef0
|
@ -1,3 +1,38 @@
|
|||
2015-12-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR ipa/67811
|
||||
* gimple.h (struct gtransaction): Add label_norm, label_uninst;
|
||||
replace label with label_over.
|
||||
(gimple_build_transaction): Remove label parameter.
|
||||
(gimple_transaction_label_norm): New.
|
||||
(gimple_transaction_label_uninst): New.
|
||||
(gimple_transaction_label_over): Rename from gimple_transaction_label.
|
||||
(gimple_transaction_label_norm_ptr): New.
|
||||
(gimple_transaction_label_uninst_ptr): New.
|
||||
(gimple_transaction_label_over_ptr): Rename from
|
||||
gimple_transaction_label_ptr.
|
||||
(gimple_transaction_set_label_norm): New.
|
||||
(gimple_transaction_set_label_uninst): New.
|
||||
(gimple_transaction_set_label_over): Rename from
|
||||
gimple_transaction_set_label.
|
||||
* gimple-pretty-print.c (dump_gimple_transaction): Update.
|
||||
* gimple-streamer-in.c (input_gimple_stmt) [GIMPLE_TRANSACTION]: Same.
|
||||
* gimple-streamer-out.c (output_gimple_stmt) [GIMPLE_TRANSACTION]: Same.
|
||||
* gimple-walk.c (walk_gimple_op) [GIMPLE_TRANSACTION]: Same.
|
||||
* tree-cfg.c (make_edges_bb) [GIMPLE_TRANSACTION]: Same.
|
||||
(cleanup_dead_labels) [GIMPLE_TRANSACTION]: Same.
|
||||
(verify_gimple_transaction): Same.
|
||||
(gimple_redirect_edge_and_branch) [GIMPLE_TRANSACTION]: Same.
|
||||
* tree-inline.c (remap_gimple_stmt) [GIMPLE_TRANSACTION]: Same.
|
||||
* gimple.c (gimple_build_transaction): Remove label parameter;
|
||||
initialize all three label memebers.
|
||||
* gimplify.c (gimplify_transaction): Update call
|
||||
to gimple_build_transaction.
|
||||
* trans-mem.c (make_tm_uninst): New.
|
||||
(lower_transaction): Create uninstrumented code path here...
|
||||
(ipa_tm_scan_calls_transaction): ... not here.
|
||||
(ipa_uninstrument_transaction): Remove.
|
||||
|
||||
2015-12-22 Peter Bergner <bergner@vnet.ibm.com>
|
||||
|
||||
PR target/68772
|
||||
|
|
|
@ -1607,8 +1607,11 @@ dump_gimple_transaction (pretty_printer *buffer, gtransaction *gs,
|
|||
if (flags & TDF_RAW)
|
||||
{
|
||||
dump_gimple_fmt (buffer, spc, flags,
|
||||
"%G [SUBCODE=%x,LABEL=%T] <%+BODY <%S> >",
|
||||
gs, subcode, gimple_transaction_label (gs),
|
||||
"%G [SUBCODE=%x,NORM=%T,UNINST=%T,OVER=%T] "
|
||||
"<%+BODY <%S> >",
|
||||
gs, subcode, gimple_transaction_label_norm (gs),
|
||||
gimple_transaction_label_uninst (gs),
|
||||
gimple_transaction_label_over (gs),
|
||||
gimple_transaction_body (gs));
|
||||
}
|
||||
else
|
||||
|
@ -1621,13 +1624,35 @@ dump_gimple_transaction (pretty_printer *buffer, gtransaction *gs,
|
|||
pp_string (buffer, "__transaction_atomic");
|
||||
subcode &= ~GTMA_DECLARATION_MASK;
|
||||
|
||||
if (subcode || gimple_transaction_label (gs))
|
||||
if (gimple_transaction_body (gs))
|
||||
{
|
||||
newline_and_indent (buffer, spc + 2);
|
||||
pp_left_brace (buffer);
|
||||
pp_newline (buffer);
|
||||
dump_gimple_seq (buffer, gimple_transaction_body (gs),
|
||||
spc + 4, flags);
|
||||
newline_and_indent (buffer, spc + 2);
|
||||
pp_right_brace (buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
pp_string (buffer, " //");
|
||||
if (gimple_transaction_label (gs))
|
||||
if (gimple_transaction_label_norm (gs))
|
||||
{
|
||||
pp_string (buffer, " LABEL=");
|
||||
dump_generic_node (buffer, gimple_transaction_label (gs),
|
||||
pp_string (buffer, " NORM=");
|
||||
dump_generic_node (buffer, gimple_transaction_label_norm (gs),
|
||||
spc, flags, false);
|
||||
}
|
||||
if (gimple_transaction_label_uninst (gs))
|
||||
{
|
||||
pp_string (buffer, " UNINST=");
|
||||
dump_generic_node (buffer, gimple_transaction_label_uninst (gs),
|
||||
spc, flags, false);
|
||||
}
|
||||
if (gimple_transaction_label_over (gs))
|
||||
{
|
||||
pp_string (buffer, " OVER=");
|
||||
dump_generic_node (buffer, gimple_transaction_label_over (gs),
|
||||
spc, flags, false);
|
||||
}
|
||||
if (subcode)
|
||||
|
@ -1668,17 +1693,6 @@ dump_gimple_transaction (pretty_printer *buffer, gtransaction *gs,
|
|||
pp_right_bracket (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gimple_seq_empty_p (gimple_transaction_body (gs)))
|
||||
{
|
||||
newline_and_indent (buffer, spc + 2);
|
||||
pp_left_brace (buffer);
|
||||
pp_newline (buffer);
|
||||
dump_gimple_seq (buffer, gimple_transaction_body (gs),
|
||||
spc + 4, flags);
|
||||
newline_and_indent (buffer, spc + 2);
|
||||
pp_right_brace (buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,11 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
|||
break;
|
||||
|
||||
case GIMPLE_TRANSACTION:
|
||||
gimple_transaction_set_label (as_a <gtransaction *> (stmt),
|
||||
gimple_transaction_set_label_norm (as_a <gtransaction *> (stmt),
|
||||
stream_read_tree (ib, data_in));
|
||||
gimple_transaction_set_label_uninst (as_a <gtransaction *> (stmt),
|
||||
stream_read_tree (ib, data_in));
|
||||
gimple_transaction_set_label_over (as_a <gtransaction *> (stmt),
|
||||
stream_read_tree (ib, data_in));
|
||||
break;
|
||||
|
||||
|
|
|
@ -180,9 +180,11 @@ output_gimple_stmt (struct output_block *ob, gimple *stmt)
|
|||
|
||||
case GIMPLE_TRANSACTION:
|
||||
{
|
||||
gtransaction *trans_stmt = as_a <gtransaction *> (stmt);
|
||||
gcc_assert (gimple_transaction_body (trans_stmt) == NULL);
|
||||
stream_write_tree (ob, gimple_transaction_label (trans_stmt), true);
|
||||
gtransaction *txn = as_a <gtransaction *> (stmt);
|
||||
gcc_assert (gimple_transaction_body (txn) == NULL);
|
||||
stream_write_tree (ob, gimple_transaction_label_norm (txn), true);
|
||||
stream_write_tree (ob, gimple_transaction_label_uninst (txn), true);
|
||||
stream_write_tree (ob, gimple_transaction_label_over (txn), true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -474,11 +474,22 @@ walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
|
|||
break;
|
||||
|
||||
case GIMPLE_TRANSACTION:
|
||||
ret = walk_tree (gimple_transaction_label_ptr (
|
||||
as_a <gtransaction *> (stmt)),
|
||||
{
|
||||
gtransaction *txn = as_a <gtransaction *> (stmt);
|
||||
|
||||
ret = walk_tree (gimple_transaction_label_norm_ptr (txn),
|
||||
callback_op, wi, pset);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = walk_tree (gimple_transaction_label_uninst_ptr (txn),
|
||||
callback_op, wi, pset);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = walk_tree (gimple_transaction_label_over_ptr (txn),
|
||||
callback_op, wi, pset);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_RETURN:
|
||||
|
|
|
@ -1131,12 +1131,14 @@ gimple_build_omp_atomic_store (tree val)
|
|||
/* Build a GIMPLE_TRANSACTION statement. */
|
||||
|
||||
gtransaction *
|
||||
gimple_build_transaction (gimple_seq body, tree label)
|
||||
gimple_build_transaction (gimple_seq body)
|
||||
{
|
||||
gtransaction *p
|
||||
= as_a <gtransaction *> (gimple_alloc (GIMPLE_TRANSACTION, 0));
|
||||
gimple_transaction_set_body (p, body);
|
||||
gimple_transaction_set_label (p, label);
|
||||
gimple_transaction_set_label_norm (p, 0);
|
||||
gimple_transaction_set_label_uninst (p, 0);
|
||||
gimple_transaction_set_label_over (p, 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
59
gcc/gimple.h
59
gcc/gimple.h
|
@ -836,8 +836,10 @@ struct GTY((tag("GSS_TRANSACTION")))
|
|||
/* [ WORD 10 ] */
|
||||
gimple_seq body;
|
||||
|
||||
/* [ WORD 11 ] */
|
||||
tree label;
|
||||
/* [ WORD 11-13 ] */
|
||||
tree label_norm;
|
||||
tree label_uninst;
|
||||
tree label_over;
|
||||
};
|
||||
|
||||
#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM,
|
||||
|
@ -1463,7 +1465,7 @@ gomp_target *gimple_build_omp_target (gimple_seq, int, tree);
|
|||
gomp_teams *gimple_build_omp_teams (gimple_seq, tree);
|
||||
gomp_atomic_load *gimple_build_omp_atomic_load (tree, tree);
|
||||
gomp_atomic_store *gimple_build_omp_atomic_store (tree);
|
||||
gtransaction *gimple_build_transaction (gimple_seq, tree);
|
||||
gtransaction *gimple_build_transaction (gimple_seq);
|
||||
extern void gimple_seq_add_stmt (gimple_seq *, gimple *);
|
||||
extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple *);
|
||||
void gimple_seq_add_seq (gimple_seq *, gimple_seq);
|
||||
|
@ -5847,21 +5849,45 @@ gimple_transaction_body_ptr (gtransaction *transaction_stmt)
|
|||
static inline gimple_seq
|
||||
gimple_transaction_body (gtransaction *transaction_stmt)
|
||||
{
|
||||
return *gimple_transaction_body_ptr (transaction_stmt);
|
||||
return transaction_stmt->body;
|
||||
}
|
||||
|
||||
/* Return the label associated with a GIMPLE_TRANSACTION. */
|
||||
|
||||
static inline tree
|
||||
gimple_transaction_label (const gtransaction *transaction_stmt)
|
||||
gimple_transaction_label_norm (const gtransaction *transaction_stmt)
|
||||
{
|
||||
return transaction_stmt->label;
|
||||
return transaction_stmt->label_norm;
|
||||
}
|
||||
|
||||
static inline tree *
|
||||
gimple_transaction_label_ptr (gtransaction *transaction_stmt)
|
||||
gimple_transaction_label_norm_ptr (gtransaction *transaction_stmt)
|
||||
{
|
||||
return &transaction_stmt->label;
|
||||
return &transaction_stmt->label_norm;
|
||||
}
|
||||
|
||||
static inline tree
|
||||
gimple_transaction_label_uninst (const gtransaction *transaction_stmt)
|
||||
{
|
||||
return transaction_stmt->label_uninst;
|
||||
}
|
||||
|
||||
static inline tree *
|
||||
gimple_transaction_label_uninst_ptr (gtransaction *transaction_stmt)
|
||||
{
|
||||
return &transaction_stmt->label_uninst;
|
||||
}
|
||||
|
||||
static inline tree
|
||||
gimple_transaction_label_over (const gtransaction *transaction_stmt)
|
||||
{
|
||||
return transaction_stmt->label_over;
|
||||
}
|
||||
|
||||
static inline tree *
|
||||
gimple_transaction_label_over_ptr (gtransaction *transaction_stmt)
|
||||
{
|
||||
return &transaction_stmt->label_over;
|
||||
}
|
||||
|
||||
/* Return the subcode associated with a GIMPLE_TRANSACTION. */
|
||||
|
@ -5885,9 +5911,21 @@ gimple_transaction_set_body (gtransaction *transaction_stmt,
|
|||
/* Set the label associated with a GIMPLE_TRANSACTION. */
|
||||
|
||||
static inline void
|
||||
gimple_transaction_set_label (gtransaction *transaction_stmt, tree label)
|
||||
gimple_transaction_set_label_norm (gtransaction *transaction_stmt, tree label)
|
||||
{
|
||||
transaction_stmt->label = label;
|
||||
transaction_stmt->label_norm = label;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gimple_transaction_set_label_uninst (gtransaction *transaction_stmt, tree label)
|
||||
{
|
||||
transaction_stmt->label_uninst = label;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gimple_transaction_set_label_over (gtransaction *transaction_stmt, tree label)
|
||||
{
|
||||
transaction_stmt->label_over = label;
|
||||
}
|
||||
|
||||
/* Set the subcode associated with a GIMPLE_TRANSACTION. */
|
||||
|
@ -5899,7 +5937,6 @@ gimple_transaction_set_subcode (gtransaction *transaction_stmt,
|
|||
transaction_stmt->subcode = subcode;
|
||||
}
|
||||
|
||||
|
||||
/* Return a pointer to the return value for GIMPLE_RETURN GS. */
|
||||
|
||||
static inline tree *
|
||||
|
|
|
@ -9739,7 +9739,7 @@ gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
|
|||
body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
|
||||
pop_gimplify_context (body_stmt);
|
||||
|
||||
trans_stmt = gimple_build_transaction (body, NULL);
|
||||
trans_stmt = gimple_build_transaction (body);
|
||||
if (TRANSACTION_EXPR_OUTER (expr))
|
||||
subcode = GTMA_IS_OUTER;
|
||||
else if (TRANSACTION_EXPR_RELAXED (expr))
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2015-12-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* g++.dg/tm/noexcept-1.C: Update expected must_not_throw count.
|
||||
* g++.dg/tm/noexcept-4.C: Likewise.
|
||||
* g++.dg/tm/noexcept-5.C: Likewise.
|
||||
* g++.dg/tm/pr67811.C: New.
|
||||
|
||||
2015-12-22 Peter Bergner <bergner@vnet.ibm.com>
|
||||
|
||||
PR target/68772
|
||||
|
|
|
@ -32,5 +32,5 @@ int f3()
|
|||
return global;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 6 "tmlower" } } */
|
||||
/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 12 "tmlower" } } */
|
||||
/* { dg-final { scan-tree-dump-times "ITM_RU" 6 "tmmark" } } */
|
||||
|
|
|
@ -29,5 +29,5 @@ int f3()
|
|||
+ __transaction_atomic noexcept (global + 6);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 6 "tmlower" } } */
|
||||
/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 12 "tmlower" } } */
|
||||
/* { dg-final { scan-tree-dump-times "ITM_RU" 6 "tmmark" } } */
|
||||
|
|
|
@ -15,5 +15,5 @@ void f2(int x)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 1 "tmlower" } } */
|
||||
/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 2 "tmlower" } } */
|
||||
/* { dg-final { scan-tree-dump-times "ITM_RU" 1 "tmmark" } } */
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options "-fgnu-tm" }
|
||||
|
||||
void f()
|
||||
{
|
||||
__transaction_relaxed {
|
||||
try { throw 42; }
|
||||
catch (...) { }
|
||||
}
|
||||
}
|
||||
|
115
gcc/trans-mem.c
115
gcc/trans-mem.c
|
@ -1608,6 +1608,27 @@ examine_call_tm (unsigned *state, gimple_stmt_iterator *gsi)
|
|||
*state |= GTMA_HAVE_LOAD | GTMA_HAVE_STORE;
|
||||
}
|
||||
|
||||
/* Iterate through the statements in the sequence, moving labels
|
||||
(and thus edges) of transactions from "label_norm" to "label_uninst". */
|
||||
|
||||
static tree
|
||||
make_tm_uninst (gimple_stmt_iterator *gsi, bool *handled_ops_p,
|
||||
struct walk_stmt_info *)
|
||||
{
|
||||
gimple *stmt = gsi_stmt (*gsi);
|
||||
|
||||
if (gtransaction *txn = dyn_cast <gtransaction *> (stmt))
|
||||
{
|
||||
*handled_ops_p = true;
|
||||
txn->label_uninst = txn->label_norm;
|
||||
txn->label_norm = NULL;
|
||||
}
|
||||
else
|
||||
*handled_ops_p = !gimple_has_substatements (stmt);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Lower a GIMPLE_TRANSACTION statement. */
|
||||
|
||||
static void
|
||||
|
@ -1670,20 +1691,49 @@ lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi)
|
|||
|
||||
g = gimple_build_try (gimple_transaction_body (stmt),
|
||||
gimple_seq_alloc_with_stmt (g), GIMPLE_TRY_FINALLY);
|
||||
gsi_insert_after (gsi, g, GSI_CONTINUE_LINKING);
|
||||
|
||||
gimple_transaction_set_body (stmt, NULL);
|
||||
/* For a (potentially) outer transaction, create two paths. */
|
||||
gimple_seq uninst = NULL;
|
||||
if (outer_state == NULL)
|
||||
{
|
||||
uninst = copy_gimple_seq_and_replace_locals (g);
|
||||
/* In the uninstrumented copy, reset inner transactions to have only
|
||||
an uninstrumented code path. */
|
||||
memset (&this_wi, 0, sizeof (this_wi));
|
||||
walk_gimple_seq (uninst, make_tm_uninst, NULL, &this_wi);
|
||||
}
|
||||
|
||||
tree label1 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
gsi_insert_after (gsi, gimple_build_label (label1), GSI_CONTINUE_LINKING);
|
||||
gsi_insert_after (gsi, g, GSI_CONTINUE_LINKING);
|
||||
gimple_transaction_set_label_norm (stmt, label1);
|
||||
|
||||
/* If the transaction calls abort or if this is an outer transaction,
|
||||
add an "over" label afterwards. */
|
||||
if ((this_state & (GTMA_HAVE_ABORT))
|
||||
tree label3 = NULL;
|
||||
if ((this_state & GTMA_HAVE_ABORT)
|
||||
|| outer_state == NULL
|
||||
|| (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER))
|
||||
{
|
||||
tree label = create_artificial_label (UNKNOWN_LOCATION);
|
||||
gimple_transaction_set_label (stmt, label);
|
||||
gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
|
||||
label3 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
gimple_transaction_set_label_over (stmt, label3);
|
||||
}
|
||||
|
||||
if (uninst != NULL)
|
||||
{
|
||||
gsi_insert_after (gsi, gimple_build_goto (label3), GSI_CONTINUE_LINKING);
|
||||
|
||||
tree label2 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
gsi_insert_after (gsi, gimple_build_label (label2), GSI_CONTINUE_LINKING);
|
||||
gsi_insert_seq_after (gsi, uninst, GSI_CONTINUE_LINKING);
|
||||
gimple_transaction_set_label_uninst (stmt, label2);
|
||||
}
|
||||
|
||||
if (label3 != NULL)
|
||||
gsi_insert_after (gsi, gimple_build_label (label3), GSI_CONTINUE_LINKING);
|
||||
|
||||
gimple_transaction_set_body (stmt, NULL);
|
||||
|
||||
/* Record the set of operations found for use later. */
|
||||
this_state |= gimple_transaction_subcode (stmt) & GTMA_DECLARATION_MASK;
|
||||
gimple_transaction_set_subcode (stmt, this_state);
|
||||
|
@ -4113,35 +4163,6 @@ maybe_push_queue (struct cgraph_node *node,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
static void
|
||||
ipa_uninstrument_transaction (struct tm_region *region,
|
||||
vec<basic_block> queue)
|
||||
{
|
||||
gimple *transaction = region->transaction_stmt;
|
||||
basic_block transaction_bb = gimple_bb (transaction);
|
||||
int n = queue.length ();
|
||||
basic_block *new_bbs = XNEWVEC (basic_block, n);
|
||||
|
||||
copy_bbs (queue.address (), n, new_bbs, NULL, 0, NULL, NULL, transaction_bb,
|
||||
true);
|
||||
edge e = make_edge (transaction_bb, new_bbs[0], EDGE_TM_UNINSTRUMENTED);
|
||||
add_phi_args_after_copy (new_bbs, n, e);
|
||||
|
||||
// Now we will have a GIMPLE_ATOMIC with 3 possible edges out of it.
|
||||
// a) EDGE_FALLTHRU into the transaction
|
||||
// b) EDGE_TM_ABORT out of the transaction
|
||||
// c) EDGE_TM_UNINSTRUMENTED into the uninstrumented blocks.
|
||||
|
||||
free (new_bbs);
|
||||
}
|
||||
|
||||
/* A subroutine of ipa_tm_scan_calls_transaction and ipa_tm_scan_calls_clone.
|
||||
Queue all callees within block BB. */
|
||||
|
||||
|
@ -4189,43 +4210,23 @@ static void
|
|||
ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d,
|
||||
cgraph_node_queue *callees_p)
|
||||
{
|
||||
struct tm_region *r;
|
||||
|
||||
d->transaction_blocks_normal = BITMAP_ALLOC (&tm_obstack);
|
||||
d->all_tm_regions = all_tm_regions;
|
||||
|
||||
for (r = all_tm_regions; r; r = r->next)
|
||||
for (tm_region *r = all_tm_regions; r; r = r->next)
|
||||
{
|
||||
vec<basic_block> bbs;
|
||||
basic_block bb;
|
||||
unsigned i;
|
||||
|
||||
bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks, NULL,
|
||||
d->transaction_blocks_normal, false);
|
||||
|
||||
// Generate the uninstrumented code path for this transaction.
|
||||
ipa_uninstrument_transaction (r, bbs);
|
||||
d->transaction_blocks_normal, false, false);
|
||||
|
||||
FOR_EACH_VEC_ELT (bbs, i, bb)
|
||||
ipa_tm_scan_calls_block (callees_p, bb, false);
|
||||
|
||||
bbs.release ();
|
||||
}
|
||||
|
||||
// ??? copy_bbs should maintain cgraph edges for the blocks as it is
|
||||
// copying them, rather than forcing us to do this externally.
|
||||
cgraph_edge::rebuild_edges ();
|
||||
|
||||
// ??? In ipa_uninstrument_transaction we don't try to update dominators
|
||||
// because copy_bbs doesn't return a VEC like iterate_fix_dominators expects.
|
||||
// Instead, just release dominators here so update_ssa recomputes them.
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
// When building the uninstrumented code path, copy_bbs will have invoked
|
||||
// create_new_def_for starting an "ssa update context". There is only one
|
||||
// instance of this context, so resolve ssa updates before moving on to
|
||||
// the next function.
|
||||
update_ssa (TODO_update_ssa);
|
||||
}
|
||||
|
||||
/* Scan all calls in NODE as if this is the transactional clone,
|
||||
|
|
|
@ -828,11 +828,21 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
|
|||
|
||||
case GIMPLE_TRANSACTION:
|
||||
{
|
||||
tree abort_label
|
||||
= gimple_transaction_label (as_a <gtransaction *> (last));
|
||||
if (abort_label)
|
||||
make_edge (bb, label_to_block (abort_label), EDGE_TM_ABORT);
|
||||
fallthru = true;
|
||||
gtransaction *txn = as_a <gtransaction *> (last);
|
||||
tree label1 = gimple_transaction_label_norm (txn);
|
||||
tree label2 = gimple_transaction_label_uninst (txn);
|
||||
|
||||
if (label1)
|
||||
make_edge (bb, label_to_block (label1), EDGE_FALLTHRU);
|
||||
if (label2)
|
||||
make_edge (bb, label_to_block (label2),
|
||||
EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU));
|
||||
|
||||
tree label3 = gimple_transaction_label_over (txn);
|
||||
if (gimple_transaction_subcode (txn) & GTMA_HAVE_ABORT)
|
||||
make_edge (bb, label_to_block (label3), EDGE_TM_ABORT);
|
||||
|
||||
fallthru = false;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1517,13 +1527,30 @@ cleanup_dead_labels (void)
|
|||
|
||||
case GIMPLE_TRANSACTION:
|
||||
{
|
||||
gtransaction *trans_stmt = as_a <gtransaction *> (stmt);
|
||||
tree label = gimple_transaction_label (trans_stmt);
|
||||
gtransaction *txn = as_a <gtransaction *> (stmt);
|
||||
|
||||
label = gimple_transaction_label_norm (txn);
|
||||
if (label)
|
||||
{
|
||||
tree new_label = main_block_label (label);
|
||||
new_label = main_block_label (label);
|
||||
if (new_label != label)
|
||||
gimple_transaction_set_label (trans_stmt, new_label);
|
||||
gimple_transaction_set_label_norm (txn, new_label);
|
||||
}
|
||||
|
||||
label = gimple_transaction_label_uninst (txn);
|
||||
if (label)
|
||||
{
|
||||
new_label = main_block_label (label);
|
||||
if (new_label != label)
|
||||
gimple_transaction_set_label_uninst (txn, new_label);
|
||||
}
|
||||
|
||||
label = gimple_transaction_label_over (txn);
|
||||
if (label)
|
||||
{
|
||||
new_label = main_block_label (label);
|
||||
if (new_label != label)
|
||||
gimple_transaction_set_label_over (txn, new_label);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -4732,9 +4759,18 @@ verify_gimple_in_seq_2 (gimple_seq stmts)
|
|||
static bool
|
||||
verify_gimple_transaction (gtransaction *stmt)
|
||||
{
|
||||
tree lab = gimple_transaction_label (stmt);
|
||||
tree lab;
|
||||
|
||||
lab = gimple_transaction_label_norm (stmt);
|
||||
if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
|
||||
return true;
|
||||
lab = gimple_transaction_label_uninst (stmt);
|
||||
if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
|
||||
return true;
|
||||
lab = gimple_transaction_label_over (stmt);
|
||||
if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
|
||||
return true;
|
||||
|
||||
return verify_gimple_in_seq_2 (gimple_transaction_body (stmt));
|
||||
}
|
||||
|
||||
|
@ -5642,10 +5678,14 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
|
|||
break;
|
||||
|
||||
case GIMPLE_TRANSACTION:
|
||||
/* The ABORT edge has a stored label associated with it, otherwise
|
||||
the edges are simply redirectable. */
|
||||
if (e->flags == 0)
|
||||
gimple_transaction_set_label (as_a <gtransaction *> (stmt),
|
||||
if (e->flags & EDGE_TM_ABORT)
|
||||
gimple_transaction_set_label_over (as_a <gtransaction *> (stmt),
|
||||
gimple_block_label (dest));
|
||||
else if (e->flags & EDGE_TM_UNINSTRUMENTED)
|
||||
gimple_transaction_set_label_uninst (as_a <gtransaction *> (stmt),
|
||||
gimple_block_label (dest));
|
||||
else
|
||||
gimple_transaction_set_label_norm (as_a <gtransaction *> (stmt),
|
||||
gimple_block_label (dest));
|
||||
break;
|
||||
|
||||
|
|
|
@ -1518,13 +1518,15 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
|
|||
gtransaction *new_trans_stmt;
|
||||
s1 = remap_gimple_seq (gimple_transaction_body (old_trans_stmt),
|
||||
id);
|
||||
copy = new_trans_stmt
|
||||
= gimple_build_transaction (
|
||||
s1,
|
||||
gimple_transaction_label (old_trans_stmt));
|
||||
gimple_transaction_set_subcode (
|
||||
new_trans_stmt,
|
||||
copy = new_trans_stmt = gimple_build_transaction (s1);
|
||||
gimple_transaction_set_subcode (new_trans_stmt,
|
||||
gimple_transaction_subcode (old_trans_stmt));
|
||||
gimple_transaction_set_label_norm (new_trans_stmt,
|
||||
gimple_transaction_label_norm (old_trans_stmt));
|
||||
gimple_transaction_set_label_uninst (new_trans_stmt,
|
||||
gimple_transaction_label_uninst (old_trans_stmt));
|
||||
gimple_transaction_set_label_over (new_trans_stmt,
|
||||
gimple_transaction_label_over (old_trans_stmt));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue