summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-05 20:20:57 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-05 20:20:57 +0000
commitd7ff3ab6455d3c222ff98a4d30e0e86d115564bf (patch)
tree990059fd6e94d825094e7d8bc0afd68533edad28 /gcc
parent1aed71d6a8edf6d77849059d17daf851bc646cca (diff)
downloadgcc-d7ff3ab6455d3c222ff98a4d30e0e86d115564bf.tar.gz
PR rtl-optimization/51767
* cfgrtl.c (force_nonfallthru_and_redirect): Force addition of jump_block and add an extra edge for degenerated asm gotos. * gcc.c-torture/compile/pr51767.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182922 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/cfgrtl.c47
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr51767.c23
4 files changed, 71 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e59648f2fa..1bd3bb26295 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2012-01-05 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/51767
+ * cfgrtl.c (force_nonfallthru_and_redirect): Force addition
+ of jump_block and add an extra edge for degenerated asm gotos.
+
PR middle-end/51768
* stmt.c (check_unique_operand_names): Don't ICE during error
reporting if i is from labels chain.
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 4b1d8350de5..635955b7990 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1,7 +1,7 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
rtx note;
edge new_edge;
int abnormal_edge_flags = 0;
+ bool asm_goto_edge = false;
int loc;
/* In the case the last instruction is conditional jump to the next
@@ -1208,8 +1209,28 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
}
}
- if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags)
+ /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
+ don't point to target label. */
+ if (JUMP_P (BB_END (e->src))
+ && target != EXIT_BLOCK_PTR
+ && e->dest == target
+ && (e->flags & EDGE_FALLTHRU)
+ && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
{
+ int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+
+ for (i = 0; i < n; ++i)
+ if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
+ {
+ asm_goto_edge = true;
+ break;
+ }
+ }
+
+ if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
+ {
+ gcov_type count = e->count;
+ int probability = e->probability;
/* Create the new structures. */
/* If the old block ended with a tablejump, skip its table
@@ -1220,7 +1241,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
note = NEXT_INSN (note);
jump_block = create_basic_block (note, NULL, e->src);
- jump_block->count = e->count;
+ jump_block->count = count;
jump_block->frequency = EDGE_FREQUENCY (e);
jump_block->loop_depth = target->loop_depth;
@@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
/* Wire edge in. */
new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
- new_edge->probability = e->probability;
- new_edge->count = e->count;
+ new_edge->probability = probability;
+ new_edge->count = count;
/* Redirect old edge. */
redirect_edge_pred (e, jump_block);
e->probability = REG_BR_PROB_BASE;
+ /* If asm goto has any label refs to target's label,
+ add also edge from asm goto bb to target. */
+ if (asm_goto_edge)
+ {
+ new_edge->probability /= 2;
+ new_edge->count /= 2;
+ jump_block->count /= 2;
+ jump_block->frequency /= 2;
+ new_edge = make_edge (new_edge->src, target,
+ e->flags & ~EDGE_FALLTHRU);
+ new_edge->probability = probability - probability / 2;
+ new_edge->count = count - count / 2;
+ }
+
new_bb = jump_block;
}
else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5341574befe..8db8b22655a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2012-01-05 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/51767
+ * gcc.c-torture/compile/pr51767.c: New test.
+
PR middle-end/51768
* c-c++-common/pr51768.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51767.c b/gcc/testsuite/gcc.c-torture/compile/pr51767.c
new file mode 100644
index 00000000000..62a192d660d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr51767.c
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/51767 */
+
+extern void fn1 (void), fn2 (void);
+
+static inline __attribute__((always_inline)) int
+foo (int *x, long y)
+{
+ asm goto ("" : : "r" (x), "r" (y) : "memory" : lab);
+ return 0;
+lab:
+ return 1;
+}
+
+void
+bar (int *x)
+{
+ if (foo (x, 23))
+ fn1 ();
+ else
+ fn2 ();
+
+ foo (x, 2);
+}