17dd7cddfSDavid du Colombier /***** spin: pangen5.c *****/
27dd7cddfSDavid du Colombier
3312a1df1SDavid du Colombier /* Copyright (c) 1999-2003 by Lucent Technologies, Bell Laboratories. */
47dd7cddfSDavid du Colombier /* All Rights Reserved. This software is for educational purposes only. */
5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6312a1df1SDavid du Colombier /* this code. Permission is given to distribute this code provided that */
7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged. */
8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann. For tool documentation see: */
9312a1df1SDavid du Colombier /* http://spinroot.com/ */
10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com */
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier #include "spin.h"
137dd7cddfSDavid du Colombier #include "y.tab.h"
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier typedef struct BuildStack {
167dd7cddfSDavid du Colombier FSM_trans *t;
177dd7cddfSDavid du Colombier struct BuildStack *nxt;
187dd7cddfSDavid du Colombier } BuildStack;
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier extern ProcList *rdy;
21312a1df1SDavid du Colombier extern int verbose, eventmapnr, claimnr, rvopt, export_ast, u_sync;
227dd7cddfSDavid du Colombier extern Element *Al_El;
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier static FSM_state *fsm_free;
257dd7cddfSDavid du Colombier static FSM_trans *trans_free;
267dd7cddfSDavid du Colombier static BuildStack *bs, *bf;
277dd7cddfSDavid du Colombier static int max_st_id;
287dd7cddfSDavid du Colombier static int cur_st_id;
29312a1df1SDavid du Colombier int o_max;
30312a1df1SDavid du Colombier FSM_state *fsm;
31312a1df1SDavid du Colombier FSM_state **fsm_tbl;
32312a1df1SDavid du Colombier FSM_use *use_free;
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier static void ana_seq(Sequence *);
357dd7cddfSDavid du Colombier static void ana_stmnt(FSM_trans *, Lextok *, int);
367dd7cddfSDavid du Colombier
37312a1df1SDavid du Colombier extern void AST_slice(void);
38312a1df1SDavid du Colombier extern void AST_store(ProcList *, int);
39312a1df1SDavid du Colombier extern int has_global(Lextok *);
40312a1df1SDavid du Colombier extern void exit(int);
41312a1df1SDavid du Colombier
42312a1df1SDavid du Colombier static void
fsm_table(void)437dd7cddfSDavid du Colombier fsm_table(void)
447dd7cddfSDavid du Colombier { FSM_state *f;
457dd7cddfSDavid du Colombier max_st_id += 2;
467dd7cddfSDavid du Colombier /* fprintf(stderr, "omax %d, max=%d\n", o_max, max_st_id); */
477dd7cddfSDavid du Colombier if (o_max < max_st_id)
487dd7cddfSDavid du Colombier { o_max = max_st_id;
497dd7cddfSDavid du Colombier fsm_tbl = (FSM_state **) emalloc(max_st_id * sizeof(FSM_state *));
507dd7cddfSDavid du Colombier } else
517dd7cddfSDavid du Colombier memset((char *)fsm_tbl, 0, max_st_id * sizeof(FSM_state *));
527dd7cddfSDavid du Colombier cur_st_id = max_st_id;
537dd7cddfSDavid du Colombier max_st_id = 0;
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier for (f = fsm; f; f = f->nxt)
567dd7cddfSDavid du Colombier fsm_tbl[f->from] = f;
577dd7cddfSDavid du Colombier }
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier static int
FSM_DFS(int from,FSM_use * u)607dd7cddfSDavid du Colombier FSM_DFS(int from, FSM_use *u)
617dd7cddfSDavid du Colombier { FSM_state *f;
627dd7cddfSDavid du Colombier FSM_trans *t;
637dd7cddfSDavid du Colombier FSM_use *v;
647dd7cddfSDavid du Colombier int n;
657dd7cddfSDavid du Colombier
667dd7cddfSDavid du Colombier if (from == 0)
677dd7cddfSDavid du Colombier return 1;
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier f = fsm_tbl[from];
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier if (!f)
727dd7cddfSDavid du Colombier { printf("cannot find state %d\n", from);
737dd7cddfSDavid du Colombier fatal("fsm_dfs: cannot happen\n", (char *) 0);
747dd7cddfSDavid du Colombier }
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier if (f->seen)
777dd7cddfSDavid du Colombier return 1;
787dd7cddfSDavid du Colombier f->seen = 1;
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier for (t = f->t; t; t = t->nxt)
817dd7cddfSDavid du Colombier {
827dd7cddfSDavid du Colombier for (n = 0; n < 2; n++)
837dd7cddfSDavid du Colombier for (v = t->Val[n]; v; v = v->nxt)
847dd7cddfSDavid du Colombier if (u->var == v->var)
857dd7cddfSDavid du Colombier return n; /* a read or write */
867dd7cddfSDavid du Colombier
877dd7cddfSDavid du Colombier if (!FSM_DFS(t->to, u))
887dd7cddfSDavid du Colombier return 0;
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier return 1;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier
937dd7cddfSDavid du Colombier static void
new_dfs(void)947dd7cddfSDavid du Colombier new_dfs(void)
957dd7cddfSDavid du Colombier { int i;
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier for (i = 0; i < cur_st_id; i++)
987dd7cddfSDavid du Colombier if (fsm_tbl[i])
997dd7cddfSDavid du Colombier fsm_tbl[i]->seen = 0;
1007dd7cddfSDavid du Colombier }
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier static int
good_dead(Element * e,FSM_use * u)1037dd7cddfSDavid du Colombier good_dead(Element *e, FSM_use *u)
1047dd7cddfSDavid du Colombier {
1057dd7cddfSDavid du Colombier switch (u->special) {
1067dd7cddfSDavid du Colombier case 2: /* ok if it's a receive */
1077dd7cddfSDavid du Colombier if (e->n->ntyp == ASGN
1087dd7cddfSDavid du Colombier && e->n->rgt->ntyp == CONST
1097dd7cddfSDavid du Colombier && e->n->rgt->val == 0)
1107dd7cddfSDavid du Colombier return 0;
1117dd7cddfSDavid du Colombier break;
1127dd7cddfSDavid du Colombier case 1: /* must be able to use oval */
1137dd7cddfSDavid du Colombier if (e->n->ntyp != 'c'
1147dd7cddfSDavid du Colombier && e->n->ntyp != 'r')
1157dd7cddfSDavid du Colombier return 0; /* can't really happen */
1167dd7cddfSDavid du Colombier break;
1177dd7cddfSDavid du Colombier }
1187dd7cddfSDavid du Colombier return 1;
1197dd7cddfSDavid du Colombier }
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier #if 0
1227dd7cddfSDavid du Colombier static int howdeep = 0;
123312a1df1SDavid du Colombier #endif
1247dd7cddfSDavid du Colombier
1257dd7cddfSDavid du Colombier static int
eligible(FSM_trans * v)1267dd7cddfSDavid du Colombier eligible(FSM_trans *v)
1277dd7cddfSDavid du Colombier { Element *el = ZE;
1287dd7cddfSDavid du Colombier Lextok *lt = ZN;
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier if (v) el = v->step;
1317dd7cddfSDavid du Colombier if (el) lt = v->step->n;
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier if (!lt /* dead end */
1347dd7cddfSDavid du Colombier || v->nxt /* has alternatives */
1357dd7cddfSDavid du Colombier || el->esc /* has an escape */
1367dd7cddfSDavid du Colombier || (el->status&CHECK2) /* remotely referenced */
1377dd7cddfSDavid du Colombier || lt->ntyp == ATOMIC
1387dd7cddfSDavid du Colombier || lt->ntyp == NON_ATOMIC /* used for inlines -- should be able to handle this */
1397dd7cddfSDavid du Colombier || lt->ntyp == IF
140312a1df1SDavid du Colombier || lt->ntyp == C_CODE
141312a1df1SDavid du Colombier || lt->ntyp == C_EXPR
1427dd7cddfSDavid du Colombier || has_lab(el, 0) /* any label at all */
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier || lt->ntyp == DO
1457dd7cddfSDavid du Colombier || lt->ntyp == UNLESS
1467dd7cddfSDavid du Colombier || lt->ntyp == D_STEP
1477dd7cddfSDavid du Colombier || lt->ntyp == ELSE
1487dd7cddfSDavid du Colombier || lt->ntyp == '@'
1497dd7cddfSDavid du Colombier || lt->ntyp == 'c'
1507dd7cddfSDavid du Colombier || lt->ntyp == 'r'
1517dd7cddfSDavid du Colombier || lt->ntyp == 's')
1527dd7cddfSDavid du Colombier return 0;
153312a1df1SDavid du Colombier
1547dd7cddfSDavid du Colombier if (!(el->status&(2|4))) /* not atomic */
1557dd7cddfSDavid du Colombier { int unsafe = (el->status&I_GLOB)?1:has_global(el->n);
1567dd7cddfSDavid du Colombier if (unsafe)
1577dd7cddfSDavid du Colombier return 0;
1587dd7cddfSDavid du Colombier }
1597dd7cddfSDavid du Colombier
1607dd7cddfSDavid du Colombier return 1;
1617dd7cddfSDavid du Colombier }
1627dd7cddfSDavid du Colombier
1637dd7cddfSDavid du Colombier static int
canfill_in(FSM_trans * v)1647dd7cddfSDavid du Colombier canfill_in(FSM_trans *v)
1657dd7cddfSDavid du Colombier { Element *el = v->step;
1667dd7cddfSDavid du Colombier Lextok *lt = v->step->n;
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier if (!lt /* dead end */
1697dd7cddfSDavid du Colombier || v->nxt /* has alternatives */
1707dd7cddfSDavid du Colombier || el->esc /* has an escape */
1717dd7cddfSDavid du Colombier || (el->status&CHECK2)) /* remotely referenced */
1727dd7cddfSDavid du Colombier return 0;
1737dd7cddfSDavid du Colombier
1747dd7cddfSDavid du Colombier if (!(el->status&(2|4)) /* not atomic */
1757dd7cddfSDavid du Colombier && ((el->status&I_GLOB)
1767dd7cddfSDavid du Colombier || has_global(el->n))) /* and not safe */
1777dd7cddfSDavid du Colombier return 0;
1787dd7cddfSDavid du Colombier
1797dd7cddfSDavid du Colombier return 1;
1807dd7cddfSDavid du Colombier }
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier static int
pushbuild(FSM_trans * v)1837dd7cddfSDavid du Colombier pushbuild(FSM_trans *v)
1847dd7cddfSDavid du Colombier { BuildStack *b;
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier for (b = bs; b; b = b->nxt)
1877dd7cddfSDavid du Colombier if (b->t == v)
1887dd7cddfSDavid du Colombier return 0;
1897dd7cddfSDavid du Colombier if (bf)
1907dd7cddfSDavid du Colombier { b = bf;
1917dd7cddfSDavid du Colombier bf = bf->nxt;
1927dd7cddfSDavid du Colombier } else
1937dd7cddfSDavid du Colombier b = (BuildStack *) emalloc(sizeof(BuildStack));
1947dd7cddfSDavid du Colombier b->t = v;
1957dd7cddfSDavid du Colombier b->nxt = bs;
1967dd7cddfSDavid du Colombier bs = b;
1977dd7cddfSDavid du Colombier return 1;
1987dd7cddfSDavid du Colombier }
1997dd7cddfSDavid du Colombier
2007dd7cddfSDavid du Colombier static void
popbuild(void)2017dd7cddfSDavid du Colombier popbuild(void)
2027dd7cddfSDavid du Colombier { BuildStack *f;
2037dd7cddfSDavid du Colombier if (!bs)
2047dd7cddfSDavid du Colombier fatal("cannot happen, popbuild", (char *) 0);
2057dd7cddfSDavid du Colombier f = bs;
2067dd7cddfSDavid du Colombier bs = bs->nxt;
2077dd7cddfSDavid du Colombier f->nxt = bf;
2087dd7cddfSDavid du Colombier bf = f; /* freelist */
2097dd7cddfSDavid du Colombier }
2107dd7cddfSDavid du Colombier
2117dd7cddfSDavid du Colombier static int
build_step(FSM_trans * v)2127dd7cddfSDavid du Colombier build_step(FSM_trans *v)
2137dd7cddfSDavid du Colombier { FSM_state *f;
214*00d97012SDavid du Colombier Element *el;
215312a1df1SDavid du Colombier #if 0
2167dd7cddfSDavid du Colombier Lextok *lt = ZN;
217312a1df1SDavid du Colombier #endif
218*00d97012SDavid du Colombier int st;
2197dd7cddfSDavid du Colombier int r;
2207dd7cddfSDavid du Colombier
221*00d97012SDavid du Colombier if (!v) return -1;
222*00d97012SDavid du Colombier
223*00d97012SDavid du Colombier el = v->step;
224*00d97012SDavid du Colombier st = v->to;
225*00d97012SDavid du Colombier
2267dd7cddfSDavid du Colombier if (!el) return -1;
2277dd7cddfSDavid du Colombier
2287dd7cddfSDavid du Colombier if (v->step->merge)
2297dd7cddfSDavid du Colombier return v->step->merge; /* already done */
2307dd7cddfSDavid du Colombier
2317dd7cddfSDavid du Colombier if (!eligible(v)) /* non-blocking */
2327dd7cddfSDavid du Colombier return -1;
2337dd7cddfSDavid du Colombier
2347dd7cddfSDavid du Colombier if (!pushbuild(v)) /* cycle detected */
2357dd7cddfSDavid du Colombier return -1; /* break cycle */
2367dd7cddfSDavid du Colombier
2377dd7cddfSDavid du Colombier f = fsm_tbl[st];
2387dd7cddfSDavid du Colombier #if 0
239312a1df1SDavid du Colombier lt = v->step->n;
2407dd7cddfSDavid du Colombier if (verbose&32)
2417dd7cddfSDavid du Colombier { if (++howdeep == 1)
242*00d97012SDavid du Colombier printf("spin: %s:%d, merge:\n", lt->fn->name, lt->ln);
2437dd7cddfSDavid du Colombier printf("\t[%d] <seqno %d>\t", howdeep, el->seqno);
2447dd7cddfSDavid du Colombier comment(stdout, lt, 0);
2457dd7cddfSDavid du Colombier printf(";\n");
2467dd7cddfSDavid du Colombier }
2477dd7cddfSDavid du Colombier #endif
2487dd7cddfSDavid du Colombier r = build_step(f->t);
2497dd7cddfSDavid du Colombier v->step->merge = (r == -1) ? st : r;
2507dd7cddfSDavid du Colombier #if 0
2517dd7cddfSDavid du Colombier if (verbose&32)
252312a1df1SDavid du Colombier { printf(" merge value: %d (st=%d,r=%d, line %d)\n",
253312a1df1SDavid du Colombier v->step->merge, st, r, el->n->ln);
2547dd7cddfSDavid du Colombier howdeep--;
255312a1df1SDavid du Colombier }
2567dd7cddfSDavid du Colombier #endif
2577dd7cddfSDavid du Colombier popbuild();
2587dd7cddfSDavid du Colombier
2597dd7cddfSDavid du Colombier return v->step->merge;
2607dd7cddfSDavid du Colombier }
2617dd7cddfSDavid du Colombier
2627dd7cddfSDavid du Colombier static void
FSM_MERGER(void)263*00d97012SDavid du Colombier FSM_MERGER(/* char *pname */ void) /* find candidates for safely merging steps */
2647dd7cddfSDavid du Colombier { FSM_state *f, *g;
2657dd7cddfSDavid du Colombier FSM_trans *t;
2667dd7cddfSDavid du Colombier Lextok *lt;
2677dd7cddfSDavid du Colombier
2687dd7cddfSDavid du Colombier for (f = fsm; f; f = f->nxt) /* all states */
2697dd7cddfSDavid du Colombier for (t = f->t; t; t = t->nxt) /* all edges */
2707dd7cddfSDavid du Colombier { if (!t->step) continue; /* happens with 'unless' */
2717dd7cddfSDavid du Colombier
2727dd7cddfSDavid du Colombier t->step->merge_in = f->in; /* ?? */
2737dd7cddfSDavid du Colombier
2747dd7cddfSDavid du Colombier if (t->step->merge)
2757dd7cddfSDavid du Colombier continue;
2767dd7cddfSDavid du Colombier lt = t->step->n;
2777dd7cddfSDavid du Colombier
2787dd7cddfSDavid du Colombier if (lt->ntyp == 'c'
2797dd7cddfSDavid du Colombier || lt->ntyp == 'r'
2807dd7cddfSDavid du Colombier || lt->ntyp == 's') /* blocking stmnts */
2817dd7cddfSDavid du Colombier continue; /* handled in 2nd scan */
2827dd7cddfSDavid du Colombier
2837dd7cddfSDavid du Colombier if (!eligible(t))
2847dd7cddfSDavid du Colombier continue;
2857dd7cddfSDavid du Colombier
2867dd7cddfSDavid du Colombier g = fsm_tbl[t->to];
287*00d97012SDavid du Colombier if (!g || !eligible(g->t))
2887dd7cddfSDavid du Colombier {
2897dd7cddfSDavid du Colombier #define SINGLES
2907dd7cddfSDavid du Colombier #ifdef SINGLES
2917dd7cddfSDavid du Colombier t->step->merge_single = t->to;
2927dd7cddfSDavid du Colombier #if 0
2937dd7cddfSDavid du Colombier if ((verbose&32))
294*00d97012SDavid du Colombier { printf("spin: %s:%d, merge_single:\n\t<seqno %d>\t",
2957dd7cddfSDavid du Colombier t->step->n->fn->name,
2967dd7cddfSDavid du Colombier t->step->n->ln,
2977dd7cddfSDavid du Colombier t->step->seqno);
2987dd7cddfSDavid du Colombier comment(stdout, t->step->n, 0);
2997dd7cddfSDavid du Colombier printf(";\n");
3007dd7cddfSDavid du Colombier }
3017dd7cddfSDavid du Colombier #endif
3027dd7cddfSDavid du Colombier #endif
3037dd7cddfSDavid du Colombier /* t is an isolated eligible step:
3047dd7cddfSDavid du Colombier *
3057dd7cddfSDavid du Colombier * a merge_start can connect to a proper
3067dd7cddfSDavid du Colombier * merge chain or to a merge_single
3077dd7cddfSDavid du Colombier * a merge chain can be preceded by
3087dd7cddfSDavid du Colombier * a merge_start, but not by a merge_single
3097dd7cddfSDavid du Colombier */
3107dd7cddfSDavid du Colombier
3117dd7cddfSDavid du Colombier continue;
3127dd7cddfSDavid du Colombier }
3137dd7cddfSDavid du Colombier
3147dd7cddfSDavid du Colombier (void) build_step(t);
3157dd7cddfSDavid du Colombier }
3167dd7cddfSDavid du Colombier
3177dd7cddfSDavid du Colombier /* 2nd scan -- find possible merge_starts */
3187dd7cddfSDavid du Colombier
3197dd7cddfSDavid du Colombier for (f = fsm; f; f = f->nxt) /* all states */
3207dd7cddfSDavid du Colombier for (t = f->t; t; t = t->nxt) /* all edges */
3217dd7cddfSDavid du Colombier { if (!t->step || t->step->merge)
3227dd7cddfSDavid du Colombier continue;
3237dd7cddfSDavid du Colombier
3247dd7cddfSDavid du Colombier lt = t->step->n;
325312a1df1SDavid du Colombier #if 0
326312a1df1SDavid du Colombier 4.1.3:
327312a1df1SDavid du Colombier an rv send operation inside an atomic, *loses* atomicity
328312a1df1SDavid du Colombier when executed
329312a1df1SDavid du Colombier and should therefore never be merged with a subsequent
330312a1df1SDavid du Colombier statement within the atomic sequence
331312a1df1SDavid du Colombier the same is not true for non-rv send operations
332312a1df1SDavid du Colombier #endif
3337dd7cddfSDavid du Colombier
334312a1df1SDavid du Colombier if (lt->ntyp == 'c' /* potentially blocking stmnts */
3357dd7cddfSDavid du Colombier || lt->ntyp == 'r'
336312a1df1SDavid du Colombier || (lt->ntyp == 's' && u_sync == 0)) /* added !u_sync in 4.1.3 */
337312a1df1SDavid du Colombier { if (!canfill_in(t)) /* atomic, non-global, etc. */
3387dd7cddfSDavid du Colombier continue;
3397dd7cddfSDavid du Colombier
3407dd7cddfSDavid du Colombier g = fsm_tbl[t->to];
3417dd7cddfSDavid du Colombier if (!g || !g->t || !g->t->step)
3427dd7cddfSDavid du Colombier continue;
3437dd7cddfSDavid du Colombier if (g->t->step->merge)
3447dd7cddfSDavid du Colombier t->step->merge_start = g->t->step->merge;
3457dd7cddfSDavid du Colombier #ifdef SINGLES
3467dd7cddfSDavid du Colombier else if (g->t->step->merge_single)
3477dd7cddfSDavid du Colombier t->step->merge_start = g->t->step->merge_single;
3487dd7cddfSDavid du Colombier #endif
3497dd7cddfSDavid du Colombier #if 0
3507dd7cddfSDavid du Colombier if ((verbose&32)
3517dd7cddfSDavid du Colombier && t->step->merge_start)
352*00d97012SDavid du Colombier { printf("spin: %s:%d, merge_START:\n\t<seqno %d>\t",
353*00d97012SDavid du Colombier lt->fn->name, lt->ln,
3547dd7cddfSDavid du Colombier t->step->seqno);
3557dd7cddfSDavid du Colombier comment(stdout, lt, 0);
3567dd7cddfSDavid du Colombier printf(";\n");
3577dd7cddfSDavid du Colombier }
3587dd7cddfSDavid du Colombier #endif
3597dd7cddfSDavid du Colombier }
3607dd7cddfSDavid du Colombier }
3617dd7cddfSDavid du Colombier }
3627dd7cddfSDavid du Colombier
3637dd7cddfSDavid du Colombier static void
FSM_ANA(void)3647dd7cddfSDavid du Colombier FSM_ANA(void)
3657dd7cddfSDavid du Colombier { FSM_state *f;
3667dd7cddfSDavid du Colombier FSM_trans *t;
3677dd7cddfSDavid du Colombier FSM_use *u, *v, *w;
3687dd7cddfSDavid du Colombier int n;
3697dd7cddfSDavid du Colombier
3707dd7cddfSDavid du Colombier for (f = fsm; f; f = f->nxt) /* all states */
3717dd7cddfSDavid du Colombier for (t = f->t; t; t = t->nxt) /* all edges */
3727dd7cddfSDavid du Colombier for (n = 0; n < 2; n++) /* reads and writes */
3737dd7cddfSDavid du Colombier for (u = t->Val[n]; u; u = u->nxt)
3747dd7cddfSDavid du Colombier { if (!u->var->context /* global */
3757dd7cddfSDavid du Colombier || u->var->type == CHAN
3767dd7cddfSDavid du Colombier || u->var->type == STRUCT)
3777dd7cddfSDavid du Colombier continue;
3787dd7cddfSDavid du Colombier new_dfs();
3797dd7cddfSDavid du Colombier if (FSM_DFS(t->to, u)) /* cannot hit read before hitting write */
3807dd7cddfSDavid du Colombier u->special = n+1; /* means, reset to 0 after use */
3817dd7cddfSDavid du Colombier }
3827dd7cddfSDavid du Colombier
383312a1df1SDavid du Colombier if (!export_ast)
3847dd7cddfSDavid du Colombier for (f = fsm; f; f = f->nxt)
3857dd7cddfSDavid du Colombier for (t = f->t; t; t = t->nxt)
3867dd7cddfSDavid du Colombier for (n = 0; n < 2; n++)
3877dd7cddfSDavid du Colombier for (u = t->Val[n], w = (FSM_use *) 0; u; )
3887dd7cddfSDavid du Colombier { if (u->special)
3897dd7cddfSDavid du Colombier { v = u->nxt;
3907dd7cddfSDavid du Colombier if (!w) /* remove from list */
3917dd7cddfSDavid du Colombier t->Val[n] = v;
3927dd7cddfSDavid du Colombier else
3937dd7cddfSDavid du Colombier w->nxt = v;
394312a1df1SDavid du Colombier #if q
3957dd7cddfSDavid du Colombier if (verbose&32)
3967dd7cddfSDavid du Colombier { printf("%s : %3d: %d -> %d \t",
3977dd7cddfSDavid du Colombier t->step->n->fn->name,
3987dd7cddfSDavid du Colombier t->step->n->ln,
3997dd7cddfSDavid du Colombier f->from,
4007dd7cddfSDavid du Colombier t->to);
4017dd7cddfSDavid du Colombier comment(stdout, t->step->n, 0);
4027dd7cddfSDavid du Colombier printf("\t%c%d: %s\n", n==0?'R':'L',
4037dd7cddfSDavid du Colombier u->special, u->var->name);
4047dd7cddfSDavid du Colombier }
4057dd7cddfSDavid du Colombier #endif
4067dd7cddfSDavid du Colombier if (good_dead(t->step, u))
4077dd7cddfSDavid du Colombier { u->nxt = t->step->dead; /* insert into dead */
4087dd7cddfSDavid du Colombier t->step->dead = u;
4097dd7cddfSDavid du Colombier }
4107dd7cddfSDavid du Colombier u = v;
4117dd7cddfSDavid du Colombier } else
4127dd7cddfSDavid du Colombier { w = u;
4137dd7cddfSDavid du Colombier u = u->nxt;
4147dd7cddfSDavid du Colombier } }
4157dd7cddfSDavid du Colombier }
4167dd7cddfSDavid du Colombier
417312a1df1SDavid du Colombier void
rel_use(FSM_use * u)4187dd7cddfSDavid du Colombier rel_use(FSM_use *u)
4197dd7cddfSDavid du Colombier {
4207dd7cddfSDavid du Colombier if (!u) return;
4217dd7cddfSDavid du Colombier rel_use(u->nxt);
4227dd7cddfSDavid du Colombier u->var = (Symbol *) 0;
4237dd7cddfSDavid du Colombier u->special = 0;
4247dd7cddfSDavid du Colombier u->nxt = use_free;
4257dd7cddfSDavid du Colombier use_free = u;
4267dd7cddfSDavid du Colombier }
4277dd7cddfSDavid du Colombier
4287dd7cddfSDavid du Colombier static void
rel_trans(FSM_trans * t)4297dd7cddfSDavid du Colombier rel_trans(FSM_trans *t)
4307dd7cddfSDavid du Colombier {
4317dd7cddfSDavid du Colombier if (!t) return;
4327dd7cddfSDavid du Colombier rel_trans(t->nxt);
4337dd7cddfSDavid du Colombier rel_use(t->Val[0]);
4347dd7cddfSDavid du Colombier rel_use(t->Val[1]);
4357dd7cddfSDavid du Colombier t->Val[0] = t->Val[1] = (FSM_use *) 0;
4367dd7cddfSDavid du Colombier t->nxt = trans_free;
4377dd7cddfSDavid du Colombier trans_free = t;
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier
4407dd7cddfSDavid du Colombier static void
rel_state(FSM_state * f)4417dd7cddfSDavid du Colombier rel_state(FSM_state *f)
4427dd7cddfSDavid du Colombier {
4437dd7cddfSDavid du Colombier if (!f) return;
4447dd7cddfSDavid du Colombier rel_state(f->nxt);
4457dd7cddfSDavid du Colombier rel_trans(f->t);
4467dd7cddfSDavid du Colombier f->t = (FSM_trans *) 0;
4477dd7cddfSDavid du Colombier f->nxt = fsm_free;
4487dd7cddfSDavid du Colombier fsm_free = f;
4497dd7cddfSDavid du Colombier }
4507dd7cddfSDavid du Colombier
4517dd7cddfSDavid du Colombier static void
FSM_DEL(void)4527dd7cddfSDavid du Colombier FSM_DEL(void)
4537dd7cddfSDavid du Colombier {
4547dd7cddfSDavid du Colombier rel_state(fsm);
4557dd7cddfSDavid du Colombier fsm = (FSM_state *) 0;
4567dd7cddfSDavid du Colombier }
4577dd7cddfSDavid du Colombier
4587dd7cddfSDavid du Colombier static FSM_state *
mkstate(int s)4597dd7cddfSDavid du Colombier mkstate(int s)
4607dd7cddfSDavid du Colombier { FSM_state *f;
4617dd7cddfSDavid du Colombier
4627dd7cddfSDavid du Colombier /* fsm_tbl isn't allocated yet */
4637dd7cddfSDavid du Colombier for (f = fsm; f; f = f->nxt)
4647dd7cddfSDavid du Colombier if (f->from == s)
4657dd7cddfSDavid du Colombier break;
4667dd7cddfSDavid du Colombier if (!f)
4677dd7cddfSDavid du Colombier { if (fsm_free)
4687dd7cddfSDavid du Colombier { f = fsm_free;
4697dd7cddfSDavid du Colombier memset(f, 0, sizeof(FSM_state));
4707dd7cddfSDavid du Colombier fsm_free = fsm_free->nxt;
4717dd7cddfSDavid du Colombier } else
4727dd7cddfSDavid du Colombier f = (FSM_state *) emalloc(sizeof(FSM_state));
4737dd7cddfSDavid du Colombier f->from = s;
4747dd7cddfSDavid du Colombier f->t = (FSM_trans *) 0;
4757dd7cddfSDavid du Colombier f->nxt = fsm;
4767dd7cddfSDavid du Colombier fsm = f;
4777dd7cddfSDavid du Colombier if (s > max_st_id)
4787dd7cddfSDavid du Colombier max_st_id = s;
4797dd7cddfSDavid du Colombier }
4807dd7cddfSDavid du Colombier return f;
4817dd7cddfSDavid du Colombier }
4827dd7cddfSDavid du Colombier
483312a1df1SDavid du Colombier static FSM_trans *
get_trans(int to)484312a1df1SDavid du Colombier get_trans(int to)
485312a1df1SDavid du Colombier { FSM_trans *t;
4867dd7cddfSDavid du Colombier
4877dd7cddfSDavid du Colombier if (trans_free)
4887dd7cddfSDavid du Colombier { t = trans_free;
4897dd7cddfSDavid du Colombier memset(t, 0, sizeof(FSM_trans));
4907dd7cddfSDavid du Colombier trans_free = trans_free->nxt;
4917dd7cddfSDavid du Colombier } else
4927dd7cddfSDavid du Colombier t = (FSM_trans *) emalloc(sizeof(FSM_trans));
493312a1df1SDavid du Colombier
4947dd7cddfSDavid du Colombier t->to = to;
495312a1df1SDavid du Colombier return t;
496312a1df1SDavid du Colombier }
497312a1df1SDavid du Colombier
498312a1df1SDavid du Colombier static void
FSM_EDGE(int from,int to,Element * e)499312a1df1SDavid du Colombier FSM_EDGE(int from, int to, Element *e)
500312a1df1SDavid du Colombier { FSM_state *f;
501312a1df1SDavid du Colombier FSM_trans *t;
502312a1df1SDavid du Colombier
503312a1df1SDavid du Colombier f = mkstate(from); /* find it or else make it */
504312a1df1SDavid du Colombier t = get_trans(to);
505312a1df1SDavid du Colombier
5067dd7cddfSDavid du Colombier t->step = e;
5077dd7cddfSDavid du Colombier t->nxt = f->t;
5087dd7cddfSDavid du Colombier f->t = t;
5097dd7cddfSDavid du Colombier
5107dd7cddfSDavid du Colombier f = mkstate(to);
5117dd7cddfSDavid du Colombier f->in++;
5127dd7cddfSDavid du Colombier
513312a1df1SDavid du Colombier if (export_ast)
514312a1df1SDavid du Colombier { t = get_trans(from);
515312a1df1SDavid du Colombier t->step = e;
516312a1df1SDavid du Colombier t->nxt = f->p; /* from is a predecessor of to */
517312a1df1SDavid du Colombier f->p = t;
518312a1df1SDavid du Colombier }
519312a1df1SDavid du Colombier
5207dd7cddfSDavid du Colombier if (t->step)
5217dd7cddfSDavid du Colombier ana_stmnt(t, t->step->n, 0);
5227dd7cddfSDavid du Colombier }
5237dd7cddfSDavid du Colombier
5247dd7cddfSDavid du Colombier #define LVAL 1
5257dd7cddfSDavid du Colombier #define RVAL 0
5267dd7cddfSDavid du Colombier
5277dd7cddfSDavid du Colombier static void
ana_var(FSM_trans * t,Lextok * now,int usage)5287dd7cddfSDavid du Colombier ana_var(FSM_trans *t, Lextok *now, int usage)
5297dd7cddfSDavid du Colombier { FSM_use *u, *v;
5307dd7cddfSDavid du Colombier
531312a1df1SDavid du Colombier if (!t || !now || !now->sym)
532312a1df1SDavid du Colombier return;
533312a1df1SDavid du Colombier
534312a1df1SDavid du Colombier if (now->sym->name[0] == '_'
535312a1df1SDavid du Colombier && (strcmp(now->sym->name, "_") == 0
536312a1df1SDavid du Colombier || strcmp(now->sym->name, "_pid") == 0
537312a1df1SDavid du Colombier || strcmp(now->sym->name, "_last") == 0))
5387dd7cddfSDavid du Colombier return;
5397dd7cddfSDavid du Colombier
5407dd7cddfSDavid du Colombier v = t->Val[usage];
5417dd7cddfSDavid du Colombier for (u = v; u; u = u->nxt)
5427dd7cddfSDavid du Colombier if (u->var == now->sym)
5437dd7cddfSDavid du Colombier return; /* it's already there */
5447dd7cddfSDavid du Colombier
5457dd7cddfSDavid du Colombier if (!now->lft)
5467dd7cddfSDavid du Colombier { /* not for array vars -- it's hard to tell statically
5477dd7cddfSDavid du Colombier if the index would, at runtime, evaluate to the
5487dd7cddfSDavid du Colombier same values at lval and rval references
5497dd7cddfSDavid du Colombier */
5507dd7cddfSDavid du Colombier if (use_free)
5517dd7cddfSDavid du Colombier { u = use_free;
5527dd7cddfSDavid du Colombier use_free = use_free->nxt;
5537dd7cddfSDavid du Colombier } else
5547dd7cddfSDavid du Colombier u = (FSM_use *) emalloc(sizeof(FSM_use));
5557dd7cddfSDavid du Colombier
5567dd7cddfSDavid du Colombier u->var = now->sym;
5577dd7cddfSDavid du Colombier u->nxt = t->Val[usage];
5587dd7cddfSDavid du Colombier t->Val[usage] = u;
5597dd7cddfSDavid du Colombier } else
5607dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, RVAL); /* index */
5617dd7cddfSDavid du Colombier
5627dd7cddfSDavid du Colombier if (now->sym->type == STRUCT
5637dd7cddfSDavid du Colombier && now->rgt
5647dd7cddfSDavid du Colombier && now->rgt->lft)
5657dd7cddfSDavid du Colombier ana_var(t, now->rgt->lft, usage);
5667dd7cddfSDavid du Colombier }
5677dd7cddfSDavid du Colombier
5687dd7cddfSDavid du Colombier static void
ana_stmnt(FSM_trans * t,Lextok * now,int usage)5697dd7cddfSDavid du Colombier ana_stmnt(FSM_trans *t, Lextok *now, int usage)
5707dd7cddfSDavid du Colombier { Lextok *v;
5717dd7cddfSDavid du Colombier
5727dd7cddfSDavid du Colombier if (!t || !now) return;
5737dd7cddfSDavid du Colombier
5747dd7cddfSDavid du Colombier switch (now->ntyp) {
5757dd7cddfSDavid du Colombier case '.':
5767dd7cddfSDavid du Colombier case BREAK:
5777dd7cddfSDavid du Colombier case GOTO:
5787dd7cddfSDavid du Colombier case CONST:
5797dd7cddfSDavid du Colombier case TIMEOUT:
5807dd7cddfSDavid du Colombier case NONPROGRESS:
5817dd7cddfSDavid du Colombier case ELSE:
5827dd7cddfSDavid du Colombier case '@':
5837dd7cddfSDavid du Colombier case 'q':
5847dd7cddfSDavid du Colombier case IF:
5857dd7cddfSDavid du Colombier case DO:
5867dd7cddfSDavid du Colombier case ATOMIC:
5877dd7cddfSDavid du Colombier case NON_ATOMIC:
5887dd7cddfSDavid du Colombier case D_STEP:
589312a1df1SDavid du Colombier case C_CODE:
590312a1df1SDavid du Colombier case C_EXPR:
5917dd7cddfSDavid du Colombier break;
5927dd7cddfSDavid du Colombier
5937dd7cddfSDavid du Colombier case '!':
5947dd7cddfSDavid du Colombier case UMIN:
5957dd7cddfSDavid du Colombier case '~':
5967dd7cddfSDavid du Colombier case ENABLED:
5977dd7cddfSDavid du Colombier case PC_VAL:
5987dd7cddfSDavid du Colombier case LEN:
5997dd7cddfSDavid du Colombier case FULL:
6007dd7cddfSDavid du Colombier case EMPTY:
6017dd7cddfSDavid du Colombier case NFULL:
6027dd7cddfSDavid du Colombier case NEMPTY:
6037dd7cddfSDavid du Colombier case ASSERT:
6047dd7cddfSDavid du Colombier case 'c':
6057dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, RVAL);
6067dd7cddfSDavid du Colombier break;
6077dd7cddfSDavid du Colombier
6087dd7cddfSDavid du Colombier case '/':
6097dd7cddfSDavid du Colombier case '*':
6107dd7cddfSDavid du Colombier case '-':
6117dd7cddfSDavid du Colombier case '+':
6127dd7cddfSDavid du Colombier case '%':
6137dd7cddfSDavid du Colombier case '&':
6147dd7cddfSDavid du Colombier case '^':
6157dd7cddfSDavid du Colombier case '|':
6167dd7cddfSDavid du Colombier case LT:
6177dd7cddfSDavid du Colombier case GT:
6187dd7cddfSDavid du Colombier case LE:
6197dd7cddfSDavid du Colombier case GE:
6207dd7cddfSDavid du Colombier case NE:
6217dd7cddfSDavid du Colombier case EQ:
6227dd7cddfSDavid du Colombier case OR:
6237dd7cddfSDavid du Colombier case AND:
6247dd7cddfSDavid du Colombier case LSHIFT:
6257dd7cddfSDavid du Colombier case RSHIFT:
6267dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, RVAL);
6277dd7cddfSDavid du Colombier ana_stmnt(t, now->rgt, RVAL);
6287dd7cddfSDavid du Colombier break;
6297dd7cddfSDavid du Colombier
6307dd7cddfSDavid du Colombier case ASGN:
6317dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, LVAL);
6327dd7cddfSDavid du Colombier ana_stmnt(t, now->rgt, RVAL);
6337dd7cddfSDavid du Colombier break;
6347dd7cddfSDavid du Colombier
6357dd7cddfSDavid du Colombier case PRINT:
6367dd7cddfSDavid du Colombier case RUN:
6377dd7cddfSDavid du Colombier for (v = now->lft; v; v = v->rgt)
6387dd7cddfSDavid du Colombier ana_stmnt(t, v->lft, RVAL);
6397dd7cddfSDavid du Colombier break;
6407dd7cddfSDavid du Colombier
641312a1df1SDavid du Colombier case PRINTM:
642312a1df1SDavid du Colombier if (now->lft && !now->lft->ismtyp)
643312a1df1SDavid du Colombier ana_stmnt(t, now->lft, RVAL);
644312a1df1SDavid du Colombier break;
645312a1df1SDavid du Colombier
6467dd7cddfSDavid du Colombier case 's':
6477dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, RVAL);
6487dd7cddfSDavid du Colombier for (v = now->rgt; v; v = v->rgt)
6497dd7cddfSDavid du Colombier ana_stmnt(t, v->lft, RVAL);
6507dd7cddfSDavid du Colombier break;
6517dd7cddfSDavid du Colombier
6527dd7cddfSDavid du Colombier case 'R':
6537dd7cddfSDavid du Colombier case 'r':
6547dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, RVAL);
6557dd7cddfSDavid du Colombier for (v = now->rgt; v; v = v->rgt)
6567dd7cddfSDavid du Colombier { if (v->lft->ntyp == EVAL)
6577dd7cddfSDavid du Colombier ana_stmnt(t, v->lft->lft, RVAL);
6587dd7cddfSDavid du Colombier else
6597dd7cddfSDavid du Colombier if (v->lft->ntyp != CONST
6607dd7cddfSDavid du Colombier && now->ntyp != 'R') /* was v->lft->ntyp */
6617dd7cddfSDavid du Colombier ana_stmnt(t, v->lft, LVAL);
6627dd7cddfSDavid du Colombier }
6637dd7cddfSDavid du Colombier break;
6647dd7cddfSDavid du Colombier
6657dd7cddfSDavid du Colombier case '?':
6667dd7cddfSDavid du Colombier ana_stmnt(t, now->lft, RVAL);
667312a1df1SDavid du Colombier if (now->rgt)
668312a1df1SDavid du Colombier { ana_stmnt(t, now->rgt->lft, RVAL);
6697dd7cddfSDavid du Colombier ana_stmnt(t, now->rgt->rgt, RVAL);
670312a1df1SDavid du Colombier }
6717dd7cddfSDavid du Colombier break;
6727dd7cddfSDavid du Colombier
6737dd7cddfSDavid du Colombier case NAME:
6747dd7cddfSDavid du Colombier ana_var(t, now, usage);
6757dd7cddfSDavid du Colombier break;
6767dd7cddfSDavid du Colombier
6777dd7cddfSDavid du Colombier case 'p': /* remote ref */
6787dd7cddfSDavid du Colombier ana_stmnt(t, now->lft->lft, RVAL); /* process id */
6797dd7cddfSDavid du Colombier ana_var(t, now, RVAL);
6807dd7cddfSDavid du Colombier ana_var(t, now->rgt, RVAL);
6817dd7cddfSDavid du Colombier break;
6827dd7cddfSDavid du Colombier
6837dd7cddfSDavid du Colombier default:
684*00d97012SDavid du Colombier printf("spin: %s:%d, bad node type %d (ana_stmnt)\n",
685*00d97012SDavid du Colombier now->fn->name, now->ln, now->ntyp);
6867dd7cddfSDavid du Colombier fatal("aborting", (char *) 0);
6877dd7cddfSDavid du Colombier }
6887dd7cddfSDavid du Colombier }
6897dd7cddfSDavid du Colombier
6907dd7cddfSDavid du Colombier void
ana_src(int dataflow,int merger)691312a1df1SDavid du Colombier ana_src(int dataflow, int merger) /* called from main.c and guided.c */
6927dd7cddfSDavid du Colombier { ProcList *p;
6937dd7cddfSDavid du Colombier Element *e;
694312a1df1SDavid du Colombier #if 0
6957dd7cddfSDavid du Colombier int counter = 1;
696312a1df1SDavid du Colombier #endif
6977dd7cddfSDavid du Colombier for (p = rdy; p; p = p->nxt)
698*00d97012SDavid du Colombier {
6997dd7cddfSDavid du Colombier ana_seq(p->s);
7007dd7cddfSDavid du Colombier fsm_table();
7017dd7cddfSDavid du Colombier
7027dd7cddfSDavid du Colombier e = p->s->frst;
7037dd7cddfSDavid du Colombier #if 0
7047dd7cddfSDavid du Colombier if (dataflow || merger)
7057dd7cddfSDavid du Colombier { printf("spin: %d, optimizing '%s'",
7067dd7cddfSDavid du Colombier counter++, p->n->name);
7077dd7cddfSDavid du Colombier fflush(stdout);
7087dd7cddfSDavid du Colombier }
7097dd7cddfSDavid du Colombier #endif
7107dd7cddfSDavid du Colombier if (dataflow)
7117dd7cddfSDavid du Colombier { FSM_ANA();
7127dd7cddfSDavid du Colombier }
7137dd7cddfSDavid du Colombier if (merger)
714*00d97012SDavid du Colombier { FSM_MERGER(/* p->n->name */);
715312a1df1SDavid du Colombier huntele(e, e->status, -1)->merge_in = 1; /* start-state */
7167dd7cddfSDavid du Colombier #if 0
7177dd7cddfSDavid du Colombier printf("\n");
7187dd7cddfSDavid du Colombier #endif
7197dd7cddfSDavid du Colombier }
720312a1df1SDavid du Colombier if (export_ast)
721312a1df1SDavid du Colombier AST_store(p, huntele(e, e->status, -1)->seqno);
722312a1df1SDavid du Colombier
7237dd7cddfSDavid du Colombier FSM_DEL();
7247dd7cddfSDavid du Colombier }
7257dd7cddfSDavid du Colombier for (e = Al_El; e; e = e->Nxt)
7267dd7cddfSDavid du Colombier {
7277dd7cddfSDavid du Colombier if (!(e->status&DONE) && (verbose&32))
7287dd7cddfSDavid du Colombier { printf("unreachable code: ");
729*00d97012SDavid du Colombier printf("%s:%3d ", e->n->fn->name, e->n->ln);
7307dd7cddfSDavid du Colombier comment(stdout, e->n, 0);
7317dd7cddfSDavid du Colombier printf("\n");
7327dd7cddfSDavid du Colombier }
7337dd7cddfSDavid du Colombier e->status &= ~DONE;
7347dd7cddfSDavid du Colombier }
735312a1df1SDavid du Colombier if (export_ast)
736312a1df1SDavid du Colombier { AST_slice();
737*00d97012SDavid du Colombier alldone(0); /* changed in 5.3.0: was exit(0) */
738312a1df1SDavid du Colombier }
7397dd7cddfSDavid du Colombier }
7407dd7cddfSDavid du Colombier
7417dd7cddfSDavid du Colombier void
spit_recvs(FILE * f1,FILE * f2)742312a1df1SDavid du Colombier spit_recvs(FILE *f1, FILE *f2) /* called from pangen2.c */
7437dd7cddfSDavid du Colombier { Element *e;
7447dd7cddfSDavid du Colombier Sequence *s;
7457dd7cddfSDavid du Colombier extern int Unique;
7467dd7cddfSDavid du Colombier
7477dd7cddfSDavid du Colombier fprintf(f1, "unsigned char Is_Recv[%d];\n", Unique);
7487dd7cddfSDavid du Colombier
7497dd7cddfSDavid du Colombier fprintf(f2, "void\nset_recvs(void)\n{\n");
7507dd7cddfSDavid du Colombier for (e = Al_El; e; e = e->Nxt)
7517dd7cddfSDavid du Colombier { if (!e->n) continue;
7527dd7cddfSDavid du Colombier
7537dd7cddfSDavid du Colombier switch (e->n->ntyp) {
7547dd7cddfSDavid du Colombier case 'r':
7557dd7cddfSDavid du Colombier markit: fprintf(f2, "\tIs_Recv[%d] = 1;\n", e->Seqno);
7567dd7cddfSDavid du Colombier break;
7577dd7cddfSDavid du Colombier case D_STEP:
7587dd7cddfSDavid du Colombier s = e->n->sl->this;
7597dd7cddfSDavid du Colombier switch (s->frst->n->ntyp) {
7607dd7cddfSDavid du Colombier case DO:
7617dd7cddfSDavid du Colombier fatal("unexpected: do at start of d_step", (char *) 0);
7627dd7cddfSDavid du Colombier case IF: /* conservative: fall through */
7637dd7cddfSDavid du Colombier case 'r': goto markit;
7647dd7cddfSDavid du Colombier }
7657dd7cddfSDavid du Colombier break;
7667dd7cddfSDavid du Colombier }
7677dd7cddfSDavid du Colombier }
7687dd7cddfSDavid du Colombier fprintf(f2, "}\n");
7697dd7cddfSDavid du Colombier
7707dd7cddfSDavid du Colombier if (rvopt)
7717dd7cddfSDavid du Colombier {
7727dd7cddfSDavid du Colombier fprintf(f2, "int\nno_recvs(int me)\n{\n");
7737dd7cddfSDavid du Colombier fprintf(f2, " int h; uchar ot; short tt;\n");
7747dd7cddfSDavid du Colombier fprintf(f2, " Trans *t;\n");
7757dd7cddfSDavid du Colombier fprintf(f2, " for (h = BASE; h < (int) now._nr_pr; h++)\n");
7767dd7cddfSDavid du Colombier fprintf(f2, " { if (h == me) continue;\n");
7777dd7cddfSDavid du Colombier fprintf(f2, " tt = (short) ((P0 *)pptr(h))->_p;\n");
7787dd7cddfSDavid du Colombier fprintf(f2, " ot = (uchar) ((P0 *)pptr(h))->_t;\n");
7797dd7cddfSDavid du Colombier fprintf(f2, " for (t = trans[ot][tt]; t; t = t->nxt)\n");
7807dd7cddfSDavid du Colombier fprintf(f2, " if (Is_Recv[t->t_id]) return 0;\n");
7817dd7cddfSDavid du Colombier fprintf(f2, " }\n");
7827dd7cddfSDavid du Colombier fprintf(f2, " return 1;\n");
7837dd7cddfSDavid du Colombier fprintf(f2, "}\n");
7847dd7cddfSDavid du Colombier }
7857dd7cddfSDavid du Colombier }
7867dd7cddfSDavid du Colombier
7877dd7cddfSDavid du Colombier static void
ana_seq(Sequence * s)7887dd7cddfSDavid du Colombier ana_seq(Sequence *s)
7897dd7cddfSDavid du Colombier { SeqList *h;
7907dd7cddfSDavid du Colombier Sequence *t;
7917dd7cddfSDavid du Colombier Element *e, *g;
7927dd7cddfSDavid du Colombier int From, To;
7937dd7cddfSDavid du Colombier
7947dd7cddfSDavid du Colombier for (e = s->frst; e; e = e->nxt)
7957dd7cddfSDavid du Colombier { if (e->status & DONE)
7967dd7cddfSDavid du Colombier goto checklast;
7977dd7cddfSDavid du Colombier
7987dd7cddfSDavid du Colombier e->status |= DONE;
7997dd7cddfSDavid du Colombier
8007dd7cddfSDavid du Colombier From = e->seqno;
8017dd7cddfSDavid du Colombier
8027dd7cddfSDavid du Colombier if (e->n->ntyp == UNLESS)
8037dd7cddfSDavid du Colombier ana_seq(e->sub->this);
8047dd7cddfSDavid du Colombier else if (e->sub)
8057dd7cddfSDavid du Colombier { for (h = e->sub; h; h = h->nxt)
8067dd7cddfSDavid du Colombier { g = huntstart(h->this->frst);
8077dd7cddfSDavid du Colombier To = g->seqno;
8087dd7cddfSDavid du Colombier
8097dd7cddfSDavid du Colombier if (g->n->ntyp != 'c'
8107dd7cddfSDavid du Colombier || g->n->lft->ntyp != CONST
8117dd7cddfSDavid du Colombier || g->n->lft->val != 0
8127dd7cddfSDavid du Colombier || g->esc)
8137dd7cddfSDavid du Colombier FSM_EDGE(From, To, e);
8147dd7cddfSDavid du Colombier /* else it's a dead link */
8157dd7cddfSDavid du Colombier }
8167dd7cddfSDavid du Colombier for (h = e->sub; h; h = h->nxt)
8177dd7cddfSDavid du Colombier ana_seq(h->this);
8187dd7cddfSDavid du Colombier } else if (e->n->ntyp == ATOMIC
8197dd7cddfSDavid du Colombier || e->n->ntyp == D_STEP
8207dd7cddfSDavid du Colombier || e->n->ntyp == NON_ATOMIC)
8217dd7cddfSDavid du Colombier {
8227dd7cddfSDavid du Colombier t = e->n->sl->this;
8237dd7cddfSDavid du Colombier g = huntstart(t->frst);
8247dd7cddfSDavid du Colombier t->last->nxt = e->nxt;
8257dd7cddfSDavid du Colombier To = g->seqno;
8267dd7cddfSDavid du Colombier FSM_EDGE(From, To, e);
8277dd7cddfSDavid du Colombier
8287dd7cddfSDavid du Colombier ana_seq(t);
8297dd7cddfSDavid du Colombier } else
8307dd7cddfSDavid du Colombier { if (e->n->ntyp == GOTO)
8317dd7cddfSDavid du Colombier { g = get_lab(e->n, 1);
832312a1df1SDavid du Colombier g = huntele(g, e->status, -1);
8337dd7cddfSDavid du Colombier To = g->seqno;
8347dd7cddfSDavid du Colombier } else if (e->nxt)
835312a1df1SDavid du Colombier { g = huntele(e->nxt, e->status, -1);
8367dd7cddfSDavid du Colombier To = g->seqno;
8377dd7cddfSDavid du Colombier } else
8387dd7cddfSDavid du Colombier To = 0;
8397dd7cddfSDavid du Colombier
8407dd7cddfSDavid du Colombier FSM_EDGE(From, To, e);
8417dd7cddfSDavid du Colombier
8427dd7cddfSDavid du Colombier if (e->esc
8437dd7cddfSDavid du Colombier && e->n->ntyp != GOTO
8447dd7cddfSDavid du Colombier && e->n->ntyp != '.')
8457dd7cddfSDavid du Colombier for (h = e->esc; h; h = h->nxt)
8467dd7cddfSDavid du Colombier { g = huntstart(h->this->frst);
8477dd7cddfSDavid du Colombier To = g->seqno;
8487dd7cddfSDavid du Colombier FSM_EDGE(From, To, ZE);
8497dd7cddfSDavid du Colombier ana_seq(h->this);
8507dd7cddfSDavid du Colombier }
8517dd7cddfSDavid du Colombier }
8527dd7cddfSDavid du Colombier
8537dd7cddfSDavid du Colombier checklast: if (e == s->last)
8547dd7cddfSDavid du Colombier break;
8557dd7cddfSDavid du Colombier }
8567dd7cddfSDavid du Colombier }
857