[PATCH][mem-ref2] Re-enable SRA
Richard Guenther
rguenther@suse.de
Wed Mar 31 11:06:00 GMT 2010
This re-enables SRA by just dropping the intended simplification
of build_ref_for_offset and leave that for a followup. It fixes
some pieces that I missed during the initial conversion attempts.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
branch.
Richard.
2010-03-31 Richard Guenther <rguenther@suse.de>
* tree-sra.c (create_access): Swap INDIRECT_REF handling for
MEM_REF handling.
(disqualify_base_of_expr): Likewise.
(build_ref_for_offset_1): Re-instantiate.
(build_ref_for_offset): Revert previous changes.
(gate_intra_sra): Re-enable.
(ptr_parm_has_direct_uses): Swap INDIRECT_REF handling for
MEM_REF handling.
(sra_ipa_modify_expr): Remove INDIRECT_REF handling.
Use mem_ref_offset.
(ipa_early_sra_gate): Re-enable.
Index: tree-sra.c
===================================================================
--- tree-sra.c (revision 157630)
+++ tree-sra.c (working copy)
@@ -746,7 +746,8 @@ create_access (tree expr, gimple stmt, b
base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
- if (sra_mode == SRA_MODE_EARLY_IPA && INDIRECT_REF_P (base))
+ if (sra_mode == SRA_MODE_EARLY_IPA
+ && TREE_CODE (base) == MEM_REF)
{
base = get_ssa_base_param (TREE_OPERAND (base, 0));
if (!base)
@@ -885,7 +886,7 @@ disqualify_base_of_expr (tree t, const c
if (sra_mode == SRA_MODE_EARLY_IPA)
{
- if (INDIRECT_REF_P (t))
+ if (TREE_CODE (t) == MEM_REF)
t = TREE_OPERAND (t, 0);
t = get_ssa_base_param (t);
}
@@ -931,7 +932,6 @@ build_access_from_expr_1 (tree *expr_ptr
switch (TREE_CODE (expr))
{
- case INDIRECT_REF:
case MEM_REF:
if (sra_mode != SRA_MODE_EARLY_IPA)
return NULL;
@@ -1375,6 +1375,100 @@ make_fancy_name (tree expr)
return XOBFINISH (&name_obstack, char *);
}
+/* Helper function for build_ref_for_offset. */
+
+static bool
+build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
+ tree exp_type)
+{
+ while (1)
+ {
+ tree fld;
+ tree tr_size, index, minidx;
+ HOST_WIDE_INT el_size;
+
+ if (offset == 0 && exp_type
+ && types_compatible_p (exp_type, type))
+ return true;
+
+ switch (TREE_CODE (type))
+ {
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ case RECORD_TYPE:
+ for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
+ {
+ HOST_WIDE_INT pos, size;
+ tree expr, *expr_ptr;
+
+ if (TREE_CODE (fld) != FIELD_DECL)
+ continue;
+
+ pos = int_bit_position (fld);
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
+ tr_size = DECL_SIZE (fld);
+ if (!tr_size || !host_integerp (tr_size, 1))
+ continue;
+ size = tree_low_cst (tr_size, 1);
+ if (size == 0)
+ {
+ if (pos != offset)
+ continue;
+ }
+ else if (pos > offset || (pos + size) <= offset)
+ continue;
+
+ if (res)
+ {
+ expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
+ NULL_TREE);
+ expr_ptr = &expr;
+ }
+ else
+ expr_ptr = NULL;
+ if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
+ offset - pos, exp_type))
+ {
+ if (res)
+ *res = expr;
+ return true;
+ }
+ }
+ return false;
+
+ case ARRAY_TYPE:
+ tr_size = TYPE_SIZE (TREE_TYPE (type));
+ if (!tr_size || !host_integerp (tr_size, 1))
+ return false;
+ el_size = tree_low_cst (tr_size, 1);
+
+ minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
+ if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
+ return false;
+ if (res)
+ {
+ index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
+ if (!integer_zerop (minidx))
+ index = int_const_binop (PLUS_EXPR, index, minidx, 0);
+ *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
+ NULL_TREE, NULL_TREE);
+ }
+ offset = offset % el_size;
+ type = TREE_TYPE (type);
+ break;
+
+ default:
+ if (offset != 0)
+ return false;
+
+ if (exp_type)
+ return false;
+ else
+ return true;
+ }
+ }
+}
+
/* Construct an expression that would reference a part of aggregate *EXPR of
type TYPE at the given OFFSET of the type EXP_TYPE. If EXPR is NULL, the
function only determines whether it can build such a reference without
@@ -1392,36 +1486,17 @@ build_ref_for_offset (tree *expr, tree t
{
location_t loc = expr ? EXPR_LOCATION (*expr) : UNKNOWN_LOCATION;
- if (offset % BITS_PER_UNIT != 0)
- return false;
-
- if (!expr)
- return true;
-
- *expr = unshare_expr (*expr);
+ if (expr)
+ *expr = unshare_expr (*expr);
if (allow_ptr && POINTER_TYPE_P (type))
- *expr = build2 (MEM_REF, exp_type,
- *expr, build_int_cst (type, offset / BITS_PER_UNIT));
- else if (TREE_CODE (*expr) == MEM_REF)
- {
- tree addr = TREE_OPERAND (*expr, 0);
- tree off = build_int_cst (TREE_TYPE (TREE_OPERAND (*expr, 1)),
- offset / BITS_PER_UNIT);
- off = int_const_binop (PLUS_EXPR, TREE_OPERAND (*expr, 1), off, 0);
- *expr = build2 (MEM_REF, exp_type, addr, off);
- }
- else
{
- tree ptype = build_pointer_type (type);
- tree off = build_int_cst (ptype, offset / BITS_PER_UNIT);
- tree addr = build_fold_addr_expr (*expr);
- STRIP_NOPS (addr);
- *expr = build2 (MEM_REF, exp_type, addr, off);
+ type = TREE_TYPE (type);
+ if (expr)
+ *expr = build_simple_mem_ref_loc (loc, *expr);
}
- SET_EXPR_LOCATION (*expr, loc);
- return true;
+ return build_ref_for_offset_1 (expr, type, offset, exp_type);
}
/* Return true iff TYPE is stdarg va_list type. */
@@ -2767,7 +2842,7 @@ late_intra_sra (void)
static bool
gate_intra_sra (void)
{
- return 0 && flag_tree_sra != 0;
+ return flag_tree_sra != 0;
}
@@ -2855,8 +2930,10 @@ ptr_parm_has_direct_uses (tree parm)
tree lhs = gimple_get_lhs (stmt);
while (handled_component_p (lhs))
lhs = TREE_OPERAND (lhs, 0);
- if (INDIRECT_REF_P (lhs)
- && TREE_OPERAND (lhs, 0) == name)
+ if (TREE_CODE (lhs) == MEM_REF
+ && TREE_OPERAND (lhs, 0) == name
+ && integer_zerop (TREE_OPERAND (lhs, 1))
+ && types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (name)))
uses_ok++;
}
if (gimple_assign_single_p (stmt))
@@ -2864,8 +2941,10 @@ ptr_parm_has_direct_uses (tree parm)
tree rhs = gimple_assign_rhs1 (stmt);
while (handled_component_p (rhs))
rhs = TREE_OPERAND (rhs, 0);
- if (INDIRECT_REF_P (rhs)
- && TREE_OPERAND (rhs, 0) == name)
+ if (TREE_CODE (rhs) == MEM_REF
+ && TREE_OPERAND (rhs, 0) == name
+ && integer_zerop (TREE_OPERAND (rhs, 1))
+ && types_compatible_p (TREE_TYPE (rhs), TREE_TYPE (name)))
uses_ok++;
}
else if (is_gimple_call (stmt))
@@ -2876,8 +2955,10 @@ ptr_parm_has_direct_uses (tree parm)
tree arg = gimple_call_arg (stmt, i);
while (handled_component_p (arg))
arg = TREE_OPERAND (arg, 0);
- if (INDIRECT_REF_P (arg)
- && TREE_OPERAND (arg, 0) == name)
+ if (TREE_CODE (arg) == MEM_REF
+ && TREE_OPERAND (arg, 0) == name
+ && integer_zerop (TREE_OPERAND (arg, 1))
+ && types_compatible_p (TREE_TYPE (arg), TREE_TYPE (name)))
uses_ok++;
}
}
@@ -3755,12 +3836,9 @@ sra_ipa_modify_expr (tree *expr, gimple_
if (!base || size == -1 || max_size == -1)
return false;
- if (INDIRECT_REF_P (base))
- base = TREE_OPERAND (base, 0);
-
if (TREE_CODE (base) == MEM_REF)
{
- offset += TREE_INT_CST_LOW (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
+ offset += mem_ref_offset (base).low * BITS_PER_UNIT;
base = TREE_OPERAND (base, 0);
}
@@ -3785,8 +3863,7 @@ sra_ipa_modify_expr (tree *expr, gimple_
if (cand->by_ref)
{
tree folded;
- src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
- cand->reduction);
+ src = build_simple_mem_ref (cand->reduction);
folded = gimple_fold_indirect_ref (src);
if (folded)
src = folded;
@@ -4153,7 +4230,7 @@ ipa_early_sra (void)
static bool
ipa_early_sra_gate (void)
{
- return 0 && flag_ipa_sra;
+ return flag_ipa_sra;
}
struct gimple_opt_pass pass_early_ipa_sra =
More information about the Gcc-patches
mailing list