source: vis_dev/vl2mv-2.3/src/parser/vl_flowgraph.c

Last change on this file was 18, checked in by cecile, 13 years ago

vl2mv added

File size: 49.9 KB
Line 
1/*
2
3  Copyright (c) 1992, 1993
4        Regents of the University of California
5  All rights reserved.
6
7  Use and copying of this software and preparation of derivative works
8  based upon this software are permitted.  However, any distribution of
9  this software or derivative works must include the above copyright
10  notice.
11
12  This software is made available AS IS, and neither the Electronics
13  Research Laboratory or the Universify of California make any
14  warranty about the software, its performance or its conformity to
15  any specification.
16
17  Author: Szu-Tsung Cheng, stcheng@ic.Berkeley.EDU
18          10/92
19          10/93
20
21  $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/vl_flowgraph.c,v 1.2 2009/03/09 20:25:58 fabio Exp $
22
23
24*/
25
26#include "util.h"
27#include "st.h"
28#include "list.h"
29#include "array.h"
30#include "set.h"
31#include "stack.h"
32#include "graph.h"
33#include "vl_defs.h"
34#include "vl_types.h"
35#include "vlr_int.h"
36#include "vl_fg_defs.h"
37#include "vl_fg_types.h"
38#include "vl_flowgraph.h"
39#include "vl_create.h"
40#include "vl_write.h"
41#include "vl_write_util.h"
42#include "vl_edgedetector.h"
43#include "verilog.h"
44
45#define IABS(x) (((x)>=0)?(x):(-(x)))
46
47extern double vl_expr_aux1_val, vl_expr_aux2_val, vl_expr_aux3_val;
48extern int vl_expr_aux1_flag, vl_expr_aux2_flag, vl_expr_aux3_flag;
49extern graph_t *vl_writeFlowGraph;
50extern int encodeTimer;
51extern int vl_preDeclare;
52extern int vl_noTimers;
53
54int RQautomata=1;
55
56static graph_t *vl_currentFlowGraph=NIL(graph_t);
57static graph_t *vl_currentCMPFlowGraph=NIL(graph_t);
58static graph_t *workingFlowGraph=NIL(graph_t);
59static vertex_t *fg_Srce, *fg_Sink;
60static vertex_t *fg_CMPSrce, *fg_CMPSink;
61static int pause_counter=1;
62static FILE *fg_out_file = NIL(FILE);
63
64
65static char *new_pausename()
66{
67    static char retval[MAXSTRLEN];
68
69    sprintf(retval, "%s%d%s", FG_LLOC, pause_counter++, FG_RLOC);
70    return retval;
71}
72
73
74
75graph_t *fg_new_graph()
76{
77
78    vl_currentFlowGraph = g_alloc();
79    vl_currentCMPFlowGraph = g_alloc();
80
81    vl_currentFlowGraph->user_data = (char*)fg_new_graph_info();
82
83    return vl_currentFlowGraph;
84}
85
86
87
88void fg_clean_fg()
89{
90    if (vl_currentFlowGraph->user_data) {
91        ((fg_graph_info*)vl_currentFlowGraph->user_data)->pause_hi =
92            pause_counter;
93    }
94    vl_currentCMPFlowGraph = vl_currentFlowGraph = NIL(graph_t);
95}
96
97
98
99int fg_not_empty()
100{
101    return (vl_currentFlowGraph != NIL(graph_t));
102}
103
104
105
106void fg_set_fg(graph_t *graph)
107{
108      workingFlowGraph = graph;
109}
110
111
112
113void fg_record_SrcSink(vertex_t **src, vertex_t **sink,
114                       vertex_t **cmp_src, vertex_t **cmp_sink)
115{
116    *src = fg_Srce;
117    *sink = fg_Sink;
118    *cmp_src = fg_CMPSrce;
119    *cmp_sink = fg_CMPSink;
120}
121
122
123
124void fg_restore_SrcSink(vertex_t *src, vertex_t *sink,
125                        vertex_t *cmp_src, vertex_t *cmp_sink)
126{
127    fg_Srce = src;
128    fg_Sink = sink;
129    fg_CMPSrce = cmp_src;
130    fg_CMPSink = cmp_sink;
131}
132
133
134
135edge_t *fg_new_always_block()
136{
137    edge_t *retval;
138
139    fg_Srce = g_add_vertex(vl_currentFlowGraph);
140    fg_Sink = g_add_vertex(vl_currentFlowGraph);
141    fg_Srce->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
142    fg_Sink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
143    retval = g_add_edge(fg_Sink, fg_Srce);
144    ((fg_graph_info*)vl_currentFlowGraph->user_data)->init_node = fg_Srce;
145
146    fg_CMPSrce = g_add_vertex(vl_currentCMPFlowGraph);
147    fg_CMPSink = g_add_vertex(vl_currentCMPFlowGraph);
148    fg_CMPSrce->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
149    fg_CMPSink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
150    g_add_edge(fg_CMPSink, fg_CMPSrce);
151
152    return retval;
153}
154
155
156
157void fg_new_seq_block()
158{
159    fg_Srce = g_add_vertex(vl_currentFlowGraph);
160    fg_Sink = g_add_vertex(vl_currentFlowGraph);
161    fg_Srce->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
162    fg_Sink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
163
164    fg_CMPSrce = g_add_vertex(vl_currentCMPFlowGraph);
165    fg_CMPSink = g_add_vertex(vl_currentCMPFlowGraph);
166    fg_CMPSrce->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
167    fg_CMPSink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
168}
169
170
171
172vertex_t *fg_new_loop_block(vertex_t **old_srce,
173                            vertex_t **old_sink,
174                            vertex_t **new_src,
175                            vertex_t **new_sink,
176                            vertex_t **old_cmpsrc,
177                            vertex_t **old_cmpsink,
178                            vertex_t **new_cmpsrc,
179                            vertex_t **new_cmpsink)
180{
181    vertex_t *retval;
182
183    *old_srce = fg_Srce;
184    *old_sink = fg_Sink;
185    fg_Srce = g_add_vertex(vl_currentFlowGraph);
186    fg_Sink = g_add_vertex(vl_currentFlowGraph);
187    fg_Srce->user_data = (char*)fg_new_node_info(FG_ND_FORBRANCH);
188    fg_Sink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
189    g_add_edge(*old_srce, fg_Srce);
190
191    retval = fg_Srce;
192    *new_src = fg_Srce;
193    *new_sink = fg_Sink;
194
195    *old_cmpsrc  = fg_CMPSrce;
196    *old_cmpsink = fg_CMPSink;
197    fg_CMPSrce = g_add_vertex(vl_currentCMPFlowGraph);
198    fg_CMPSink = g_add_vertex(vl_currentCMPFlowGraph);
199    fg_CMPSrce->user_data = (char*)fg_new_node_info(FG_ND_FORBRANCH);
200    fg_CMPSink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
201    g_add_edge(*old_cmpsrc, fg_CMPSrce);
202
203    *new_cmpsrc = fg_CMPSrce;
204    *new_cmpsink = fg_CMPSink;
205
206    return retval;
207}
208
209
210
211vertex_t *fg_new_ifelse_block(old_srce, old_sink, new_src, new_sink,
212                              old_cmpsrc, old_cmpsink, new_cmpsrc, new_cmpsink)
213vertex_t **old_srce;
214vertex_t **old_sink;
215vertex_t **new_src;
216vertex_t **new_sink;
217vertex_t **old_cmpsrc;
218vertex_t **old_cmpsink;
219vertex_t **new_cmpsrc;
220vertex_t **new_cmpsink;
221{
222    vertex_t *retval;
223
224    *old_srce = fg_Srce;
225    *old_sink = fg_Sink;
226    fg_Srce = g_add_vertex(vl_currentFlowGraph);
227    fg_Sink = g_add_vertex(vl_currentFlowGraph);
228    fg_Srce->user_data = (char*)fg_new_node_info(FG_ND_IFBRANCH);
229    fg_Sink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
230    g_add_edge(*old_srce, fg_Srce);
231
232    retval = fg_Srce;
233    *new_src = fg_Srce;
234    *new_sink = fg_Sink;
235
236    *old_cmpsrc  = fg_CMPSrce;
237    *old_cmpsink = fg_CMPSink;
238    fg_CMPSrce = g_add_vertex(vl_currentCMPFlowGraph);
239    fg_CMPSink = g_add_vertex(vl_currentCMPFlowGraph);
240    fg_CMPSrce->user_data = (char*)fg_new_node_info(FG_ND_IFBRANCH);
241    fg_CMPSink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
242    g_add_edge(*old_cmpsrc, fg_CMPSrce);
243
244    *new_cmpsrc = fg_CMPSrce;
245    *new_cmpsink = fg_CMPSink;
246
247    return retval;
248}
249
250
251
252vertex_t *fg_new_case_block(old_srce, old_sink, new_src, new_sink,
253                            old_CMPsrce, old_CMPsink, new_CMPsrc, new_CMPsink)
254vertex_t **old_srce;
255vertex_t **old_sink;
256vertex_t **new_src;
257vertex_t **new_sink;
258vertex_t **old_CMPsrce;
259vertex_t **old_CMPsink;
260vertex_t **new_CMPsrc;
261vertex_t **new_CMPsink;
262{
263    vertex_t *retval;
264
265    *old_srce = fg_Srce;
266    *old_sink = fg_Sink;
267    fg_Srce = g_add_vertex(vl_currentFlowGraph);
268    fg_Sink = g_add_vertex(vl_currentFlowGraph);
269    fg_Srce->user_data = (char*)fg_new_node_info(FG_ND_CASEBRANCH);
270    fg_Sink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
271    g_add_edge(*old_srce, fg_Srce);
272
273    retval = fg_Srce;
274    *new_src = fg_Srce;
275    *new_sink = fg_Sink;
276
277    *old_CMPsrce = fg_CMPSrce;
278    *old_CMPsink = fg_CMPSink;
279    fg_CMPSrce = g_add_vertex(vl_currentCMPFlowGraph);
280    fg_CMPSink = g_add_vertex(vl_currentCMPFlowGraph);
281    fg_CMPSrce->user_data = (char*)fg_new_node_info(FG_ND_CASEBRANCH);
282    fg_CMPSink->user_data = (char*)fg_new_node_info(FG_ND_DUMMY);
283    g_add_edge(*old_CMPsrce, fg_CMPSrce);
284
285    *new_CMPsrc = fg_CMPSrce;
286    *new_CMPsink = fg_CMPSink;
287
288    return retval;
289}
290
291
292
293edge_t *fg_new_case_tag_block(cur_srce, cur_sink, cur_CMPsrce, cur_CMPsink)
294vertex_t *cur_srce;
295vertex_t *cur_sink;
296vertex_t *cur_CMPsrce;
297vertex_t *cur_CMPsink;
298{
299    edge_t *new_edge;
300
301    fg_Srce = g_add_vertex(vl_currentFlowGraph);
302    fg_Srce->user_data = (char*)fg_new_node_info(FG_ND_CASETAG);
303    new_edge = g_add_edge(cur_srce, fg_Srce);
304    new_edge->user_data = (char*)fg_new_arc_info(FG_ARC_CASETAG);
305
306    fg_CMPSrce = g_add_vertex(vl_currentCMPFlowGraph);
307    fg_CMPSrce->user_data = (char*)fg_new_node_info(FG_ND_CASETAG);
308    g_add_edge(cur_CMPsrce, fg_CMPSrce);
309
310    return new_edge;
311}
312
313
314
315vertex_t *fg_new_pause_node()
316{
317    vertex_t *retval, *new_vtx;
318
319    retval = g_add_vertex(vl_currentFlowGraph);
320    retval->user_data = (char*)fg_new_node_info(FG_ND_PAUSE);
321    ((fg_node_info*)retval->user_data)->loc = vlStrdup(new_pausename());
322    g_add_edge(fg_Srce, retval);
323    fg_Srce = retval;
324    lsNewEnd(((fg_graph_info*)vl_currentFlowGraph->user_data)->pause_list,
325             (lsGeneric)retval, 0);
326
327    new_vtx = g_add_vertex(vl_currentCMPFlowGraph);
328    new_vtx->user_data = retval->user_data;
329    g_add_edge(fg_CMPSrce, new_vtx);
330    fg_CMPSrce = new_vtx;
331
332    return retval;
333}
334
335
336
337vertex_t *fg_new_assign_node()
338{
339    vertex_t *retval;
340
341    retval = g_add_vertex(vl_currentCMPFlowGraph);
342    retval->user_data = (char*)fg_new_node_info(FG_ND_ASSIGN);
343    g_add_edge(fg_CMPSrce, retval);
344    fg_CMPSrce = retval;
345
346    return retval;
347}
348
349
350
351int fg_reduce_simple_branches_back_block(
352  vertex_t *old_src,
353  vertex_t *old_sink,
354  vertex_t *old_CMPsrc,
355  vertex_t *old_CMPsink
356)
357{
358    lsList out_edges;
359    lsGen gen;
360    lsHandle handle;
361    edge_t *edge;
362    int contain_pause;
363
364    out_edges = g_get_out_edges(fg_Srce);
365    for (gen=lsStart(out_edges), contain_pause=0;
366         lsNext(gen, (lsGeneric*)&edge, &handle) != LS_NOMORE; ) {
367        if (((fg_node_info*)(fg_Srce->user_data))->type != FG_ND_CASEBRANCH) {
368
369            if (g_e_dest(edge) != fg_Sink)
370                contain_pause = 1;
371        } else {
372
373            vertex_t *dest;
374            lsList inner_edges;
375            lsGen inner_gen;
376            lsHandle inner_handle;
377            edge_t *inner_edge;
378
379            dest = g_e_dest(edge);
380            inner_edges = g_get_out_edges(dest);
381            for (inner_gen=lsStart(inner_edges);
382                 lsNext(inner_gen, (lsGeneric*)&inner_edge, &inner_handle) !=
383                     LS_NOMORE; ) {
384                if (g_e_dest(inner_edge) != fg_Sink) contain_pause = 1;
385            }
386            lsFinish(inner_gen);
387        }
388    }
389    lsFinish(gen);
390
391    if (contain_pause) {
392        fg_Srce = fg_Sink;
393        fg_Sink = old_sink;
394    } else {
395
396        if (((fg_node_info*)(fg_Srce->user_data))->type == FG_ND_CASEBRANCH) {
397            out_edges = g_get_out_edges(fg_Srce);
398            for (gen=lsStart(out_edges);
399                 lsNext(gen, (lsGeneric*)&edge, &handle) != LS_NOMORE; ) {
400                vertex_t *dest;
401                dest = g_e_dest(edge);
402                g_delete_vertex(dest,
403                                fg_clean_vertex_data,
404                                fg_clean_edge_data);
405            }
406            lsFinish(gen);
407        }
408
409        g_delete_vertex(fg_Srce, fg_clean_vertex_data, fg_clean_edge_data);
410        g_delete_vertex(fg_Sink, fg_clean_vertex_data, fg_clean_edge_data);
411        fg_Srce = old_src;
412        fg_Sink = old_sink;
413    }
414
415    fg_CMPSrce = fg_CMPSink;
416    fg_CMPSink = old_CMPsink;
417
418    return contain_pause;
419}
420
421
422
423fg_graph_info *fg_new_graph_info()
424{
425    fg_graph_info *retval;
426
427    retval = (fg_graph_info*)chk_malloc(sizeof(fg_graph_info));
428    retval->type = 0;
429    retval->fg_id = -1;
430    retval->init_node = NIL(vertex_t);
431    retval->pause_lo = retval->pause_hi = pause_counter;
432    retval->pause_list = lsCreate();
433
434    return retval;
435}
436
437
438
439fg_node_info *fg_new_node_info(type)
440int type;
441{
442    fg_node_info *retval;
443
444    retval = (fg_node_info*)chk_malloc(sizeof(fg_node_info));
445    retval->type = type;
446    retval->data = NIL(char);
447    retval->loc  = NIL(char);
448    retval->SRFSMnode = NIL(ctrlNetNode);
449
450    return retval;
451}
452
453
454
455fg_arc_info *fg_new_arc_info(type)
456int type;
457{
458    fg_arc_info *retval;
459
460    retval = (fg_arc_info*)chk_malloc(sizeof(fg_arc_info));
461    retval->type = type;
462    retval->data = NIL(char);
463
464    return retval;
465}
466
467
468
469edge_t *fg_force_edge(src, sink, CMPsrc, CMPsink)
470vertex_t *src;
471vertex_t *sink;
472vertex_t *CMPsrc;
473vertex_t *CMPsink;
474{
475    edge_t *retval;
476
477    retval = g_add_edge(src, sink);
478    g_add_edge(CMPsrc, CMPsink);
479
480    return retval;
481}
482
483
484
485edge_t *fg_closeloop()
486{
487    edge_t *retval;
488
489    if (fg_Srce == NIL(vertex_t) && fg_Sink == NIL(vertex_t))
490        return NIL(edge_t);
491
492    retval = g_add_edge(fg_Srce, fg_Sink);
493
494    g_add_edge(fg_CMPSrce, fg_CMPSink);
495
496    return retval;
497}
498
499
500
501vertex_t *fg_pseudo_sink()
502{
503    vertex_t *retval;
504    vertex_t *pseudo_sink, *pseudo_CMPsink;
505
506    if (fg_Srce == NIL(vertex_t) && fg_Sink == NIL(vertex_t))
507        return NIL(vertex_t);
508
509    pseudo_sink =    g_add_vertex(vl_currentFlowGraph);
510    pseudo_CMPsink = g_add_vertex(vl_currentCMPFlowGraph);
511    pseudo_sink->user_data =    (char*)fg_new_node_info(FG_ND_PAUSE);
512    pseudo_CMPsink->user_data = (char*)fg_new_node_info(FG_ND_PAUSE);
513    ((fg_node_info*)pseudo_sink->user_data)->loc = vlStrdup(new_pausename());
514    lsNewEnd(((fg_graph_info*)vl_currentFlowGraph->user_data)->pause_list,
515             (lsGeneric)pseudo_sink, 0);
516    g_add_edge(fg_Srce, pseudo_sink);
517    g_add_edge(fg_CMPSrce, pseudo_CMPsink);
518    retval = pseudo_sink;
519    return retval;
520}
521
522
523
524int fg_check_cyclic()
525{
526    if (fg_Srce == NIL(vertex_t) && fg_Sink == NIL(vertex_t))
527        return 1;
528
529    return !g_is_acyclic(vl_currentFlowGraph);
530}
531
532
533
534void fg_clean_vertex_data(user_data)
535gGeneric user_data;
536{
537    if (!user_data) return;
538    if (!((fg_node_info*)user_data)->data) return;
539    ((vl_expr*)(((fg_node_info*)user_data)->data))->fg_info1 = NIL(char);
540    ((vl_expr*)(((fg_node_info*)user_data)->data))->fg_info2 = NIL(char);
541    ((vl_expr*)(((fg_node_info*)user_data)->data))->fg_aux1 = NIL(char);
542    ((vl_expr*)(((fg_node_info*)user_data)->data))->fg_aux2 = NIL(char);
543    free((fg_node_info*)user_data);
544}
545
546
547
548void fg_clean_edge_data(user_data)
549gGeneric user_data;
550{
551    if (!user_data) return;
552    if (!((fg_arc_info*)user_data)->data) return;
553    ((vl_case_item*)(((fg_arc_info*)user_data)->data))->fg_info = NIL(char);
554    free((fg_node_info*)user_data);
555}
556
557
558
559void fg_update_node_info(vertex_t *vtx, char *data)
560{
561    ((fg_node_info*)vtx->user_data)->data = data;
562}
563
564
565
566void fg_update_arc_info(edge_t *arc, char *data)
567{
568    ((fg_arc_info*)arc->user_data)->data = data;
569}
570
571
572static
573void fg_dfs_int(src, sink, vtx_massager, arc_massager, visit_st)
574vertex_t *src;
575vertex_t *sink;
576void (*vtx_massager)();
577void (*arc_massager)();
578st_table *visit_st;
579{
580    edge_t *e;
581    vertex_t *v;
582    int val;
583    lsList visit_list;
584    lsGen gen;
585    lsHandle handle;
586
587    if (src==sink) {
588        if (!st_lookup(visit_st, (char*)sink, (char**)&val)) {
589            if (vtx_massager) (*vtx_massager)(sink->user_data);
590            st_insert(visit_st, (char*)sink, (char*)0);
591        }
592        return;
593    }
594
595    if (vtx_massager) (*vtx_massager)(src->user_data);
596    st_insert(visit_st, (char*)src, (char*)0);
597    visit_list = g_get_out_edges(src);
598    for (gen=lsStart(visit_list);
599         lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; ) {
600        if (arc_massager) (*arc_massager)(e->user_data);
601        v = g_e_dest(e);
602        if (!st_lookup(visit_st, (char*)v, (char**)&val)) {
603            fg_dfs_int(v, sink, vtx_massager, arc_massager, visit_st);
604        }
605    }
606    lsFinish(gen);
607}
608
609
610
611int fg_dfs(src, sink, vtx_massager, arc_massager)
612vertex_t *src;
613vertex_t *sink;
614void (*vtx_massager)();
615void (*arc_massager)();
616{
617    st_table *visit_st;
618
619    if (sink) if (g_vertex_graph(src) != g_vertex_graph(sink)) return 0;
620
621    visit_st = st_init_table(st_ptrcmp, st_ptrhash);
622    fg_dfs_int(src, sink, vtx_massager, arc_massager, visit_st);
623    st_free_table(visit_st);
624
625    return 1;
626}
627
628
629static
630void fg_back_dfs_int(src, leaf_criterion, vtx_massager, arc_massager, visit_st)
631vertex_t *src;
632int (*leaf_criterion)();
633void (*vtx_massager)();
634void (*arc_massager)();
635st_table *visit_st;
636{
637    edge_t *e;
638    vertex_t *v;
639    int val;
640    lsList visit_list;
641    lsGen gen;
642    lsHandle handle;
643
644    if ((*leaf_criterion)(src->user_data)) {
645        if (!st_lookup(visit_st, (char*)src, (char**)&val)) {
646            if (vtx_massager)
647                (*vtx_massager)(src->user_data);
648            st_insert(visit_st, (char*)src, (char*)0);
649        }
650        return;
651    }
652
653    if (vtx_massager) (*vtx_massager)(src->user_data);
654    st_insert(visit_st, (char*)src, (char*)0);
655    visit_list = g_get_in_edges(src);
656    for (gen=lsStart(visit_list);
657         lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; ) {
658        if (arc_massager) (*arc_massager)(e->user_data);
659        v = g_e_source(e);
660        if (!st_lookup(visit_st, (char*)v, (char**)&val)) {
661            fg_back_dfs_int(v, leaf_criterion, vtx_massager, arc_massager,
662                            visit_st);
663        }
664    }
665    lsFinish(gen);
666}
667
668
669
670int fg_back_dfs(src, leaf_criterion, vtx_massager, arc_massager)
671vertex_t *src;
672int (*leaf_criterion)();
673void (*vtx_massager)();
674void (*arc_massager)();
675{
676    st_table *visit_st;
677
678    if (!src) return 0;
679
680    visit_st = st_init_table(st_ptrcmp, st_ptrhash);
681    fg_back_dfs_int(src, leaf_criterion, vtx_massager, arc_massager, visit_st);
682    st_free_table(visit_st);
683
684    return 1;
685}
686
687
688static
689void fg_fore_dfs_int(src, leaf_criterion, vtx_massager, arc_massager, visit_st)
690vertex_t *src;
691int (*leaf_criterion)();
692void (*vtx_massager)();
693void (*arc_massager)();
694st_table *visit_st;
695{
696    edge_t *e;
697    vertex_t *v;
698    int val;
699    lsList visit_list;
700    lsGen gen;
701    lsHandle handle;
702
703    if ((*leaf_criterion)(src->user_data)) {
704        if (!st_lookup(visit_st, (char*)src, (char**)&val)) {
705            if (vtx_massager)
706                (*vtx_massager)(src->user_data);
707            st_insert(visit_st, (char*)src, (char*)0);
708        }
709        return;
710    }
711
712    if (vtx_massager) (*vtx_massager)(src->user_data);
713    st_insert(visit_st, (char*)src, (char*)0);
714    visit_list = g_get_out_edges(src);
715    for (gen=lsStart(visit_list);
716         lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; ) {
717        if (arc_massager) (*arc_massager)(e->user_data);
718        v = g_e_dest(e);
719        if (!st_lookup(visit_st, (char*)v, (char**)&val)) {
720            fg_fore_dfs_int(v, leaf_criterion, vtx_massager, arc_massager,
721                            visit_st);
722        }
723    }
724    lsFinish(gen);
725}
726
727
728
729int fg_fore_dfs(src, leaf_criterion, vtx_massager, arc_massager)
730vertex_t *src;
731int (*leaf_criterion)();
732void (*vtx_massager)();
733void (*arc_massager)();
734{
735    st_table *visit_st;
736
737    if (!src) return 0;
738
739    visit_st = st_init_table(st_ptrcmp, st_ptrhash);
740    fg_fore_dfs_int(src, leaf_criterion, vtx_massager, arc_massager, visit_st);
741    st_free_table(visit_st);
742
743    return 1;
744}
745
746
747static
748void fg_gen_fore_dfs_int(src, leaf_criterion, leaf_massager,
749                    vtx_pre_massager, vtx_in_massager, vtx_post_massager,
750                    arc_pre_massager, arc_post_massager,
751                    visit_st, all_paths)
752vertex_t *src;
753int (*leaf_criterion)();
754void (*leaf_massager)();
755void (*vtx_pre_massager)();
756void (*vtx_in_massager)();
757void (*vtx_post_massager)();
758void (*arc_pre_massager)();
759void (*arc_post_massager)();
760st_table *visit_st;
761int all_paths;
762{
763    int i;
764    edge_t *e;
765    vertex_t *v;
766    int val;
767    lsList visit_list;
768    lsGen gen;
769    lsHandle handle;
770
771    if ((*leaf_criterion)(src->user_data)) {
772        if (!st_lookup(visit_st, (char*)src, (char**)&val) || all_paths) {
773            if (vtx_pre_massager) (*vtx_pre_massager)(src->user_data);
774            if (leaf_massager) (*leaf_massager)(src->user_data);
775            if (vtx_post_massager) (*vtx_post_massager)(src->user_data);
776            st_insert(visit_st, (char*)src, (char*)0);
777        }
778        return;
779    }
780
781    if (vtx_pre_massager) (*vtx_pre_massager)(src->user_data);
782    st_insert(visit_st, (char*)src, (char*)0);
783    visit_list = g_get_out_edges(src);
784    for (gen=lsStart(visit_list), i=0;
785         lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; i++) {
786        if (arc_pre_massager) (*arc_pre_massager)(e->user_data);
787        v = g_e_dest(e);
788        if (!st_lookup(visit_st, (char*)v, (char**)&val) || all_paths) {
789            fg_gen_fore_dfs_int(v, leaf_criterion, leaf_massager,
790                            vtx_pre_massager,
791                            vtx_in_massager,
792                            vtx_post_massager,
793                            arc_pre_massager, arc_post_massager,
794                            visit_st, all_paths);
795        }
796        if (vtx_in_massager) (*vtx_in_massager)(src->user_data, e->user_data);
797        if (arc_post_massager) (*arc_post_massager)(e->user_data);
798    }
799    lsFinish(gen);
800    if (vtx_post_massager) (*vtx_post_massager)(src->user_data, src);
801}
802
803
804
805int fg_gen_fore_dfs(src, leaf_criterion, leaf_massager,
806            vtx_pre_massager, vtx_in_massager, vtx_post_massager,
807            arc_pre_massager, arc_post_massager, all_paths)
808vertex_t *src;
809int (*leaf_criterion)();
810void (*leaf_massager)();
811void (*vtx_pre_massager)();
812void (*vtx_in_massager)();
813void (*vtx_post_massager)();
814void (*arc_pre_massager)();
815void (*arc_post_massager)();
816int all_paths;
817{
818    st_table *visit_st;
819
820    if (!src) return 0;
821
822    visit_st = st_init_table(st_ptrcmp, st_ptrhash);
823    fg_gen_fore_dfs_int(src, leaf_criterion, leaf_massager,
824                        vtx_pre_massager, vtx_in_massager, vtx_post_massager,
825                        arc_pre_massager, arc_post_massager, visit_st,
826                        all_paths);
827    st_free_table(visit_st);
828
829    return 1;
830}
831
832
833static st_table *pause_set=NIL(st_table);
834
835static void remember_pause(user_data)
836gGeneric user_data;
837{
838    char *loc;
839
840    if (((fg_node_info*)user_data)->type == FG_ND_PAUSE) {
841        if (((fg_node_info*)user_data)->loc)
842            loc = ((fg_node_info*)user_data)->loc;
843        else
844            loc = ((fg_node_info*)user_data)->loc = vlStrdup(new_pausename());
845
846        st_insert(pause_set, loc, (char*)0);
847    }
848}
849
850
851static st_table *terminal_set=NIL(st_table);
852static st_table *full_terminal_set=NIL(st_table);
853static int terminal_set_count=1;
854
855static void remember_node_terminal(user_data)
856gGeneric user_data;
857{
858    vl_term *key;
859    int val;
860    vl_event_control_stmt *pause_stmt;
861
862    if (!user_data) return;
863    key = (vl_term*)((fg_node_info*)user_data)->data;
864    if (((fg_node_info*)user_data)->type == FG_ND_IFBRANCH ||
865        ((fg_node_info*)user_data)->type == FG_ND_FORBRANCH) {
866        if (!st_lookup(terminal_set, (char*)key, (char**)&val)) {
867            if (full_terminal_set) {
868                int retval = st_lookup(full_terminal_set, (char*)key,
869                                       (char**)&val);
870                assert(retval);
871                st_insert(terminal_set, (char*)key, (char*)val);
872            } else {
873                st_insert(terminal_set, (char*)key, (char*)terminal_set_count);
874                terminal_set_count++;
875            }
876        }
877    } else if (((fg_node_info*)user_data)->type == FG_ND_PAUSE) {
878        vl_term *edge_ctrl = NIL(vl_term);
879
880        pause_stmt = (vl_event_control_stmt*)((fg_node_info*)user_data)->data;
881        if (pause_stmt->type == EventControlStmt) {
882            if (!full_terminal_set) {
883                if (!st_lookup(terminal_set,
884                               pause_stmt->fg_info, (char**)&val)) {
885                    if (!vl_preDeclare) {
886                        if (pause_stmt->event->type == OrEventExpr) {
887                            edge_ctrl =
888                                write_ored_edge_detector(fg_out_file,
889                                                         pause_stmt->event);
890                        } else {
891                            edge_ctrl =
892                                write_edge_detector(fg_out_file,
893                                                    pause_stmt->event->expr,
894                                (pause_stmt->event->type==PosedgeEventExpr)?1:
895                                (pause_stmt->event->type==NegedgeEventExpr)?-1:
896                                                                            0);
897                            edge_ctrl->flag |= EdgeSignal;
898                        }
899                    }
900                    pause_stmt->fg_info = (char*)edge_ctrl;
901                    st_insert(terminal_set, (char*)edge_ctrl,
902                              (char*)(FG_MAGIC_UB_EDGE+terminal_set_count));
903                    terminal_set_count++;
904                }
905            } else {
906                int retval = st_lookup(full_terminal_set, pause_stmt->fg_info,
907                                       (char**)&val);
908                assert(retval);
909                st_insert(terminal_set, pause_stmt->fg_info, (char*)val);
910            }
911        }
912    }
913}
914
915static void switch_node_branch(user_data, edge_data)
916gGeneric user_data;
917gGeneric edge_data;
918{
919    vl_term *key;
920    int val;
921
922    if (!user_data) return;
923    key = (vl_term*)((fg_node_info*)user_data)->data;
924    if (((fg_node_info*)user_data)->type == FG_ND_IFBRANCH ||
925        ((fg_node_info*)user_data)->type == FG_ND_FORBRANCH) {
926        int retval = st_lookup(terminal_set, (char*)key, (char**)&val);
927        assert(retval);
928        st_delete(terminal_set, (char**)&key, (char**)&val);
929        st_insert(terminal_set, (char*)key, (char*)-val);
930    } else if (((fg_node_info*)user_data)->type == FG_ND_CASEBRANCH) {
931        int retval;
932        key = (vl_term*)((fg_arc_info*)edge_data)->data;
933        retval = st_lookup(terminal_set, (char*)key, (char**)&val);
934        assert(retval);
935        st_delete(terminal_set, (char**)&key, (char**)&val);
936        st_insert(terminal_set, (char*)key, (char*)-val);
937    }
938}
939
940static void forget_node_terminal(user_data, v)
941gGeneric user_data;
942vertex_t *v;
943{
944    vl_term *key;
945    int val;
946
947    if (!user_data) return;
948    key = (vl_term*)((fg_node_info*)user_data)->data;
949    if (((fg_node_info*)user_data)->type == FG_ND_IFBRANCH ||
950        ((fg_node_info*)user_data)->type == FG_ND_FORBRANCH) {
951        key = (vl_term*)((fg_node_info*)user_data)->data;
952        if (st_lookup(terminal_set, (char*)key, (char**)&val))
953            st_delete(terminal_set, (char**)&key, (char**)&val);
954    } else if (((fg_node_info*)user_data)->type == FG_ND_CASEBRANCH) {
955        lsList e_list;
956        lsGen gen;
957        lsHandle handle;
958        edge_t *e;
959
960
961        e_list = g_get_out_edges(v);
962        for (gen=lsStart(e_list);
963             lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; ) {
964            if (!e->user_data) continue;
965            if (((fg_arc_info*)e->user_data)->type == FG_ND_CASETAG) {
966                key = (vl_term*)((fg_arc_info*)e->user_data)->data;
967                if (st_lookup(terminal_set, (char*)key, (char**)&val))
968                    st_delete(terminal_set, (char**)&key, (char**)&val);
969            }
970        }
971        lsFinish(gen);
972    } else if (((fg_node_info*)user_data)->type ==FG_ND_PAUSE) {
973        vl_event_control_stmt *pause_stmt;
974        pause_stmt = (vl_event_control_stmt*)((fg_node_info*)user_data)->data;
975        if (pause_stmt->type == EventControlStmt) {
976            key = (vl_term*)pause_stmt->fg_info;
977            if (st_lookup(terminal_set, (char*)key, (char**)&val))
978                st_delete(terminal_set, (char**)&key, (char**)&val);
979        }
980    }
981}
982
983static void remember_arc_terminal(user_data)
984gGeneric user_data;
985{
986    vl_term *key;
987    int val;
988
989    if (!user_data) return;
990    key = (vl_term*)((fg_arc_info*)user_data)->data;
991    if (((fg_arc_info*)user_data)->type == FG_ND_CASETAG) {
992        if (!st_lookup(terminal_set, (char*)key, (char**)&val)) {
993            if (full_terminal_set) {
994                int retval = st_lookup(full_terminal_set, (char*)key,
995                                       (char**)&val);
996                assert(retval);
997                st_insert(terminal_set, (char*)key, (char*)val);
998            } else {
999                st_insert(terminal_set, (char*)key, (char*)terminal_set_count);
1000                terminal_set_count++;
1001            }
1002        }
1003    }
1004}
1005
1006static void forget_arc_terminal(user_data)
1007gGeneric user_data;
1008{
1009
1010    if (!user_data) return;
1011    if (((fg_arc_info*)user_data)->type == FG_ND_CASETAG) {
1012        /* nothing */
1013    }
1014}
1015
1016
1017
1018void fg_if_collect_pause_rewrite_ctrl(file, src, sink, spacial_ctrl)
1019FILE *file;
1020vertex_t *src;
1021vertex_t *sink;
1022vl_term **spacial_ctrl;
1023{
1024    vl_term *t_lc_control=NIL(vl_term), *f_lc_control=NIL(vl_term);
1025    vl_term *new_lc_ctrl;
1026    vertex_t *branch_src;
1027    edge_t *branch_edge;
1028    int i;
1029    lsList out_edges;
1030    lsGen gen;
1031    lsHandle handle;
1032
1033    out_edges = g_get_out_edges(src);
1034
1035    for (gen=lsStart(out_edges), i=0;
1036         lsNext(gen, (lsGeneric*)&branch_edge, &handle)!=LS_NOMORE; i++) {
1037        int retval;
1038        pause_set = st_init_table(strcmp, st_strhash);
1039        branch_src = g_e_dest(branch_edge);
1040        retval = fg_dfs(branch_src, sink, remember_pause, 0);
1041        assert(retval);
1042
1043        if (i==0)
1044            t_lc_control = fg_write_lc_in_LabelSet(file, pause_set, 0);
1045        else
1046            f_lc_control = fg_write_lc_in_LabelSet(file, pause_set, 0);
1047
1048        st_free_table(pause_set);
1049        pause_set = NIL(st_table);
1050    }
1051    lsFinish(gen);
1052
1053    new_lc_ctrl = fg_write_if_priority_decoder(file,
1054                      t_lc_control, f_lc_control, *spacial_ctrl);
1055
1056    *spacial_ctrl = new_lc_ctrl;
1057}
1058
1059
1060
1061void fg_case_collect_pause_rewrite_ctrl(FILE *file, vertex_t *src,
1062                                        vertex_t *sink,
1063                                        vl_term **spacial_ctrl,
1064                                        vl_term **temporal_ctrl)
1065{
1066    vl_term *ripple_in;
1067    vl_term *lc_control;
1068    vl_term *new_lc_ctrl;
1069
1070    pause_set = st_init_table(strcmp, st_strhash);
1071    fg_dfs(src, sink, remember_pause, 0);
1072
1073    ripple_in = new_term(NIL(vl_range), 0, -1);
1074    lc_control = fg_write_lc_in_LabelSet(file, pause_set, 0);
1075    new_lc_ctrl = fg_write_case_priority_decoder(file,
1076                      ripple_in, *temporal_ctrl, lc_control, *spacial_ctrl);
1077
1078    *spacial_ctrl = new_lc_ctrl;
1079    *temporal_ctrl = ripple_in;
1080
1081    st_free_table(pause_set);
1082    pause_set = NIL(st_table);
1083}
1084
1085
1086
1087void fg_loop_collect_pause(FILE *file, vertex_t *src,
1088                           vertex_t *sink,
1089                           vl_term **dom_sel)
1090{
1091    vl_term *t_lc_control=NIL(vl_term);
1092    vertex_t *branch_src;
1093    edge_t *branch_edge;
1094    int i;
1095    lsList out_edges;
1096    lsGen gen;
1097    lsHandle handle;
1098
1099    out_edges = g_get_out_edges(src);
1100
1101    for (gen=lsStart(out_edges), i=0;
1102         lsNext(gen, (lsGeneric*)&branch_edge, &handle)!=LS_NOMORE; i++) {
1103        int retval;
1104        pause_set = st_init_table(strcmp, st_strhash);
1105        branch_src = g_e_dest(branch_edge);
1106        retval = fg_dfs(branch_src, sink, remember_pause, 0);
1107        assert(retval);
1108
1109        if (i==0)
1110
1111            t_lc_control = fg_write_lc_in_LabelSet(file, pause_set, -1);
1112
1113        st_free_table(pause_set);
1114        pause_set = NIL(st_table);
1115    }
1116    lsFinish(gen);
1117
1118    *dom_sel = t_lc_control;
1119}
1120
1121
1122
1123vl_term *fg_write_lc_in_LabelSet(file, pause_set, ns)
1124FILE *file;
1125st_table* pause_set;
1126int ns;
1127{
1128    vl_term *retval;
1129    st_generator *gen;
1130    int *val;
1131    char *key;
1132    char *timer_st;
1133
1134    retval = new_term(NIL(vl_range), 0, -1);
1135    timer_st = (ns==-1) ? FG_TIMER_PS :
1136                          ((ns) ? FG_LC_NS : FG_LC_PS);
1137
1138    if (st_count(pause_set)==0) {
1139        fprintf(file, ".names %s\n0\n", retval->name->name);
1140    } else {
1141        fprintf(file, ".names %s%06x %s\n", timer_st,
1142                ((fg_graph_info*)vl_writeFlowGraph->user_data)->fg_id,
1143                retval->name->name);
1144        fprintf(file, "%s 0\n", HSIS_DEFAULT);
1145        gen = st_init_gen(pause_set);
1146        while (st_gen(gen, &key, (char**)&val)) {
1147            if (RQautomata)
1148                fprintf(file, "%s 1\n%s%s 1\n", key, key, FG_TIMER_PRIME);
1149            else
1150                fprintf(file, "%s 1\n", key);
1151        }
1152        st_free_gen(gen);
1153    }
1154
1155    return retval;
1156}
1157
1158
1159
1160vl_term *
1161fg_write_if_priority_decoder(file, t_local_lc, f_local_lc, spacial_ctrl)
1162FILE *file;
1163vl_term *t_local_lc;
1164vl_term *f_local_lc;
1165vl_term *spacial_ctrl;
1166{
1167    vl_term *retval;
1168
1169    retval = new_term(NIL(vl_range), 0, -1);
1170
1171
1172    if (f_local_lc) {
1173        fprintf(file, ".names %s %s %s %s\n",
1174                t_local_lc->name->name, f_local_lc->name->name,
1175                spacial_ctrl->name->name, retval->name->name);
1176        fprintf(file, "1 - - 1\n");
1177        fprintf(file, "0 1 - 0\n");
1178        fprintf(file, "0 0 - %s%s\n",
1179                HSIS_EQUAL,spacial_ctrl->name->name);
1180    } else {
1181        fprintf(file, ".names %s %s %s\n",
1182                t_local_lc->name->name, spacial_ctrl->name->name,
1183                retval->name->name);
1184        fprintf(file, "1 - 1\n");
1185        fprintf(file, "0 - %s%s\n",
1186                HSIS_EQUAL, spacial_ctrl->name->name);
1187    }
1188
1189    return retval;
1190}
1191
1192
1193
1194vl_term *
1195fg_write_case_priority_decoder(file, ripple_in, ripple_out,
1196                               local_lc, spacial_ctrl)
1197FILE *file;
1198vl_term *ripple_in;
1199vl_term *ripple_out;
1200vl_term *local_lc;
1201vl_term *spacial_ctrl;
1202{
1203    vl_term *retval;
1204
1205    retval = new_term(NIL(vl_range), 0, -1);
1206
1207
1208    if (spacial_ctrl) {
1209        fprintf(file, ".names %s %s %s %s\n",
1210                local_lc->name->name, ripple_in->name->name,
1211                spacial_ctrl->name->name, retval->name->name);
1212        fprintf(file, "1 - - 1\n");
1213        fprintf(file, "0 1 - 0\n");
1214        fprintf(file, "0 0 - %s%s\n",
1215                HSIS_EQUAL, spacial_ctrl->name->name);
1216    } else {
1217        fprintf(file, ".names %s %s %s\n",
1218                local_lc->name->name, ripple_in->name->name,
1219                retval->name->name);
1220        fprintf(file, "1 - 1\n");
1221        fprintf(file, "0 1 0\n");
1222        fprintf(file, "0 0 1\n");
1223    }
1224
1225    if (ripple_out) {
1226        fprintf(file, ".names %s %s %s\n", ripple_in->name->name,
1227                local_lc->name->name, ripple_out->name->name);
1228        fprintf(file, "%s 1\n", HSIS_DEFAULT);
1229        fprintf(file, "0 0 0\n");
1230    }
1231
1232    return retval;
1233}
1234
1235
1236static int fg_node_is_pause(void *user_data)
1237{
1238    return (((fg_node_info*)user_data)->type == FG_ND_PAUSE);
1239}
1240
1241
1242
1243st_table *fg_assign_temporal_context(src)
1244vertex_t *src;
1245{
1246    st_table *retval;
1247
1248    retval = pause_set = st_init_table(st_ptrcmp, st_ptrhash);
1249
1250    fg_back_dfs(src, fg_node_is_pause, remember_pause, 0);
1251
1252    pause_set = NIL(st_table);
1253
1254    return retval;
1255}
1256
1257
1258
1259void fg_put_loc_context(FILE *file, st_table *pre_cond, char *lc_name)
1260{
1261    st_generator *gen;
1262    char *loc, *val;
1263    int i;
1264    char buf[MAXSTRLEN];
1265    fg_graph_info *graph_info;
1266
1267    if (st_count(pre_cond)==0) {
1268        fprintf(file, "%d", 1);
1269        return;
1270    }
1271
1272    fprintf(file, "%s", HSIS_SET_BEGIN);
1273    i = 1;
1274    gen = st_init_gen(pre_cond);
1275    while (st_gen(gen, &loc, &val)) {
1276        graph_info = (fg_graph_info*)get_assoc_lc_name(loc, buf);
1277        if (i==st_count(pre_cond))
1278            if (RQautomata)
1279                fprintf(file, "%s%s%s%s",
1280                        loc, HSIS_SET_SEP, loc, FG_TIMER_PRIME);
1281            else
1282                fprintf(file, "%s", loc);
1283        else
1284            if (RQautomata)
1285                fprintf(file, "%s%s%s%s%s",
1286                        loc, HSIS_SET_SEP, loc, FG_TIMER_PRIME, HSIS_SET_SEP);
1287            else
1288                fprintf(file, "%s%s", loc, HSIS_SET_SEP);
1289        i++;
1290    }
1291    st_free_gen(gen);
1292    fprintf(file, "%s", HSIS_SET_END);
1293}
1294
1295
1296void fg_declare_timer(file, terminal_set, graph)
1297FILE *file;
1298st_table *terminal_set;
1299graph_t *graph;
1300{
1301    fg_graph_info *gdata;
1302    int i;
1303
1304    gdata = ((fg_graph_info*)graph->user_data);
1305
1306    if (vl_preDeclare) {
1307        fprintf(file, ".mv %s%06x, %s%06x %d %s%d%s ",
1308                FG_LC_PS, gdata->fg_id, FG_LC_NS, gdata->fg_id,
1309                (gdata->pause_hi-gdata->pause_lo)*2+2,
1310                FG_LLOC, 0, FG_RLOC);
1311        for (i=gdata->pause_lo; i<gdata->pause_hi; i++)
1312            fprintf(file, "%s%d%s %s%d%s%s ",
1313                    FG_LLOC, i, FG_RLOC, FG_LLOC, i, FG_RLOC,
1314                    FG_TIMER_PRIME);
1315        fprintf(file, "%s%s\n", FG_LLOC, FG_RLOC);
1316    }
1317
1318    fprintf(file, ".mv %s%06x %d %s%d%s ", FG_TIMER_PS, gdata->fg_id,
1319            (gdata->pause_hi-gdata->pause_lo)*2+1, FG_LLOC, 0, FG_RLOC);
1320    for (i=gdata->pause_lo; i<gdata->pause_hi; i++)
1321        fprintf(file, "%s%d%s %s%d%s%s ",
1322                FG_LLOC, i, FG_RLOC, FG_LLOC, i, FG_RLOC, FG_TIMER_PRIME);
1323    fprintf(file, "\n");
1324
1325    fprintf(file, ".mv %s%06x %d %s%d%s ", FG_TIMER_NS, gdata->fg_id,
1326            (gdata->pause_hi-gdata->pause_lo)*2+1, FG_LLOC, 0, FG_RLOC);
1327    for (i=gdata->pause_lo; i<gdata->pause_hi; i++)
1328        fprintf(file, "%s%d%s %s%d%s%s ",
1329                FG_LLOC, i, FG_RLOC, FG_LLOC, i, FG_RLOC, FG_TIMER_PRIME);
1330    fprintf(file, "\n");
1331
1332
1333    if (!vl_noTimers) {
1334        fprintf(file, ".timers ");
1335        for (i=((fg_graph_info*)graph->user_data)->pause_lo;
1336             i<((fg_graph_info*)graph->user_data)->pause_hi; i++)
1337            if (i<((fg_graph_info*)graph->user_data)->pause_hi-1)
1338                fprintf(file, "T%d,", i);
1339            else
1340                fprintf(file, "T%d ", i);
1341        fprintf(file, "\n");
1342    }
1343    fprintf(file, ".latch %s%06x %s%06x\n",
1344            FG_TIMER_NS, gdata->fg_id, FG_TIMER_PS, gdata->fg_id);
1345    fprintf(file, ".r %s%06x\n%s%d%s\n", FG_TIMER_PS, gdata->fg_id,
1346            FG_LLOC, (vl_noTimers)?gdata->pause_lo:0, FG_RLOC);
1347}
1348
1349
1350
1351void fg_put_timer_header(file, terminal_set, graph)
1352FILE *file;
1353st_table *terminal_set;
1354graph_t *graph;
1355{
1356    st_generator *gen;
1357    vl_term *key;
1358    int val;
1359    int i;
1360
1361    fprintf(file, ".names ");
1362    for (i=1; i<=st_count(terminal_set); i++) {
1363        gen = st_init_gen(terminal_set);
1364        while (st_gen(gen, (char**)&key, (char**)&val)) {
1365            if (val == i) {
1366                fprintf(file, "%s ", key->name->name);
1367                break;
1368            } else if ((val-FG_MAGIC_UB_EDGE) == i) {
1369                fprintf(file, "%s ", key->name->name);
1370                break;
1371            }
1372        }
1373        st_free_gen(gen);
1374    }
1375    fprintf(file, "%s%06x %s %s%06x %s%06x %s%06x\n",
1376            FG_TIMER_PS, ((fg_graph_info*)graph->user_data)->fg_id,
1377            HSIS_ARROW,
1378            FG_LC_PS, ((fg_graph_info*)graph->user_data)->fg_id,
1379            FG_LC_NS, ((fg_graph_info*)graph->user_data)->fg_id,
1380            FG_TIMER_NS, ((fg_graph_info*)graph->user_data)->fg_id);
1381    fprintf(file, "%s %s%s %s%s %s%s%06x\n",
1382            HSIS_DEFAULT, FG_LLOC, FG_RLOC, FG_LLOC, FG_RLOC,
1383            HSIS_EQUAL,
1384            FG_TIMER_PS, ((fg_graph_info*)graph->user_data)->fg_id);
1385}
1386
1387
1388static vertex_t *current_source_vtx=NIL(vertex_t);
1389
1390
1391static void fg_put_timer_transition(int user_data)
1392{
1393    int i;
1394    st_generator *gen;
1395    vl_term *key;
1396    int val, ival;
1397    int control_entry=0;
1398    int src_timer, dest_timer, delay1;
1399    vl_delay_control_stmt *pausing_stmt;
1400    int primed_transition = 0;
1401    char buf[MAXSTRLEN];
1402    char str[MAXSTRLEN];
1403
1404    if (((fg_node_info*)user_data)->type != FG_ND_PAUSE) return;
1405    pausing_stmt = (vl_delay_control_stmt*)
1406        ((fg_node_info*)current_source_vtx->user_data)->data;
1407    if (pausing_stmt->type != DelayControlStmt &&
1408        pausing_stmt->type != EventControlStmt) return;
1409
1410    buf[0]='\0';
1411    if (pausing_stmt->type == EventControlStmt) {
1412        if (!st_lookup(full_terminal_set,
1413                       ((vl_event_control_stmt*)pausing_stmt)->fg_info,
1414                       (char**)&ival))
1415            ival = 0;
1416        else
1417            ival -= FG_MAGIC_UB_EDGE;
1418    }
1419
1420
1421    if (!strcmp(((fg_node_info*)current_source_vtx->user_data)->loc,
1422                ((fg_node_info*)user_data)->loc) &&
1423        RQautomata)
1424        primed_transition = 1;
1425
1426    for (i=1; i<=st_count(full_terminal_set); i++) {
1427        control_entry = 0;
1428        gen = st_init_gen(terminal_set);
1429        while (st_gen(gen, (char**)&key, (char**)&val)) {
1430            if (IABS(val) == i) {
1431                sprintf(str, "%c ", (val>0)?'1':'0'); control_entry=1;
1432                strcat(buf, str);
1433                break;
1434            }  else if (pausing_stmt->type == EventControlStmt) {
1435                if (i==ival) {
1436                    sprintf(str, "1 "); strcat(buf, str); control_entry=1;
1437                    break;
1438                }
1439            }
1440        }
1441        if (i==ival && !control_entry &&
1442            pausing_stmt->type == EventControlStmt) {
1443            sprintf(str, "1 "); strcat(buf, str);
1444            control_entry=1;
1445        }
1446        st_free_gen(gen);
1447        if (!control_entry) { sprintf(str, "- "); strcat(buf, str); }
1448    }
1449
1450    if (pausing_stmt->type != DelayControlStmt) {
1451
1452        if (!primed_transition) {
1453            if (!vl_noTimers) {
1454                fprintf(fg_out_file, "%s %s %s %s %s %s %s%d=0\n", buf,
1455                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1456                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1457                        ((fg_node_info*)user_data)->loc,
1458                        ((fg_node_info*)user_data)->loc,
1459                        HSIS_TIMER_SEP,
1460                        HSIS_BLIF_MVT_TIMER,
1461                        atoi(((fg_node_info*)user_data)->loc+1));
1462            } else {
1463                fprintf(fg_out_file, "%s %s %s %s %s\n", buf,
1464                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1465                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1466                        ((fg_node_info*)user_data)->loc,
1467                        ((fg_node_info*)user_data)->loc);
1468            }
1469
1470            if (RQautomata) {
1471                if (!vl_noTimers) {
1472                    fprintf(fg_out_file, "%s %s%s %s%s %s %s %s %s%d=0\n", buf,
1473                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1474                            FG_TIMER_PRIME,
1475                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1476                            FG_TIMER_PRIME,
1477                            ((fg_node_info*)user_data)->loc,
1478                            ((fg_node_info*)user_data)->loc,
1479                            HSIS_TIMER_SEP,
1480                            HSIS_BLIF_MVT_TIMER,
1481                            atoi(((fg_node_info*)user_data)->loc+1));
1482                } else {
1483                    fprintf(fg_out_file, "%s %s%s %s%s %s %s\n", buf,
1484                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1485                            FG_TIMER_PRIME,
1486                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1487                            FG_TIMER_PRIME,
1488                            ((fg_node_info*)user_data)->loc,
1489                            ((fg_node_info*)user_data)->loc);
1490                }
1491            }
1492        } else {
1493
1494            if (!vl_noTimers) {
1495                fprintf(fg_out_file, "%s %s %s %s%s %s%s %s %s%d=0\n", buf,
1496                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1497                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1498                        ((fg_node_info*)user_data)->loc, FG_TIMER_PRIME,
1499                        ((fg_node_info*)user_data)->loc, FG_TIMER_PRIME,
1500                        HSIS_TIMER_SEP,
1501                        HSIS_BLIF_MVT_TIMER,
1502                        atoi(((fg_node_info*)user_data)->loc+1));
1503
1504                fprintf(fg_out_file, "%s %s%s %s%s %s %s %s %s%d=0\n", buf,
1505                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1506                        FG_TIMER_PRIME,
1507                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1508                        FG_TIMER_PRIME,
1509                        ((fg_node_info*)user_data)->loc,
1510                        ((fg_node_info*)user_data)->loc,
1511                        HSIS_TIMER_SEP,
1512                        HSIS_BLIF_MVT_TIMER,
1513                        atoi(((fg_node_info*)user_data)->loc+1));
1514            } else {
1515                fprintf(fg_out_file, "%s %s %s %s%s %s%s\n", buf,
1516                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1517                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1518                        ((fg_node_info*)user_data)->loc, FG_TIMER_PRIME,
1519                        ((fg_node_info*)user_data)->loc, FG_TIMER_PRIME);
1520
1521                fprintf(fg_out_file, "%s %s%s %s%s %s %s\n", buf,
1522                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1523                        FG_TIMER_PRIME,
1524                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1525                        FG_TIMER_PRIME,
1526                        ((fg_node_info*)user_data)->loc,
1527                        ((fg_node_info*)user_data)->loc);
1528            }
1529        }
1530    } else {
1531
1532        int idx;
1533
1534        src_timer =
1535            atoi(((fg_node_info*)current_source_vtx->user_data)->loc+1);
1536        dest_timer = atoi(((fg_node_info*)user_data)->loc+1);
1537        vl_expr_aux1_flag = vl_expr_aux2_flag = vl_expr_aux3_flag = 0;
1538        vl_expr_aux1_val = vl_expr_aux2_val = vl_expr_aux3_val = (double)0;
1539        if (!(pausing_stmt->delay->delay3 && !pausing_stmt->delay->delay2))
1540            delay1 = vl_eval_expr(pausing_stmt->delay->delay1);
1541        else {
1542            vl_expr *expr;
1543            lsFirstItem((lsList)pausing_stmt->delay->delay1,
1544                        (lsGeneric*)&expr, 0);
1545            delay1 = vl_eval_expr(expr);
1546        }
1547
1548
1549
1550        for (idx=0; idx<2; idx++) {
1551            if (idx==0) {
1552
1553                if (!primed_transition) {
1554                    fprintf(fg_out_file, "%s %s %s %s %s ", buf,
1555                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1556                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1557                            ((fg_node_info*)user_data)->loc,
1558                            ((fg_node_info*)user_data)->loc);
1559                } else {
1560
1561
1562                    fprintf(fg_out_file, "%s %s %s %s%s %s%s ", buf,
1563                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1564                            ((fg_node_info*)current_source_vtx->user_data)->loc,
1565                            ((fg_node_info*)user_data)->loc, FG_TIMER_PRIME,
1566                            ((fg_node_info*)user_data)->loc, FG_TIMER_PRIME);
1567                }
1568            } else if (idx==1 && RQautomata) {
1569
1570
1571                fprintf(fg_out_file, "%s %s%s %s%s %s %s ", buf,
1572                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1573                        FG_TIMER_PRIME,
1574                        ((fg_node_info*)current_source_vtx->user_data)->loc,
1575                        FG_TIMER_PRIME,
1576                        ((fg_node_info*)user_data)->loc,
1577                        ((fg_node_info*)user_data)->loc);
1578            }
1579            if (idx == 0 || RQautomata) {
1580
1581                if (!vl_noTimers) {
1582                    if (!vl_expr_aux3_flag) {
1583                        if (vl_expr_aux1_flag)
1584                            fprintf(fg_out_file, "%s %s%d==%.3f %s %s%d=0\n",
1585                                    HSIS_TIMER_SEP,
1586                                    HSIS_BLIF_MVT_TIMER,src_timer,vl_expr_aux1_val,
1587                                    HSIS_TIMER_SEP,HSIS_BLIF_MVT_TIMER,dest_timer);
1588                        else
1589                            fprintf(fg_out_file, "%s %s%d==%d %s %s%d=0\n",
1590                                    HSIS_TIMER_SEP,
1591                                    HSIS_BLIF_MVT_TIMER, src_timer, delay1,
1592                                    HSIS_TIMER_SEP,HSIS_BLIF_MVT_TIMER,dest_timer);
1593                    } else {
1594                        fprintf(fg_out_file,
1595                                "%s %s%d>=%.3f %s %s%d<=%.3f %s %s%d=0\n",
1596                                HSIS_TIMER_SEP,
1597                                HSIS_BLIF_MVT_TIMER, src_timer, vl_expr_aux1_val,
1598                                HSIS_TIMER_SEP,
1599                                HSIS_BLIF_MVT_TIMER, src_timer, vl_expr_aux3_val,
1600                                HSIS_TIMER_SEP,
1601                                HSIS_BLIF_MVT_TIMER, dest_timer);
1602                    }
1603                } else {
1604                    fprintf(fg_out_file, "\n");
1605                }
1606            }
1607        }
1608    }
1609}
1610
1611
1612
1613static void fg_put_init_timer_trans_int(void *user_data)
1614{
1615    int i;
1616    st_generator *gen;
1617    vl_term *key;
1618    int val;
1619    int control_entry=0;
1620    int dest_timer;
1621
1622    if (((fg_node_info*)user_data)->type != FG_ND_PAUSE) return;
1623
1624    for (i=1; i<=st_count(full_terminal_set); i++) {
1625        control_entry = 0;
1626        gen = st_init_gen(terminal_set);
1627        while (st_gen(gen, (char**)&key, (char**)&val)) {
1628            if (IABS(val) == i) {
1629                fprintf(fg_out_file, "%c ", (val>0)?'1':'0');
1630                control_entry=1;
1631                break;
1632            }
1633        }
1634        st_free_gen(gen);
1635        if (!control_entry) {
1636            fprintf(fg_out_file, "- ");
1637        }
1638    }
1639    dest_timer = atoi(((fg_node_info*)user_data)->loc+1);
1640
1641    fprintf(fg_out_file, "%s%d%s ", FG_LLOC, 0, FG_RLOC);
1642    fprintf(fg_out_file, "%s%d%s ", FG_LLOC, 0, FG_RLOC);
1643    fprintf(fg_out_file, "%s ", ((fg_node_info*)user_data)->loc);
1644    fprintf(fg_out_file, "%s ", ((fg_node_info*)user_data)->loc);
1645    if (!vl_noTimers) {
1646        fprintf(fg_out_file, "%s %s%d=0\n", HSIS_TIMER_SEP,
1647                HSIS_BLIF_MVT_TIMER, dest_timer);
1648    } else {
1649        fprintf(fg_out_file, "\n");
1650    }
1651}
1652
1653
1654
1655void fg_put_init_transition(file, graph)
1656FILE *file;
1657graph_t *graph;
1658{
1659    terminal_set = st_init_table(st_ptrcmp, st_ptrhash);
1660    fg_gen_fore_dfs(((fg_graph_info*)graph->user_data)->init_node,
1661                    fg_node_is_pause, fg_put_init_timer_trans_int,
1662                    remember_node_terminal,
1663                    switch_node_branch,
1664                    forget_node_terminal,
1665                    remember_arc_terminal, forget_arc_terminal, 1);
1666    st_free_table(terminal_set);
1667    terminal_set = NIL(st_table);
1668}
1669
1670
1671
1672void fg_put_stay_pause(file, pause)
1673FILE *file;
1674vertex_t *pause;
1675{
1676    int i, val;
1677    int src_timer;
1678    int delay1;
1679    double delay;
1680    vl_delay_control_stmt *pausing_stmt;
1681    char buf[MAXSTRLEN];
1682    char str[MAXSTRLEN];
1683
1684    if (((fg_node_info*)pause->user_data)->type != FG_ND_PAUSE) return;
1685    pausing_stmt = (vl_delay_control_stmt*)
1686        ((fg_node_info*)current_source_vtx->user_data)->data;
1687    if (pausing_stmt->type != DelayControlStmt &&
1688        pausing_stmt->type != EventControlStmt) return;
1689
1690    if (pausing_stmt->type == EventControlStmt) {
1691        if (!st_lookup(full_terminal_set,
1692                       ((vl_event_control_stmt*)pausing_stmt)->fg_info,
1693                       (char**)&val))
1694            val = 0;
1695        else
1696            val -= FG_MAGIC_UB_EDGE;
1697    }
1698
1699    buf[0]='\0';
1700    for (i=1; i<=st_count(full_terminal_set); i++)
1701        if (i == val) {
1702            sprintf(str, "0 "); strcat(buf, str);
1703        } else {
1704            sprintf(str, "- "); strcat(buf, str);
1705        }
1706
1707
1708    if (pausing_stmt->type != DelayControlStmt) {
1709
1710        fprintf(file, "%s %s %s%s %s%s %s%s%06x\n", buf,
1711                ((fg_node_info*)pause->user_data)->loc,
1712                FG_LLOC, FG_RLOC, FG_LLOC, FG_RLOC,
1713                HSIS_EQUAL, FG_TIMER_PS,
1714                ((fg_graph_info*)g_vertex_graph(pause)->user_data)->fg_id);
1715        if (RQautomata) {
1716
1717            fprintf(file, "%s %s%s %s%s %s%s %s%s%06x\n", buf,
1718                    ((fg_node_info*)pause->user_data)->loc, FG_TIMER_PRIME,
1719                    FG_LLOC, FG_RLOC, FG_LLOC, FG_RLOC,
1720                    HSIS_EQUAL, FG_TIMER_PS,
1721                    ((fg_graph_info*)g_vertex_graph(pause)->user_data)->fg_id);
1722        }
1723        return;
1724    }
1725
1726
1727    src_timer = atoi(((fg_node_info*)pause->user_data)->loc+1);
1728    vl_expr_aux1_flag = vl_expr_aux2_flag = vl_expr_aux3_flag = 0;
1729    vl_expr_aux1_val = vl_expr_aux2_val = vl_expr_aux3_val = (double)0;
1730    if (!(pausing_stmt->delay->delay3 && !pausing_stmt->delay->delay2))
1731        delay1 = vl_eval_expr(pausing_stmt->delay->delay1);
1732    else {
1733        vl_expr *expr;
1734        lsFirstItem((lsList)pausing_stmt->delay->delay1, (lsGeneric*)&expr, 0);
1735        delay1 = vl_eval_expr(expr);
1736    }
1737    if (!vl_expr_aux3_flag)
1738        if (vl_expr_aux1_flag) delay = vl_expr_aux1_val;
1739        else delay = delay1;
1740    else
1741        delay = vl_expr_aux3_val;
1742
1743    if (!vl_noTimers) {
1744        fprintf(file, "%s %s %s%s %s%s %s%s%06x %s %s%d<%.3f\n", buf,
1745                ((fg_node_info*)pause->user_data)->loc,
1746                FG_LLOC, FG_RLOC, FG_LLOC,FG_RLOC, HSIS_EQUAL, FG_TIMER_PS,
1747                ((fg_graph_info*)g_vertex_graph(pause)->user_data)->fg_id,
1748                HSIS_TIMER_SEP, HSIS_BLIF_MVT_TIMER, src_timer, delay);
1749     }
1750
1751    if (RQautomata) {
1752        if (!vl_noTimers) {
1753            fprintf(file, "%s %s%s %s%s %s%s %s%s%06x %s %s%d<%.3f\n", buf,
1754                    ((fg_node_info*)pause->user_data)->loc, FG_TIMER_PRIME,
1755                    FG_LLOC, FG_RLOC, FG_LLOC, FG_RLOC,
1756                    HSIS_EQUAL, FG_TIMER_PS,
1757                    ((fg_graph_info*)g_vertex_graph(pause)->user_data)
1758                    ->fg_id,
1759                    HSIS_TIMER_SEP, HSIS_BLIF_MVT_TIMER, src_timer, delay);
1760        }
1761    }
1762}
1763
1764
1765static vertex_t *next_node_in_string(u)
1766vertex_t *u;
1767{
1768    vertex_t *v;
1769    lsList out_edges;
1770    edge_t *edge;
1771
1772    out_edges = g_get_out_edges(u);
1773    if (lsLength(out_edges) == 0) return NIL(vertex_t);
1774
1775    lsFirstItem(out_edges, (lsGeneric*)&edge, 0);
1776    v = g_e_dest(edge);
1777
1778    return v;
1779}
1780
1781
1782
1783void fg_write_timer(FILE *file, graph_t *graph)
1784{
1785    vertex_t *pause;
1786    vertex_t *v;
1787    lsGen gen;
1788    lsHandle handle;
1789    int pass;
1790
1791    fg_out_file = file;
1792    fprintf(file, "%s timing automatan: time flies\n", HSIS_COMMENT);
1793
1794    for (pass=1; pass<=2; pass++) {
1795
1796
1797
1798        if (pass == 1) {
1799            terminal_set = st_init_table(st_ptrcmp, st_ptrhash);
1800        }
1801
1802        for (gen=lsStart(((fg_graph_info*)graph->user_data)->pause_list);
1803             lsNext(gen, (lsGeneric*)&pause, &handle) != LS_NOMORE; ) {
1804            current_source_vtx = pause;
1805            if (!(v = next_node_in_string(pause)))
1806                continue;
1807
1808            if (pass == 1) {
1809                fg_fore_dfs(v, fg_node_is_pause,
1810                            remember_node_terminal, remember_arc_terminal);
1811            } else if (pass == 2) {
1812                fg_put_stay_pause(file, pause);
1813                terminal_set = st_init_table(st_ptrcmp, st_ptrhash);
1814                fg_gen_fore_dfs(v,
1815                                fg_node_is_pause, fg_put_timer_transition,
1816                                remember_node_terminal,
1817                                switch_node_branch,
1818                                forget_node_terminal,
1819                                remember_arc_terminal, forget_arc_terminal, 1);
1820
1821                st_free_table(terminal_set);
1822                terminal_set = NIL(st_table);
1823                terminal_set_count = 1;
1824            }
1825            current_source_vtx = NIL(vertex_t);
1826        }
1827        lsFinish(gen);
1828
1829        if (pass == 1) {
1830            fg_declare_timer(file, terminal_set, graph);
1831            fg_put_timer_header(file, terminal_set, graph);
1832
1833            full_terminal_set = terminal_set;
1834            terminal_set = NIL(st_table);
1835            terminal_set_count = 1;
1836        }
1837     }
1838
1839    fg_put_init_transition(file, graph);
1840
1841    st_free_table(full_terminal_set);
1842    full_terminal_set = NIL(st_table);
1843    fg_out_file = NIL(FILE);
1844}
1845
1846
1847static st_table *fg_node_set=NIL(st_table);
1848static int fg_consistency = 1;
1849
1850static void fg_check_duplicate(vertex_t *src)
1851{
1852    int val;
1853    vertex_t *v;
1854    edge_t *e;
1855    lsList visit_list;
1856    lsGen gen;
1857    lsHandle handle;
1858
1859    if (!fg_consistency) return;
1860    if (!src) return;
1861    if (((fg_node_info*)src->user_data)->type == FG_ND_PAUSE) return;
1862
1863    if (st_lookup(fg_node_set, (char*)src, (char**)&val)) {
1864        fg_consistency = 0;
1865    } else {
1866        st_insert(fg_node_set, (char*)src, 0);
1867        visit_list = g_get_out_edges(src);
1868        for (gen=lsStart(visit_list);
1869             lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; ) {
1870            v = g_e_dest(e);
1871            fg_check_duplicate(v);
1872        }
1873        lsFinish(gen);
1874    }
1875}
1876
1877
1878
1879int fg_check_timer_consistency(FILE *file, graph_t *graph)
1880{
1881    fg_consistency = 1;
1882    fg_node_set = st_init_table(st_ptrcmp, st_ptrhash);
1883
1884    fg_check_duplicate(((fg_graph_info*)graph->user_data)->init_node);
1885
1886    st_free_table(fg_node_set);
1887    fg_node_set = NIL(st_table);
1888    return fg_consistency;
1889}
1890
1891
1892
1893static int fg_id = 0;
1894static int fg_current_id = 0;
1895
1896
1897int fg_new_fg_id()
1898{
1899    fg_current_id = ++fg_id;
1900    return fg_current_id;
1901}
1902
1903
1904void fg_set_fg_id(int id)
1905{
1906    fg_current_id = id;
1907}
1908
1909
1910
1911int fg_fg_id()
1912{
1913    return fg_current_id;
1914}
1915
1916
1917
1918void fg_associate_id_vars(int id, st_table *vars)
1919{
1920    st_insert(vl_description->fg_vars_st, (char*)id, (char*)vars);
1921}
1922
1923
1924static int data_pause_count=0;
1925
1926st_table *fg_graph_has_one_data_detector(graph)
1927graph_t *graph;
1928{
1929    vl_event_control_stmt *pstmt;
1930    vl_event_expr *e;
1931    lsGen gen, ggen;
1932    vertex_t *v;
1933    lsHandle handle;
1934    int non_data_pause;
1935    int check_failed;
1936    st_table *new_sensitiveList;
1937
1938    if (!graph) return NIL(st_table);
1939
1940    non_data_pause = 0;
1941    check_failed = 0;
1942    data_pause_count=0;
1943    new_sensitiveList = st_init_table(strcmp, st_strhash);
1944    foreach_vertex(graph, ggen, v) {
1945        if (((fg_node_info*)v->user_data)->type == FG_ND_PAUSE &&
1946            !check_failed) {
1947            pstmt =
1948              (vl_event_control_stmt*)((fg_node_info*)v->user_data)->data;
1949            if (pstmt->type == EventControlStmt) {
1950
1951                if (pstmt->event->type == OrEventExpr) {
1952                    for (gen=lsStart(pstmt->event->list);
1953                         lsNext(gen,(lsGeneric*)&e,&handle)!=LS_NOMORE; ) {
1954                        if (e->type == NegedgeEventExpr ||
1955                            e->type == PosedgeEventExpr) {
1956                            non_data_pause = 1;
1957                            break;
1958                        }
1959                        if (e->expr->type == IDExpr)
1960                            st_insert(new_sensitiveList,
1961                                      e->expr->u.name->name,0);
1962                        else if (e->expr->type == MinTypMaxExpr) {
1963                            if (e->expr->u.exprs.e1->type == IDExpr)
1964                                st_insert(new_sensitiveList,
1965                                          e->expr->u.exprs.e1->u.name->name,0);
1966                        }
1967                    }
1968                    lsFinish(gen);
1969                } else {
1970                    if (pstmt->event->type == NegedgeEventExpr ||
1971                        pstmt->event->type == PosedgeEventExpr) {
1972                        non_data_pause = 1;
1973                    }
1974                    if (pstmt->event->expr->type == IDExpr)
1975                        st_insert(new_sensitiveList,
1976                                  pstmt->event->expr->u.name->name,0);
1977                }
1978
1979                if (!non_data_pause)
1980                    data_pause_count++;
1981                else
1982                    check_failed = 1;
1983            }
1984        }
1985    }
1986
1987    if (data_pause_count==1 && !check_failed) {
1988    } else {
1989        st_free_table(new_sensitiveList);
1990        new_sensitiveList = NIL(st_table);
1991    }
1992
1993    return new_sensitiveList;
1994}
Note: See TracBrowser for help on using the repository browser.