Skip to content

Commit 8056b86

Browse files
committed
peephole optimization for sign extend+and
1 parent 4ddd45b commit 8056b86

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

backends/asm/optimize_ir.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6885,6 +6885,65 @@ static int FixupQMux(int arg, IRList *irl, IR *ir)
68856885
return 1;
68866886
}
68876887

6888+
/*
6889+
* sign extend followed by AND is sometimes redundant
6890+
*/
6891+
static PeepholePattern pat_shl_shr_and[] = {
6892+
{ COND_ANY, OPC_SHL, PEEP_OP_SET|0, PEEP_OP_SET_IMM|1, PEEP_FLAGS_NONE },
6893+
{ COND_ANY, OPC_SAR, PEEP_OP_MATCH|0, PEEP_OP_MATCH|1, PEEP_FLAGS_NONE },
6894+
{ COND_ANY, OPC_AND, PEEP_OP_MATCH|0, PEEP_OP_SET_IMM|2, PEEP_FLAGS_NONE },
6895+
6896+
{ 0, 0, 0, 0, PEEP_FLAGS_DONE }
6897+
};
6898+
static PeepholePattern pat_signx_and[] = {
6899+
{ COND_ANY, OPC_SIGNX, PEEP_OP_SET|0, PEEP_OP_SET_IMM|1, PEEP_FLAGS_P2 },
6900+
{ COND_ANY, OPC_AND, PEEP_OP_MATCH|0, PEEP_OP_SET_IMM|2, PEEP_FLAGS_P2 },
6901+
6902+
{ 0, 0, 0, 0, PEEP_FLAGS_DONE }
6903+
};
6904+
6905+
static int FixupShlShrAndImm(int arg, IRList *irl, IR *ir0)
6906+
{
6907+
IR *ir1, *ir2;
6908+
int signx_width;
6909+
unsigned and_pat, signx_pat;
6910+
6911+
ir1 = NextIR(ir0); // this is the SHR
6912+
ir2 = NextIR(ir1); // and this is the AND
6913+
signx_width = ir0->src->val & 0x1f;
6914+
and_pat = (unsigned)ir2->src->val;
6915+
signx_pat = (1U<<(signx_width)) - 1;
6916+
if ( (and_pat & signx_pat) == and_pat ) {
6917+
// we can delete the shl and shr
6918+
DeleteIR(irl, ir1);
6919+
DeleteIR(irl, ir0);
6920+
return 1;
6921+
}
6922+
return 0;
6923+
}
6924+
6925+
static int FixupSignxAndImm(int arg, IRList *irl, IR *ir0)
6926+
{
6927+
IR *ir1;
6928+
int signx_width;
6929+
unsigned and_pat, signx_pat;
6930+
6931+
ir1 = NextIR(ir0); // this is the AND
6932+
signx_width = ir0->src->val & 0x1f;
6933+
and_pat = (unsigned)ir1->src->val;
6934+
signx_pat = (1U<<(signx_width+1)) - 1;
6935+
if ( (and_pat & signx_pat) == and_pat ) {
6936+
// we can delete the signx
6937+
DeleteIR(irl, ir0);
6938+
return 1;
6939+
}
6940+
return 0;
6941+
}
6942+
6943+
/*
6944+
* the actual list of peepholes
6945+
*/
6946+
68886947
struct Peepholes {
68896948
PeepholePattern *check;
68906949
int arg;
@@ -6900,6 +6959,9 @@ struct Peepholes {
69006959
{ pat_zeroex, OPC_ZEROX, ReplaceExtend },
69016960
{ pat_signex, OPC_SIGNX, ReplaceExtend },
69026961

6962+
{ pat_signx_and, 0, FixupSignxAndImm },
6963+
{ pat_shl_shr_and, 0, FixupShlShrAndImm },
6964+
69036965
{ pat_drvc1, OPC_DRVC, ReplaceDrvc },
69046966
{ pat_drvc2, OPC_DRVC, ReplaceDrvc },
69056967
{ pat_drvnc1, OPC_DRVNC, ReplaceDrvc },

0 commit comments

Comments
 (0)