aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-16.c43
-rw-r--r--gcc/trans-mem.c13
3 files changed, 61 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 681007b..2b11aa5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-09-10 Andrew Pinski <apinski@cavium.com>
+
+ PR tree-opt/54362
+ * trans-mem.c (thread_private_new_memory): Handle COND_EXPR also.
+
2012-09-10 Maxim Kuvyrkov <maxim@codesourcery.com>
* config/m68k/m68k.c (m68k_sched_dfa_post_advance_cycle): Support
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-16.c b/gcc/testsuite/gcc.dg/tm/memopt-16.c
new file mode 100644
index 0000000..c230240
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-16.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O3 -fdump-tree-tmmark" } */
+/* Like memopt-12.c but the phi is inside a look which causes
+ it to be converted into a COND_EXPR. */
+
+extern int test(void) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+struct large { int foo[500]; };
+
+int f(int j)
+{
+ int *p1, *p2, *p3;
+
+ p1 = malloc (sizeof (*p1)*5000);
+ __transaction_atomic {
+ _Bool t;
+ int i = 1;
+ *p1 = 0;
+
+ p2 = malloc (sizeof (*p2)*6000);
+ *p2 = 1;
+ t = test();
+
+ for (i = 0;i < j;i++)
+ {
+
+ /* p3 = PHI (p1, p2) */
+ if (t)
+ p3 = p1;
+ else
+ p3 = p2;
+
+ /* Since both p1 and p2 are thread-private, we can inherit the
+ logging already done. No ITM_W* instrumentation necessary. */
+ *p3 = 555;
+ }
+ }
+ return p3[something()];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_WU" 0 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index edb678e..e71efff 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -1379,6 +1379,19 @@ thread_private_new_memory (basic_block entry_block, tree x)
/* x = (cast*) foo ==> foo */
else if (code == VIEW_CONVERT_EXPR || code == NOP_EXPR)
x = gimple_assign_rhs1 (stmt);
+ /* x = c ? op1 : op2 == > op1 or op2 just like a PHI */
+ else if (code == COND_EXPR)
+ {
+ tree op1 = gimple_assign_rhs2 (stmt);
+ tree op2 = gimple_assign_rhs3 (stmt);
+ enum thread_memory_type mem;
+ retval = thread_private_new_memory (entry_block, op1);
+ if (retval == mem_non_local)
+ goto new_memory_ret;
+ mem = thread_private_new_memory (entry_block, op2);
+ retval = MIN (retval, mem);
+ goto new_memory_ret;
+ }
else
{
retval = mem_non_local;