aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-operands.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r--gcc/tree-ssa-operands.c67
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);
});
}