From aa24864c2389a86dbba4e0a04c3eb0a3c14d10d9 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 28 Sep 2004 19:50:47 -0700 Subject: [PATCH] re PR tree-optimization/15089 (local register variable with a specified register is bad) 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. From-SVN: r88269 --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/gcc.dg/tree-ssa/asm-2.c | 12 ++++++++++++ gcc/tree-flow.h | 1 + gcc/tree-ssa-ccp.c | 23 ++++++++++++++--------- gcc/tree-ssa-copy.c | 10 ++++++++++ gcc/tree-ssa-dom.c | 5 +++++ 6 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/asm-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2212c39b42cd..8b803fa8596c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2004-09-28 Richard Henderson + + 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 * 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 000000000000..c07b0f1db8b3 --- /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 292879ac4306..d62e6b7efa08 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 144a8bfaeb0e..d3ad9563a6b8 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 447f149ab4ab..63a3c20417d7 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 1e6830bb54b1..15bf695db4b2 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);