📄 optimize.c
字号:
if (!floatrecurse(ep->v.p[1])) {
sc = pwrof2(ep->v.p[0]->v.i);
if( sc != -1 )
{
ENODE *temp = ep->v.p[0];
ep->v.p[0 ] = ep->v.p[1];
ep->v.p[1] = temp;
ep->v.p[1]->v.i = sc;
switch(ep->nodetype) {
case en_mul:
ep->nodetype = en_alsh;
break;
case en_asmul:
ep->nodetype = en_asalsh;
break;
case en_umul:
case en_pmul:
ep->nodetype = en_lsh;
break;
case en_asumul:
ep->nodetype = en_aslsh;
break;
}
break;
}
}
val = ep->v.p[0]->v.i;
if (val == 0)
*node = ep->v.p[0];
else if (val == 1)
*node = ep->v.p[1];
else if (val == -1)
*node = makenode(en_uminus,(char *)ep->v.p[1],0);
else dooper(node,mode);
break;
case 6:
dval = ep->v.p[0]->v.f;
if (dval == 0)
*node = ep->v.p[0];
else if (dval == 1)
*node = ep->v.p[1];
else if (dval == -1)
*node = makenode(en_uminus,(char *)ep->v.p[1],0);
else dooper(node,mode);
break;
case 7:
if (!floatrecurse(ep->v.p[0])) {
sc = pwrof2(ep->v.p[1]->v.i);
if( sc != -1 )
{
ep->v.p[1]->v.i = sc;
switch(ep->nodetype) {
case en_mul:
ep->nodetype = en_alsh;
break;
case en_asmul:
ep->nodetype = en_asalsh;
break;
case en_umul:
case en_pmul:
ep->nodetype = en_lsh;
break;
case en_asumul:
ep->nodetype = en_aslsh;
break;
}
break;
}
}
val = ep->v.p[1]->v.i;
if (val == 0)
*node = ep->v.p[1];
else if (val == 1)
*node = ep->v.p[0];
else if (val == -1)
*node = makenode(en_uminus,(char *)ep->v.p[0],0);
else dooper(node,mode);
break;
case 8:
dval = ep->v.p[1]->v.f;
if (dval == 0)
*node = ep->v.p[1];
else if (dval == 1)
*node = ep->v.p[0];
else if (dval == -1)
*node = makenode(en_uminus,(char *)ep->v.p[0],0);
else dooper(node,mode);
break;
}
break;
case en_pdiv:
case en_div:
case en_udiv:
case en_asdiv:
case en_asudiv:
opt0(&(ep->v.p[0]));
opt0(&(ep->v.p[1]));
mode = getmode(ep->v.p[0],ep->v.p[1]);
switch(mode) {
case 1:
case 2:
case 3:
case 4:
dooper(node,mode);
break;
case 5:
if (ep->v.p[0]->v.i == 0)
*node = ep->v.p[0];
else
dooper(node,mode);
break;
case 6:
if (ep->v.p[0]->v.f == 0)
*node = ep->v.p[0];
else
dooper(node,mode);
break;
case 7:
if (!floatrecurse(ep->v.p[0])) {
sc = pwrof2(ep->v.p[1]->v.i);
if( sc != -1 )
{
ep->v.p[1]->v.i = sc;
switch(ep->nodetype) {
case en_div:
ep->nodetype = en_arsh;
break;
case en_asdiv:
ep->nodetype = en_asarsh;
break;
case en_udiv:
case en_pdiv:
ep->nodetype = en_rsh;
break;
case en_asudiv:
ep->nodetype = en_asrsh;
break;
}
break;
}
}
val = ep->v.p[1]->v.i;
if (val == 1)
*node = ep->v.p[0];
else if (val == -1)
*node = makenode(en_uminus,(char *)ep->v.p[0],0);
else dooper(node,mode);
break;
case 8:
dval = ep->v.p[1]->v.f;
if (dval == 1)
*node = ep->v.p[0];
else if (dval == -1)
*node = makenode(en_uminus,(char *)ep->v.p[0],0);
else dooper(node,mode);
break;
}
break;
case en_mod:
case en_umod:
case en_asmod: case en_asumod:
opt0(&(ep->v.p[0]));
opt0(&(ep->v.p[1]));
mode = getmode(ep->v.p[0],ep->v.p[1]);
switch(mode) {
case 7:
if (!floatrecurse(ep->v.p[0])) {
sc = pwrof2(ep->v.p[1]->v.i);
if( sc != -1 )
{
ep->v.p[1]->v.i = mod_mask(sc);
if (ep->nodetype == en_asmod || ep->nodetype == en_asumod)
ep->nodetype = en_asand;
else
ep->nodetype = en_and;
break;
}
}
case 1:
case 2:
case 3:
case 4:
case 5: case 6: case 8:
dooper(node,mode);
}
break;
case en_and: case en_or:
case en_xor: case en_rsh:
case en_lsh: case en_arsh: case en_alsh:
opt0(&(ep->v.p[0]));
opt0(&(ep->v.p[1]));
if( isintconst(ep->v.p[0]->nodetype) &&
isintconst(ep->v.p[1]->nodetype) )
dooper(node,getmode(ep->v.p[0],ep->v.p[1]));
break;
case en_land: case en_lor:
case en_lt: case en_le:
case en_ugt: case en_uge: case en_ult: case en_ule:
case en_gt: case en_ge:
case en_eq: case en_ne:
case en_asalsh: case en_asarsh:
case en_asand: case en_asor: case en_asxor:
case en_asadd: case en_assub:
case en_asrsh:
case en_aslsh: case en_cond:
case en_fcall: case en_void: case en_trapcall: case en_intcall:
case en_pfcall: case en_pfcallb:
case en_assign: case en_moveblock: case en_stackblock: case en_callblock:
case en_fcallb: case en_refassign: case en_pcallblock:
opt0(&(ep->v.p[0]));
opt0(&(ep->v.p[1]));
break;
}
}
long xfold2(ENODE * node)
/*
* xfold2 will remove constant nodes and return the values to
* the calling routines.
*/
{ long i;
if( node == 0 )
return 0;
switch( node->nodetype )
{
case en_icon:
case en_lcon:
case en_iucon:
case en_lucon:
case en_ccon:
i = node->v.i;
node->v.i = 0;
return i;
case en_add:
return xfold2(node->v.p[0]) + xfold2(node->v.p[1]);
case en_sub:
return xfold2(node->v.p[0]) - xfold2(node->v.p[1]);
case en_or:
return xfold2(node->v.p[0]) | xfold2(node->v.p[1]);
case en_xor:
return xfold2(node->v.p[0]) ^ xfold2(node->v.p[1]);
case en_uminus:
return - xfold2(node->v.p[0]);
case en_mul:
case en_pmul:
case en_umul:
case en_lsh:
case en_alsh:
case en_asalsh: case en_asarsh: case en_arsh:
case en_rsh: case en_div: case en_pdiv:
case en_mod: case en_asadd:
case en_assub: case en_asmul:
case en_asdiv: case en_asmod:
case en_land: case en_lor:
case en_asand: case en_and:
case en_asor: case en_void: case en_asxor:
case en_pfcall: case en_pfcallb:
case en_fcall: case en_assign: case en_moveblock: case en_trapcall:
case en_stackblock: case en_intcall: case en_callblock: case en_fcallb:
case en_asumul: case en_asudiv: case en_asumod: case en_refassign:
case en_udiv: case en_pcallblock:
fold_const2(&node->v.p[0]);
fold_const2(&node->v.p[1]);
return 0;
case en_b_ref: case en_w_ref:
case en_ub_ref: case en_uw_ref:
case en_l_ref: case en_compl: case en_ul_ref:
case en_floatref: case en_doubleref: case en_longdoubleref:
case en_not: case en_bits:
fold_const2(&node->v.p[0]);
return 0;
}
return 0;
}
void fold_const2(ENODE ** node)
/*
* reorganize an expression for optimal constant grouping.
*/
{ ENODE *ep;
long i;
ep = *node;
if( ep == 0 )
return;
switch (ep->nodetype) {
case en_add:
if (ep->v.p[0]->nodetype == en_cp && isintconst(ep->v.p[0]->v.p[0]->nodetype)) {
ep->v.p[0]->v.p[0]->v.i += xfold2(ep->v.p[1]);
return;
}
else if (ep->v.p[1]->nodetype == en_cp && isintconst(ep->v.p[1]->v.p[0]->nodetype)) {
ep->v.p[1]->v.p[0]->v.i += xfold2(ep->v.p[1]);
return;
}
else if( isintconst(ep->v.p[0]->nodetype))
{
ep->v.p[0]->v.i += xfold2(ep->v.p[1]);
return;
}
else if( isintconst(ep->v.p[1]->nodetype))
{
ep->v.p[1]->v.i += xfold2(ep->v.p[0]);
return;
}
break;
case en_sub:
if (ep->v.p[0]->nodetype == en_cp && isintconst(ep->v.p[0]->v.p[0]->nodetype == en_icon)) {
ep->v.p[0]->v.p[0]->v.i -= xfold2(ep->v.p[1]);
return;
}
else if (ep->v.p[1]->nodetype == en_cp && isintconst(ep->v.p[1]->v.p[0]->nodetype)) {
ep->v.p[1]->v.p[0]->v.i -= xfold2(ep->v.p[1]);
return;
}
else if( isintconst(ep->v.p[0]->nodetype))
{
ep->v.p[0]->v.i -= xfold2(ep->v.p[1]);
return;
}
else if( isintconst(ep->v.p[1]->nodetype))
{
ep->v.p[1]->v.i -= xfold2(ep->v.p[0]);
return;
}
break;
case en_or:
if(isintconst( ep->v.p[0]->nodetype) )
{
ep->v.p[0]->v.i |= xfold2(ep->v.p[1]);
return;
}
else if(isintconst( ep->v.p[1]->nodetype) )
{
ep->v.p[1]->v.i |= xfold2(ep->v.p[0]);
return;
}
break;
case en_xor:
if( isintconst(ep->v.p[0]->nodetype))
{
ep->v.p[0]->v.i ^= xfold2(ep->v.p[1]);
return;
}
else if( isintconst(ep->v.p[1]->nodetype))
{
ep->v.p[1]->v.i ^= xfold2(ep->v.p[0]);
return;
}
break;
}
i = xfold2(ep);
if( i != 0 ) {
ep = xalloc(sizeof(ENODE));
ep->nodetype = en_icon;
ep->v.i = i;
ep = makenode(en_add,ep,*node);
*node = ep;
}
}
void opt4(ENODE ** node)
/*
* apply all constant optimizations.
*/
{
opt0(node);
fold_const2(node);
opt0(node);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -