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.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index b784a68b18e..5b17ce22427 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;
@@ -693,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,
- ALIGN_INDIRECT_REF and MISALIGNED_INDIRECT_REF.
+/* A subroutine of get_expr_operands to handle MEM_REF,
+ 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.
@@ -725,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)));
}
@@ -802,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. */
@@ -818,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"); */
@@ -862,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
@@ -876,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,8 +914,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
/* fall through */
- case ALIGN_INDIRECT_REF:
- case INDIRECT_REF:
+ case MEM_REF:
get_indirect_ref_operands (stmt, expr, flags, true);
return;