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

📄 analyze.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
/*                                                
Copyright 1994-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "diag.h"

extern SYM *currentfunc;
extern int prm_xcept;
extern TRYBLOCK *try_block_list;
extern int cf_freeaddress, cf_freedata, cf_freefloat;
extern long framedepth, stackdepth;
extern LIST *varlisthead;
extern int lc_maxauto;
extern int stackadd, stackmod;
extern int anyusedfloat;
extern int stdaddrsize;

int funcfloat;
int floatregs = 1, dataregs = 1, addrregs = 1;
CSE *olist; /* list of optimizable expressions */
/*
 *      this module will step through the parse tree and find all
 *      optimizable expressions. at present these expressions are
 *      limited to expressions that are valid throughout the scope
 *      of the function. the list of optimizable expressions is:
 *
 *              constants
 *              global and static addresses
 *              auto addresses
 *              contents of auto addresses.
 *
 *      contents of auto addresses are valid only if the address is
 *      never referred to without dereferencing.
 *
 *      scan will build a list of optimizable expressions which
 *      opt1 will replace during the second optimization pass.
 */


int equalnode(ENODE *node1, ENODE *node2)
/*
 *      equalnode will return 1 if the expressions pointed to by
 *      node1 and node2 are equivalent.
 */
{
    if (node1 == 0 || node2 == 0)
        return 0;
    if (node1->nodetype != node2->nodetype)
    {
        if (lvalue(node1) && lvalue(node2))
        {
            return equalnode(node1->v.p[0], node2->v.p[0]);
        }
        return 0;
    }
    if (natural_size(node1) != natural_size(node2))
        return 0;
    switch (node1->nodetype)
    {
        default:
            return (lvalue(node1) && equalnode(node1->v.p[0], node2->v.p[0]));
            return 1;
        case en_autoreg:
        case en_autocon:
        case en_nacon:
        case en_napccon:
            return node1->v.sp->mainsym == node2->v.sp->mainsym;
        case en_labcon:
        case en_nalabcon:
        case en_absacon:
        case en_icon:
        case en_lcon:
        case en_lucon:
        case en_iucon:
        case en_boolcon:
        case en_ccon:
        case en_cucon:
        case en_llcon:
        case en_llucon:
            return node1->v.i == node2->v.i;
        case en_rcon:
        case en_fcon:
        case en_lrcon:
        case en_rimaginarycon:
        case en_fimaginarycon:
        case en_lrimaginarycon:
            return node1->v.f == node2->v.f;
        case en_rcomplexcon:
        case en_fcomplexcon:
        case en_lrcomplexcon:
            return node1->v.c.r == node2->v.c.r && node1->v.c.i == node2->v.c.i;
    }
}

//-------------------------------------------------------------------------

CSE *searchnode(ENODE *node)
/*
 *      searchnode will search the common expression table for an entry
 *      that matches the node passed and return a pointer to it.
 */
{
    CSE *csp;
    csp = olist;
    while (csp != 0)
    {
        if (equalnode(node, csp->exp))
            return csp;
        csp = csp->next;
    }
    return 0;
}

//-------------------------------------------------------------------------

CSE *enternode(ENODE *node, int duse, int size)
/*
 *      enternode will enter a reference to an expression node into the
 *      common expression table. duse is a flag indicating whether or not
 *      this reference will be dereferenced.
 */
{
    CSE *csp;
    if (size == 0)
        size = natural_size(node);
    if ((csp = searchnode(node)) == 0)
    {
         /* add to tree */
        csp = xalloc(sizeof(CSE));
        csp->next = olist;
        csp->uses = 1;
        csp->reg =  - 1;
        csp->duses = (duse != 0);
        csp->exp = copynode(node);
        csp->voidf = 0;
        csp->size = size;
        olist = csp;
        return csp;
    }
    else
        if (chksize(csp->size, size))
            csp->size = size;
    ++(csp->uses);
    if (duse)
        ++(csp->duses);
    return csp;
}

//-------------------------------------------------------------------------

CSE *voidauto(ENODE *node)
/*
 *      voidauto will void an auto dereference node which points to
 *      the same auto constant as node.
 */
{
    CSE *csp;
    csp = olist;
    while (csp != 0)
    {
        if (lvalue(csp->exp) && equalnode(node, csp->exp->v.p[0]))
        {
            if (csp->voidf)
                return 0;
            csp->voidf = 1;
            return csp;
        }
        csp = csp->next;
    }
    return 0;
}

//-------------------------------------------------------------------------

CSE *voidlref(ENODE *node)
/*
 *      voidlref will void an lref
 */
{
    CSE *csp;
    csp = olist;
    while (csp != 0)
    {
        if (equalnode(node, csp->exp))
        {
            if (csp->voidf)
                return 0;
            csp->voidf = 1;
            return csp;
        }
        csp = csp->next;
    }
    return 0;
}

//-------------------------------------------------------------------------

