diff options
| author | 2025-11-14 22:21:06 +0100 | |
|---|---|---|
| committer | 2025-11-14 22:21:06 +0100 | |
| commit | 345b8c4476db29a1d5a46393c857cdeff4740f50 (patch) | |
| tree | ddb6d3b1533eb9cadd7c2c89f40f9583765b0fe3 /amd64/isel.c | |
| parent | 0d3d363f5b4b026a5fd73df721636710d6c361d8 (diff) | |
isel: fold arith
Diffstat (limited to 'amd64/isel.c')
| -rw-r--r-- | amd64/isel.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/amd64/isel.c b/amd64/isel.c index f8adb9a..6635abc 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -297,6 +297,19 @@ loadstoreaddr(struct block *blk, union ref *r, int *curi) } } +static bool +arithfold(struct instr *ins) +{ + if (isnumcon(ins->l) && (!ins->r.t || isnumcon(ins->r))) { + union ref r; + bool ok = ins->r.t ? foldbinop(&r, ins->op, ins->cls, ins->l, ins->r) : foldunop(&r, ins->op, ins->cls, ins->l); + assert(ok && "fold?"); + *ins = mkinstr(Ocopy, insrescls(*ins), r); + return 1; + } + return 0; +} + static void sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) { @@ -305,6 +318,11 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) struct instr temp = {0}; enum op op = ins->op; + if (oisarith(ins->op) && arithfold(ins)) { + fixarg(&ins->l, ins, blk, curi); + return; + } + switch (op) { default: assert(0); case Onop: break; @@ -422,8 +440,10 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) if (!(op == Oadd && kisint(ins->cls))) /* 3-address add is lea */ if (!(in_range(op, Omul, Oumul) && kisint(ins->cls) && isimm32(ins->r))) /* for (I)MUL r,r/m,imm */ ins->inplace = 1; - if (iscon(ins->l)) + if (iscon(ins->l)) { + fixarg(&ins->l, ins, blk, curi); ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, ins->l)); + } if (ins->r.bits) case Omove: fixarg(&ins->r, ins, blk, curi); |