📄 optimize.c
字号:
break;
case en_and:
ep->nodetype = maxinttype(ep1, ep2);
ep->v.i = ep1->v.i &ep2->v.i;
ep->v.i = reint(ep);
break;
case en_or:
ep->nodetype = maxinttype(ep1, ep2);
ep->v.i = ep1->v.i | ep2->v.i;
ep->v.i = reint(ep);
break;
case en_xor:
ep->nodetype = maxinttype(ep1, ep2);
ep->v.i = ep1->v.i ^ ep2->v.i;
ep->v.i = reint(ep);
break;
}
}
int pwrof2(LLONG_TYPE i)
/*
* return which power of two i is or -1.
*/
{
if (i > 1)
{
int top = sizeof(shifts)/sizeof(LLONG_TYPE);
int bottom = - 1;
while (top - bottom > 1)
{
int mid = (top + bottom) / 2;
if (i < shifts[mid])
{
top = mid;
}
else
{
bottom = mid;
}
}
if (bottom <= 0) // ignore the oth power
return -1;
if (i == shifts[bottom])
return bottom;
}
return -1 ;
}
//-------------------------------------------------------------------------
LLONG_TYPE mod_mask(int i)
/*
* make a mod mask for a power of two.
*/
{
if (i >= sizeof(shifts)/sizeof(LLONG_TYPE))
return (LLONG_TYPE)-1;
return shifts[i] - 1;
}
//-------------------------------------------------------------------------
void addaside(ENODE *node)
{
*asidetail = makenode(en_void, node, 0);
asidetail = &(*asidetail)->v.p[1];
}
//-------------------------------------------------------------------------
int opt0(ENODE **node)
/*
* opt0 - delete useless expressions and combine constants.
*
* opt0 will delete expressions such as x + 0, x - 0, x * 0,
* x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to
* by node and combine obvious constant operations. It cannot
* combine name and label constants but will combine icon type
* nodes.
*
* en_addstruc is not optimized to keep from optimizing struct members
* into regs later... just en: en_addstruc is now equiv to en_add
* again. I have fixed the optimize struct thing another way...
* leaving en_addstruc in in case we need it later.
*/
{
ENODE *ep;
LLONG_TYPE val;
int sc;
int rv = FALSE;
int mode;
double dval;
int negtype = en_uminus;
ep = *node;
if (ep == 0)
return FALSE ;
switch (ep->nodetype)
{
case en_asumul:
case en_asmul:
case en_asudiv:
case en_asdiv:
negtype = en_asuminus;
}
switch (ep->nodetype)
{
case en_structret:
break;
case en_fp_ref:
case en_bool_ref:
case en_cbool:
case en_b_ref:
case en_w_ref:
/* optimize unary node */
case en_ub_ref:
case en_uw_ref:
/* optimize unary node */
case en_a_ref:
case en_ua_ref:
case en_i_ref:
case en_ui_ref:
case en_l_ref:
case en_ul_ref:
case en_ll_ref:
case en_ull_ref:
case en_floatref:
case en_doubleref:
case en_longdoubleref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
case en_cb:
case en_cub:
case en_cw:
case en_cuw:
case en_cl:
case en_cul:
case en_ci:
case en_cui:
case en_cll:
case en_cull:
case en_cf:
case en_cd:
case en_cp:
case en_bits:
case en_cld:
case en_cfp:
case en_csp:
case en_cl_reg:
rv |= opt0(&((*node)->v.p[0]));
return rv ;
case en_ascompl:
case en_compl:
rv |= opt0(&(ep->v.p[0]));
if (isintconst(ep->v.p[0]->nodetype))
{
rv = TRUE;
ep->nodetype = ep->v.p[0]->nodetype;
ep->v.i = ~ep->v.p[0]->v.i;
}
return rv ;
case en_uminus:
case en_asuminus:
rv = opt0(&(ep->v.p[0]));
if (isintconst(ep->v.p[0]->nodetype))
{
rv = TRUE;
ep->nodetype = ep->v.p[0]->nodetype;
ep->v.i = - ep->v.p[0]->v.i;
}
else if (ep->v.p[0]->nodetype == en_rcon || ep->v.p[0]->nodetype ==
en_fcon || ep->v.p[0]->nodetype == en_lrcon ||
ep->v.p[0]->nodetype == en_rimaginarycon || ep->v.p[0]->nodetype ==
en_fimaginarycon || ep->v.p[0]->nodetype == en_lrimaginarycon)
{
rv = TRUE;
ep->nodetype = ep->v.p[0]->nodetype;
ep->v.f = - ep->v.p[0]->v.f;
}
else if (ep->v.p[0]->nodetype == en_rcomplexcon || ep->v.p[0]->nodetype ==
en_fcomplexcon || ep->v.p[0]->nodetype == en_lrcomplexcon)
{
rv = TRUE;
ep->nodetype = ep->v.p[0]->nodetype;
ep->v.c.r = - ep->v.p[0]->v.c.r;
ep->v.c.i = - ep->v.p[0]->v.c.i;
}
return rv ;
case en_add:
case en_addstruc:
case en_array:
case en_sub:
case en_asadd:
case en_assub:
rv |= opt0(&(ep->v.p[0]));
rv |= 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:
default:
rv = TRUE;
dooper(node, mode);
break;
case 5:
if (ep->v.p[0]->v.i == 0)
{
if (ep->v.p[0]->nodetype != en_autocon)
{
if (ep->nodetype == en_sub)
*node = makenode(en_uminus, ep->v.p[1], 0);
else
*node = ep->v.p[1];
rv = TRUE;
}
}
else
{
dooper(node, mode);
rv = TRUE;
}
break;
case 6:
if (ep->v.p[0]->v.f == 0)
{
if (ep->nodetype == en_sub)
{
*node = ep->v.p[1];
ep->v.p[1]->v.f = - ep->v.p[1]->v.f;
}
else
*node = ep->v.p[1];
}
else
dooper(node, mode);
rv = TRUE;
break;
case 7:
if (ep->v.p[1]->v.i == 0)
{
if (ep->v.p[0]->nodetype != en_autocon)
{
*node = ep->v.p[0];
rv = TRUE;
}
}
else
{
dooper(node, mode);
rv = TRUE;
}
break;
case 8:
if (ep->v.p[1]->v.f == 0)
{
*node = ep->v.p[0];
}
else
dooper(node, mode);
rv = TRUE;
break;
}
return rv ;
case en_mul:
case en_umul:
case en_pmul:
case en_arrayindex:
case en_asmul:
case en_asumul:
rv |= opt0(&(ep->v.p[0]));
rv |= 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:
default:
dooper(node, mode);
rv = TRUE;
break;
case 5:
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;
rv = TRUE;
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:
case en_arrayindex:
ep->nodetype = en_lsh;
break;
case en_asumul:
ep->nodetype = en_aslsh;
break;
}
break;
}
}
val = ep->v.p[0]->v.i;
if (val == 0)
{
addaside(ep->v.p[1]);
*node = ep->v.p[0];
}
else if (val == 1)
*node = ep->v.p[1];
else if (val == - 1)
*node = makenode(negtype, (char*)ep->v.p[1], 0);
else
dooper(node, mode);
rv = TRUE;
break;
case 6:
dval = ep->v.p[0]->v.f;
if (dval == 0)
{
addaside(ep->v.p[1]);
*node = ep->v.p[0];
}
else if (dval == 1)
*node = ep->v.p[1];
else if (dval == - 1)
*node = makenode(negtype, (char*)ep->v.p[1], 0);
else
dooper(node, mode);
rv = TRUE;
break;
case 7:
if (!floatrecurse(ep->v.p[0]))
{
sc = pwrof2(ep->v.p[1]->v.i);
if (sc != - 1)
{
rv = TRUE;
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:
case en_arrayindex:
ep->nodetype = en_lsh;
break;
case en_asumul:
ep->nodetype = en_aslsh;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -