⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 analyze.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -