/* Copyright (c) 1992, 1993 Regents of the University of California All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. However, any distribution of this software or derivative works must include the above copyright notice. This software is made available AS IS, and neither the Electronics Research Laboratory or the Universify of California make any warranty about the software, its performance or its conformity to any specification. Author: Szu-Tsung Cheng, stcheng@ic.Berkeley.EDU 10/92 10/93 $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/dataflow.c,v 1.1.1.1 2001/07/09 23:22:38 fabio Exp $ */ #include "util.h" #include "st.h" #include "list.h" #include "array.h" #include "set.h" #include "stack.h" #include "vl_types.h" #include "vl_defs.h" #include "vlr_int.h" #include "dataflow.h" #include "verilog.h" int dflow_analysis = 0; int dflow_context = 0; lsList init_var_stack; void dataflow_init() { init_var_stack = lsCreate(); push_stack(init_var_stack, set_empty()); } void dataflow_end() { lsGen gen; lsHandle handle; set_t *set; gen = lsStart(init_var_stack); while (lsNext(gen, (lsGeneric*)&set, &handle) != LS_NOMORE) { set_destroy(set); } lsFinish(gen); lsDestroy(init_var_stack, 0); init_var_stack = 0; } void dataflow_analysis(analysis_type, id_sym, gen, kill) int analysis_type; vl_id_range *id_sym; int gen; int kill; { if (gen && kill) { char buf[MAXSTRLEN]; sprintf("dataflow analysis: GEN and KILL '%s' at the same time", id_sym->name); internal_error(buf); } if (vl_currentModule) { if (analysis_type & DF_UninitVar && (dflow_context & DFLOW_Always)) { if (gen) record_uninitialized_var(id_sym); else if (kill) record_initialized_var(id_sym); } } } void dataflow_dup_set() { if (!init_var_stack) return; push_stack(init_var_stack, (void*)set_dup(top_stack(init_var_stack))); } set_t *dataflow_pop_set() { set_t *retval; if (!init_var_stack) return NIL(set_t); pop_stack(init_var_stack, (void**)&retval); return retval; } void dataflow_replace_set(new_set) set_t *new_set; { set_t *top_set; if (!init_var_stack) return; pop_stack(init_var_stack, (void**)&top_set); push_stack(init_var_stack, new_set); set_destroy(top_set); } set_t *dataflow_merge_set(set1, set2) set_t *set1, *set2; { set_t *retval; if (!init_var_stack) return NIL(set_t); retval = set_intersect(set1, set2); return retval; } void dataflow_free_set(set) set_t *set; { if (set) set_destroy(set); } void record_uninitialized_var(id_sym) vl_id_range *id_sym; { if (!init_var_stack) return; if (!set_find(id_sym->name, (set_t*)top_stack(init_var_stack))) { if (!set_find(id_sym->name, vl_currentModule->uninit_set)) { vl_id_range *id_range; if (st_lookup(vl_currentModule->sig_st, id_sym->name, (char**)&id_range)) { id_range->flags |= UninitializeVar; set_add(id_range->name, vl_currentModule->uninit_set); } } } } void record_initialized_var(id_sym) vl_id_range *id_sym; { if (!init_var_stack) return; if (!set_find(id_sym->name, (set_t*)top_stack(init_var_stack))) { set_add(id_sym->name, (set_t*)top_stack(init_var_stack)); } }