aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-30 17:45:59 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:18 -0700
commit9f1e671ad17c83efe805314e2a061287a81956ae (patch)
treee29148ea0f0485807677125c0e25522af71fb76c /simplify.c
parentDo real flow simplification only after liveness analysis. (diff)
downloadsparse-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.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/simplify.c b/simplify.c
index 3cc05ec..1d6f428 100644
--- a/simplify.c
+++ b/simplify.c
@@ -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)