summaryrefslogtreecommitdiff
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.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 68be8fae8f4..fdc906a8b1b 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -127,6 +127,12 @@ static struct
clobbering sites like function calls or ASM_EXPRs. */
#define opf_implicit (1 << 2)
+/* Operand is in a place where address-taken does not imply addressable. */
+#define opf_non_addressable (1 << 3)
+
+/* Operand is in a place where opf_non_addressable does not apply. */
+#define opf_not_non_addressable (1 << 4)
+
/* Array for building all the def operands. */
static VEC(tree,heap) *build_defs;
@@ -320,9 +326,10 @@ ssa_operand_alloc (unsigned size)
gcc_unreachable ();
}
- ptr = (struct ssa_operand_memory_d *)
- ggc_alloc (sizeof (void *)
- + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
+
+ ptr = ggc_alloc_ssa_operand_memory_d (sizeof (void *)
+ + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
+
ptr->next = gimple_ssa_operands (cfun)->operand_memory;
gimple_ssa_operands (cfun)->operand_memory = ptr;
gimple_ssa_operands (cfun)->operand_memory_index = 0;
@@ -692,15 +699,22 @@ mark_address_taken (tree ref)
be referenced using pointer arithmetic. See PR 21407 and the
ensuing mailing list discussion. */
var = get_base_address (ref);
- if (var && DECL_P (var))
- TREE_ADDRESSABLE (var) = 1;
+ if (var)
+ {
+ if (DECL_P (var))
+ TREE_ADDRESSABLE (var) = 1;
+ else if (TREE_CODE (var) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (var, 0)) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (TREE_OPERAND (var, 0), 0)))
+ TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (var, 0), 0)) = 1;
+ }
}
-/* A subroutine of get_expr_operands to handle INDIRECT_REF,
+/* A subroutine of get_expr_operands to handle MEM_REF,
ALIGN_INDIRECT_REF and MISALIGNED_INDIRECT_REF.
- STMT is the statement being processed, EXPR is the INDIRECT_REF
+ STMT is the statement being processed, EXPR is the MEM_REF
that got us here.
FLAGS is as in get_expr_operands.
@@ -724,7 +738,8 @@ get_indirect_ref_operands (gimple stmt, tree expr, int flags,
/* If requested, add a USE operand for the base pointer. */
if (recurse_on_base)
get_expr_operands (stmt, pptr,
- opf_use | (flags & opf_no_vops));
+ opf_non_addressable | opf_use
+ | (flags & (opf_no_vops|opf_not_non_addressable)));
}
@@ -801,7 +816,7 @@ get_asm_expr_operands (gimple stmt)
if (!allows_reg && allows_mem)
mark_address_taken (TREE_VALUE (link));
- get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
+ get_expr_operands (stmt, &TREE_VALUE (link), opf_def | opf_not_non_addressable);
}
/* Gather all input operands. */
@@ -817,7 +832,7 @@ get_asm_expr_operands (gimple stmt)
if (!allows_reg && allows_mem)
mark_address_taken (TREE_VALUE (link));
- get_expr_operands (stmt, &TREE_VALUE (link), 0);
+ get_expr_operands (stmt, &TREE_VALUE (link), opf_not_non_addressable);
}
/* Clobber all memory and addressable symbols for asm ("" : : : "memory"); */
@@ -861,7 +876,9 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
reference to it, but the fact that the statement takes its
address will be of interest to some passes (e.g. alias
resolution). */
- if (!is_gimple_debug (stmt))
+ if ((!(flags & opf_non_addressable)
+ || (flags & opf_not_non_addressable))
+ && !is_gimple_debug (stmt))
mark_address_taken (TREE_OPERAND (expr, 0));
/* If the address is invariant, there may be no interesting
@@ -875,7 +892,8 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
here are ARRAY_REF indices which will always be real operands
(GIMPLE does not allow non-registers as array indices). */
flags |= opf_no_vops;
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
+ flags | opf_not_non_addressable);
return;
case SSA_NAME:
@@ -897,7 +915,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
/* fall through */
case ALIGN_INDIRECT_REF:
- case INDIRECT_REF:
+ case MEM_REF:
get_indirect_ref_operands (stmt, expr, flags, true);
return;
@@ -987,11 +1005,13 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
case DOT_PROD_EXPR:
case REALIGN_LOAD_EXPR:
+ case WIDEN_MULT_PLUS_EXPR:
+ case WIDEN_MULT_MINUS_EXPR:
{
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
- return;
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
+ return;
}
case FUNCTION_DECL: