[trans-mem] expand transactions inside cloned functions
Aldy Hernandez
aldyh@redhat.com
Thu May 6 19:14:00 GMT 2010
Howdy!
Cloned functions have an outermost transaction that encompasses the
entire function (see gate_tm_init()). This outermost transaction has no
exit blocks, which causes execute_tm_edges() to skip expanding any
transactions therein.
The problem/ICE can be seen in either a recursive transaction call, or
while compiling a clone of a function which itself is transaction
callable. See both tests below.
Fixed by looking in the inner transaction (the actual transaction) when
analyzing a clone.
OK for branch?
* trans-mem.c (execute_tm_edges): Look for transactions inside
cloned functions.
Index: testsuite/c-c++-common/tm/recurse.c
===================================================================
--- testsuite/c-c++-common/tm/recurse.c (revision 0)
+++ testsuite/c-c++-common/tm/recurse.c (revision 0)
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+void foobar(void)
+{
+ __transaction {
+ foobar();
+ }
+}
+
+void doit(void) __attribute__((transaction_safe));
+
+__attribute__((transaction_callable))
+void callable(void)
+{
+ __transaction {
+ doit();
+ }
+}
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 159008)
+++ trans-mem.c (working copy)
@@ -2449,27 +2449,37 @@ expand_transaction (struct tm_region *re
static unsigned int
execute_tm_edges (void)
{
- struct tm_region *region;
+ struct tm_region *region, *r;
VEC (basic_block, heap) *queue;
for (region = all_tm_regions; region ; region = region->next)
- if (region->exit_blocks)
- {
- unsigned int i;
- basic_block bb;
+ {
+ /* If this is a clone, the outermost region is the entire
+ transaction and has no exit block. Look inside for the
+ actual region. */
+ if (region->transaction_stmt == NULL && region->inner&&0)
+ r = region->inner;
+ else
+ r = region;
- /* Collect the set of blocks in this region. Do this before
- splitting edges, so that we don't have to play with the
- dominator tree in the middle. */
- queue = get_tm_region_blocks (region->entry_block,
- region->exit_blocks,
- region->irr_blocks,
- /*stop_at_irr_p=*/false);
- expand_transaction (region);
- for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
- expand_block_edges (region, bb);
- VEC_free (basic_block, heap, queue);
- }
+ if (r->exit_blocks)
+ {
+ unsigned int i;
+ basic_block bb;
+
+ /* Collect the set of blocks in this region. Do this before
+ splitting edges, so that we don't have to play with the
+ dominator tree in the middle. */
+ queue = get_tm_region_blocks (r->entry_block,
+ r->exit_blocks,
+ r->irr_blocks,
+ /*stop_at_irr_p=*/false);
+ expand_transaction (r);
+ for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
+ expand_block_edges (r, bb);
+ VEC_free (basic_block, heap, queue);
+ }
+ }
tm_log_delete ();
/* We've got to release the dominance info now, to indicate that it
More information about the Gcc-patches
mailing list