diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-30 17:45:59 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:05:18 -0700 |
commit | 9f1e671ad17c83efe805314e2a061287a81956ae (patch) | |
tree | e29148ea0f0485807677125c0e25522af71fb76c /simplify.c | |
parent | Do real flow simplification only after liveness analysis. (diff) | |
download | sparse-9f1e671ad17c83efe805314e2a061287a81956ae.tar.gz sparse-9f1e671ad17c83efe805314e2a061287a81956ae.tar.bz2 sparse-9f1e671ad17c83efe805314e2a061287a81956ae.zip |
Simplify "setcc + select $0<->$1" into "setne/seteq".
It's a common idiom, keep it in common format.
Diffstat (limited to 'simplify.c')
-rw-r--r-- | simplify.c | 36 |
1 files changed, 29 insertions, 7 deletions
@@ -472,7 +472,7 @@ static int simplify_cast(struct instruction *insn) static int simplify_select(struct instruction *insn, struct instruction *setcc) { - pseudo_t cond; + pseudo_t cond, src1, src2; assert(setcc && setcc->bb); if (dead_insn(insn, &insn->src1, &insn->src2)) { @@ -480,12 +480,34 @@ static int simplify_select(struct instruction *insn, struct instruction *setcc) return REPEAT_CSE; } cond = setcc->src; - if (!constant(cond) && insn->src1 != insn->src2) - return 0; - setcc->bb = NULL; - kill_use(&setcc->cond); - replace_with_pseudo(insn, cond->value ? insn->src1 : insn->src2); - return REPEAT_CSE; + src1 = insn->src1; + src2 = insn->src2; + if (constant(cond) || src1 == src2) { + setcc->bb = NULL; + kill_use(&setcc->cond); + replace_with_pseudo(insn, cond->value ? src1 : src2); + return REPEAT_CSE; + } + if (constant(src1) && constant(src2)) { + long long val1 = src1->value; + long long val2 = src2->value; + + /* The pair 0/1 is special - replace with SETNE/SETEQ */ + if ((val1 | val2) == 1) { + int opcode = OP_SET_EQ; + if (val1) { + src1 = src2; + opcode = OP_SET_NE; + } + insn->opcode = opcode; + insn->src2 = src1; /* Zero */ + use_pseudo(cond, &insn->src1); + setcc->bb = NULL; + kill_use(&setcc->cond); + return REPEAT_CSE; + } + } + return 0; } static int simplify_branch(struct instruction *insn) |