/* We can reuse all operands without copying, because we are about
to delete the insn that contained it. */
if (srcoff)
- new_insn = gen_add3_insn (dest, src, srcoff);
+ {
+ start_sequence ();
+ emit_insn (gen_add3_insn (dest, src, srcoff));
+ new_insn = get_insns ();
+ end_sequence ();
+ }
else
new_insn = gen_move_insn (dest, src);
info.first = new_insn;
insn_info->wild_read = false;
}
-/* Check if EXPR can possibly escape the current function scope. */
+/* Return whether DECL, a local variable, can possibly escape the current
+ function scope. */
+
+static bool
+local_variable_can_escape (tree decl)
+{
+ if (TREE_ADDRESSABLE (decl))
+ return true;
+
+ /* If this is a partitioned variable, we need to consider all the variables
+ in the partition. This is necessary because a store into one of them can
+ be replaced with a store into another and this may not change the outcome
+ of the escape analysis. */
+ if (cfun->gimple_df->decls_to_pointers != NULL)
+ {
+ void *namep
+ = pointer_map_contains (cfun->gimple_df->decls_to_pointers, decl);
+ if (namep)
+ return TREE_ADDRESSABLE (*(tree *)namep);
+ }
+
+ return false;
+}
+
+/* Return whether EXPR can possibly escape the current function scope. */
+
static bool
can_escape (tree expr)
{
return true;
base = get_base_address (expr);
if (DECL_P (base)
- && !may_be_aliased (base))
+ && !may_be_aliased (base)
+ && !(TREE_CODE (base) == VAR_DECL
+ && !DECL_EXTERNAL (base)
+ && !TREE_STATIC (base)
+ && local_variable_can_escape (base)))
return false;
return true;
}
if (canon_true_dependence (s_info->mem,
GET_MODE (s_info->mem),
s_info->mem_addr,
- mem, mem_addr, rtx_varies_p))
+ mem, mem_addr))
{
s_info->rhs = NULL;
s_info->const_rhs = NULL;
c |= (c << shift);
shift <<= 1;
}
- read_reg = GEN_INT (trunc_int_for_mode (c, store_mode));
+ read_reg = gen_int_mode (c, store_mode);
read_reg = extract_low_bits (read_mode, store_mode, read_reg);
}
}
= canon_true_dependence (store_info->mem,
GET_MODE (store_info->mem),
store_info->mem_addr,
- mem, mem_addr, rtx_varies_p);
+ mem, mem_addr);
else if (group_id == store_info->group_id)
{
= canon_true_dependence (store_info->mem,
GET_MODE (store_info->mem),
store_info->mem_addr,
- mem, mem_addr, rtx_varies_p);
+ mem, mem_addr);
/* If this read is just reading back something that we just
stored, rewrite the read. */
remove = canon_true_dependence (store_info->mem,
GET_MODE (store_info->mem),
store_info->mem_addr,
- mem, mem_addr, rtx_varies_p);
+ mem, mem_addr);
if (remove)
{
{
if (!tmp || !CONST_INT_P (tmp))
return false;
- tmp = GEN_INT (trunc_int_for_mode (INTVAL (tmp), mode));
+ tmp = gen_int_mode (INTVAL (tmp), mode);
}
if (tmp)
args[idx] = tmp;
&& canon_true_dependence (group->base_mem,
GET_MODE (group->base_mem),
group->canon_base_addr,
- read_info->mem, NULL_RTX,
- rtx_varies_p))
+ read_info->mem, NULL_RTX))
{
if (kill)
bitmap_ior_into (kill, group->group_kill);