aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-26 23:26:44 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:03 -0700
commitb22aa7228d7fab35b86cb57a4b33d3826ec7e916 (patch)
tree4b2b80b7fa19b38946be9e5920b8989888e9c089 /simplify.c
parentSimplify constant subtraction into addition. (diff)
downloadsparse-b22aa7228d7fab35b86cb57a4b33d3826ec7e916.tar.gz
sparse-b22aa7228d7fab35b86cb57a4b33d3826ec7e916.tar.bz2
sparse-b22aa7228d7fab35b86cb57a4b33d3826ec7e916.zip
Teach 'memop' simplification about offsetting.
Handle simple constant offsets and fold them into the memop offset.
Diffstat (limited to 'simplify.c')
-rw-r--r--simplify.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index 85c04c1..0ecd7d0 100644
--- a/simplify.c
+++ b/simplify.c
@@ -409,6 +409,8 @@ static int simplify_unop(struct instruction *insn)
static int simplify_memop(struct instruction *insn)
{
pseudo_t addr = insn->src;
+ pseudo_t new, off;
+
if (addr->type == PSEUDO_REG) {
struct instruction *def = addr->def;
if (def->opcode == OP_SETVAL && def->src) {
@@ -416,8 +418,25 @@ static int simplify_memop(struct instruction *insn)
use_pseudo(def->src, &insn->src);
return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
}
+ if (def->opcode == OP_ADD) {
+ new = def->src1;
+ off = def->src2;
+ if (constant(off))
+ goto offset;
+ new = off;
+ off = def->src1;
+ if (constant(off))
+ goto offset;
+ return 0;
+ }
}
return 0;
+
+offset:
+ insn->offset += off->value;
+ use_pseudo(new, &insn->src);
+ remove_usage(addr, &insn->src);
+ return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
}
int simplify_instruction(struct instruction *insn)