X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-ssa-operands.c;h=7f76cbfe9c090d46ee1cf6dff4d2a5e60f5ca469;hb=046f323efd9149bb5d2d5638466e98ed238b7635;hp=68be8fae8f484b522ab1eecf93e16658a92e3ebb;hpb=8e3cb73bc66100e137b20bcd98316bc415b6e53c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 68be8fae8f4..7f76cbfe9c0 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "ggc.h" #include "timevar.h" -#include "toplev.h" #include "langhooks.h" #include "ipa-reference.h" @@ -127,6 +126,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 +325,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 +698,21 @@ 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. - 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 +736,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))); } @@ -739,9 +752,7 @@ get_tmr_operands (gimple stmt, tree expr, int flags) /* First record the real operands. */ get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops)); get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops)); - - if (TMR_SYMBOL (expr)) - mark_address_taken (TMR_SYMBOL (expr)); + get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops)); add_virtual_operand (stmt, flags); } @@ -801,7 +812,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,19 +828,12 @@ 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"); */ - for (i = 0; i < gimple_asm_nclobbers (stmt); i++) - { - tree link = gimple_asm_clobber_op (stmt, i); - if (strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory") == 0) - { - add_virtual_operand (stmt, opf_def); - break; - } - } + if (gimple_asm_clobbers_memory_p (stmt)) + add_virtual_operand (stmt, opf_def); } @@ -861,7 +865,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 +881,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: @@ -892,12 +899,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags) gcc_assert (gimple_debug_bind_p (stmt)); return; - case MISALIGNED_INDIRECT_REF: - 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; @@ -987,11 +989,14 @@ 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: + case FMA_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: @@ -1053,6 +1058,9 @@ parse_ssa_operands (gimple stmt) /* Add call-clobbered operands, if needed. */ if (code == GIMPLE_CALL) maybe_add_call_vops (stmt); + + if (code == GIMPLE_RETURN) + append_vuse (gimple_vop (cfun)); } } @@ -1119,6 +1127,12 @@ update_stmt_operands (gimple stmt) timevar_push (TV_TREE_OPS); + /* If the stmt is a noreturn call queue it to be processed by + split_bbs_on_noreturn_calls during cfg cleanup. */ + if (is_gimple_call (stmt) + && gimple_call_noreturn_p (stmt)) + VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), stmt); + gcc_assert (gimple_modified_p (stmt)); build_ssa_operands (stmt); gimple_set_modified (stmt, false);