From: erg Date: Tue, 30 Jun 2009 02:17:55 +0000 (+0000) Subject: Add pipelining mechanism to language X-Git-Tag: LAST_LIBGRAPH~32^2~1860 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae348ebd060959fa49367fcb9d8873a97ffbda55;p=graphviz Add pipelining mechanism to language --- diff --git a/lib/gvpr/compile.c b/lib/gvpr/compile.c index 1a8c6a7b5..6319dd9b4 100644 --- a/lib/gvpr/compile.c +++ b/lib/gvpr/compile.c @@ -2203,6 +2203,59 @@ static case_stmt *mkStmts(Expr_t * prog, char *src, case_info * sp, return cs; } +/* mkBlocks: + */ +static int mkBlock(comp_block* bp, Expr_t * prog, char *src, parse_block *inp, Sfio_t* tmps, int i) +{ + int rv = 0; + + codePhase = 1; + if (inp->begg_stmt) { + sfprintf(tmps, "_begin_g_%d", i); + symbols[0].type = T_graph; + tchk[V_this][1] = Y(G); + bp->begg_stmt = compile(prog, src, inp->begg_stmt, + inp->l_beging, sfstruse(tmps), 0, VOIDTYPE); + if (getErrorErrors()) + goto finishBlk; + rv |= BEGG; + } + + codePhase = 2; + if (inp->node_stmts) { + symbols[0].type = T_node; + tchk[V_this][1] = Y(V); + bp->n_nstmts = inp->n_nstmts; + bp->node_stmts = mkStmts(prog, src, inp->node_stmts, + inp->n_nstmts, "_nd", tmps); + if (getErrorErrors()) + goto finishBlk; + bp->walks |= WALKSG; + } + + codePhase = 3; + if (inp->edge_stmts) { + symbols[0].type = T_edge; + tchk[V_this][1] = Y(E); + bp->n_estmts = inp->n_estmts; + bp->edge_stmts = mkStmts(prog, src, inp->edge_stmts, + inp->n_estmts, "_eg", tmps); + if (getErrorErrors()) + goto finishBlk; + bp->walks |= WALKSG; + } + + finishBlk: + if (getErrorErrors()) { + free (bp->node_stmts); + free (bp->edge_stmts); + bp->node_stmts = 0; + bp->edge_stmts = 0; + } + + return (rv | bp->walks); +} + /* doFlags: * Convert command line flags to actions in END_G. */ @@ -2224,6 +2277,7 @@ comp_prog *compileProg(parse_prog * inp, Gpr_t * state, int flags) comp_prog *p; Sfio_t *tmps = state->tmp; char *endg_sfx = 0; + int i, useflags = 0; /* Make sure we have enough bits for types */ assert(BITS_PER_BYTE * sizeof(tctype) >= (1 << TBITS)); @@ -2256,37 +2310,23 @@ comp_prog *compileProg(parse_prog * inp, Gpr_t * state, int flags) goto finish; } - codePhase = 1; - if (inp->begg_stmt) { - symbols[0].type = T_graph; - tchk[V_this][1] = Y(G); - p->begg_stmt = compile(p->prog, inp->source, inp->begg_stmt, - inp->l_beging, "_begin_g", 0, VOIDTYPE); - if (getErrorErrors()) - goto finish; - } + if (inp->blocks) { + comp_block* bp; + parse_block* ibp = inp->blocks; - codePhase = 2; - if (inp->node_stmts) { - symbols[0].type = T_node; - tchk[V_this][1] = Y(V); - p->n_nstmts = inp->n_nstmts; - p->node_stmts = mkStmts(p->prog, inp->source, inp->node_stmts, - inp->n_nstmts, "_nd", tmps); - if (getErrorErrors()) - goto finish; - } + p->blocks = bp = newof(0, comp_block, inp->n_blocks, 0); - codePhase = 3; - if (inp->edge_stmts) { - symbols[0].type = T_edge; - tchk[V_this][1] = Y(E); - p->n_estmts = inp->n_estmts; - p->edge_stmts = mkStmts(p->prog, inp->source, inp->edge_stmts, - inp->n_estmts, "_eg", tmps); - if (getErrorErrors()) - goto finish; + for (i = 0; i < inp->n_blocks; bp++, i++) { + useflags |= mkBlock (bp, p->prog, inp->source, ibp, tmps, i); + if (getErrorErrors()) + goto finish; + else { + ibp = ibp->next; + p->n_blocks++; + } + } } + p->flags = useflags; codePhase = 4; if (inp->endg_stmt || endg_sfx) { @@ -2308,6 +2348,9 @@ comp_prog *compileProg(parse_prog * inp, Gpr_t * state, int flags) } setErrorLine (0); /* execution errors have no line numbers */ + if (p->end_stmt) + p->flags |= ENDG; + finish: if (getErrorErrors()) { freeCompileProg (p); @@ -2320,20 +2363,27 @@ comp_prog *compileProg(parse_prog * inp, Gpr_t * state, int flags) void freeCompileProg (comp_prog *p) { + comp_block* bp; + int i; + if (!p) return; exclose (p->prog, 1); - free (p->node_stmts); - free (p->edge_stmts); + for (i = 0; i < p->n_blocks; i++) { + bp = p->blocks + i; + free (bp->node_stmts); + free (bp->edge_stmts); + } + free (p->blocks); free (p); } /* walksGraph; - * Returns true if program actually has node or edge statements. + * Returns true if block actually has node or edge statements. */ -int walksGraph(comp_prog * p) +int walksGraph(comp_block * p) { - return (p->n_nstmts || p->n_estmts); + return (p->walks); } /* usesGraph; @@ -2342,7 +2392,7 @@ int walksGraph(comp_prog * p) */ int usesGraph(comp_prog * p) { - return (walksGraph(p) || p->begg_stmt || p->endg_stmt); + return (p->flags); } void ptchk(void) diff --git a/lib/gvpr/compile.h b/lib/gvpr/compile.h index 588d73ae0..5c2e7e372 100644 --- a/lib/gvpr/compile.h +++ b/lib/gvpr/compile.h @@ -64,14 +64,25 @@ extern "C" { #define INDUCE 0x2 #define CLONE 0x4 +#define WALKSG 0x1 +#define BEGG 0x2 +#define ENDG 0x4 + typedef struct { - Expr_t *prog; - Exnode_t *begin_stmt; Exnode_t *begg_stmt; + int walks; int n_nstmts; int n_estmts; case_stmt *node_stmts; case_stmt *edge_stmts; + } comp_block; + + typedef struct { + int flags; + Expr_t *prog; + Exnode_t *begin_stmt; + int n_blocks; + comp_block *blocks; Exnode_t *endg_stmt; Exnode_t *end_stmt; } comp_prog; @@ -79,7 +90,7 @@ extern "C" { extern comp_prog *compileProg(parse_prog *, Gpr_t *, int); extern void freeCompileProg (comp_prog *p); extern int usesGraph(comp_prog *); - extern int walksGraph(comp_prog *); + extern int walksGraph(comp_block *); extern Agraph_t *readG(Sfio_t * fp); extern Agraph_t *openG(char *name, Agdesc_t); extern Agraph_t *openSubg(Agraph_t * g, char *name); diff --git a/lib/gvpr/gvpr.c b/lib/gvpr/gvpr.c index 497ea9018..620117201 100644 --- a/lib/gvpr/gvpr.c +++ b/lib/gvpr/gvpr.c @@ -419,7 +419,7 @@ static options* scanArgs(int argc, char **argv, gvpropts* uopts) return opts; } -static void evalEdge(Gpr_t * state, comp_prog * xprog, Agedge_t * e) +static void evalEdge(Gpr_t * state, Expr_t* prog, comp_block * xprog, Agedge_t * e) { int i; case_stmt *cs; @@ -429,19 +429,19 @@ static void evalEdge(Gpr_t * state, comp_prog * xprog, Agedge_t * e) for (i = 0; i < xprog->n_estmts; i++) { cs = xprog->edge_stmts + i; if (cs->guard) - okay = (exeval(xprog->prog, cs->guard, state)).integer; + okay = (exeval(prog, cs->guard, state)).integer; else okay = 1; if (okay) { if (cs->action) - exeval(xprog->prog, cs->action, state); + exeval(prog, cs->action, state); else agsubedge(state->target, e, TRUE); } } } -static void evalNode(Gpr_t * state, comp_prog * xprog, Agnode_t * n) +static void evalNode(Gpr_t * state, Expr_t* prog, comp_block * xprog, Agnode_t * n) { int i; case_stmt *cs; @@ -451,12 +451,12 @@ static void evalNode(Gpr_t * state, comp_prog * xprog, Agnode_t * n) for (i = 0; i < xprog->n_nstmts; i++) { cs = xprog->node_stmts + i; if (cs->guard) - okay = (exeval(xprog->prog, cs->guard, state)).integer; + okay = (exeval(prog, cs->guard, state)).integer; else okay = 1; if (okay) { if (cs->action) - exeval(xprog->prog, cs->action, state); + exeval(prog, cs->action, state); else agsubnode(state->target, n, TRUE); } @@ -505,7 +505,7 @@ static trav_fns DFSfns = { agfstedge, agnxtedge, 1, 0 }; static trav_fns FWDfns = { agfstout, (nxttedgefn_t) agnxtout, 0, 0 }; static trav_fns REVfns = { agfstin, (nxttedgefn_t) agnxtin, 0, 0 }; -static void travBFS(Gpr_t * state, comp_prog * xprog) +static void travBFS(Gpr_t * state, Expr_t* prog, comp_block * xprog) { nodestream nodes; queue *q; @@ -527,13 +527,13 @@ static void travBFS(Gpr_t * state, comp_prog * xprog) nd = nData(n); MARK(nd); POP(nd); - evalNode(state, xprog, n); + evalNode(state, prog, xprog, n); for (cure = agfstedge(g, n); cure; cure = agnxtedge(g, cure, n)) { nd = nData(cure->node); if (MARKED(nd)) continue; - evalEdge(state, xprog, cure); + evalEdge(state, prog, xprog, cure); if (!ONSTACK(nd)) { push(q, cure->node); PUSH(nd); @@ -544,7 +544,7 @@ static void travBFS(Gpr_t * state, comp_prog * xprog) freeQ(q); } -static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns) +static void travDFS(Gpr_t * state, Expr_t* prog, comp_block * xprog, trav_fns * fns) { Agnode_t *n; queue *stk; @@ -571,7 +571,7 @@ static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns) MARK(nd); PUSH(nd); if (fns->visit & PRE_VISIT) - evalNode(state, xprog, n); + evalNode(state, prog, xprog, n); more = 1; while (more) { if (cure) @@ -589,23 +589,23 @@ static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns) */ if (fns->undirected) { if (ONSTACK(nd)) - evalEdge(state, xprog, cure); + evalEdge(state, prog, xprog, cure); } else - evalEdge(state, xprog, cure); + evalEdge(state, prog, xprog, cure); } else { - evalEdge(state, xprog, cure); + evalEdge(state, prog, xprog, cure); push(stk, entry); entry = cure; curn = cure->node; cure = 0; if (fns->visit & PRE_VISIT) - evalNode(state, xprog, curn); + evalNode(state, prog, xprog, curn); MARK(nd); PUSH(nd); } } else { if (fns->visit & POST_VISIT) - evalNode(state, xprog, curn); + evalNode(state, prog, xprog, curn); nd = nData(curn); POP(nd); cure = entry; @@ -620,37 +620,37 @@ static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns) freeQ(stk); } -static void travNodes(Gpr_t * state, comp_prog * xprog) +static void travNodes(Gpr_t * state, Expr_t* prog, comp_block * xprog) { Agnode_t *n; Agraph_t *g = state->curgraph; for (n = agfstnode(g); n; n = agnxtnode(g, n)) { - evalNode(state, xprog, n); + evalNode(state, prog, xprog, n); } } -static void travEdges(Gpr_t * state, comp_prog * xprog) +static void travEdges(Gpr_t * state, Expr_t* prog, comp_block * xprog) { Agnode_t *n; Agedge_t *e; Agraph_t *g = state->curgraph; for (n = agfstnode(g); n; n = agnxtnode(g, n)) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { - evalEdge(state, xprog, e); + evalEdge(state, prog, xprog, e); } } } -static void travFlat(Gpr_t * state, comp_prog * xprog) +static void travFlat(Gpr_t * state, Expr_t* prog, comp_block * xprog) { Agnode_t *n; Agedge_t *e; Agraph_t *g = state->curgraph; for (n = agfstnode(g); n; n = agnxtnode(g, n)) { - evalNode(state, xprog, n); + evalNode(state, prog, xprog, n); if (xprog->n_estmts > 0) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { - evalEdge(state, xprog, e); + evalEdge(state, prog, xprog, e); } } } @@ -658,70 +658,72 @@ static void travFlat(Gpr_t * state, comp_prog * xprog) /* traverse: */ -static void traverse(Gpr_t * state, comp_prog * xprog) +static void traverse(Gpr_t * state, Expr_t* prog, comp_block * bp) { char *target; - if (state->name_used) { - sfprintf(state->tmp, "%s%d", state->tgtname, state->name_used); - target = sfstruse(state->tmp); - } else - target = state->tgtname; - state->name_used++; - state->target = openSubg(state->curgraph, target); + if (!state->target) { + if (state->name_used) { + sfprintf(state->tmp, "%s%d", state->tgtname, state->name_used); + target = sfstruse(state->tmp); + } else + target = state->tgtname; + state->name_used++; + state->target = openSubg(state->curgraph, target); + } if (!state->outgraph) state->outgraph = state->target; switch (state->tvt) { case TV_flat: - travFlat(state, xprog); + travFlat(state, prog, bp); break; case TV_bfs: - travBFS(state, xprog); + travBFS(state, prog, bp); break; case TV_dfs: DFSfns.visit = PRE_VISIT; - travDFS(state, xprog, &DFSfns); + travDFS(state, prog, bp, &DFSfns); break; case TV_fwd: FWDfns.visit = PRE_VISIT; - travDFS(state, xprog, &FWDfns); + travDFS(state, prog, bp, &FWDfns); break; case TV_rev: REVfns.visit = PRE_VISIT; - travDFS(state, xprog, &REVfns); + travDFS(state, prog, bp, &REVfns); break; case TV_postdfs: DFSfns.visit = POST_VISIT; - travDFS(state, xprog, &DFSfns); + travDFS(state, prog, bp, &DFSfns); break; case TV_postfwd: FWDfns.visit = POST_VISIT; - travDFS(state, xprog, &FWDfns); + travDFS(state, prog, bp, &FWDfns); break; case TV_postrev: REVfns.visit = POST_VISIT | PRE_VISIT; - travDFS(state, xprog, &REVfns); + travDFS(state, prog, bp, &REVfns); break; case TV_prepostdfs: DFSfns.visit = POST_VISIT | PRE_VISIT; - travDFS(state, xprog, &DFSfns); + travDFS(state, prog, bp, &DFSfns); break; case TV_prepostfwd: FWDfns.visit = POST_VISIT | PRE_VISIT; - travDFS(state, xprog, &FWDfns); + travDFS(state, prog, bp, &FWDfns); break; case TV_prepostrev: REVfns.visit = POST_VISIT; - travDFS(state, xprog, &REVfns); + travDFS(state, prog, bp, &REVfns); break; case TV_ne: - travNodes(state, xprog); - travEdges(state, xprog); + travNodes(state, prog, bp); + travEdges(state, prog, bp); break; case TV_en: - travEdges(state, xprog); - travNodes(state, xprog); + travEdges(state, prog, bp); + travNodes(state, prog, bp); break; } } @@ -833,7 +835,7 @@ int gvpr (int argc, char *argv[], gvpropts * uopts) gpr_info info; int rv = 0; options* opts = 0; - int incoreGraphs; + int i, incoreGraphs; setErrorErrors (0); ingDisc.dflt = sfstdin; @@ -909,17 +911,21 @@ int gvpr (int argc, char *argv[], gvpropts * uopts) while ((state->curgraph = nextGraph(ing))) { state->infname = fileName(ing); - /* begin graph */ - if (incoreGraphs && (opts->compflags & CLONE)) - state->curgraph = clone (0, (Agobj_t*)(state->curgraph)); - state->curobj = (Agobj_t *) state->curgraph; - state->tvroot = 0; - if (xprog->begg_stmt) - exeval(xprog->prog, xprog->begg_stmt, state); + for (i = 0; i < xprog->n_blocks; i++) { + comp_block* bp = xprog->blocks + i; - /* walk graph */ - if (walksGraph(xprog)) - traverse(state, xprog); + /* begin graph */ + if (incoreGraphs && (opts->compflags & CLONE)) + state->curgraph = (Agraph_t*)clone (0, (Agobj_t*)(state->curgraph)); + state->curobj = (Agobj_t *) state->curgraph; + state->tvroot = 0; + if (bp->begg_stmt) + exeval(xprog->prog, bp->begg_stmt, state); + + /* walk graph */ + if (walksGraph(bp)) + traverse(state, xprog->prog, bp); + } /* end graph */ state->curobj = (Agobj_t *) state->curgraph; diff --git a/lib/gvpr/parse.c b/lib/gvpr/parse.c index 5628a0176..98a2a010d 100644 --- a/lib/gvpr/parse.c +++ b/lib/gvpr/parse.c @@ -395,6 +395,27 @@ parseCase(Sfio_t * str, char **guard, int *gline, char **action, return kind; } +/* addBlock: + * create new block and append to list; + * return new item as tail + */ +static parse_block *addBlock (parse_block * last, char *stmt, int line, + int n_nstmts, case_info *nodelist, int n_estmts, case_info *edgelist) +{ + parse_block* item = newof(0, parse_block, 1, 0); + + item->l_beging = line; + item->begg_stmt = stmt; + item->n_nstmts = n_nstmts; + item->n_estmts = n_estmts; + item->node_stmts = nodelist; + item->edge_stmts = edgelist; + if (last) + last->next = item; + + return item; +} + /* addCase: * create new case_info and append to list; * return new item as tail @@ -456,13 +477,18 @@ parse_prog *parseProg(char *input, int isFile) char *guard = NULL; char *action = NULL; int more; + parse_block *blocklist = 0; case_info *edgelist = 0; case_info *nodelist = 0; + parse_block *blockl = 0; case_info *edgel = 0; case_info *nodel = 0; + int n_blocks = 0; int n_nstmts = 0; int n_estmts = 0; int line = 0, gline = 0; + int l_beging; + char *begg_stmt; prog = newof(0, parse_prog, 1, 0); if (!prog) { @@ -487,7 +513,8 @@ parse_prog *parseProg(char *input, int isFile) free (prog); return 0; } - + + begg_stmt = 0; more = 1; while (more) { switch (parseCase(str, &guard, &gline, &action, &line)) { @@ -496,8 +523,19 @@ parse_prog *parseProg(char *input, int isFile) &(prog->l_begin)); break; case BeginG: - bindAction(BeginG, action, line, &(prog->begg_stmt), - &(prog->l_beging)); + if (action && (begg_stmt || nodelist || edgelist)) { /* non-empty block */ + blockl = addBlock(blockl, begg_stmt, l_beging, + n_nstmts, nodelist, n_estmts, edgelist); + if (!blocklist) + blocklist = blockl; + n_blocks++; + + /* reset values */ + n_nstmts = n_estmts = 0; + edgel = nodel = edgelist = nodelist = 0; + begg_stmt = 0; + } + bindAction(BeginG, action, line, &begg_stmt, &l_beging); break; case End: bindAction(End, action, line, &(prog->end_stmt), @@ -526,10 +564,16 @@ parse_prog *parseProg(char *input, int isFile) } } - prog->node_stmts = nodelist; - prog->edge_stmts = edgelist; - prog->n_nstmts = n_nstmts; - prog->n_estmts = n_estmts; + if (begg_stmt || nodelist || edgelist) { /* non-empty block */ + blockl = addBlock(blockl, begg_stmt, l_beging, + n_nstmts, nodelist, n_estmts, edgelist); + if (!blocklist) + blocklist = blockl; + n_blocks++; + } + + prog->n_blocks = n_blocks; + prog->blocks = blocklist; sfclose(str); @@ -554,14 +598,25 @@ freeCaseList (case_info* ip) } } +static void +freeBlocks (parse_block* ip) +{ + parse_block* nxt; + while (ip) { + nxt = ip->next; + free (ip->begg_stmt); + freeCaseList (ip->node_stmts); + freeCaseList (ip->edge_stmts); + ip = nxt; + } +} + void freeParseProg (parse_prog * prog) { if (!prog) return; free (prog->begin_stmt); - free (prog->begg_stmt); - freeCaseList (prog->node_stmts); - freeCaseList (prog->edge_stmts); + freeBlocks (prog->blocks); free (prog->endg_stmt); free (prog->end_stmt); free (prog); diff --git a/lib/gvpr/parse.h b/lib/gvpr/parse.h index da348726d..199b45d8a 100644 --- a/lib/gvpr/parse.h +++ b/lib/gvpr/parse.h @@ -32,20 +32,26 @@ extern "C" { struct _case_info *next; } case_info; - typedef struct { - char *source; - int l_begin, l_beging, l_end, l_endg; - char *begin_stmt; + typedef struct _parse_block { + int l_beging; char *begg_stmt; int n_nstmts; int n_estmts; case_info *node_stmts; case_info *edge_stmts; + struct _parse_block *next; + } parse_block; + + typedef struct { + char *source; + int l_begin, l_end, l_endg; + char *begin_stmt; + int n_blocks; + parse_block *blocks; char *endg_stmt; char *end_stmt; } parse_prog; - extern parse_prog *parseProg(char *, int); extern void freeParseProg (parse_prog *);