/* We record floating-point CONST_DOUBLEs in each floating-point mode for
the values of 0, 1, and 2. For the integer entries and VOIDmode, we
- record a copy of const[012]_rtx. */
+ record a copy of const[012]_rtx and constm1_rtx. CONSTM1_RTX
+ is set only for MODE_INT and MODE_VECTOR_INT modes. */
-rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
+rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
rtx const_true_rtx;
HOST_WIDE_INT apply_bitpos = 0;
tree type;
struct mem_attrs attrs, *defattrs, *refattrs;
+ addr_space_t as;
/* It can happen that type_for_mode was given a mode for which there
is no language-level type. In which case it returns NULL, which
attrs.alias = get_alias_set (t);
MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
- MEM_IN_STRUCT_P (ref)
- = AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE;
MEM_POINTER (ref) = POINTER_TYPE_P (type);
- /* If we are making an object of this type, or if this is a DECL, we know
- that it is a scalar if the type is not an aggregate. */
- if ((objectp || DECL_P (t))
- && ! AGGREGATE_TYPE_P (type)
- && TREE_CODE (type) != COMPLEX_TYPE)
- MEM_SCALAR_P (ref) = 1;
-
/* Default values from pre-existing memory attributes if present. */
refattrs = MEM_ATTRS (ref);
if (refattrs)
MEM_NOTRAP_P (ref) = !tree_could_trap_p (t);
base = get_base_address (t);
- if (base && DECL_P (base)
- && TREE_READONLY (base)
- && (TREE_STATIC (base) || DECL_EXTERNAL (base))
- && !TREE_THIS_VOLATILE (base))
- MEM_READONLY_P (ref) = 1;
+ if (base)
+ {
+ if (DECL_P (base)
+ && TREE_READONLY (base)
+ && (TREE_STATIC (base) || DECL_EXTERNAL (base))
+ && !TREE_THIS_VOLATILE (base))
+ MEM_READONLY_P (ref) = 1;
+
+ /* Mark static const strings readonly as well. */
+ if (TREE_CODE (base) == STRING_CST
+ && TREE_READONLY (base)
+ && TREE_STATIC (base))
+ MEM_READONLY_P (ref) = 1;
+
+ if (TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (base,
+ 0))));
+ else
+ as = TYPE_ADDR_SPACE (TREE_TYPE (base));
+ }
+ else
+ as = TYPE_ADDR_SPACE (type);
/* If this expression uses it's parent's alias set, mark it such
that we won't change it. */
if (!align_computed)
{
- unsigned int obj_align = get_object_alignment (t);
+ unsigned int obj_align;
+ unsigned HOST_WIDE_INT obj_bitpos;
+ obj_align = get_object_alignment_1 (t, &obj_bitpos);
+ obj_bitpos = (obj_bitpos - bitpos) & (obj_align - 1);
+ if (obj_bitpos != 0)
+ obj_align = (obj_bitpos & -obj_bitpos);
attrs.align = MAX (attrs.align, obj_align);
}
}
+ else
+ as = TYPE_ADDR_SPACE (type);
/* If we modified OFFSET based on T, then subtract the outstanding
bit position offset. Similarly, increase the size of the accessed
}
/* Now set the attributes we computed above. */
- attrs.addrspace = TYPE_ADDR_SPACE (type);
+ attrs.addrspace = as;
set_mem_attrs (ref, &attrs);
-
- /* If this is already known to be a scalar or aggregate, we are done. */
- if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
- return;
-
- /* If it is a reference into an aggregate, this is part of an aggregate.
- Otherwise we don't know. */
- else if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF
- || TREE_CODE (t) == ARRAY_RANGE_REF
- || TREE_CODE (t) == BIT_FIELD_REF)
- MEM_IN_STRUCT_P (ref) = 1;
}
void
return insn;
}
-/* Return the last CODE_LABEL before the insn INSN, or 0 if there is none. */
-
-rtx
-prev_label (rtx insn)
-{
- while (insn)
- {
- insn = PREV_INSN (insn);
- if (insn == 0 || LABEL_P (insn))
- break;
- }
-
- return insn;
-}
-
/* Return the last label to mark the same position as LABEL. Return LABEL
itself if it is null or any return rtx. */
case REG_NORETURN:
case REG_SETJMP:
+ case REG_TM:
for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
{
if (CALL_P (insn))
return REG_NOTES (insn);
}
+
+/* Like set_unique_reg_note, but don't do anything unless INSN sets DST. */
+rtx
+set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
+{
+ rtx set = single_set (insn);
+
+ if (set && SET_DEST (set) == dst)
+ return set_unique_reg_note (insn, kind, datum);
+ return NULL_RTX;
+}
\f
/* Return an indication of which type of insn should have X as a body.
The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */
return CONST0_RTX (mode);
else if (x == CONST1_RTX (inner))
return CONST1_RTX (mode);
+ else if (x == CONSTM1_RTX (inner))
+ return CONSTM1_RTX (mode);
}
return gen_rtx_raw_CONST_VECTOR (mode, v);
dconsthalf = dconst1;
SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
- for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)
+ for (i = 0; i < 3; i++)
{
const REAL_VALUE_TYPE *const r =
(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
const_tiny_rtx[i][(int) mode] = GEN_INT (i);
}
+ const_tiny_rtx[3][(int) VOIDmode] = constm1_rtx;
+
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ const_tiny_rtx[3][(int) mode] = constm1_rtx;
+
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ const_tiny_rtx[3][(int) mode] = constm1_rtx;
+
for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_INT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
+ const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3);
}
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);