Annotation of researchv10dc/cmd/cyntax/cyn/f_equiv.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     Sydney C Compiler.
                      3:  *
                      4:  *     Copyright 1984, Bruce Ellis.
                      5:  *
                      6:  *     Unauthorised possesion, sale or use prohibited.
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       "cnodes.h"
                     11: #include       "flow.h"
                     12: 
                     13: /*
                     14:  *     Lifetime determination.
                     15:  *     
                     16:  *     Method (per pure ident):
                     17:  *     
                     18:  *     Initially the ords are set to L_NONE and the flags contain
                     19:  *     possibly the five flow set flags.  The outer loop attempts to
                     20:  *     fill in the graph's ords.  Each fill is cut by C_CUT_ID nodes
                     21:  *     and dead ends.  A fill is further processed twice.  The fill's
                     22:  *     ords are set to L_ACTIVE in the outer loop.  The first scan
                     23:  *     breaks the fill up into id equivalent classes and detects which
                     24:  *     of these classes are active.  Equivalence classes start at
                     25:  *     L_EQUIV and go up.  The equivalence class values are stored in a
                     26:  *     vector.  The second pass marks the nodes in inactive classes as
                     27:  *     dead and assigns a new ordinal, unique to this fill, to the
                     28:  *     active node.  These start at L_HEAD, which signifies that this
                     29:  *     fill started at the function entry point, and go down.
                     30:  *     
                     31:  *     Four types of diagnostics can be gained from this analysis.  The
                     32:  *     error [variable used where it cannot have a meaningful value],
                     33:  *     the weaker warning [variable may be used before set], and the
                     34:  *     warnings [value assigned to variable not used] and [initial
                     35:  *     value of argument not used].
                     36:  *
                     37:  *     Suspensions.
                     38:  *     ------------
                     39:  *     An equiv class that is under consideration goes into E_SUSP
                     40:  *     mode.  His knowledge starts off suspended.  E_SUSP is the
                     41:  *     identity element under (|), equiv combination.  Since we have no
                     42:  *     unreachable code each fill must be resolved by a write or the
                     43:  *     top of the code.  Thus we can change all current suspensions to
                     44:  *     the return value at the base level.
                     45:  */
                     46: 
                     47: /*
                     48:  *     Initialise equivalence data.
                     49:  */
                     50: void
                     51: equiv_init()
                     52: {
                     53:     register int       i;
                     54: 
                     55:     eord = L_EQUIV;
                     56: 
                     57:     for (i = 0; i < equiv_max; i++)
                     58:        equiv_value[i] = 0;
                     59: }
                     60: 
                     61: /*
                     62:  *     Store equivalence value.
                     63:  */
                     64: void
                     65: equiv_store(i, v)
                     66: register int   i;
                     67: int            v;
                     68: {
                     69:     if (i >= equiv_max)
                     70:     {
                     71:        equiv_max = E_ROUND(i);
                     72:        equiv_value = vector(equiv_value, equiv_max, char);
                     73:     }
                     74: 
                     75:     equiv_value[i] = v;
                     76: }
                     77: 
                     78: /*
                     79:  *     Trace an equivalence class of an instance of an identifier.
                     80:  */
                     81: int
                     82: trace_equiv(start)
                     83: cnode  *start;
                     84: {
                     85:     typedef enum
                     86:     {
                     87:        eq_combine,
                     88:        eq_return,
                     89:        eq_scan,
                     90:     }
                     91:        eq_states;
                     92: 
                     93:     register cnode     *c;
                     94:     register int       ret;
                     95:     register int       ord;
                     96:     register int       combine;
                     97:     register eq_states state;
                     98:     register int       cmod;
                     99: 
                    100:     static int equiv_combine[4][4]     =
                    101:     {
                    102:     /*  E_NONE,        E_SOME, E_ALL,  E_SUSP  */
                    103:        E_NONE, E_SOME, E_SOME, E_NONE, /* E_NONE */
                    104:        E_SOME, E_SOME, E_SOME, E_SOME, /* E_SOME */
                    105:        E_SOME, E_SOME, E_ALL,  E_ALL,  /* E_ALL */
                    106:        E_NONE, E_SOME, E_ALL,  E_SUSP, /* E_SUSP */
                    107:     };
                    108: 
                    109:     combine = E_NONE;
                    110:     c = start;
                    111:     ord = eord++;
                    112:     equiv_store(ord, E_SUSP);
                    113:     ret = E_SUSP;
                    114:     cmod = 0;
                    115:     state = eq_scan;
                    116: 
                    117:     loop
                    118:     {
                    119:        switch (state)
                    120:        {
                    121:        case eq_combine:
                    122:            ret = equiv_combine[ret][combine];
                    123:            state = eq_scan;
                    124:            break;
                    125: 
                    126:        case eq_return:
                    127:            if (ret == E_NONE && cmod)
                    128:                ret = E_SOME;
                    129: 
                    130:            return equiv_value[ord] = equiv_combine[ret][combine];
                    131: 
                    132:        case eq_scan:
                    133:            if (c == NULL)
                    134:            {
                    135:                if (trace_argument)
                    136:                    combine = E_ALL;
                    137:                else
                    138:                    combine = E_NONE;
                    139: 
                    140:                state = eq_return;
                    141:                continue;
                    142:            }
                    143: 
                    144: 
                    145:            if (in(mip_dead_ends, c->c_what) && c != start)
                    146:            {
                    147:                combine = E_SUSP;
                    148:                state = eq_return;
                    149:                continue;
                    150:            }
                    151: 
                    152:            if (c->c_ord == ord)
                    153:                internal("trace_equiv", "circular last trail");
                    154: 
                    155:            if ((c->c_flags & C_X_MOD) != 0 && c != start)
                    156:            {
                    157:                combine = E_ALL;
                    158:                state = eq_return;
                    159:                continue;
                    160:            }
                    161: 
                    162:            if ((c->c_flags & C_X_CMOD) != 0 && c != start)
                    163:                cmod = 1;
                    164: 
                    165:            if (c->c_ord != L_ACTIVE)
                    166:            {
                    167:                if (c->c_ord < L_NONE)
                    168:                    internal("trace_equiv", "ran into trouble");
                    169:                else if (c->c_ord == L_NONE)
                    170:                    internal("trace_equiv", "ran off fill");
                    171: 
                    172:                combine = equiv_value[c->c_ord];
                    173:                state = eq_return;
                    174:                continue;
                    175:            }
                    176: 
                    177:            if (c->c_what == ct_label)
                    178:            {
                    179:                register cnode  *d;
                    180: 
                    181:                for (d = c->c_value.c; d != NULL; d = d->c_link)
                    182:                {
                    183:                    if ((d->c_flags & C_SWITCH) != 0)
                    184:                    {
                    185:                        register cnode  *s;
                    186: 
                    187:                        s = d->c_switch;
                    188: 
                    189:                        if (s->c_ord != ord && s->c_ord != L_NONE)
                    190:                        {
                    191:                            if ((s->c_flags & C_X_CUT) != 0)
                    192:                                combine = E_ALL;
                    193:                            else if (s->c_ord == L_ACTIVE)
                    194:                            {
                    195:                                s->c_ord = ord;
                    196:                                combine = trace_equiv(s->c_last);
                    197:                            }
                    198:                            else
                    199:                            {
                    200:                                if (s->c_ord < L_NONE)
                    201:                                    internal("trace_equiv", "ran into switch trouble");
                    202:                                combine = equiv_value[s->c_ord];
                    203:                            }
                    204:                        }
                    205:                    }
                    206:                    else
                    207:                        combine = trace_equiv(d);
                    208: 
                    209:                    ret = equiv_combine[ret][combine];
                    210:                }
                    211:            }
                    212: 
                    213:            break;
                    214: 
                    215:        default:
                    216:            internal("trace_equiv", "bad state");
                    217:        }
                    218: 
                    219: 
                    220:        c->c_ord = ord;
                    221:        c = c->c_last;
                    222:     }
                    223: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.