qemu/gcc-aliasing3.diff

270 lines
7.6 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.226.2.9
diff -u -p -r1.226.2.9 fold-const.c
--- gcc/fold-const.c 21 Jul 2003 19:07:12 -0000 1.226.2.9
+++ gcc/fold-const.c 30 Jul 2003 21:29:05 -0000
@@ -1011,6 +1011,233 @@ associate_trees (t1, t2, code, type)
return fold (build (code, type, convert (type, t1), convert (type, t2)));
}
+
+static tree tree_get_index PARAMS ((tree));
+static int indirect_ref_zero_ofs_p PARAMS ((tree));
+static int indirect_ref_nonzero_ofs_p PARAMS ((tree));
+static tree associate_trees_refs PARAMS ((tree, tree, enum tree_code, tree));
+static void split_tree_indirect_refs PARAMS ((tree, enum tree_code, tree));
+static void split_tree_for_reorder PARAMS ((tree, enum tree_code, tree));
+static int compare_trees PARAMS ((const PTR, const PTR));
+static tree reorder_memrefs PARAMS ((tree, tree, enum tree_code, tree));
+static tree reorder_summands PARAMS ((tree, tree, enum tree_code, tree));
+
+static tree
+tree_get_index (t)
+ tree t;
+{
+ if (TREE_CODE (t) == ARRAY_REF)
+ return TREE_OPERAND (t, 1);
+ else
+ {
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) != PLUS_EXPR)
+ return NULL_TREE;
+ return TREE_OPERAND (t, 1);
+ }
+}
+
+static int
+indirect_ref_nonzero_ofs_p (t)
+ tree t;
+{
+ tree i = tree_get_index (t);
+ if (i && TREE_CODE (i) == INTEGER_CST && !integer_zerop (i))
+ return 1;
+ return 0;
+}
+
+static int
+indirect_ref_zero_ofs_p (t)
+ tree t;
+{
+ tree i = tree_get_index (t);
+ if (!i)
+ return 1;
+ if (TREE_CODE (i) == INTEGER_CST && integer_zerop (i))
+ return 1;
+ return 0;
+}
+
+static tree
+associate_trees_refs (t1, t2, code, type)
+ tree t1, t2;
+ enum tree_code code;
+ tree type;
+{
+ if (t1 == 0)
+ return t2;
+ else if (t2 == 0)
+ return t1;
+ return build (code, type, convert (type, t1), convert (type, t2));
+}
+
+#define MAX_SUMMANDS 100
+static tree merged_z, merged_nz, merged_rest;
+static tree summands[MAX_SUMMANDS];
+static int num_summands;
+static void
+split_tree_indirect_refs (in, code, type)
+ tree in;
+ enum tree_code code;
+ tree type;
+{
+ /* Strip any conversions that don't change the machine mode or signedness. */
+ STRIP_SIGN_NOPS (in);
+
+ if (TREE_CODE (in) == INDIRECT_REF || TREE_CODE (in) == ARRAY_REF)
+ {
+ if (indirect_ref_zero_ofs_p (in))
+ merged_z = associate_trees_refs (merged_z, in, code, type);
+ else if (indirect_ref_nonzero_ofs_p (in))
+ merged_nz = associate_trees_refs (merged_nz, in, code, type);
+ else
+ merged_rest = associate_trees_refs (merged_rest, in, code, type);
+ }
+ else if (TREE_CODE (in) == code)
+ {
+ tree op0 = TREE_OPERAND (in, 0);
+ tree op1 = TREE_OPERAND (in, 1);
+ split_tree_indirect_refs (op0, code, type);
+ split_tree_indirect_refs (op1, code, type);
+ }
+ else
+ merged_rest = associate_trees_refs (merged_rest, in, code, type);
+}
+
+static void
+split_tree_for_reorder (in, code, type)
+ tree in;
+ enum tree_code code;
+ tree type;
+{
+ /* Strip any conversions that don't change the machine mode or signedness. */
+ STRIP_SIGN_NOPS (in);
+
+ if ((TREE_CODE (in) == INDIRECT_REF
+ || TREE_CODE (in) == ARRAY_REF
+ || TREE_CODE (in) == VAR_DECL)
+ && num_summands < MAX_SUMMANDS)
+ summands[num_summands++] = in;
+ else if (TREE_CODE (in) == code)
+ {
+ tree op0 = TREE_OPERAND (in, 0);
+ tree op1 = TREE_OPERAND (in, 1);
+ split_tree_for_reorder (op0, code, type);
+ split_tree_for_reorder (op1, code, type);
+ }
+ else
+ merged_rest = associate_trees_refs (merged_rest, in, code, type);
+}
+
+static int
+compare_trees (v1, v2)
+ const PTR v1;
+ const PTR v2;
+{
+ tree t1 = *((const tree *) v1);
+ tree t2 = *((const tree *) v2);
+
+ if (t1 == t2)
+ return 0;
+ /* Everything besides var_decls and indirect_refs last. */
+ if (TREE_CODE (t1) != INDIRECT_REF
+ && TREE_CODE (t1) != ARRAY_REF
+ && TREE_CODE (t1) != VAR_DECL)
+ return 1;
+ if (TREE_CODE (t2) != INDIRECT_REF
+ && TREE_CODE (t2) != ARRAY_REF
+ && TREE_CODE (t2) != VAR_DECL)
+ return -1;
+ /* All indirect_refs with nonzero index before var_decls.
+ All indirect_refs with zero index after var_decls. */
+ if (TREE_CODE (t1) != TREE_CODE (t2))
+ {
+ if (TREE_CODE (t1) == INDIRECT_REF || TREE_CODE (t1) == ARRAY_REF)
+ {
+ if (indirect_ref_nonzero_ofs_p (t1))
+ return -1;
+ else
+ return 1;
+ }
+ /* t2 is a INDIRECT_REF or ARRAY_REF, so we can call that without
+ checking. */
+ else if (indirect_ref_nonzero_ofs_p (t2))
+ return 1;
+ else
+ return -1;
+ }
+ if (TREE_CODE (t1) == VAR_DECL)
+ {
+ if (IDENTIFIER_HASH_VALUE (DECL_NAME (t1))
+ < IDENTIFIER_HASH_VALUE (DECL_NAME (t2)))
+ return -1;
+ else
+ return 1;
+ }
+ /* We have two indirect_refs here. */
+ if (indirect_ref_nonzero_ofs_p (t1) && indirect_ref_nonzero_ofs_p (t2))
+ /* As both had non-zero index, we know that tree_get_index() really
+ returns INTEGER_CST. */
+ return tree_int_cst_compare (tree_get_index (t1), tree_get_index (t2));
+ else if (indirect_ref_zero_ofs_p (t1))
+ return 1;
+ else
+ return -1;
+}
+
+static tree
+reorder_memrefs (in0, in1, code, type)
+ tree in0, in1;
+ enum tree_code code;
+ tree type;
+{
+ tree ret = 0;
+ merged_z = 0;
+ merged_nz = 0;
+ merged_rest = 0;
+ /* XXX We can't yet handle MINUS_EXPR. */
+ if (code == MINUS_EXPR)
+ return 0;
+ if (in0)
+ split_tree_indirect_refs (in0, code, type);
+ if (in1)
+ split_tree_indirect_refs (in1, code, type);
+ if (merged_nz || merged_z)
+ {
+ ret = associate_trees_refs (merged_nz, merged_z, code, type);
+ ret = associate_trees_refs (ret, merged_rest, code, type);
+ }
+ return ret;
+}
+
+static tree
+reorder_summands (in0, in1, code, type)
+ tree in0, in1;
+ enum tree_code code;
+ tree type;
+{
+ tree ret = 0;
+ merged_rest = 0;
+ num_summands = 0;
+ /* XXX We can't yet handle MINUS_EXPR. */
+ if (code == MINUS_EXPR)
+ return 0;
+ if (in0)
+ split_tree_for_reorder (in0, code, type);
+ if (in1)
+ split_tree_for_reorder (in1, code, type);
+ if (num_summands > 2)
+ {
+ int i;
+ qsort (summands, num_summands, sizeof (tree), compare_trees);
+ ret = summands[0];
+ for (i = 1; i < num_summands; i++)
+ ret = associate_trees_refs (ret, summands[i], code, type);
+ ret = associate_trees_refs (ret, merged_rest, code, type);
+ }
+ return ret;
+}
/* Combine two integer constants ARG1 and ARG2 under operation CODE
to produce a new constant.
@@ -5378,11 +5605,16 @@ fold (expr)
+ (lit0 != 0) + (lit1 != 0)
+ (minus_lit0 != 0) + (minus_lit1 != 0)))
{
+ tree tmp;
+ tmp = reorder_summands (var0, var1, code, type);
/* Recombine MINUS_EXPR operands by using PLUS_EXPR. */
if (code == MINUS_EXPR)
code = PLUS_EXPR;
- var0 = associate_trees (var0, var1, code, type);
+ if (tmp)
+ var0 = tmp;
+ else
+ var0 = associate_trees (var0, var1, code, type);
con0 = associate_trees (con0, con1, code, type);
lit0 = associate_trees (lit0, lit1, code, type);
minus_lit0 = associate_trees (minus_lit0, minus_lit1, code, type);
@@ -5424,6 +5656,9 @@ fold (expr)
con0 = associate_trees (con0, lit0, code, type);
return convert (type, associate_trees (var0, con0, code, type));
}
+ var0 = reorder_summands (arg0, arg1, code, type);
+ if (var0)
+ return convert (type, var0);
}
binary: