diff options
author | Richard Henderson <rth@redhat.com> | 2015-12-22 11:42:24 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2015-12-22 11:42:24 -0800 |
commit | 7c11b0fef088480510a74f0f43015776c40be047 (patch) | |
tree | a8d42a55a283fef873d7bbbede9d1387b48f417a /gcc/tree-cfg.c | |
parent | ebe9921f0ce92a25657dee9e7913b944db8f0271 (diff) | |
download | gcc-7c11b0fef088480510a74f0f43015776c40be047.zip gcc-7c11b0fef088480510a74f0f43015776c40be047.tar.gz gcc-7c11b0fef088480510a74f0f43015776c40be047.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 5aad9ee..436ea14 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -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) + { + new_label = main_block_label (label); + if (new_label != 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) { - 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_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,11 +5678,15 @@ 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), - gimple_block_label (dest)); + 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; default: |