diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-10-16 22:49:07 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-10-16 22:49:07 +0000 |
commit | 88d8330d67ec17569e4b7e52989934bf6908a1f0 (patch) | |
tree | 01d1822515deb56bf92d32e9ff0cc1bcea39dc1b /gcc/dse.c | |
parent | da4fdf2d3ff45366d9378882ad1646306ceee305 (diff) | |
download | gcc-88d8330d67ec17569e4b7e52989934bf6908a1f0.tar.gz |
re PR rtl-optimization/54870 (gfortran.dg/array_constructor_4.f90 FAILs)
PR rtl-optimization/54870
* tree.h (TREE_ADDRESSABLE): Document special usage on SSA_NAME.
* cfgexpand.c (update_alias_info_with_stack_vars ): Set it on the
SSA_NAME pointer that points to a partition if there is at least
one variable with it set in the partition.
* dse.c (local_variable_can_escape): New predicate.
(can_escape): Call it.
* gimplify.c (mark_addressable): If this is a partitioned decl, also
mark the SSA_NAME pointer that points to a partition.
From-SVN: r192517
Diffstat (limited to 'gcc/dse.c')
-rw-r--r-- | gcc/dse.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/gcc/dse.c b/gcc/dse.c index 318bbc940c0..631a1f20ac7 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -989,7 +989,32 @@ delete_dead_store_insn (insn_info_t insn_info) insn_info->wild_read = false; } -/* Check if EXPR can possibly escape the current function scope. */ +/* Return whether DECL, a local variable, can possibly escape the current + function scope. */ + +static bool +local_variable_can_escape (tree decl) +{ + if (TREE_ADDRESSABLE (decl)) + return true; + + /* If this is a partitioned variable, we need to consider all the variables + in the partition. This is necessary because a store into one of them can + be replaced with a store into another and this may not change the outcome + of the escape analysis. */ + if (cfun->gimple_df->decls_to_pointers != NULL) + { + void *namep + = pointer_map_contains (cfun->gimple_df->decls_to_pointers, decl); + if (namep) + return TREE_ADDRESSABLE (*(tree *)namep); + } + + return false; +} + +/* Return whether EXPR can possibly escape the current function scope. */ + static bool can_escape (tree expr) { @@ -998,7 +1023,11 @@ can_escape (tree expr) return true; base = get_base_address (expr); if (DECL_P (base) - && !may_be_aliased (base)) + && !may_be_aliased (base) + && !(TREE_CODE (base) == VAR_DECL + && !DECL_EXTERNAL (base) + && !TREE_STATIC (base) + && local_variable_can_escape (base))) return false; return true; } |