📄 analyze.c
字号:
case en_asdiv:
case en_asmod:
case en_aslsh:
case en_asumod:
case en_asudiv:
case en_asumul:
case en_asrsh:
case en_asand:
case en_assign:
case en_refassign:
en_lassign: case en_asor:
case en_asxor:
size = natural_size(node->v.p[0]);
scanexpr(node->v.p[0], 0, 0);
scanexpr(node->v.p[1], 0, size);
break;
case en_callblock:
case en_pcallblock:
case en_scallblock:
scan_for_inline(node);
case en_void:
case en_voidnz:
case en_dvoid:
case en_pmul:
case en_arrayindex:
case en_pdiv:
case en_mul:
case en_div:
case en_umul:
case en_udiv:
case en_umod:
case en_lsh:
case en_rsh:
case en_mod:
case en_and:
case en_or:
case en_xor:
case en_lor:
case en_land:
case en_eq:
case en_ne:
case en_gt:
case en_ge:
case en_lt:
case en_le:
case en_ugt:
case en_uge:
case en_ult:
case en_ule:
case en_cond:
case en_intcall:
case en_moveblock:
case en_stackblock:
case en_array:
scanexpr(node->v.p[0], 0, natural_size(node->v.p[0]));
scanexpr(node->v.p[1], 0, natural_size(node->v.p[1]));
break;
case en_trapcall:
case en_substack:
case en_clearblock:
scanexpr(node->v.p[0], 0, natural_size(node->v.p[0]));
break;
case en_fcall:
case en_fcallb:
case en_pfcall:
case en_pfcallb:
case en_sfcall:
case en_sfcallb:
/* used to put funcs in regs, but not any more */
scan_for_inline(node);
case en_thiscall:
scanexpr(node->v.p[0], 0, 0);
scanexpr(node->v.p[1], 0, 0);
break;
default:
DIAG("scan_expression: invalid node type");
break;
}
}
//-------------------------------------------------------------------------
void scan(SNODE *block)
/*
* scan will gather all optimizable expressions into the expression
* list for a block of statements.
*/
{
while (block != 0)
{
switch (block->stype)
{
case st_tryblock:
break;
case st_throw:
if (block->exp)
{
opt4(&block->exp);
scanexpr(block->exp, 0, 0);
}
break;
case st_return:
case st_expr:
opt4(&block->exp);
scanexpr(block->exp, 0, 0);
break;
case st_while:
case st_do:
opt4(&block->exp);
scanexpr(block->exp, 0, 0);
scan(block->s1);
break;
case st_for:
opt4(&block->label);
scanexpr(block->label, 0, 0);
opt4(&block->exp);
scanexpr(block->exp, 0, 0);
scan(block->s1);
opt4(&block->s2);
scanexpr(block->s2, 0, 0);
break;
case st_if:
opt4(&block->exp);
scanexpr(block->exp, 0, 0);
scan(block->s1);
scan(block->s2);
break;
case st_switch:
opt4(&block->exp);
scanexpr(block->exp, 0, 0);
scan(block->s1);
break;
case st_case:
scan(block->s1);
break;
case st_block:
scan(block->exp);
break;
case st_asm:
if (block->exp)
asm_scan(block->exp);
break;
}
block = block->next;
}
}
//-------------------------------------------------------------------------
void exchange(CSE **c1)
/*
* exchange will exchange the order of two expression entries
* following c1 in the linked list.
*/
{
CSE *csp1, *csp2;
csp1 = *c1;
csp2 = csp1->next;
csp1->next = csp2->next;
csp2->next = csp1;
*c1 = csp2;
}
//-------------------------------------------------------------------------
int desire(CSE *csp)
/*
* returns the desirability of optimization for a subexpression.
*/
{
if (csp->voidf || (isintconst(csp->exp->nodetype) && csp->exp->v.i < 16 &&
csp->exp->v.i >= 0))
return 0;
if (lvalue(csp->exp))
return 2 *csp->uses;
return csp->uses;
}
//-------------------------------------------------------------------------
int bsort(CSE **list)
/*
* bsort implements a bubble sort on the expression list.
*/
{
CSE *csp1, *csp2;
csp1 = *list;
if (csp1 == 0 || csp1->next == 0)
return 0;
bsort(&(csp1->next));
csp2 = csp1->next;
if (desire(csp1) < desire(csp2))
{
exchange(list);
return 1;
}
return 0;
}
//-------------------------------------------------------------------------
void repexpr(ENODE *node, int size)
/*
* repexpr will replace all allocated references within an expression
* with tempref nodes.
*/
{
CSE *csp;
if (node == 0)
return ;
if (size == 0)
size = natural_size(node);
switch (node->nodetype)
{
case en_tempref:
case en_labcon:
case en_nalabcon:
case en_regref:
break;
case en_structret:
break;
case en_conslabel:
case en_destlabel:
case en_movebyref:
repexpr(node->v.p[0], size);
break;
case en_rcomplexcon:
case en_lrcomplexcon:
case en_fcomplexcon:
case en_rimaginarycon:
case en_lrimaginarycon:
case en_fimaginarycon:
case en_rcon:
case en_lrcon:
case en_fcon:
case en_icon:
case en_lcon:
case en_iucon:
case en_lucon:
case en_llcon:
case en_llucon:
case en_boolcon:
case en_ccon:
case en_cucon:
case en_nacon:
case en_napccon:
case en_absacon:
case en_autocon:
case en_autoreg:
if ((csp = searchnode(node)) != 0)
if (csp->reg > 0)
{
node->nodetype = en_tempref;
#ifdef i386
node->v.i = csp->reg | (size << 16) | (csp->seg << 8);
#else
node->v.i = csp->reg | (size << 16);
#endif
}
break;
case en_fp_ref:
repexpr(node->v.p[0], 0);
break;
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
repexpr(node->v.p[0], 0);
break;
case en_floatref:
case en_doubleref:
case en_longdoubleref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_ub_ref:
case en_uw_ref:
case en_b_ref:
case en_bool_ref:
case en_w_ref:
case en_l_ref:
case en_ul_ref:
case en_i_ref:
case en_ui_ref:
case en_a_ref: case en_ua_ref:
if ((csp = searchnode(node)) != 0)
{
if (csp->reg > 0)
{
node->nodetype = en_tempref;
#ifdef i386
node->v.i = csp->reg | (size << 16);
#else
node->v.i = csp->reg | (size << 16);
#endif
}
else
repexpr(node->v.p[0], 0);
}
else
repexpr(node->v.p[0], 0);
break;
case en_ll_ref:
case en_ull_ref:
case en_cl_reg:
repexpr(node->v.p[0], 0);
break;
case en_uminus:
case en_bits:
case en_asuminus:
case en_ascompl:
case en_not:
case en_compl:
repexpr(node->v.p[0], 0);
break;
case en_cfc:
case en_cfi:
case en_crc:
case en_cri:
case en_clrc:
case en_clri:
case en_cb:
case en_cub:
case en_cbool:
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_csp:
case en_cf:
case en_cd:
case en_cp:
case en_cld:
case en_cfp:
repexpr(node->v.p[0], natural_size(node->v.p[0]));
break;
case en_pfcall:
case en_pfcallb:
case en_sfcall:
case en_sfcallb:
case en_fcallb:
case en_fcall:
{
SYM *sp;
ENODE *node2 = node->v.p[1]->v.p[0]->v.p[0];
if (node2->nodetype == en_nacon || node2->nodetype ==
en_napccon)
{
sp = node2->v.sp;
if (sp && (sp->value.classdata.cppflags &PF_INLINE))
repcse(sp->value.classdata.inlinefunc->stmt);
}
}
case en_stackblock:
case en_callblock:
case en_pcallblock:
case en_scallblock:
case en_assign:
case en_intcall:
case en_refassign:
en_lassign: case en_ainc:
case en_adec:
case en_add:
case en_sub:
case en_addstruc:
en_addcast: case en_umul:
case en_udiv:
case en_umod:
case en_mul:
case en_div:
case en_mod:
case en_lsh:
case en_asalsh:
case en_asarsh:
case en_alsh:
case en_arsh:
case en_arshd:
case en_asarshd:
case en_rsh:
case en_and:
case en_or:
case en_xor:
case en_land:
case en_lor:
case en_eq:
case en_ne:
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_cond:
case en_void:
case en_voidnz:
case en_dvoid:
case en_asadd:
case en_assub:
case en_asmul:
case en_asdiv:
case en_asor:
case en_asand:
case en_asxor:
case en_asmod:
case en_aslsh:
case en_asumod:
case en_asudiv:
case en_asumul:
case en_pmul:
case en_arrayindex:
case en_asrsh:
case en_pdiv:
case en_moveblock:
case en_thiscall:
case en_repcons:
case en_array:
repexpr(node->v.p[1], 0);
case en_trapcall:
case en_substack:
case en_clearblock:
repexpr(node->v.p[0], 0);
break;
default:
DIAG("repexpr: invalid node type");
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -