home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #
- /* depth-first search used to identify back edges, unreachable nodes;
- each node v entered by back edge replaced by
- LOOPVX ->ITERVX -> v,
- so that back edges entering v now enter the ITERVX,
- and other edges entering v now enter the LOOPVX.
- Nodes are numbered according to depth-first search:
- before numbering- ntobef[v] = i => node numbered v is i'th
- node in order of first visit during the search;
- after numbering- ntoaft[v] = i => node numbered v is i'th
- node visited in order of last visit during the search.
- Also, in this case after[i] = v.
- */
-
- #include "def.h"
- #include "2.def.h"
-
- #define MAXINS 3 /* spacing needed between numbers generated during depth first search */
-
- int *status;
- int befcount, aftcount;
- /* following defines used to mark back edges and nodes entered by back edges */
- #define UNPROCESSED 0
- #define STACKED 1
- #define FINISHED 2
- #define MARK(v) {REACH(v) = 1; } /* mark node v */
- #define UNMARK(v) {REACH(v) = 0; }
- #define MARKED(v) (REACH(v))
- #define MKEDGE(e) {if (e >= -1) e = -(e+3); } /* mark edge e */
- #define UNMKEDGE(e) {if (e < -1) e = -(e+3); }
- #define BACKEDGE(e) (e < -1)
-
-
- dfs(v) /* depth first search */
- VERT v;
- {
- int i; VERT w;
- accessnum = 0;
- status = challoc(sizeof(*status) * nodenum);
- for (w = 0; w < nodenum; ++w)
- {
- status[w] = UNPROCESSED;
- UNMARK(w);
- }
- search(v);
- chreach();
- chfree(status, sizeof(*status) * nodenum);
- addloop();
- after = challoc(sizeof(*after) * accessnum);
- for (i = 0; i < accessnum; ++i)
- after[i] = UNDEFINED;
- ntoaft = challoc(sizeof(*ntoaft) * nodenum);
- ntobef = challoc(sizeof(*ntobef) * nodenum);
- for (w = 0; w < nodenum; ++w)
- ntobef[w] = ntoaft[w] = UNDEFINED;
- befcount = 0;
- aftcount = 0;
- repsearch(v);
- }
-
-
- search(v)
- /* using depth first search, mark back edges using MKEDGE, and nodes entered by back
- edges using MARK */
- VERT v;
- {
- VERT adj; int i;
- status[v] = STACKED;
- for(i = 0; i < ARCNUM(v); ++i)
- {
- adj = ARC(v,i);
- if (!DEFINED(adj)) continue;
- else if (status[adj] == UNPROCESSED)
- search(adj);
- else if (status[adj] == STACKED)
- {
- MARK(adj); /* mark adj as entered by back edge */
- MKEDGE(ARC(v,i)); /* mark edge ARC(v,i) as being back edge */
- }
- }
- status[v] = FINISHED;
- ++accessnum;
- }
-
- chreach() /* look for unreachable nodes */
- {
- VERT v;
- LOGICAL unreach;
- unreach = FALSE;
- for (v = 0; v < nodenum; ++v)
- if (status[v] == UNPROCESSED && NTYPE(v) != FMTVX
- && NTYPE(v) != STOPVX && NTYPE(v) != RETVX)
- {
- unreach = TRUE;
- if (debug)
- fprintf(stderr,"node %d unreachable\n",v);
- }
- if (unreach)
- error(": unreachable statements - ","will be ignored","");
- }
-
-
- addloop() /* add LOOPVX, ITERVX at nodes entered by back edges, and adjust edges */
- {
- VERT v, adj;
- int j, oldnum;
- for (v = 0, oldnum = nodenum; v < oldnum; ++v) /* insloop increases nodenum */
- if (MARKED(v))
- {
- UNMARK(v); /* remove mark indicating v entered by back edge */
- if (NTYPE(v) != ITERVX) /* DO loops already have ITERVX */
- insloop(v); /* add LOOPVX, ITERVX since v entered by back edge*/
- }
- /* arcs which used to enter v now enter LOOPVX; must make back edges enter ITERVX */
- for (v = 0; v < nodenum; ++v)
- for (j = 0; j < ARCNUM(v); ++j)
- {
- if (BACKEDGE(ARC(v,j)))
- {
- UNMKEDGE(ARC(v,j)); /* return edge to normal value */
- adj = ARC(v,j);
- if (NTYPE(adj) == ITERVX) continue;
- ASSERT(NTYPE(adj) == LOOPVX,addloop);
- ARC(v,j) = ARC(adj,0); /* change arc to point to ITERVX */
- ASSERT(NTYPE(ARC(v,j)) == ITERVX,addloop);
- }
- }
- }
-
- insloop(v) /* insert LOOPVX, ITERVX at node number v */
- VERT v;
- {
- VERT loo, iter;
- loo = create(LOOPVX, 1);
- iter = create(ITERVX,1);
- accessnum += 2;
- /* want LOOPVX to take on node number v, so that arcs other than back arcs
- entering v will enter the LOOPVX automatically */
- exchange(&graph[v], &graph[loo]);
- exchange(&v, &loo);
- ARC(loo,0) = iter;
- ARC(iter,0) = v;
- FATH(iter) = UNDEFINED; /* will be defined later along with FATH for DOVX */
- }
-
- exchange(p1,p2) /* exchange values of p1,p2 */
- int *p1,*p2;
- {
- int temp;
- temp = *p1;
- *p1 = *p2;
- *p2 = temp;
- }
-
-
- repsearch(v) /* repeat df search in order to fill in after, ntoaft, ntobef tables */
- VERT v;
- {
- VERT adj; int i,temp;
- ntobef[v] = befcount;
- ++befcount;
- for(i = 0; i < ARCNUM(v); ++i)
- {
- adj = ARC(v,i);
- if (DEFINED(adj) && ntobef[adj] == UNDEFINED)
- repsearch(adj);
- }
- ++aftcount;
- temp = accessnum - aftcount;
- after[temp] = v;
- ntoaft[v] = temp;
- }
-