|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)2.dfs.c 4.1 (Berkeley) 2/11/83"; ! 3: #endif not lint ! 4: ! 5: #include <stdio.h> ! 6: # ! 7: /* depth-first search used to identify back edges, unreachable nodes; ! 8: each node v entered by back edge replaced by ! 9: LOOPVX ->ITERVX -> v, ! 10: so that back edges entering v now enter the ITERVX, ! 11: and other edges entering v now enter the LOOPVX. ! 12: Nodes are numbered according to depth-first search: ! 13: before numbering- ntobef[v] = i => node numbered v is i'th ! 14: node in order of first visit during the search; ! 15: after numbering- ntoaft[v] = i => node numbered v is i'th ! 16: node visited in order of last visit during the search. ! 17: Also, in this case after[i] = v. ! 18: */ ! 19: ! 20: #include "def.h" ! 21: #include "2.def.h" ! 22: ! 23: #define MAXINS 3 /* spacing needed between numbers generated during depth first search */ ! 24: ! 25: int *status; ! 26: int befcount, aftcount; ! 27: /* following defines used to mark back edges and nodes entered by back edges */ ! 28: #define UNPROCESSED 0 ! 29: #define STACKED 1 ! 30: #define FINISHED 2 ! 31: #define MARK(v) {REACH(v) = 1; } /* mark node v */ ! 32: #define UNMARK(v) {REACH(v) = 0; } ! 33: #define MARKED(v) (REACH(v)) ! 34: #define MKEDGE(e) {if (e >= -1) e = -(e+3); } /* mark edge e */ ! 35: #define UNMKEDGE(e) {if (e < -1) e = -(e+3); } ! 36: #define BACKEDGE(e) (e < -1) ! 37: ! 38: ! 39: dfs(v) /* depth first search */ ! 40: VERT v; ! 41: { ! 42: int i; VERT w; ! 43: accessnum = 0; ! 44: status = challoc(sizeof(*status) * nodenum); ! 45: for (w = 0; w < nodenum; ++w) ! 46: { ! 47: status[w] = UNPROCESSED; ! 48: UNMARK(w); ! 49: } ! 50: search(v); ! 51: chreach(); ! 52: chfree(status, sizeof(*status) * nodenum); ! 53: addloop(); ! 54: after = challoc(sizeof(*after) * accessnum); ! 55: for (i = 0; i < accessnum; ++i) ! 56: after[i] = UNDEFINED; ! 57: ntoaft = challoc(sizeof(*ntoaft) * nodenum); ! 58: ntobef = challoc(sizeof(*ntobef) * nodenum); ! 59: for (w = 0; w < nodenum; ++w) ! 60: ntobef[w] = ntoaft[w] = UNDEFINED; ! 61: befcount = 0; ! 62: aftcount = 0; ! 63: repsearch(v); ! 64: } ! 65: ! 66: ! 67: search(v) ! 68: /* using depth first search, mark back edges using MKEDGE, and nodes entered by back ! 69: edges using MARK */ ! 70: VERT v; ! 71: { ! 72: VERT adj; int i; ! 73: status[v] = STACKED; ! 74: for(i = 0; i < ARCNUM(v); ++i) ! 75: { ! 76: adj = ARC(v,i); ! 77: if (!DEFINED(adj)) continue; ! 78: else if (status[adj] == UNPROCESSED) ! 79: search(adj); ! 80: else if (status[adj] == STACKED) ! 81: { ! 82: MARK(adj); /* mark adj as entered by back edge */ ! 83: MKEDGE(ARC(v,i)); /* mark edge ARC(v,i) as being back edge */ ! 84: } ! 85: } ! 86: status[v] = FINISHED; ! 87: ++accessnum; ! 88: } ! 89: ! 90: chreach() /* look for unreachable nodes */ ! 91: { ! 92: VERT v; ! 93: LOGICAL unreach; ! 94: unreach = FALSE; ! 95: for (v = 0; v < nodenum; ++v) ! 96: if (status[v] == UNPROCESSED && NTYPE(v) != FMTVX ! 97: && NTYPE(v) != STOPVX && NTYPE(v) != RETVX) ! 98: { ! 99: unreach = TRUE; ! 100: if (debug) ! 101: fprintf(stderr,"node %d unreachable\n",v); ! 102: } ! 103: if (unreach) ! 104: error(": unreachable statements - ","will be ignored",""); ! 105: } ! 106: ! 107: ! 108: addloop() /* add LOOPVX, ITERVX at nodes entered by back edges, and adjust edges */ ! 109: { ! 110: VERT v, adj; ! 111: int j, oldnum; ! 112: for (v = 0, oldnum = nodenum; v < oldnum; ++v) /* insloop increases nodenum */ ! 113: if (MARKED(v)) ! 114: { ! 115: UNMARK(v); /* remove mark indicating v entered by back edge */ ! 116: if (NTYPE(v) != ITERVX) /* DO loops already have ITERVX */ ! 117: insloop(v); /* add LOOPVX, ITERVX since v entered by back edge*/ ! 118: } ! 119: /* arcs which used to enter v now enter LOOPVX; must make back edges enter ITERVX */ ! 120: for (v = 0; v < nodenum; ++v) ! 121: for (j = 0; j < ARCNUM(v); ++j) ! 122: { ! 123: if (BACKEDGE(ARC(v,j))) ! 124: { ! 125: UNMKEDGE(ARC(v,j)); /* return edge to normal value */ ! 126: adj = ARC(v,j); ! 127: if (NTYPE(adj) == ITERVX) continue; ! 128: ASSERT(NTYPE(adj) == LOOPVX,addloop); ! 129: ARC(v,j) = ARC(adj,0); /* change arc to point to ITERVX */ ! 130: ASSERT(NTYPE(ARC(v,j)) == ITERVX,addloop); ! 131: } ! 132: } ! 133: } ! 134: ! 135: insloop(v) /* insert LOOPVX, ITERVX at node number v */ ! 136: VERT v; ! 137: { ! 138: VERT loo, iter; ! 139: loo = create(LOOPVX, 1); ! 140: iter = create(ITERVX,1); ! 141: accessnum += 2; ! 142: /* want LOOPVX to take on node number v, so that arcs other than back arcs ! 143: entering v will enter the LOOPVX automatically */ ! 144: exchange(&graph[v], &graph[loo]); ! 145: exchange(&v, &loo); ! 146: ARC(loo,0) = iter; ! 147: ARC(iter,0) = v; ! 148: FATH(iter) = UNDEFINED; /* will be defined later along with FATH for DOVX */ ! 149: } ! 150: ! 151: exchange(p1,p2) /* exchange values of p1,p2 */ ! 152: int *p1,*p2; ! 153: { ! 154: int temp; ! 155: temp = *p1; ! 156: *p1 = *p2; ! 157: *p2 = temp; ! 158: } ! 159: ! 160: ! 161: repsearch(v) /* repeat df search in order to fill in after, ntoaft, ntobef tables */ ! 162: VERT v; ! 163: { ! 164: VERT adj; int i,temp; ! 165: ntobef[v] = befcount; ! 166: ++befcount; ! 167: for(i = 0; i < ARCNUM(v); ++i) ! 168: { ! 169: adj = ARC(v,i); ! 170: if (DEFINED(adj) && ntobef[adj] == UNDEFINED) ! 171: repsearch(adj); ! 172: } ! 173: ++aftcount; ! 174: temp = accessnum - aftcount; ! 175: after[temp] = v; ! 176: ntoaft[v] = temp; ! 177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.