From 62fce50f8c2cec4d7dc26a1e8a201c48b90b4a72 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 24 Oct 2014 13:07:53 -0700 Subject: [PATCH] Remove dead code for allocate_vec handling. --- tgt-vvp/draw_ufunc.c | 3 - tgt-vvp/stmt_assign.c | 216 ------------------------------------------ tgt-vvp/vector.c | 175 ---------------------------------- tgt-vvp/vvp_priv.h | 51 ---------- tgt-vvp/vvp_process.c | 58 +----------- 5 files changed, 5 insertions(+), 498 deletions(-) diff --git a/tgt-vvp/draw_ufunc.c b/tgt-vvp/draw_ufunc.c index 42a561d0a..22d406f6d 100644 --- a/tgt-vvp/draw_ufunc.c +++ b/tgt-vvp/draw_ufunc.c @@ -156,9 +156,6 @@ void draw_ufunc_vec4(ivl_expr_t expr) /* Take in arguments to function and call function code. */ draw_ufunc_preamble(expr); - /* Fresh basic block starts after the join. */ - clear_expression_lookaside(); - assert(ivl_signal_dimensions(retval) == 0); fprintf(vvp_out, " %%load/vec4 v%p_0;\n", retval); diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index 927a073c3..efc9fdefa 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -323,222 +323,6 @@ static ivl_type_t draw_lval_expr(ivl_lval_t lval) return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval)); } -#if 0 -static void set_vec_to_lval_slice_nest(ivl_lval_t lval, unsigned bit, unsigned wid) -{ - ivl_lval_t lval_nest = ivl_lval_nest(lval); - ivl_type_t ltype = draw_lval_expr(lval_nest); - assert(ivl_type_base(ltype) == IVL_VT_CLASS); - - fprintf(vvp_out, " %%store/prop/v %d, %u, %u;\n", - ivl_lval_property_idx(lval), bit, wid); - fprintf(vvp_out, " %%pop/obj 1, 0;\n"); -} -#endif - -#if 0 -static void set_vec_to_lval_slice(ivl_lval_t lval, unsigned bit, unsigned wid) -{ - ivl_signal_t sig = ivl_lval_sig(lval); - ivl_expr_t part_off_ex = ivl_lval_part_off(lval); - unsigned long part_off = 0; - - /* Although Verilog doesn't support it, we'll handle - here the case of an l-value part select of an array - word if the address is constant. */ - ivl_expr_t word_ix = ivl_lval_idx(lval); - unsigned long use_word = 0; - - /* If the l-value is nested, then it is something like a class - with a chain of member names, so handle that elsewhere. */ - if (ivl_lval_nest(lval)) { - set_vec_to_lval_slice_nest(lval, bit, wid); - return; - } - - if (part_off_ex == 0) { - part_off = 0; - } else if (number_is_immediate(part_off_ex, IMM_WID, 0) && - !number_is_unknown(part_off_ex)) { - part_off = get_number_immediate(part_off_ex); - part_off_ex = 0; - } - - /* If the word index is a constant expression, then evaluate - it to select the word, and pay no further heed to the - expression itself. Out-of-bounds and undefined indices are - converted to a canonical index of 'bx during elaboration, - and we don't try to optimise that case. */ - if (word_ix && number_is_immediate(word_ix, IMM_WID, 0) && - !number_is_unknown(word_ix)) { - use_word = get_number_immediate(word_ix); - assert(use_word < ivl_signal_array_count(sig)); - word_ix = 0; - } - - if (part_off_ex && ivl_signal_dimensions(sig) == 0) { - unsigned skip_set = transient_id++; - - /* There is a mux expression, so this must be a write to - a bit-select l-val. Presumably, the x0 index register - has been loaded wit the result of the evaluated - part select base expression. */ - assert(!word_ix); - - draw_eval_expr_into_integer(part_off_ex, 0); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - - fprintf(vvp_out, " %%set/x0 v%p_%lu, %u, %u;\n", - sig, use_word, bit, wid); - fprintf(vvp_out, "t_%u ;\n", skip_set); - /* save_signal width of 0 CLEARS the signal from the - lookaside. */ - save_signal_lookaside(bit, sig, use_word, 0); - - } else if (part_off_ex && ivl_signal_dimensions(sig) > 0) { - - /* Here we have a part select write into an array word. */ - unsigned skip_set = transient_id++; - if (word_ix) { - int part_off_reg = allocate_word(); - draw_eval_expr_into_integer(part_off_ex, part_off_reg); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - draw_eval_expr_into_integer(word_ix, 3); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - fprintf(vvp_out, " %%ix/mov 1, %d;\n", part_off_reg); - clr_word(part_off_reg); - } else { - draw_eval_expr_into_integer(part_off_ex, 1); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n", use_word); - } - fprintf(vvp_out, " %%set/av v%p, %u, %u;\n", - sig, bit, wid); - fprintf(vvp_out, "t_%u ;\n", skip_set); - - } else if ((part_off>0 || ivl_lval_width(lval)!=ivl_signal_width(sig)) - && ivl_signal_dimensions(sig) > 0) { - - /* Here we have a part select write into an array word. */ - unsigned skip_set = transient_id++; - if (word_ix) { - draw_eval_expr_into_integer(word_ix, 3); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - } else { - fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n", use_word); - } - fprintf(vvp_out, " %%ix/load 1, %lu, 0;\n", part_off); - fprintf(vvp_out, " %%set/av v%p, %u, %u;\n", - sig, bit, wid); - if (word_ix) /* Only need this label if word_ix is set. */ - fprintf(vvp_out, "t_%u ;\n", skip_set); - - } else if (part_off>0 || ivl_lval_width(lval)!=ivl_signal_width(sig)) { - /* There is no mux expression, but a constant part - offset. Load that into index x0 and generate a - vector set instruction. */ - assert(ivl_lval_width(lval) == wid); - - /* If the word index is a constant, then we can write - directly to the word and save the index - calculation. Also, note the special case that we are - writing to a UWIRE. In that case, use the %force/x0 - instruction to get the desired effect. */ - if (word_ix == 0 && ivl_signal_type(sig)==IVL_SIT_UWIRE) { - fprintf(vvp_out, " %%ix/load 0, %lu, 0;\n", part_off); - fprintf(vvp_out, " %%force/x0 v%p_%lu, %u, %u;\n", - sig, use_word, bit, wid); - - } else if (word_ix == 0) { - fprintf(vvp_out, " %%ix/load 0, %lu, 0;\n", part_off); - fprintf(vvp_out, " %%set/x0 v%p_%lu, %u, %u;\n", - sig, use_word, bit, wid); - - } else { - unsigned skip_set = transient_id++; - unsigned index_reg = 3; - draw_eval_expr_into_integer(word_ix, index_reg); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - fprintf(vvp_out, " %%ix/load 1, %lu, 0;\n", part_off); - fprintf(vvp_out, " %%set/av v%p, %u, %u;\n", - sig, bit, wid); - fprintf(vvp_out, "t_%u ;\n", skip_set); - } - /* save_signal width of 0 CLEARS the signal from the - lookaside. */ - save_signal_lookaside(bit, sig, use_word, 0); - - } else if (ivl_signal_dimensions(sig) > 0) { - - /* If the word index is a constant, then we can write - directly to the word and save the index calculation. */ - if (word_ix == 0) { - fprintf(vvp_out, " %%ix/load 1, 0, 0;\n"); - fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n", use_word); - fprintf(vvp_out, " %%set/av v%p, %u, %u;\n", - sig, bit, wid); - - } else { - unsigned skip_set = transient_id++; - unsigned index_reg = 3; - draw_eval_expr_into_integer(word_ix, index_reg); - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - fprintf(vvp_out, " %%ix/load 1, 0, 0;\n"); - fprintf(vvp_out, " %%set/av v%p, %u, %u;\n", - sig, bit, wid); - fprintf(vvp_out, "t_%u ;\n", skip_set); - } - /* save_signal width of 0 CLEARS the signal from the - lookaside. */ - save_signal_lookaside(bit, sig, use_word, 0); - - - } else { - fprintf(vvp_out, " %%set/v v%p_%lu, %u, %u;\n", - sig, use_word, bit, wid); - /* save_signal width of 0 CLEARS the signal from the - lookaside. */ - save_signal_lookaside(bit, sig, use_word, 0); - - } -} -#endif -#if 0 -/* - * This is a private function to generate %set code for the - * statement. At this point, the r-value is evaluated and stored in - * the res vector, I just need to generate the %set statements for the - * l-values of the assignment. - */ -static void set_vec_to_lval(ivl_statement_t net, struct vector_info res) -{ - unsigned wid = res.wid; - unsigned lidx; - unsigned cur_rbit = 0; - - for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { - unsigned bidx; - unsigned bit_limit = wid - cur_rbit; - - ivl_lval_t lval = ivl_stmt_lval(net, lidx); - - /* Reduce bit_limit to the width of this l-value. */ - if (bit_limit > ivl_lval_width(lval)) - bit_limit = ivl_lval_width(lval); - - /* This is the address within the larger r-value of the - bit that this l-value takes. */ - bidx = res.base < 4? res.base : (res.base+cur_rbit); - - set_vec_to_lval_slice(lval, bidx, bit_limit); - - /* Now we've consumed this many r-value bits for the - current l-value. */ - cur_rbit += bit_limit; - } -} -#endif - /* * Store a vector from the vec4 stack to the statement l-values. This * all assumes that the value to be assigned is already on the top of diff --git a/tgt-vvp/vector.c b/tgt-vvp/vector.c index 464ebf1d6..7c901ff6d 100644 --- a/tgt-vvp/vector.c +++ b/tgt-vvp/vector.c @@ -18,178 +18,3 @@ # include "vvp_priv.h" # include - -/* Maximum vector bits in a thread. If a thread co-processor is - * implemented, this value may need to be reduced. At that time - * wider operations will need to be partitioned. For example - * shift operations on WIDE (say > 64k bit) registers. - */ -#define MAX_VEC (256*1024) - -static struct allocation_score_s { - ivl_expr_t exp; - ivl_signal_t sig; - unsigned sig_word; - unsigned exp_bit : 24; - unsigned sig_bit : 24; - unsigned alloc : 8; -} allocation_map[MAX_VEC] = { {0, 0, 0, 0, 0, 0} }; - -/* This is the largest bit to have lookaside values. */ -static unsigned lookaside_top = 0; - -static __inline__ ivl_expr_t peek_exp(unsigned addr) -{ - return allocation_map[addr].exp; -} - -static __inline__ unsigned peek_exp_bit(unsigned addr) -{ - return allocation_map[addr].exp_bit; -} - -static __inline__ void set_exp(unsigned addr, ivl_expr_t expr, unsigned ebit) -{ - allocation_map[addr].exp = expr; - allocation_map[addr].exp_bit = ebit; -} - -static __inline__ void set_sig(unsigned addr, ivl_signal_t expr, - unsigned sig_word, unsigned ebit) -{ - allocation_map[addr].sig = expr; - allocation_map[addr].sig_word = sig_word; - allocation_map[addr].sig_bit = ebit; -} - -/* - * This clears a vector that was previously allocated by - * allocate_vector. That is, it unmarks all the bits of the map that - * represent this vector. - * - * If the vector is based in one of 4 constant bit values, then there - * are no bits to clear. If the vector is based in the 4-8 result - * area, then someone is broken. - */ -void clr_vector(struct vector_info vec) -{ - unsigned idx; - if (vec.base < 4) - return; - assert(vec.base >= 8); - for (idx = 0 ; idx < vec.wid ; idx += 1) { - assert( allocation_map[vec.base+idx].alloc > 0); - allocation_map[vec.base+idx].alloc -= 1; - } -} - -#if 0 -static unsigned allocate_vector_no_lookaside(unsigned wid, int skip_lookaside) -{ - unsigned base = 8; - unsigned idx = 0; - - while (idx < wid) { - if (base+idx >= MAX_VEC) - return 0; - - assert((base + idx) < MAX_VEC); - if ((allocation_map[base+idx].alloc > 0) - || (skip_lookaside && peek_exp(base+idx))) { - base = base + idx + 1; - idx = 0; - - } else { - idx += 1; - } - } - - for (idx = 0 ; idx < wid ; idx += 1) { - allocation_map[base+idx].alloc += 1; - set_exp(base+idx, 0, 0); - set_sig(base+idx, 0, 0, 0); - } - - return base; -} -#endif - -/* - * This unconditionally allocates a stretch of bits from the register - * set. It never returns a bit addressed <8 (0-3 are constant, 4-7 are - * condition codes). - * - * First try to allocate a vector without interfering with any bits - * cached by the lookaside buffer. If that doesn't work, then try - * again without worrying about trashing lookaside results. This - * should lead to preferentially allocating new bits instead of - * constantly overwriting intermediate results. - * - * If there is no space for a vector of the given width, then give up - * and return 0. - */ -unsigned allocate_vector(unsigned wid) -{ -#if 0 - unsigned base = allocate_vector_no_lookaside(wid, 1); - - if (base == 0) - base = allocate_vector_no_lookaside(wid, 0); - return base; -#else - assert(0); - return 0; -#endif -} - -/* - * This clears the expression cache of the allocation map. It is - * called to prevent reuse of existing expressions, normally at the - * start of a basic block, but also at the end of thread processing. - */ -void clear_expression_lookaside(void) -{ - unsigned idx; - - for (idx = 0 ; idx < lookaside_top ; idx += 1) { - set_exp(idx, 0, 0); - set_sig(idx, 0, 0, 0); - } - - lookaside_top = 0; -} - -static void clear_signal_lookaside_bit(unsigned idx, ivl_signal_t sig, unsigned sig_word) -{ - if (allocation_map[idx].alloc > 0) - return; - if (allocation_map[idx].sig != sig) - return; - if (allocation_map[idx].sig_word != sig_word) - return; - - set_sig(idx, 0, 0, 0); -} - -void save_signal_lookaside(unsigned addr, ivl_signal_t sig, unsigned sig_word, unsigned wid) -{ - unsigned idx; - /* Don't bind any of the low bits to a signal. */ - if (addr < 8 && wid > 0) - return; - - assert((addr+wid) <= MAX_VEC); - - for (idx = 8 ; idx < addr ; idx += 1) - clear_signal_lookaside_bit(idx, sig, sig_word); - - for (idx = 0 ; idx < wid ; idx += 1) - set_sig(addr+idx, sig, sig_word, idx); - - if ((addr+wid) > lookaside_top) - lookaside_top = addr+wid; - - for (idx = addr+wid ; idx < lookaside_top ; idx += 1) - clear_signal_lookaside_bit(idx, sig, sig_word); -} - diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index 455cb4029..821d1304a 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -207,57 +207,6 @@ extern const char*draw_input_from_net(ivl_nexus_t nex); */ extern void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix); -/* - * These functions manage vector allocation in the thread register - * space. They presume that we work on one thread at a time, to - * completion. - * - * allocate_vector - * Return the base of an allocated vector in the thread. The bits - * are marked allocated in the process. - * - * clr_vector - * Clear a vector previously allocated. - * - * The thread vector allocator also keeps a lookaside of expression - * results that are stored in register bit. This lookaside can be used - * by the code generator to notice that certain expression bits are - * already calculated, and can be reused. - * - * clear_expression_lookaside - * Clear the lookaside tables for the current thread. This must be - * called before starting a new thread, and around basic blocks - * that are entered from unknown places. - * - * save_expression_lookaside - * Mark the given expression as available in the given register - * bits. This remains until the lookaside is cleared. This does not - * clear the allocation, it is still necessary to call clr_vector. - * - * save_signal_lookaside - * Mark the given signal as available in the given register bits. - * This is different from a given expression, in that the signal - * lookaside is in addition to the expression lookaside. The signal - * lookaside is specifically to save on unnecessary loads of a - * signal recently written. - * - * allocate_vector_exp - * This function attempts to locate the expression in the - * lookaside. If it finds it, return a reallocated base for the - * expression. Otherwise, return 0. - * - * The allocate_vector and allocate_vector_exp calls must have - * matching call to clr_vector. Although the allocate_vector will - * never reallocate a vector already allocated, the allocate_vector_exp - * might, so it is possible for allocations to nest in that - * manner. The exclusive_flag to allocate_vector_exp will prevent - * nested allocations. This is needed where the expression result is - * expected to be overwritten. - */ -extern unsigned allocate_vector(unsigned wid); -extern void clr_vector(struct vector_info vec); - -extern void clear_expression_lookaside(void); extern int number_is_unknown(ivl_expr_t ex); extern int number_is_immediate(ivl_expr_t ex, unsigned lim_wid, int negative_is_ok); diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index ea299c5c9..4183df81f 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -107,7 +107,6 @@ static void assign_to_array_r_word(ivl_signal_t lsig, ivl_expr_t word_ix, fprintf(vvp_out, "t_%u ;\n", end_assign); if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n"); - clear_expression_lookaside(); } static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, @@ -200,7 +199,6 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, clr_flag(error_flag); if (part_off_reg) clr_word(part_off_reg); - clear_expression_lookaside(); } /* @@ -580,8 +578,7 @@ static int show_stmt_assign_nb(ivl_statement_t net) } - { struct vector_info res = {0,0}; - unsigned wid; + { unsigned wid; unsigned lidx; unsigned cur_rbit = 0; /* Handle the special case that the expression is a real @@ -593,19 +590,7 @@ static int show_stmt_assign_nb(ivl_statement_t net) assignment. */ wid = ivl_stmt_lwidth(net); - res.base = allocate_vector(wid); - res.wid = wid; - - if (res.base == 0) { - fprintf(stderr, "%s:%u: vvp.tgt error: " - "Unable to allocate %u thread bits for " - "r-value expression.\n", ivl_expr_file(rval), - ivl_expr_lineno(rval), wid); - vvp_errors += 1; - } - - fprintf(vvp_out, " %%cvt/vr %u, %u;\n", - res.base, res.wid); + fprintf(vvp_out, " %%cvt/vr %u;\n", wid); } else { wid = ivl_stmt_lwidth(net); @@ -637,9 +622,6 @@ static int show_stmt_assign_nb(ivl_statement_t net) cur_rbit += bit_limit; } - - if (res.base > 3) - clr_vector(res); } return 0; @@ -679,17 +661,12 @@ static int show_stmt_block_named(ivl_statement_t net, ivl_scope_t scope) fprintf(vvp_out, " .scope S_%p;\n", subscope); fprintf(vvp_out, "t_%u ;\n", sub_id); - /* The statement within the fork is in a new thread, so no - expression lookaside is valid. */ - clear_expression_lookaside(); - rc = show_stmt_block(net, subscope); fprintf(vvp_out, " %%end;\n"); /* Return to the previous scope. */ fprintf(vvp_out, " .scope S_%p;\n", scope); fprintf(vvp_out, "t_%u %%join;\n", out_id); - clear_expression_lookaside(); return rc; } @@ -775,7 +752,6 @@ static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope) continue; fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_base+idx); - clear_expression_lookaside(); rc += show_statement(cst, sscope); /* Statement is done, jump to the out of the case. */ @@ -791,8 +767,6 @@ static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope) the stack, but we are done with it now. Pop it. */ fprintf(vvp_out, " %%pop/vec4 1;\n"); - clear_expression_lookaside(); - return rc; } @@ -857,7 +831,6 @@ static int show_stmt_case_r(ivl_statement_t net, ivl_scope_t sscope) continue; fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_base+idx); - clear_expression_lookaside(); rc += show_statement(cst, sscope); fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, @@ -1277,16 +1250,13 @@ static int show_stmt_condit(ivl_statement_t net, ivl_scope_t sscope) if (ivl_stmt_cond_false(net)) { fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, lab_out); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_false); - clear_expression_lookaside(); rc += show_statement(ivl_stmt_cond_false(net), sscope); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_out); - clear_expression_lookaside(); } else { fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_false); - clear_expression_lookaside(); } return rc; @@ -1312,8 +1282,6 @@ static int show_stmt_delay(ivl_statement_t net, ivl_scope_t sscope) show_stmt_file_line(net, "Delay statement."); fprintf(vvp_out, " %%delay %lu, %lu;\n", low, hig); - /* Lots of things can happen during a delay. */ - clear_expression_lookaside(); rc += show_statement(stmt, sscope); @@ -1357,9 +1325,6 @@ static int show_stmt_delayx(ivl_statement_t net, ivl_scope_t sscope) fprintf(vvp_out, " %%delayx %d;\n", use_idx); clr_word(use_idx); - /* Lots of things can happen during a delay. */ - clear_expression_lookaside(); - rc += show_statement(stmt, sscope); return rc; } @@ -1396,7 +1361,6 @@ static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope) because it can be entered from above or from the bottom of the loop. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label); - clear_expression_lookaside(); /* Draw the body of the loop. */ rc += show_statement(ivl_stmt_sub_stmt(net), sscope); @@ -1520,7 +1484,6 @@ static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope) /* Generate the sub-threads themselves. */ for (idx = 0 ; idx < (join_count + join_detach_count) ; idx += 1) { fprintf(vvp_out, "t_%u ;\n", id_base+idx); - clear_expression_lookaside(); rc += show_statement(ivl_stmt_block_stmt(net, idx), scope); fprintf(vvp_out, " %%end;\n"); } @@ -1529,7 +1492,6 @@ static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope) /* This is the label for the out. Use this to branch around the implementations of all the child threads. */ - clear_expression_lookaside(); fprintf(vvp_out, "t_%u ;\n", out); return rc; @@ -1700,7 +1662,7 @@ static int show_stmt_utask(ivl_statement_t net) vvp_mangle_id(ivl_scope_name(task))); fprintf(vvp_out, ", S_%p;\n", task); fprintf(vvp_out, " %%join;\n"); - clear_expression_lookaside(); + return 0; } @@ -1733,9 +1695,6 @@ static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope) fprintf(vvp_out, ";\n %%wait Ewait_%u;\n", cascade_counter); cascade_counter += 1; } - /* Always clear the expression lookaside after a - %wait. Anything can happen while the thread is waiting. */ - clear_expression_lookaside(); return show_statement(ivl_stmt_sub_stmt(net), sscope); } @@ -1753,7 +1712,7 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) because it can be entered from above or from the bottom of the loop. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label); - clear_expression_lookaside(); + /* Draw the evaluation of the condition expression, and test the result. If the expression evaluates to false, then @@ -1776,7 +1735,7 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) test is repeated, and also draw the out label. */ fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, top_label); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, out_label); - clear_expression_lookaside(); + return rc; } @@ -1859,10 +1818,6 @@ static int show_system_task_call(ivl_statement_t net) draw_vpi_task_call(net); - /* VPI calls can manipulate anything, so clear the expression - lookahead table after the call. */ - clear_expression_lookaside(); - return 0; } @@ -2414,7 +2369,6 @@ int draw_process(ivl_process_t net, void*x) /* Generate the entry label. Just give the thread a number so that we ar certain the label is unique. */ fprintf(vvp_out, "T_%u ;\n", thread_count); - clear_expression_lookaside(); /* Draw the contents of the thread. */ rc += show_statement(stmt, scope); @@ -2463,7 +2417,6 @@ int draw_task_definition(ivl_scope_t scope) ivl_statement_t def = ivl_scope_def(scope); fprintf(vvp_out, "TD_%s ;\n", vvp_mangle_id(ivl_scope_name(scope))); - clear_expression_lookaside(); assert(def); rc += show_statement(def, scope); @@ -2480,7 +2433,6 @@ int draw_func_definition(ivl_scope_t scope) ivl_statement_t def = ivl_scope_def(scope); fprintf(vvp_out, "TD_%s ;\n", vvp_mangle_id(ivl_scope_name(scope))); - clear_expression_lookaside(); assert(def); rc += show_statement(def, scope);