From f7b5f69431a542cf0fff141c4c899782d6a5177c Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Tue, 16 Oct 2012 22:49:07 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192517 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cfgexpand.c | 2 ++ gcc/dse.c | 33 +++++++++++++++++++++++++++++++-- gcc/gimplify.c | 13 +++++++++++++ gcc/tree.h | 10 +++++++--- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 57589ad..4ae1600 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -635,6 +635,8 @@ update_alias_info_with_stack_vars (void) (void *)(size_t) uid)) = part; *((tree *) pointer_map_insert (cfun->gimple_df->decls_to_pointers, decl)) = name; + if (TREE_ADDRESSABLE (decl)) + TREE_ADDRESSABLE (name) = 1; } /* Make the SSA name point to all partition members. */ diff --git a/gcc/dse.c b/gcc/dse.c index 318bbc9..631a1f2 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; } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index b83a634..14e7007 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -116,6 +116,19 @@ mark_addressable (tree x) && TREE_CODE (x) != RESULT_DECL) return; TREE_ADDRESSABLE (x) = 1; + + /* Also mark the artificial SSA_NAME that points to the partition of X. */ + if (TREE_CODE (x) == VAR_DECL + && !DECL_EXTERNAL (x) + && !TREE_STATIC (x) + && cfun->gimple_df != NULL + && cfun->gimple_df->decls_to_pointers != NULL) + { + void *namep + = pointer_map_contains (cfun->gimple_df->decls_to_pointers, x); + if (namep) + TREE_ADDRESSABLE (*(tree *)namep) = 1; + } } /* Return a hash value for a formal temporary table entry. */ diff --git a/gcc/tree.h b/gcc/tree.h index 12e7948..c6a5eab 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -484,9 +484,10 @@ struct GTY(()) tree_base { TREE_ADDRESSABLE in VAR_DECL, PARM_DECL, RESULT_DECL, FUNCTION_DECL, LABEL_DECL + SSA_NAME all types CONSTRUCTOR, IDENTIFIER_NODE - STMT_EXPR, it means we want the result of the enclosed expression + STMT_EXPR CALL_EXPR_TAILCALL in CALL_EXPR @@ -1085,15 +1086,18 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, /* In VAR_DECL, PARM_DECL and RESULT_DECL nodes, nonzero means address of this is needed. So it cannot be in a register. In a FUNCTION_DECL it has no meaning. - In CONSTRUCTOR nodes, it means object constructed must be in memory. In LABEL_DECL nodes, it means a goto for this label has been seen from a place outside all binding contours that restore stack levels. + In an artificial SSA_NAME that points to a stack partition with at least + two variables, it means that at least one variable has TREE_ADDRESSABLE. In ..._TYPE nodes, it means that objects of this type must be fully addressable. This means that pieces of this object cannot go into register parameters, for example. If this a function type, this means that the value must be returned in memory. + In CONSTRUCTOR nodes, it means object constructed must be in memory. In IDENTIFIER_NODEs, this means that some extern decl for this name - had its address taken. That matters for inline functions. */ + had its address taken. That matters for inline functions. + In a STMT_EXPR, it means we want the result of the enclosed expression. */ #define TREE_ADDRESSABLE(NODE) ((NODE)->base.addressable_flag) /* Set on a CALL_EXPR if the call is in a tail position, ie. just before the -- 2.7.4