diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-12-11 15:22:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:06:00 -0700 |
commit | a29db2d1bbf41ed4907cf79101e631b415a31d2d (patch) | |
tree | e87c725066525072f20009e18214644c2d9858dc /simplify.c | |
parent | Mark the backing store storage dead when marking a pseudo dead. (diff) | |
download | sparse-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.c | 41 |
1 files changed, 40 insertions, 1 deletions
@@ -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: |