/* SSA operands management for trees.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
#include "tree.h"
#include "flags.h"
#include "function.h"
-#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
#include "tree-flow.h"
#include "tree-inline.h"
#include "tree-pass.h"
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;
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;
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.
/* 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)));
}
static void
get_tmr_operands (gimple stmt, tree expr, int flags)
{
+ if (TREE_THIS_VOLATILE (expr))
+ gimple_set_has_volatile_ops (stmt, true);
+
/* 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);
}
/* Memory operands are addressable. Note that STMT needs the
address of this operand. */
if (!allows_reg && allows_mem)
- {
- tree t = get_base_address (TREE_VALUE (link));
- if (t && DECL_P (t))
- mark_address_taken (t);
- }
+ 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. */
/* Memory operands are addressable. Note that STMT needs the
address of this operand. */
if (!allows_reg && allows_mem)
- {
- tree t = get_base_address (TREE_VALUE (link));
- if (t && DECL_P (t))
- mark_address_taken (t);
- }
+ 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"); */
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
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:
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;
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:
/* Scan the immediate_use list for VAR making sure its linked properly.
Return TRUE if there is a problem and emit an error message to F. */
-bool
+DEBUG_FUNCTION bool
verify_imm_links (FILE *f, tree var)
{
use_operand_p ptr, prev, list;
/* Dump def-use edges on stderr. */
-void
+DEBUG_FUNCTION void
debug_immediate_uses (void)
{
dump_immediate_uses (stderr);
/* Dump def-use edges on stderr. */
-void
+DEBUG_FUNCTION void
debug_immediate_uses_for (tree var)
{
dump_immediate_uses_for (stderr, var);