void voidall(void)
/*
 * Go through the CSP list voiding any use of a variable that
 * has its address taken or is volatile
 */
{
    CSE *csp;
    csp = olist;
    while (csp)
    {
        if (lvalue(csp->exp) && (csp->exp->v.p[0]->nodetype == en_autocon ||
            csp->exp->v.p[0]->nodetype == en_autoreg))
        {
            int tp;
            if (tp = csp->exp->v.p[0]->v.sp->tp->type == bt_union || tp ==
                bt_struct || tp == bt_class)
                csp->voidf = 1;
        }
        if (csp->exp->nodetype == en_autocon || csp->exp->nodetype ==
            en_autoreg)
        {
            CSE *two = voidauto(csp->exp);
            if (two)
            {
                csp->uses += two->duses;
            }
        }
        csp = csp->next;
    }
}

//-------------------------------------------------------------------------

void scan_for_inline(ENODE *node)
{
    SYM *sp;
    ENODE *node2 = node->v.p[1]->v.p[0];
    if (node2->nodetype == en_nacon || node2->nodetype == en_napccon)
    {
        sp = node2->v.sp;
        if (sp && (sp->value.classdata.cppflags &PF_INLINE))
            scan(sp->value.classdata.inlinefunc->stmt);
    }
}

//-------------------------------------------------------------------------

void scanexpr(ENODE *node, int duse, int size)
/*
 *      scanexpr will scan the expression pointed to by node for optimizable
 *      subexpressions. when an optimizable expression is found it is entered
 *      into the tree. if a reference to an autocon node is scanned the
 *      corresponding auto dereferenced node will be voided. duse should be
 *      set if the expression will be dereferenced.
 *
 */
{
    CSE *csp,  *csp1;
    int sz;
    if (node == 0)
        return ;
    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:
            scanexpr(node->v.p[0], duse, size);
            break;
        case en_rcon:
        case en_lrcon:
        case en_fcon:
        case en_rcomplexcon:
        case en_lrcomplexcon:
        case en_fcomplexcon:
        case en_rimaginarycon:
        case en_lrimaginarycon:
        case en_fimaginarycon:
            funcfloat++;
            anyusedfloat++;
        case en_icon:
        case en_lcon:
        case en_iucon:
        case en_lucon:
        case en_boolcon:
        case en_ccon:
        case en_cucon:
        case en_llcon:
        case en_llucon:
            /* not putting constants in registers */
            break;
        case en_autocon:
            if (node->v.sp->iscatchvar)
                break;
        case en_autoreg:
        case en_nacon:
        case en_absacon:
            enternode(node, duse, 4);
        case en_napccon:
            break;
        case en_bits:
            scanexpr(node->v.p[0], duse, natural_size(node));
            break;
        case en_fcomplexref:
        case en_rcomplexref:
        case en_lrcomplexref:
            funcfloat++;
            scanexpr(node->v.p[0], 1, natural_size(node->v.p[0]));
            break;
        case en_fp_ref:
            scanexpr(node->v.p[0], 1, natural_size(node->v.p[0]));
            break;
        case en_fimaginaryref:
        case en_rimaginaryref:
        case en_lrimaginaryref:
        case en_floatref:
        case en_doubleref:
        case en_longdoubleref:
            funcfloat++;
        case en_b_ref:
        case en_bool_ref:
        case en_w_ref:
        case en_ub_ref:
        case en_uw_ref:
        case en_ul_ref:
        case en_l_ref:
			case en_i_ref:
			case en_ui_ref:
			case en_a_ref: case en_ua_ref:
            if (node->v.p[0]->nodetype == en_autocon && !node->v.p[0]->v.sp
                ->iscatchvar || node->v.p[0]->nodetype == en_autoreg)
                enternode(node, duse, natural_size(node));
            else
                scanexpr(node->v.p[0], 1, natural_size(node->v.p[0]));
            break;
        case en_ll_ref:
        case en_ull_ref:
        case en_cl_reg:
            scanexpr(node->v.p[0], 1, natural_size(node->v.p[0]));
            break;
        case en_uminus:
        case en_asuminus:
        case en_ascompl:
        case en_compl:
        case en_not:
            scanexpr(node->v.p[0], duse, natural_size(node->v.p[0]));
            break;
        case en_cf:
        case en_cd:
        case en_cld:
        case en_cfc:
        case en_crc:
        case en_clrc:
        case en_cfi:
        case en_cri:
        case en_clri:
            funcfloat++;
        case en_cb:
        case en_cub:
        case en_cbool:
        case en_cw:
        case en_cuw:
        case en_cfp:
        case en_csp:
        case en_cl:
        case en_cul:
		case en_ci:
		case en_cui:
        case en_cp:
        case en_cll:
        case en_cull:
            scanexpr(node->v.p[0], duse, natural_size(node));
            break;
        case en_asadd:
        case en_assub:
            size = natural_size(node->v.p[0]);
            scanexpr(node->v.p[0], duse, 0);
            scanexpr(node->v.p[1], duse, size);
            break;
        case en_ainc:
        case en_adec:
        case en_add:
        case en_sub:
        case en_addstruc:
            en_addcast: scanexpr(node->v.p[0], duse, natural_size(node->v.p[0]))
                ;
            scanexpr(node->v.p[1], duse, natural_size(node->v.p[1]));
            break;
        case en_asalsh:
        case en_asarsh:
        case en_alsh:
        case en_arsh:
        case en_arshd:
        case en_asarshd:
        case en_asmul:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -