diff options
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 52 |
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: |