Skip to content

Commit 72c5cb9

Browse files
committed
Added peephole optimizations for sequences of shifts
1 parent 65c23af commit 72c5cb9

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

Changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Version 6.6.2
22
- Added warning (-Warray-index) for constant array indices out of bounds
33
- Allow warnings and optimizations to be turned off with a `no-` prefix (so `warn(no-init-vars)` is like `warn(!init-vars)`).
44
- Added some peephole optimizations to remove unnecessary sign extension
5+
- Added peephole optimizations for sequences of shifts/adds/subs
56
- Parse --optimize= flag (spin2cpp) in a slightly more flexible way
67
- Some internal changes to make recovering from missing xxd easier
78

backends/asm/optimize_ir.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,12 @@ IsLocalOrArg(Operand *op)
465465
return op->kind == REG_LOCAL || op->kind == REG_ARG || op->kind == REG_TEMP;
466466
}
467467

468+
static bool
469+
IsDirectImmediate(Operand *op)
470+
{
471+
return op && op->kind == IMM_INT;
472+
}
473+
468474
static bool
469475
IsImmediate(Operand *op)
470476
{
@@ -3832,6 +3838,50 @@ OptimizePeepholes(IRList *irl)
38323838
}
38333839
}
38343840

3841+
// check for consecutive math opcodes
3842+
if (ir_next && ir_next->opc == opc
3843+
&& ir->dst == ir_next->dst
3844+
&& !InstrSetsAnyFlags(ir)
3845+
&& ir->cond == ir_next->cond
3846+
&& IsDirectImmediate(ir->src)
3847+
&& IsDirectImmediate(ir_next->src)
3848+
&& !IsHwReg(ir->dst)
3849+
)
3850+
{
3851+
int newval;
3852+
bool merge = true;
3853+
// check for mergeable immediate math operands
3854+
switch (opc) {
3855+
case OPC_ADD:
3856+
case OPC_SUB:
3857+
newval = ir_next->src->val + ir->src->val;
3858+
break;
3859+
case OPC_SHL:
3860+
case OPC_SAR:
3861+
case OPC_SHR:
3862+
newval = ir_next->src->val + ir->src->val;
3863+
if (newval > 0x1f) {
3864+
merge = false;
3865+
}
3866+
break;
3867+
case OPC_OR:
3868+
newval = ir_next->src->val | ir->src->val;
3869+
break;
3870+
case OPC_AND:
3871+
newval = ir_next->src->val & ir->src->val;
3872+
break;
3873+
default:
3874+
merge = false;
3875+
break;
3876+
}
3877+
if (merge) {
3878+
ir_next->src = NewImmediate(newval);
3879+
DeleteIR(irl, ir);
3880+
changed = 1;
3881+
goto done;
3882+
}
3883+
}
3884+
38353885
// check for add a,b ;; mov b,a ;; isdead a
38363886
// becomes add b, a
38373887

@@ -5705,6 +5755,7 @@ typedef struct PeepholePattern {
57055755
#define OPERAND_ANY -1
57065756
#define COND_ANY -1
57075757
#define OPC_ANY -1
5758+
57085759
#define MAX_OPERANDS_IN_PATTERN 16
57095760

57105761
#define PEEP_OPNUM_MASK 0x00ffffff
@@ -6886,7 +6937,7 @@ static int FixupQMux(int arg, IRList *irl, IR *ir)
68866937
}
68876938

68886939
/*
6889-
* sign extend followed by AND is sometimes redundant
6940+
* sign extend followed by AND, GETBYTE, or GETWORD is sometimes redundant
68906941
*/
68916942
static PeepholePattern pat_shl_shr_and[] = {
68926943
{ COND_ANY, OPC_SHL, PEEP_OP_SET|0, PEEP_OP_SET_IMM|1, PEEP_FLAGS_NONE },

0 commit comments

Comments
 (0)