diff options
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 9bac292..83f0c36 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -32,7 +32,9 @@ Boston, MA 02111-1307, USA. */ #include "tree-pass.h" #include "ggc.h" #include "timevar.h" +#include "cgraph.h" +#include "langhooks.h" /* This file contains the code required to manage the operands cache of the SSA optimizer. For every stmt, we maintain an operand cache in the stmt @@ -133,8 +135,8 @@ static inline void append_def (tree *); static inline void append_use (tree *); static void append_v_may_def (tree); static void append_v_must_def (tree); -static void add_call_clobber_ops (tree); -static void add_call_read_ops (tree); +static void add_call_clobber_ops (tree, tree); +static void add_call_read_ops (tree, tree); static void add_stmt_operand (tree *, tree, int); /* Return a vector of contiguous memory for NUM def operands. */ @@ -1380,6 +1382,7 @@ get_call_expr_operands (tree stmt, tree expr) { tree op; int call_flags = call_expr_flags (expr); + tree callee = get_callee_fndecl (expr); /* Find uses in the called function. */ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none); @@ -1396,9 +1399,9 @@ get_call_expr_operands (tree stmt, tree expr) there is no point in recording that. */ if (TREE_SIDE_EFFECTS (expr) && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN))) - add_call_clobber_ops (stmt); + add_call_clobber_ops (stmt, callee); else if (!(call_flags & ECF_CONST)) - add_call_read_ops (stmt); + add_call_read_ops (stmt, callee); } } @@ -1562,7 +1565,7 @@ note_addressable (tree var, stmt_ann_t s_ann) clobbered variables in the function. */ static void -add_call_clobber_ops (tree stmt) +add_call_clobber_ops (tree stmt, tree callee) { /* Functions that are not const, pure or never return may clobber call-clobbered variables. */ @@ -1579,16 +1582,53 @@ add_call_clobber_ops (tree stmt) { size_t i; + /* Get info for module level statics. There is a bit set for + each static if the call being processed does not read or + write that variable. */ + + bitmap not_read_b = callee + ? get_global_statics_not_read (callee) : NULL; + bitmap not_written_b = callee + ? get_global_statics_not_written (callee) : NULL; + + EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, { tree var = referenced_var (i); - /* If VAR is read-only, don't add a V_MAY_DEF, just a - VUSE operand. */ - if (!TREE_READONLY (var)) - add_stmt_operand (&var, stmt, opf_is_def); + bool not_read = not_read_b + ? bitmap_bit_p(not_read_b, i) : false; + bool not_written = not_written_b + ? bitmap_bit_p(not_written_b, i) : false; + + + if (not_read) + { /* The var is not read during the call. */ + if (not_written) + { + /* Nothing. */ + } + else + add_stmt_operand (&var, stmt, opf_is_def); + } else - add_stmt_operand (&var, stmt, opf_none); + { /* The var is read during the call. */ + if (not_written) + add_stmt_operand (&var, stmt, opf_none); + else + /* The not_read and not_written bits are only set + for module static variables. Neither is set + here, so we may be dealing with a module static + or we may not. So we still must look anywhere + else we can (such as the TREE_READONLY) to get + better info. */ + /* If VAR is read-only, don't add a V_MAY_DEF, just a + VUSE operand. */ + if (TREE_READONLY (var)) + add_stmt_operand (&var, stmt, opf_none); + else + add_stmt_operand (&var, stmt, opf_is_def); + } }); } } @@ -1598,7 +1638,7 @@ add_call_clobber_ops (tree stmt) function. */ static void -add_call_read_ops (tree stmt) +add_call_read_ops (tree stmt, tree callee) { /* Otherwise, if the function is not pure, it may reference memory. Add a VUSE for .GLOBAL_VAR if it has been created. Otherwise, add a VUSE @@ -1609,10 +1649,15 @@ add_call_read_ops (tree stmt) else { size_t i; + bitmap not_read_b = callee + ? get_global_statics_not_read (callee) : NULL; EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, { tree var = referenced_var (i); + bool not_read = not_read_b + ? bitmap_bit_p(not_read_b, i) : false; + if (!not_read) add_stmt_operand (&var, stmt, opf_none); }); } |