aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-11 15:22:31 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:06:00 -0700
commita29db2d1bbf41ed4907cf79101e631b415a31d2d (patch)
treee87c725066525072f20009e18214644c2d9858dc /simplify.c
parentMark the backing store storage dead when marking a pseudo dead. (diff)
downloadsparse-a29db2d1bbf41ed4907cf79101e631b415a31d2d.tar.gz
sparse-a29db2d1bbf41ed4907cf79101e631b415a31d2d.tar.bz2
sparse-a29db2d1bbf41ed4907cf79101e631b415a31d2d.zip
Make commutative operations use a canonical order.
This improves CSE, and simplifies code generation. Keep the "simpler" argument in "src2".
Diffstat (limited to 'simplify.c')
-rw-r--r--simplify.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/simplify.c b/simplify.c
index 9e00967..e2774f3 100644
--- a/simplify.c
+++ b/simplify.c
@@ -391,6 +391,39 @@ static int simplify_binop(struct instruction *insn)
return 0;
}
+static void switch_pseudo(pseudo_t *pp1, pseudo_t *pp2)
+{
+ pseudo_t p1 = *pp1, p2 = *pp2;
+
+ use_pseudo(p2, pp1);
+ use_pseudo(p1, pp2);
+ remove_usage(p1, pp1);
+ remove_usage(p2, pp2);
+}
+
+static int canonical_order(pseudo_t p1, pseudo_t p2)
+{
+ /* symbol/constants on the right */
+ if (p1->type == PSEUDO_VAL)
+ return p2->type == PSEUDO_VAL;
+
+ if (p1->type == PSEUDO_SYM)
+ return p2->type == PSEUDO_SYM || p2->type == PSEUDO_VAL;
+
+ return 1;
+}
+
+static int simplify_commutative_binop(struct instruction *insn)
+{
+ if (simplify_binop(insn))
+ return REPEAT_CSE;
+ if (!canonical_order(insn->src1, insn->src2)) {
+ switch_pseudo(&insn->src1, &insn->src2);
+ return REPEAT_CSE;
+ }
+ return 0;
+}
+
static int simplify_constant_unop(struct instruction *insn)
{
long long val = insn->src1->value;
@@ -641,7 +674,13 @@ int simplify_instruction(struct instruction *insn)
if (!insn->bb)
return 0;
switch (insn->opcode) {
- case OP_BINARY ... OP_BINCMP_END:
+ case OP_ADD: case OP_MUL:
+ case OP_AND: case OP_OR: case OP_XOR:
+ case OP_AND_BOOL: case OP_OR_BOOL:
+ return simplify_commutative_binop(insn);
+
+ case OP_SUB: case OP_DIV: case OP_MOD:
+ case OP_SHL: case OP_SHR:
return simplify_binop(insn);
case OP_NOT: case OP_NEG: