📄 analyze.c
字号:
case en_sub:
scannode (ep->v.p[1], duse);
scannode (ep->v.p[0], duse);
break;
case en_ainc:
case en_adec:
case en_deref:
scannode (ep->v.p[0], duse);
break;
case en_asadd:
case en_assub:
case en_mul:
case en_div:
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_asmul:
case en_asmul2:
case en_asdiv:
case en_asdiv2:
case en_asmod:
case en_aslsh:
case en_asrsh:
case en_asand:
case en_asor:
case en_asxor:
case en_cond:
case en_comma:
case en_list:
case en_assign:
case en_litval:
case en_literal:
scannode (ep->v.p[1], FALSE);
/*lint -fallthrough*/
case en_uminus:
case en_compl:
case en_not:
case en_test:
case en_cast:
scannode (ep->v.p[0], FALSE);
break;
case en_fcall:
case en_call:
case en_usercall:
scannode (ep->v.p[0], TRUE);
scannode (ep->v.p[1], FALSE);
break;
default:
CANNOT_REACH_HERE ();
break;
}
}
static EXPR *scanexpr P1 (EXPR *, ep)
{
scannode (ep, FALSE);
return ep;
}
/*
* scan() will gather all optimisable expressions into the
* expression list for a block of statements.
*/
static STMT *scan P1 (STMT *, stmt)
{
return walkstmt (stmt, null_stmt, scanexpr);
}
/*****************************************************************************/
/*
* constant() will fold all constant expression in the statement
* tree.
*/
static STMT *constant P1 (STMT *, stmt)
{
return walkstmt (stmt, null_stmt, constantopt);
}
/*****************************************************************************/
static EXPR *unsymbolnode P1 (EXPR *, ep)
{
SYM *sp;
TYP *tp;
switch (ep->nodetype) {
case en_sym:
sp = ep->v.sp;
tp = typeof (sp);
switch (storageof (sp)) {
case sc_static:
if (!is_func (tp)) {
ep->nodetype = en_labcon;
ep->v.l = sp->value.l;
ep->etp = mk_type (tp_pointer, tp);
break;
}
/*lint -fallthrough*/
case sc_global:
case sc_external:
if (datamodel_option && !is_func (tp)) {
ep->nodetype = en_global;
} else {
ep->nodetype = en_nacon;
}
ep->v.str = nameof (sp);
ep->etp = mk_type (tp_pointer, tp);
break;
case sc_const:
ep->nodetype = en_icon;
ep->v.i = sp->value.i;
break;
case sc_register:
case sc_auto:
case sc_parms:
ep->etp = mk_type (tp_pointer, tp);
ep->nodetype = en_autocon;
ep->v.i = sp->value.i;
break;
default:
CANNOT_REACH_HERE ();
break;
}
break;
default:
break;
}
return ep;
}
EXPR *unsymbolexpr P1 (EXPR *, ep)
{
return walkexpr (ep, unsymbolnode);
}
/*
* unsymbol() will remove all references to en_sym nodes.
*/
static STMT *unsymbol P1 (STMT *, stmt)
{
CSE *csp;
stmt = walkstmt (stmt, null_stmt, unsymbolexpr);
/* must also change the Common Sub-expression tree */
for (csp = olist; csp; csp = csp->next) {
csp->exp = walkexpr (csp->exp, unsymbolnode);
}
return stmt;
}
/*****************************************************************************/
static EXPR *transformnode P1 (EXPR *, ep)
{
return g_transform (ep);
}
static EXPR *transformexpr P1 (EXPR *, ep)
{
return walkexpr (ep, transformnode);
}
/*
* transform() will descend the statement tree calling a code
* generator specific routine to transform all expressions which
* are performed by run-time support routines.
*/
static STMT *transform P1 (STMT *, stmt)
{
return walkstmt (stmt, null_stmt, transformexpr);
}
/*****************************************************************************/
/*
* repcsenode() will replace all allocated references within an
* expression with register nodes.
*/
static EXPR *repcsenode P1 (EXPR *, ep)
{
CSE *csp;
switch (ep->nodetype) {
case en_fcon:
case en_icon:
case en_nacon:
case en_labcon:
case en_autocon:
case en_sym:
case en_ref:
case en_fieldref:
if (((csp = searchnode (ep)) != NIL_CSE) && (csp->reg != NO_REG)) {
ep->nodetype = en_register;
ep->v.r = csp->reg;
}
break;
default:
break;
}
return ep;
}
static EXPR *repcseexpr P1 (EXPR *, ep)
{
return walkexpr (ep, repcsenode);
}
/*
* repcse() will scan through a block of statements replacing
* the optimized expressions with their temporary references.
*/
static STMT *repcse P1 (STMT *, stmt)
{
return walkstmt (stmt, null_stmt, repcseexpr);
}
/*****************************************************************************/
static WEIGHT swapnode P1 (EXPR *, ep)
{
WEIGHT lweight, rweight;
if (ep == NIL_EXPR) {
return (WEIGHT) 0;
}
ep = opt0 (ep);
switch (ep->nodetype) {
case en_register:
return (WEIGHT) 1;
case en_icon:
case en_fcon:
case en_nacon:
case en_labcon:
case en_autocon:
case en_global:
case en_sym:
case en_str:
case en_literal:
return (WEIGHT) 2;
case en_ref:
case en_fieldref:
return swapnode (ep->v.p[0]);
case en_uminus:
case en_not:
case en_test:
case en_compl:
case en_ainc:
case en_adec:
case en_cast:
case en_deref:
return swapnode (ep->v.p[0]) + 1;
case en_lt:
case en_le:
case en_gt:
case en_ge:
/* almost commutative operators */
case en_eq:
case en_ne:
case en_add:
case en_mul:
case en_and:
case en_or:
case en_xor:
/* commutative operators */
lweight = swapnode (ep->v.p[0]);
rweight = swapnode (ep->v.p[1]);
if (rweight > lweight) {
swap_nodes (ep);
}
return lweight + rweight;
case en_sub:
case en_div:
case en_mod:
case en_lsh:
case en_rsh:
case en_land:
case en_lor:
case en_cond:
case en_comma:
case en_list:
case en_asadd:
case en_assub:
case en_asmul:
case en_asmul2:
case en_asdiv:
case en_asdiv2:
case en_asor:
case en_asxor:
case en_asand:
case en_asmod:
case en_aslsh:
case en_asrsh:
case en_assign:
return swapnode (ep->v.p[0]) + swapnode (ep->v.p[1]);
case en_fcall:
case en_call:
case en_usercall:
return (WEIGHT) 10 + swapnode (ep->v.p[0]) + swapnode (ep->v.p[1]);
default:
CANNOT_REACH_HERE ();
}
return (WEIGHT)0; /*lint !e527*/ /* unreachable */
}
static EXPR *swapexpr P1 (EXPR *, ep)
{
VOIDCAST swapnode (ep);
return ep;
}
/*
* swap() will swap commutative expression nodes so that the most
* complex node will be evaluated first - thus possibly preventing
* an intermediate value from being temporarily pushed on the stack
* during expression evaluation.
*/
static STMT *swap P1 (STMT *, stmt)
{
return walkstmt (stmt, null_stmt, swapexpr);
}
/*****************************************************************************/
static EXPR *ordernode P1 (EXPR *, ep)
{
return g_order (ep);
}
static EXPR *orderexpr P1 (EXPR *, ep)
{
return walkexpr (ep, ordernode);
}
static STMT *order P1 (STMT *, stmt)
{
return walkstmt (stmt, null_stmt, orderexpr);
}
/*****************************************************************************/
static STMT *ordercasestmt P1 (STMT *, stmt)
{
if (stmt == NIL_STMT) {
return NIL_STMT;
}
switch (stmt->stype) {
case st_case:
if (stmt->s1 != NIL_STMT) {
switch (stmt->s1->stype) {
case st_case:
if ((stmt->s1 == stmt->v1.s) && (stmt->s1->v2.i < stmt->v2.i)) {
IVAL i = stmt->v2.i;
stmt->v2.i = stmt->s1->v2.i;
stmt->s1->v2.i = i;
}
break;
case st_default:
/*
* delete this case label as it is also handled by the default
* label.
*/
stmt = stmt->s1;
break;
default:
break;
}
}
break;
case st_default:
if (stmt->s1 != NULL) {
switch (stmt->s1->stype) {
case st_case:
/*
* delete this case label as it is also handled by the default
* label.
*/
stmt->s1 = stmt->s1->v1.s;
break;
default:
break;
}
}
break;
default:
break;
}
return stmt;
}
/*
* descend the statement tree recursively and sort consecutive case
* statements into ascending order.
*
* deletes a case label if it is on the same branch as the default
* label.
*/
static STMT *ordercase P1 (STMT *, stmt)
{
return walkstmt (stmt, ordercasestmt, null_expr);
}
/*****************************************************************************/
/*
* globalopt() is the externally callable optimization routine.
* It will collect and allocate common subexpressions and substitute
* the tempref for all occurrences of the expression within
* the block.
*/
CSE *globalopt P1 (STMT *, stmt)
{
olist = NIL_CSE;
#ifdef ICODE
#ifdef DEBUG
if (icode_option) {
if (is_debugging (DEBUG_GLOBAL)) {
genicode (stmt, 0);
}
}
#endif /* DEBUG */
#endif /* ICODE */
stmt = constant (stmt); /* constant folding */
stmt = transform (stmt);
#ifdef ICODE
#ifdef DEBUG
if (icode_option) {
if (is_debugging (DEBUG_GLOBAL)) {
genicode (stmt, 0);
}
}
#endif /* DEBUG */
#endif /* ICODE */
if (opt_option) {
stmt = scan (stmt); /* collect expressions */
bsort (&olist); /* sort expressions list into usage order */
}
stmt = unsymbol (stmt); /* replace all references to symbols */
#ifdef ICODE
#ifdef DEBUG
if (icode_option) {
if (is_debugging (DEBUG_GLOBAL)) {
genicode (stmt, 0);
}
}
#endif /* DEBUG */
#endif /* ICODE */
if (opt_option) {
g_allocate (olist); /* allocate registers */
stmt = repcse (stmt); /* replace allocated expressions */
stmt = swap (stmt); /* swap commutative expression */
stmt = order (stmt); /* code generation order */
stmt = ordercase (stmt);
}
#ifdef ICODE
if (icode_option) {
#ifdef DEBUG
if (is_debugging (DEBUG_GLOBAL)) {
genicode (stmt, 0);
}
#endif /* DEBUG */
genicse (olist);
}
#endif /* ICODE */
rel_autolst ();
rel_reglst ();
return olist;
}
#endif /* CPU_DEFINED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -