+2010-09-03 Richard Guenther <rguenther@suse.de>
+
+ * tree.def (TARGET_MEM_REF): Merge TMR_SYMBOL and TMR_BASE.
+ Move TMR_OFFSET to second operand. Add TMR_INDEX2.
+ * tree.h (TMR_SYMBOL): Remove.
+ (TMR_BASE, TMR_OFFSET): Adjust.
+ (TMR_INDEX2): New.
+ * alias.c (ao_ref_from_mem): Use TMR_BASE.
+ * builtins.c (get_object_alignment): Merge TMR_BASE and
+ TMR_SYMBOL handling.
+ * cfgexpand.c (expand_debug_expr): Use TMR_BASE.
+ * gimple.c (get_base_address): Merge MEM_REF and TARGET_MEM_REF
+ handling. Also allow TARGET_MEM_REF as base address.
+ (walk_stmt_load_store_addr_ops): TMR_BASE is always non-NULL.
+ * gimplify.c (gimplify_expr): Gimplify TMR_BASE like MEM_REF
+ base. Gimplify TMR_INDEX2.
+ * tree-cfg.c (verify_types_in_gimple_reference): Adjust.
+ * tree-dfa.c (get_ref_base_and_extent): Likewise.
+ (get_addr_base_and_unit_offset): Likewise.
+ * tree-eh.c (tree_could_trap_p): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ * tree-ssa-address.c (tree_mem_ref_addr): Simplify. Handle
+ TMR_INDEX2.
+ (create_mem_ref_raw): Merge symbol and base. Move 2ndary
+ base to index2.
+ (get_address_description): Reconstruct addres description
+ from merged TMR_BASE and TMR_INDEX2.
+ (maybe_fold_tmr): Fold propagated addresses.
+ * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Merge
+ MEM_REF and TARGET_MEM_REF paths.
+ (indirect_refs_may_alias_p): Likewise.
+ * tree-ssa-live.c (mark_all_vars_used_1): Handle TMR_INDEX2
+ instead of TMR_SYMBOL.
+ * tree-ssa-operands.c (get_tmr_operands): Simplify.
+ * tree-ssa-pre.c (create_component_ref_by_pieces_1): Adjust
+ according to changes ...
+ * tree-ssa-sccvn.c (copy_reference_ops_from_ref): ... here.
+ Split TARGET_MEM_REF into two fields plus the base.
+ * tree.c (mem_ref_offset): Simplify.
+ * tree-ssa-loop-im.c (for_each_index): Handle TMR_INDEX2.
+ * tree-ssa-loop-ivopts.c (find_interesting_uses_address): Likewise.
+ Strip NOPs when folding MEM_REF addresses.
+ * tree-ssa-sink.c (is_hidden_global_store): Handle TARGET_MEM_REF.
+ * gimple-fold.c (maybe_fold_reference): Fold TARGET_MEM_REF here ...
+ (fold_gimple_assign): ... not here.
+
2010-09-03 Mingjie Xing <mingjie.xing@gmail.com>
* config/mips/mips.h (SHIFT_COUNT_TRUNCATED): Change the definition.
ref->base = build_simple_mem_ref (*(tree *)namep);
}
else if (TREE_CODE (base) == TARGET_MEM_REF
- && TMR_SYMBOL (base)
- && TREE_CODE (TREE_OPERAND (TMR_SYMBOL (base), 0)) == VAR_DECL
- && ! TREE_STATIC (TREE_OPERAND (TMR_SYMBOL (base), 0))
+ && TREE_CODE (TMR_BASE (base)) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (TMR_BASE (base), 0)) == VAR_DECL
+ && ! TREE_STATIC (TREE_OPERAND (TMR_BASE (base), 0))
&& cfun->gimple_df->decls_to_pointers != NULL)
{
void *namep;
namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers,
- TREE_OPERAND (TMR_SYMBOL (base), 0));
+ TREE_OPERAND (TMR_BASE (base), 0));
if (namep)
ref->base = build_simple_mem_ref (*(tree *)namep);
}
max_align));
bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
}
- else if (TREE_CODE (exp) == TARGET_MEM_REF
- && TMR_BASE (exp)
- && POINTER_TYPE_P (TREE_TYPE (TMR_BASE (exp))))
+ else if (TREE_CODE (exp) == TARGET_MEM_REF)
{
struct ptr_info_def *pi;
tree addr = TMR_BASE (exp);
}
else if (TMR_INDEX (exp))
align = BITS_PER_UNIT;
- }
- else if (TREE_CODE (exp) == TARGET_MEM_REF
- && TMR_SYMBOL (exp))
- {
- align = get_object_alignment (TREE_OPERAND (TMR_SYMBOL (exp), 0),
- max_align);
- if (TMR_OFFSET (exp))
- bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
- if (TMR_INDEX (exp) && TMR_STEP (exp))
- {
- unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
- align = MIN (align, (step & -step) * BITS_PER_UNIT);
- }
- else if (TMR_INDEX (exp))
- align = BITS_PER_UNIT;
- if (TMR_BASE (exp))
+ if (TMR_INDEX2 (exp))
align = BITS_PER_UNIT;
}
else
return op0;
case TARGET_MEM_REF:
- if (TMR_SYMBOL (exp)
- && !DECL_RTL_SET_P (TREE_OPERAND (TMR_SYMBOL (exp), 0)))
+ if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
+ && !DECL_RTL_SET_P (TREE_OPERAND (TMR_BASE (exp), 0)))
return NULL;
op0 = expand_debug_expr
return expr;
}
}
+ else if (TREE_CODE (*t) == TARGET_MEM_REF)
+ {
+ tree tem = maybe_fold_tmr (*t);
+ if (tem)
+ {
+ *t = tem;
+ tem = maybe_fold_reference (expr, is_lhs);
+ if (tem)
+ return tem;
+ return expr;
+ }
+ }
else if (!is_lhs
&& DECL_P (*t))
{
COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
}
- else if (TREE_CODE (rhs) == TARGET_MEM_REF)
- return maybe_fold_tmr (rhs);
-
else if (REFERENCE_CLASS_P (rhs))
return maybe_fold_reference (rhs, false);
while (handled_component_p (t))
t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == MEM_REF
+ if ((TREE_CODE (t) == MEM_REF
+ || TREE_CODE (t) == TARGET_MEM_REF)
&& TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
- else if (TREE_CODE (t) == TARGET_MEM_REF
- && TMR_SYMBOL (t))
- t = TREE_OPERAND (TMR_SYMBOL (t), 0);
if (SSA_VAR_P (t)
|| TREE_CODE (t) == STRING_CST
|| TREE_CODE (t) == CONSTRUCTOR
|| INDIRECT_REF_P (t)
- || TREE_CODE (t) == MEM_REF)
+ || TREE_CODE (t) == MEM_REF
+ || TREE_CODE (t) == TARGET_MEM_REF)
return t;
else
return NULL_TREE;
if (TREE_CODE (rhs) == ADDR_EXPR)
ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
else if (TREE_CODE (rhs) == TARGET_MEM_REF
- && TMR_BASE (rhs) != NULL_TREE
&& TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
else if (TREE_CODE (rhs) == OBJ_TYPE_REF
0), data);
lhs = gimple_assign_lhs (stmt);
if (TREE_CODE (lhs) == TARGET_MEM_REF
- && TMR_BASE (lhs) != NULL_TREE
&& TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
}
{
enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
- if (TMR_SYMBOL (*expr_p))
- /* We can't gimplify the symbol part. Assert it is
- already gimple instead.
- ??? This isn't exactly the same as ADDR_EXPR
- plus is_gimple_mem_ref_addr (), see fixed_address_object_p. */
- gcc_assert (TREE_CODE (TMR_SYMBOL (*expr_p)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (TMR_SYMBOL (*expr_p), 0))
- == VAR_DECL));
if (TMR_BASE (*expr_p))
r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
- post_p, is_gimple_val, fb_either);
+ post_p, is_gimple_mem_ref_addr, fb_either);
if (TMR_INDEX (*expr_p))
r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
post_p, is_gimple_val, fb_rvalue);
+ if (TMR_INDEX2 (*expr_p))
+ r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
/* TMR_STEP and TMR_OFFSET are always integer constants. */
ret = MIN (r0, r1);
}
}
else if (TREE_CODE (expr) == TARGET_MEM_REF)
{
- if (TMR_SYMBOL (expr)
- && TMR_BASE (expr)
- && !useless_type_conversion_p (sizetype, TREE_TYPE (TMR_BASE (expr))))
+ if (!TMR_BASE (expr)
+ || !is_gimple_mem_ref_addr (TMR_BASE (expr)))
{
- error ("Non-sizetype base in TARGET_MEM_REF with symbol");
+ error ("Invalid address operand in in TARGET_MEM_REF.");
return true;
}
if (!TMR_OFFSET (expr)
case TARGET_MEM_REF:
/* Hand back the decl for MEM[&decl, off]. */
- if (TMR_SYMBOL (exp))
+ if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
{
- /* Via the variable index or base we can reach the
+ /* Via the variable index or index2 we can reach the
whole object. */
- if (TMR_INDEX (exp) || TMR_BASE (exp))
+ if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
{
- exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+ exp = TREE_OPERAND (TMR_BASE (exp), 0);
bit_offset = 0;
maxsize = -1;
goto done;
}
if (integer_zerop (TMR_OFFSET (exp)))
- exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+ exp = TREE_OPERAND (TMR_BASE (exp), 0);
else
{
double_int off = mem_ref_offset (exp);
if (double_int_fits_in_shwi_p (off))
{
bit_offset = double_int_to_shwi (off);
- exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+ exp = TREE_OPERAND (TMR_BASE (exp), 0);
}
}
}
case TARGET_MEM_REF:
/* Hand back the decl for MEM[&decl, off]. */
- if (TMR_SYMBOL (exp))
+ if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
{
- if (TMR_INDEX (exp) || TMR_BASE (exp))
+ if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
return NULL_TREE;
if (!integer_zerop (TMR_OFFSET (exp)))
{
gcc_assert (off.high == -1 || off.high == 0);
byte_offset += double_int_to_shwi (off);
}
- exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+ exp = TREE_OPERAND (TMR_BASE (exp), 0);
}
goto done;
switch (code)
{
case TARGET_MEM_REF:
- if (TMR_SYMBOL (expr)
- && !TMR_INDEX (expr) && !TMR_BASE (expr))
+ if (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
+ && !TMR_INDEX (expr) && !TMR_INDEX2 (expr))
return false;
return !TREE_THIS_NOTRAP (expr);
pp_string (buffer, "MEM[");
- tmp = TMR_SYMBOL (node);
- if (tmp)
+ if (TREE_CODE (TMR_BASE (node)) == ADDR_EXPR)
{
pp_string (buffer, sep);
sep = ", ";
pp_string (buffer, "symbol: ");
- dump_generic_node (buffer, TREE_OPERAND (tmp, 0),
+ dump_generic_node (buffer, TREE_OPERAND (TMR_BASE (node), 0),
spc, flags, false);
}
- tmp = TMR_BASE (node);
+ else
+ {
+ pp_string (buffer, sep);
+ sep = ", ";
+ pp_string (buffer, "base: ");
+ dump_generic_node (buffer, TMR_BASE (node), spc, flags, false);
+ }
+ tmp = TMR_INDEX2 (node);
if (tmp)
{
pp_string (buffer, sep);
tree addr;
tree act_elem;
tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref);
- tree sym = TMR_SYMBOL (mem_ref), base = TMR_BASE (mem_ref);
tree addr_base = NULL_TREE, addr_off = NULL_TREE;
- if (sym)
- addr_base = fold_convert (type, sym);
- else if (base)
- {
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (base)));
- addr_base = fold_convert (type, base);
- base = NULL_TREE;
- }
+ addr_base = fold_convert (type, TMR_BASE (mem_ref));
act_elem = TMR_INDEX (mem_ref);
if (act_elem)
addr_off = act_elem;
}
- act_elem = base;
+ act_elem = TMR_INDEX2 (mem_ref);
if (act_elem)
{
if (addr_off)
}
if (addr_off)
- {
- if (addr_base)
- addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
- else
- addr = fold_convert (type, addr_off);
- }
- else if (addr_base)
- addr = addr_base;
+ addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
else
- addr = build_int_cst (type, 0);
+ addr = addr_base;
return addr;
}
static tree
create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
{
+ tree base, index2;
+
if (!valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr))
return NULL_TREE;
else
addr->offset = build_int_cst (alias_ptr_type, 0);
- /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */
- if (alias_ptr_type
- && (!addr->index || integer_zerop (addr->index))
- && (!addr->base || POINTER_TYPE_P (TREE_TYPE (addr->base))))
+ if (addr->symbol)
{
- tree base;
- gcc_assert (!addr->symbol ^ !addr->base);
- if (addr->symbol)
- base = addr->symbol;
- else
- base = addr->base;
- return fold_build2 (MEM_REF, type, base, addr->offset);
+ base = addr->symbol;
+ index2 = addr->base;
+ }
+ else if (addr->base
+ && POINTER_TYPE_P (TREE_TYPE (addr->base)))
+ {
+ base = addr->base;
+ index2 = NULL_TREE;
}
+ else
+ {
+ base = build_int_cst (ptr_type_node, 0);
+ index2 = addr->base;
+ }
+
+ /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */
+ if (alias_ptr_type
+ && (!index2 || integer_zerop (index2))
+ && (!addr->index || integer_zerop (addr->index)))
+ return fold_build2 (MEM_REF, type, base, addr->offset);
return build5 (TARGET_MEM_REF, type,
- addr->symbol, addr->base, addr->index,
- addr->step, addr->offset);
+ base, addr->offset, addr->index, addr->step, index2);
}
/* Returns true if OBJ is an object whose address is a link time constant. */
void
get_address_description (tree op, struct mem_address *addr)
{
- addr->symbol = TMR_SYMBOL (op);
- addr->base = TMR_BASE (op);
+ if (TREE_CODE (TMR_BASE (op)) == ADDR_EXPR)
+ {
+ addr->symbol = TMR_BASE (op);
+ addr->base = TMR_INDEX2 (op);
+ }
+ else
+ {
+ addr->symbol = NULL_TREE;
+ if (TMR_INDEX2 (op))
+ {
+ gcc_assert (integer_zerop (TMR_BASE (op)));
+ addr->base = TMR_INDEX2 (op);
+ }
+ else
+ addr->base = TMR_BASE (op);
+ }
addr->index = TMR_INDEX (op);
addr->step = TMR_STEP (op);
addr->offset = TMR_OFFSET (op);
get_address_description (ref, &addr);
- if (addr.base && TREE_CODE (addr.base) == INTEGER_CST)
+ if (addr.base
+ && TREE_CODE (addr.base) == INTEGER_CST
+ && !integer_zerop (addr.base))
{
addr.offset = fold_binary_to_constant (PLUS_EXPR,
TREE_TYPE (addr.offset),
changed = true;
}
+ if (addr.symbol
+ && TREE_CODE (TREE_OPERAND (addr.symbol, 0)) == MEM_REF)
+ {
+ addr.offset = fold_binary_to_constant
+ (PLUS_EXPR, TREE_TYPE (addr.offset),
+ addr.offset,
+ TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 1));
+ addr.symbol = TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 0);
+ changed = true;
+ }
+ else if (addr.symbol
+ && handled_component_p (TREE_OPERAND (addr.symbol, 0)))
+ {
+ HOST_WIDE_INT offset;
+ addr.symbol = build_fold_addr_expr
+ (get_addr_base_and_unit_offset
+ (TREE_OPERAND (addr.symbol, 0), &offset));
+ addr.offset = int_const_binop (PLUS_EXPR,
+ addr.offset, size_int (offset), 0);
+ changed = true;
+ }
+
if (addr.index && TREE_CODE (addr.index) == INTEGER_CST)
{
off = addr.index;
tree ptrtype1;
HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
- if (TREE_CODE (base1) == TARGET_MEM_REF)
- {
- if (TMR_SYMBOL (base1))
- ptr1 = TMR_SYMBOL (base1);
- else if (TMR_BASE (base1))
- {
- if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base1))))
- return true;
- ptr1 = TMR_BASE (base1);
- }
- else
- return true;
- }
- else
- ptr1 = TREE_OPERAND (base1, 0);
+ ptr1 = TREE_OPERAND (base1, 0);
/* The offset embedded in MEM_REFs can be negative. Bias them
so that the resulting offset adjustment is positive. */
tree ptr2;
tree ptrtype1, ptrtype2;
- if (TREE_CODE (base1) == TARGET_MEM_REF)
- {
- if (TMR_SYMBOL (base1))
- ptr1 = TMR_SYMBOL (base1);
- else if (TMR_BASE (base1))
- {
- if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base1))))
- return true;
- ptr1 = TMR_BASE (base1);
- }
- else
- return true;
- }
- else
- ptr1 = TREE_OPERAND (base1, 0);
-
- if (TREE_CODE (base2) == TARGET_MEM_REF)
- {
- if (TMR_SYMBOL (base2))
- ptr2 = TMR_SYMBOL (base2);
- else if (TMR_BASE (base2))
- {
- if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base2))))
- return true;
- ptr2 = TMR_BASE (base2);
- }
- else
- return true;
- }
- else
- ptr2 = TREE_OPERAND (base2, 0);
+ ptr1 = TREE_OPERAND (base1, 0);
+ ptr2 = TREE_OPERAND (base2, 0);
/* If both bases are based on pointers they cannot alias if they may not
point to the same memory object or if they point to the same object
&& (b = TREE_BLOCK (t)) != NULL)
TREE_USED (b) = true;
- /* Ignore TREE_ORIGINAL for TARGET_MEM_REFS, as well as other
- fields that do not contain vars. */
+ /* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those
+ fields do not contain vars. */
if (TREE_CODE (t) == TARGET_MEM_REF)
{
- mark_all_vars_used (&TMR_SYMBOL (t), data);
mark_all_vars_used (&TMR_BASE (t), data);
mark_all_vars_used (&TMR_INDEX (t), data);
+ mark_all_vars_used (&TMR_INDEX2 (t), data);
*walk_subtrees = 0;
return NULL;
}
&& !cbck (*addr_p, idx, data))
return false;
idx = &TMR_INDEX (*addr_p);
+ if (*idx
+ && !cbck (*addr_p, idx, data))
+ return false;
+ idx = &TMR_INDEX2 (*addr_p);
if (*idx
&& !cbck (*addr_p, idx, data))
return false;
TMR_BASE (base) = civ->base;
step = civ->step;
}
+ if (TMR_INDEX2 (base)
+ && TREE_CODE (TMR_INDEX2 (base)) == SSA_NAME)
+ {
+ civ = get_iv (data, TMR_INDEX2 (base));
+ if (!civ)
+ goto fail;
+
+ TMR_INDEX2 (base) = civ->base;
+ step = civ->step;
+ }
if (TMR_INDEX (base)
&& TREE_CODE (TMR_INDEX (base)) == SSA_NAME)
{
ref = &TREE_OPERAND (*ref, 0);
if (TREE_CODE (*ref) == MEM_REF)
{
- tree tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
- TREE_OPERAND (*ref, 0),
- TREE_OPERAND (*ref, 1));
+ tree tem = TREE_OPERAND (*ref, 0);
+ STRIP_NOPS (tem);
+ if (tem != TREE_OPERAND (*ref, 0))
+ tem = fold_build2 (MEM_REF, TREE_TYPE (*ref),
+ tem, TREE_OPERAND (*ref, 1));
+ else
+ tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
+ tem, TREE_OPERAND (*ref, 1));
if (tem)
*ref = tem;
}
/* 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 (TREE_OPERAND (TMR_SYMBOL (expr), 0));
+ get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
add_virtual_operand (stmt, flags);
}
break;
case TARGET_MEM_REF:
{
- pre_expr op0expr;
- tree genop0 = NULL_TREE;
+ pre_expr op0expr, op1expr;
+ tree genop0 = NULL_TREE, genop1 = NULL_TREE;
+ vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
+ ++*operand);
tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
stmts, domstmt);
if (!baseop)
if (!genop0)
return NULL_TREE;
}
- if (DECL_P (baseop))
- return build5 (TARGET_MEM_REF, currop->type,
- baseop, NULL_TREE,
- genop0, currop->op1, currop->op2);
- else
- return build5 (TARGET_MEM_REF, currop->type,
- NULL_TREE, baseop,
- genop0, currop->op1, currop->op2);
+ if (nextop->op0)
+ {
+ op1expr = get_or_alloc_expr_for (nextop->op0);
+ genop1 = find_or_generate_expression (block, op1expr,
+ stmts, domstmt);
+ if (!genop1)
+ return NULL_TREE;
+ }
+ return build5 (TARGET_MEM_REF, currop->type,
+ baseop, currop->op2, genop0, currop->op1, genop1);
}
break;
case ADDR_EXPR:
if (TREE_CODE (ref) == TARGET_MEM_REF)
{
vn_reference_op_s temp;
- tree base;
-
- base = TMR_SYMBOL (ref) ? TMR_SYMBOL (ref) : TMR_BASE (ref);
- if (!base)
- base = null_pointer_node;
memset (&temp, 0, sizeof (temp));
/* We do not care for spurious type qualifications. */
memset (&temp, 0, sizeof (temp));
temp.type = NULL_TREE;
- temp.opcode = TREE_CODE (base);
- temp.op0 = base;
+ temp.opcode = ERROR_MARK;
+ temp.op0 = TMR_INDEX2 (ref);
+ temp.off = -1;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+ memset (&temp, 0, sizeof (temp));
+ temp.type = NULL_TREE;
+ temp.opcode = TREE_CODE (TMR_BASE (ref));
+ temp.op0 = TMR_BASE (ref);
temp.off = -1;
VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
return;
}
else if (INDIRECT_REF_P (lhs)
- || TREE_CODE (lhs) == MEM_REF)
+ || TREE_CODE (lhs) == MEM_REF
+ || TREE_CODE (lhs) == TARGET_MEM_REF)
return ptr_deref_may_alias_global_p (TREE_OPERAND (lhs, 0));
else if (CONSTANT_CLASS_P (lhs))
return true;
double_int
mem_ref_offset (const_tree t)
{
- tree toff = TREE_CODE (t) == MEM_REF ? TREE_OPERAND (t, 1) : TMR_OFFSET (t);
+ tree toff = TREE_OPERAND (t, 1);
return double_int_sext (tree_to_double_int (toff),
TYPE_PRECISION (TREE_TYPE (toff)));
}
generated by the builtin targetm.vectorize.mask_for_load_builtin_decl. */
DEFTREECODE (REALIGN_LOAD_EXPR, "realign_load", tcc_expression, 3)
-/* Low-level memory addressing. Operands are SYMBOL (address of static or
- global variable), BASE (register), INDEX (register), STEP (integer constant),
- OFFSET (integer constant). Corresponding address is
- SYMBOL + BASE + STEP * INDEX + OFFSET. Only variations and values valid on
- the target are allowed.
-
- The type of STEP and INDEX is sizetype. The type of BASE is
- sizetype or a pointer type (if SYMBOL is NULL).
+/* Low-level memory addressing. Operands are BASE (address of static or
+ global variable or register), OFFSET (integer constant),
+ INDEX (register), STEP (integer constant), INDEX2 (register),
+ The corresponding address is BASE + STEP * INDEX + INDEX2 + OFFSET.
+ Only variations and values valid on the target are allowed.
+
+ The type of STEP, INDEX and INDEX2 is sizetype.
+
+ The type of BASE is a pointer type. If BASE is not an address of
+ a static or global variable INDEX2 will be NULL.
The type of OFFSET is a pointer type and determines TBAA the same as
the constant offset operand in MEM_REF. */
#define CASE_HIGH(NODE) TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
#define CASE_LABEL(NODE) TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
-/* The operands of a TARGET_MEM_REF. */
-#define TMR_SYMBOL(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 0))
-#define TMR_BASE(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 1))
+/* The operands of a TARGET_MEM_REF. Operands 0 and 1 have to match
+ corresponding MEM_REF operands. */
+#define TMR_BASE(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 0))
+#define TMR_OFFSET(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 1))
#define TMR_INDEX(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 2))
#define TMR_STEP(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 3))
-#define TMR_OFFSET(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
+#define TMR_INDEX2(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
/* The operands of a BIND_EXPR. */
#define BIND_EXPR_VARS(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 0))