summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/asm-2.c12
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-ssa-ccp.c23
-rw-r--r--gcc/tree-ssa-copy.c10
-rw-r--r--gcc/tree-ssa-dom.c5
6 files changed, 50 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2212c39b42c..8b803fa8596 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2004-09-28 Richard Henderson <rth@redhat.com>
+
+ PR 15089
+ * tree-ssa-copy.c (may_propagate_copy_into_asm): New.
+ * tree-flow.h (may_propagate_copy_into_asm): Declare.
+ * tree-ssa-ccp.c (replace_uses_in): Use it.
+ * tree-ssa-dom.c (cprop_operand): Likewise.
+
2004-09-28 Jeff Law <law@redhat.com>
* tree-ssa-threadupdate.c (create_block_for_threading): Request
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/asm-2.c b/gcc/testsuite/gcc.dg/tree-ssa/asm-2.c
new file mode 100644
index 00000000000..c07b0f1db8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/asm-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#define REGISTER "0"
+
+void baz(void)
+{
+ register int xyzzy asm(REGISTER) = 1;
+ asm volatile ("" : : "r"(xyzzy));
+}
+
+/* { dg-final { scan-tree-dump-times "asm\[^\\r\\n\]*xyzzy" 1 "optimized" } } */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 292879ac430..d62e6b7efa0 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -610,6 +610,7 @@ extern void propagate_value (use_operand_p, tree);
extern void propagate_tree_value (tree *, tree);
extern void replace_exp (use_operand_p, tree);
extern bool may_propagate_copy (tree, tree);
+extern bool may_propagate_copy_into_asm (tree);
/* Description of number of iterations of a loop. All the expressions inside
the structure can be evaluated at the end of the loop's preheader
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 144a8bfaeb0..d3ad9563a6b 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -454,16 +454,21 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p)
FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
- value *val = get_value (USE_FROM_PTR (use));
+ tree tuse = USE_FROM_PTR (use);
+ value *val = get_value (tuse);
- if (val->lattice_val == CONSTANT)
- {
- SET_USE (use, val->const_val);
- replaced = true;
- if (POINTER_TYPE_P (TREE_TYPE (USE_FROM_PTR (use)))
- && replaced_addresses_p)
- *replaced_addresses_p = true;
- }
+ if (val->lattice_val != CONSTANT)
+ continue;
+
+ if (TREE_CODE (stmt) == ASM_EXPR
+ && !may_propagate_copy_into_asm (tuse))
+ continue;
+
+ SET_USE (use, val->const_val);
+
+ replaced = true;
+ if (POINTER_TYPE_P (TREE_TYPE (tuse)) && replaced_addresses_p)
+ *replaced_addresses_p = true;
}
return replaced;
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 447f149ab4a..63a3c20417d 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -156,6 +156,16 @@ may_propagate_copy (tree dest, tree orig)
return true;
}
+/* Similarly, but we know that we're propagating into an ASM_EXPR. */
+
+bool
+may_propagate_copy_into_asm (tree dest)
+{
+ /* Hard register operands of asms are special. Do not bypass. */
+ return !(TREE_CODE (dest) == SSA_NAME
+ && DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
+}
+
/* Given two SSA_NAMEs pointers ORIG and NEW such that we are copy
propagating NEW into ORIG, consolidate aliasing information so that
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 1e6830bb54b..15bf695db4b 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -2536,6 +2536,11 @@ cprop_operand (tree stmt, use_operand_p op_p)
|| TREE_CODE (val) != SSA_NAME))
return false;
+ /* Do not replace hard register operands in asm statements. */
+ if (TREE_CODE (stmt) == ASM_EXPR
+ && !may_propagate_copy_into_asm (op))
+ return false;
+
/* Get the toplevel type of each operand. */
op_type = TREE_TYPE (op);
val_type = TREE_TYPE (val);