aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir/builder.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-21 17:41:50 +0100
committerlemon <lsof@mailbox.org>2025-12-21 17:42:31 +0100
commit97953ac6f077ef2ed2a59f7b1e2328573981d41e (patch)
tree1b0cf2007f29f0b010fa3cdb77c478b3843b5ed0 /ir/builder.c
parent3e74de26d16780e626241e0c42313fcb37b91cf2 (diff)
ir: simpl: optimize some constant multiplications
Reuse irbinop() and irunop() for the constant results cases.
Diffstat (limited to 'ir/builder.c')
-rw-r--r--ir/builder.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/ir/builder.c b/ir/builder.c
index 36f955c..8fb626c 100644
--- a/ir/builder.c
+++ b/ir/builder.c
@@ -16,7 +16,8 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref
if (l.bits == ZEROREF.bits) return r; /* 0 + x ==> x */
/* fallthru */
case Osub:
- if (r.bits == ZEROREF.bits) return l; /* x +/- 0 ==> x */
+ if (r.bits == ZEROREF.bits) return l; /* x - 0 ==> x */
+ if (kisint(k) && l.bits == r.bits) return ZEROREF; /* x - 0 ==> x */
break;
case Omul:
if (isnumcon(l)) rswap(l, r); /* put const in rhs */
@@ -28,7 +29,7 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref
if (isintcon(r) && ispo2(iv = intconval(r))) {
/* x * 2^y ==> x << y */
op = Oshl;
- r = mkintcon(k, ilog2(iv));
+ r = mkref(RICON, ilog2(iv));
}
break;
case Odiv:
@@ -38,7 +39,7 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref
if (isintcon(r) && ispo2(iv = intconval(r))) {
/* x / 2^y ==> x >> y */
op = Oslr;
- r = mkintcon(k, ilog2(iv));
+ r = mkref(RICON, ilog2(iv));
}
break;
case Orem:
@@ -98,7 +99,7 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref
default:
assert(!"binop?");
}
- return addinstr(fn, mkinstr(op, k, l, r));
+ return fn ? addinstr(fn, mkinstr(op, k, l, r)) : NOREF;
}
/* implements f32/f64 -> u64 conversion */
@@ -175,7 +176,7 @@ irunop(struct function *fn, enum op op, enum irclass k, union ref a)
case Ocvts64f:
break;
case Ocvtf32u: case Ocvtf64u:
- if (k == KI64) {
+ if (k == KI64 && fn) {
/* XXX some architectures like arm64 do have these instructions natively
* this should probably be handled in a separate "arithmetic-lowering" pass, earlier than isel
*/
@@ -184,14 +185,15 @@ irunop(struct function *fn, enum op op, enum irclass k, union ref a)
break;
case Ocvtu64f:
/* XXX see above */
- return cvtu64f(fn, k, a);
+ if (fn)
+ return cvtu64f(fn, k, a);
case Oexts8: case Oextu8: case Oexts16: case Oextu16:
case Oexts32: case Oextu32:
case Ocopy:
break;
default: assert(!"unop?");
}
- return addinstr(fn, mkinstr(op, k, a));
+ return fn ? addinstr(fn, mkinstr(op, k, a)) : NOREF;
}
int allocinstr(void);