Leak repairs and node leak detection
git-svn-id: file://localhost/svn/verilator/trunk/verilator@967 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
8075372675
commit
98e35b02ad
164
Changes
164
Changes
|
@ -7,23 +7,25 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** Support "#delay <statement>;" with associated STMTDLY warning.
|
||||
|
||||
**** Fix divide-by-zero errors in constant propagator. [Rodney Sinclair]
|
||||
**** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair]
|
||||
|
||||
**** Fix wrong result with obscure signed-shift underneath a "? :".
|
||||
**** Fixed wrong result with obscure signed-shift underneath a "? :".
|
||||
|
||||
**** Fixed many internal memory leaks, and added leak detector.
|
||||
|
||||
* Verilator 3.654 10/18/2007
|
||||
|
||||
**** Don't exit early if many warnings but no errors are found. [Stan Mayer]
|
||||
|
||||
**** Fix parsing module #(parameter x,y) declarations. [Oleg Rodionov]
|
||||
**** Fixed parsing module #(parameter x,y) declarations. [Oleg Rodionov]
|
||||
|
||||
**** Fix parsing system functions with empty parens. [Oleg Rodionov]
|
||||
**** Fixed parsing system functions with empty parens. [Oleg Rodionov]
|
||||
|
||||
* Verilator 3.653 8/1/2007
|
||||
|
||||
**** Support SystemVerilog ==? and !=? operators.
|
||||
|
||||
**** Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
|
||||
**** Fixed SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
|
||||
|
||||
* Verilator 3.652 6/21/2007
|
||||
|
||||
|
@ -35,7 +37,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Optimize constant $display arguments.
|
||||
|
||||
**** Fix Preprocessor dropping some `line directives. [Mark Nodine]
|
||||
**** Fixed Preprocessor dropping some `line directives. [Mark Nodine]
|
||||
|
||||
* Verilator 3.651 5/22/2007
|
||||
|
||||
|
@ -70,11 +72,11 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams]
|
||||
|
||||
**** Fix compile errors under Windows MINGW compiler. [Gerald Williams]
|
||||
**** Fixed compile errors under Windows MINGW compiler. [Gerald Williams]
|
||||
|
||||
**** Fix dotted bit reference to local memory. [Eugene Weber]
|
||||
**** Fixed dotted bit reference to local memory. [Eugene Weber]
|
||||
|
||||
**** Fix 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson]
|
||||
**** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson]
|
||||
|
||||
* Verilator 3.640 3/12/2007
|
||||
|
||||
|
@ -86,13 +88,13 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Try all +libext's in the exact order given. [Michael Shinkarovsky]
|
||||
|
||||
**** Fix elimination of public signals assigned to constants. [Eugene Weber]
|
||||
**** Fixed elimination of public signals assigned to constants. [Eugene Weber]
|
||||
|
||||
**** Fix internal error when public for loop has empty body. [David Addison]
|
||||
**** Fixed internal error when public for loop has empty body. [David Addison]
|
||||
|
||||
**** Fix "Loops detected" assertion when model exceeds 4GB. [David Hewson]
|
||||
**** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson]
|
||||
|
||||
**** Fix display %m names inside named blocks.
|
||||
**** Fixed display %m names inside named blocks.
|
||||
|
||||
* Verilator 3.633 2/7/2007
|
||||
|
||||
|
@ -100,11 +102,11 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky]
|
||||
|
||||
**** Fix isolate_assignments when many signals per always. [Mike Shinkarovsky]
|
||||
**** Fixed isolate_assignments when many signals per always. [Mike Shinkarovsky]
|
||||
|
||||
**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
|
||||
**** Fixed isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
|
||||
|
||||
**** Fix $display's with array select followed by wide AND. [David Hewson]
|
||||
**** Fixed $display's with array select followed by wide AND. [David Hewson]
|
||||
|
||||
* Verilator 3.632 1/17/2007
|
||||
|
||||
|
@ -115,11 +117,11 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
** Support standard NAME[#] for cells created by arraying or generate for.
|
||||
This replaces the non-standard name__# syntax used in earlier versions.
|
||||
|
||||
**** Fix again dotted references into generate cells. [David Hewson]
|
||||
**** Fixed again dotted references into generate cells. [David Hewson]
|
||||
Verilator no longer accepts duplicated variables inside unique
|
||||
generate blocks as this is illegal according to the specification.
|
||||
|
||||
**** Fix $readmem* with filenames < 8 characters. [Emerson Suguimoto]
|
||||
**** Fixed $readmem* with filenames < 8 characters. [Emerson Suguimoto]
|
||||
|
||||
* Verilator 3.630 12/19/2006
|
||||
|
||||
|
@ -131,21 +133,21 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** Reduce depth of priority encoded case statements. [Eugene Weber]
|
||||
|
||||
**** Fix dotted references inside generated cells. [David Hewson]
|
||||
**** Fixed dotted references inside generated cells. [David Hewson]
|
||||
|
||||
**** Fix missed split optimization points underneath other re-split blocks.
|
||||
**** Fixed missed split optimization points underneath other re-split blocks.
|
||||
|
||||
* Verilator 3.623 12/05/2006
|
||||
|
||||
*** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber]
|
||||
|
||||
**** Fix $signed mis-extending when input has a WIDTH violation. [Eugene Weber]
|
||||
**** Fixed $signed mis-extending when input has a WIDTH violation. [Eugene Weber]
|
||||
|
||||
**** Add M32 make variable to support -m32 compiles. [Eugene Weber]
|
||||
|
||||
* Verilator 3.622 10/17/2006 Stable
|
||||
|
||||
**** Fix --skip-identical without --debug, broken in 3.621. [Andy Meier]
|
||||
**** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier]
|
||||
|
||||
* Verilator 3.621 10/11/2006 Beta
|
||||
|
||||
|
@ -155,11 +157,11 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Remove .vpp intermediate files when not under --debug.
|
||||
|
||||
**** Fix link error when using --exe with --trace. [Eugene Weber]
|
||||
**** Fixed link error when using --exe with --trace. [Eugene Weber]
|
||||
|
||||
**** Fix mis-optimization of wide concats with constants.
|
||||
**** Fixed mis-optimization of wide concats with constants.
|
||||
|
||||
**** Fix core dump on printing error when not under --debug. [Allan Cochrane]
|
||||
**** Fixed core dump on printing error when not under --debug. [Allan Cochrane]
|
||||
|
||||
* Verilator 3.620 10/04/2006 Stable
|
||||
|
||||
|
@ -174,9 +176,9 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Optimize additional boolean identities (a|a = a, etc.)
|
||||
|
||||
**** Fix coredump when dotted cross-ref inside task call. [Eugene Weber]
|
||||
**** Fixed coredump when dotted cross-ref inside task call. [Eugene Weber]
|
||||
|
||||
**** Fix dotted variables in always sensitivity lists. [Allan Cochrane]
|
||||
**** Fixed dotted variables in always sensitivity lists. [Allan Cochrane]
|
||||
|
||||
* Verilator 3.610 09/20/2006 Stable
|
||||
|
||||
|
@ -186,13 +188,13 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Removed coverage request variable; see Coverage limitations in docs.
|
||||
|
||||
**** Fix DOS carriage returns in multiline defines. [Ralf Karge]
|
||||
**** Fixed DOS carriage returns in multiline defines. [Ralf Karge]
|
||||
|
||||
**** Fix printf format warnings on 64-bit linux.
|
||||
**** Fixed printf format warnings on 64-bit linux.
|
||||
|
||||
* Verilator 3.602 09/11/2006 Stable
|
||||
|
||||
**** Fix function references under top inlined module. [David Hewson]
|
||||
**** Fixed function references under top inlined module. [David Hewson]
|
||||
|
||||
* Verilator 3.601 09/06/2006 Beta
|
||||
|
||||
|
@ -205,15 +207,15 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
*** Changed how internal functions are invoked to reduce aliasing.
|
||||
Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%.
|
||||
|
||||
**** Fix memory leak when destroying modules. [John Stroebel]
|
||||
**** Fixed memory leak when destroying modules. [John Stroebel]
|
||||
|
||||
**** Fix coredump when unused modules have unused cells. [David Hewson]
|
||||
**** Fixed coredump when unused modules have unused cells. [David Hewson]
|
||||
|
||||
**** Fix 3.600 internal error with arrayed instances. [David Hewson]
|
||||
**** Fixed 3.600 internal error with arrayed instances. [David Hewson]
|
||||
|
||||
**** Fix 3.600 internal error with non-unrolled function loops. [David Hewson]
|
||||
**** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson]
|
||||
|
||||
**** Fix $display %m name not matching Verilog name inside SystemC modules.
|
||||
**** Fixed $display %m name not matching Verilog name inside SystemC modules.
|
||||
|
||||
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
|
||||
|
||||
|
@ -223,17 +225,17 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Lint for x's in generate case statements.
|
||||
|
||||
**** Fix line numbers being off by one when first file starts with newline.
|
||||
**** Fixed line numbers being off by one when first file starts with newline.
|
||||
|
||||
**** Fix naming of generate for blocks to prevent non-inline name conflict.
|
||||
**** Fixed naming of generate for blocks to prevent non-inline name conflict.
|
||||
|
||||
**** Fix redundant statements remaining after table optimization.
|
||||
**** Fixed redundant statements remaining after table optimization.
|
||||
|
||||
* Verilator 3.542 08/11/2006 Stable
|
||||
|
||||
**** Fix extraneous UNSIGNED warning when comparing genvars. [David Hewson]
|
||||
**** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson]
|
||||
|
||||
**** Fix extra white space in $display %c. [by David Addison]
|
||||
**** Fixed extra white space in $display %c. [by David Addison]
|
||||
|
||||
**** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout.
|
||||
|
||||
|
@ -241,15 +243,15 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.541 07/05/2006 Beta
|
||||
|
||||
*** Fix "// verilator lint_on" not re-enabling warnings. [David Hewson]
|
||||
*** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson]
|
||||
|
||||
*** Fix 3.540's multiple memory assignments to same block. [David Hewson]
|
||||
*** Fixed 3.540's multiple memory assignments to same block. [David Hewson]
|
||||
|
||||
**** Add warning on changeDetect to arrayed structures. [David Hewson]
|
||||
|
||||
**** Fix non-zero start number for arrayed instantiations. [Jae Hossell]
|
||||
**** Fixed non-zero start number for arrayed instantiations. [Jae Hossell]
|
||||
|
||||
**** Fix GCC 4.0 header file warnings.
|
||||
**** Fixed GCC 4.0 header file warnings.
|
||||
|
||||
* Verilator 3.540 06/27/2006 Beta
|
||||
|
||||
|
@ -257,27 +259,27 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Optimize delayed assignments to memories inside loops, ~0-5% faster.
|
||||
|
||||
**** Fix mis-width warning on bit selects of memories. [David Hewson]
|
||||
**** Fixed mis-width warning on bit selects of memories. [David Hewson]
|
||||
|
||||
**** Fix mis-width warning on dead generate-if branches. [Jae Hossell]
|
||||
**** Fixed mis-width warning on dead generate-if branches. [Jae Hossell]
|
||||
|
||||
* Verilator 3.533 06/05/2006 Stable
|
||||
|
||||
*** Add PDF user manual, verilator.pdf.
|
||||
|
||||
**** Fix delayed bit-selected arrayed assignments. [David Hewson]
|
||||
**** Fixed delayed bit-selected arrayed assignments. [David Hewson]
|
||||
|
||||
**** Fix execution path to Perl. [Shanshan Xu]
|
||||
**** Fixed execution path to Perl. [Shanshan Xu]
|
||||
|
||||
**** Fix Bison compile errors in verilog.y. [by Ben Jackson]
|
||||
**** Fixed Bison compile errors in verilog.y. [by Ben Jackson]
|
||||
|
||||
* Verilator 3.531 05/10/2006 Stable
|
||||
|
||||
*** Support $c routines which return 64 bit values.
|
||||
|
||||
**** Fix `include `DEFINE.
|
||||
**** Fixed `include `DEFINE.
|
||||
|
||||
**** Fix Verilator core dump when have empty public function. [David.Hewson]
|
||||
**** Fixed Verilator core dump when have empty public function. [David.Hewson]
|
||||
|
||||
* Verilator 3.530 04/24/2006 Stable
|
||||
|
||||
|
@ -286,11 +288,11 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.523 03/06/2006 Stable
|
||||
|
||||
**** Fix error line numbers being off due to multi-line defines. [Mat Zeno]
|
||||
**** Fixed error line numbers being off due to multi-line defines. [Mat Zeno]
|
||||
|
||||
**** Fix GCC sign extending (uint64_t)(a<b). [David Hewson]
|
||||
**** Fixed GCC sign extending (uint64_t)(a<b). [David Hewson]
|
||||
|
||||
**** Fix `systemc_imp_header "undefined macro" error.
|
||||
**** Fixed `systemc_imp_header "undefined macro" error.
|
||||
|
||||
* Verilator 3.522 02/23/2006 Beta
|
||||
|
||||
|
@ -302,7 +304,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Added SystemVerilog 'x,'z,'0,'1, and new string literals.
|
||||
|
||||
**** Fix public module's parent still getting inlined.
|
||||
**** Fixed public module's parent still getting inlined.
|
||||
|
||||
* Verilator 3.520 01/14/2006 Stable
|
||||
|
||||
|
@ -315,28 +317,28 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
This adds a small ~2% performance penalty if traces are compiled in,
|
||||
but not turned on. For best non-tracing performance, do not use --trace.
|
||||
|
||||
**** Fix $'s in specify delays causing bad PLI errors. [Mat Zeno]
|
||||
**** Fixed $'s in specify delays causing bad PLI errors. [Mat Zeno]
|
||||
|
||||
**** Fix public functions not setting up proper symbol table. [Mat Zeno]
|
||||
**** Fixed public functions not setting up proper symbol table. [Mat Zeno]
|
||||
|
||||
**** Fix genvars generating trace compile errors. [Mat Zeno]
|
||||
**** Fixed genvars generating trace compile errors. [Mat Zeno]
|
||||
|
||||
**** Fix VL_MULS_WWW compile error with MSVC++. [Wim Michiels]
|
||||
**** Fixed VL_MULS_WWW compile error with MSVC++. [Wim Michiels]
|
||||
|
||||
* Verilator 3.502 11/30/2005 Stable
|
||||
|
||||
**** Fix local non-IO variables in public functions and tasks.
|
||||
**** Fixed local non-IO variables in public functions and tasks.
|
||||
|
||||
**** Fix bad lifetime optimization when same signal is assigned multiple
|
||||
**** Fixed bad lifetime optimization when same signal is assigned multiple
|
||||
times in both branch of a if. [Danny Ding]
|
||||
|
||||
* Verilator 3.501 11/16/2005 Stable
|
||||
|
||||
*** Add --profile-cfuncs for correlating profiles back to Verilog.
|
||||
|
||||
**** Fix functions where regs are declared before inputs. [Danny Ding]
|
||||
**** Fixed functions where regs are declared before inputs. [Danny Ding]
|
||||
|
||||
**** Fix bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
|
||||
**** Fixed bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
|
||||
|
||||
* Verilator 3.500 10/30/2005 Stable
|
||||
|
||||
|
@ -350,15 +352,15 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
** With --assert, generate assertions for synthesis parallel_case and full_case.
|
||||
|
||||
**** Fix generate if's with empty if/else blocks. [Mat Zeno]
|
||||
**** Fixed generate if's with empty if/else blocks. [Mat Zeno]
|
||||
|
||||
**** Fix generate for cell instantiations with same name. [Mat Zeno]
|
||||
**** Fixed generate for cell instantiations with same name. [Mat Zeno]
|
||||
|
||||
* Verilator 3.481 10/12/2005 Stable
|
||||
|
||||
*** Add /*verilator tracing_on/off*/ for waveform control.
|
||||
|
||||
**** Fix split optimization reordering $display statements.
|
||||
**** Fixed split optimization reordering $display statements.
|
||||
|
||||
* Verilator 3.480 9/27/2005 Beta
|
||||
|
||||
|
@ -383,9 +385,9 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Add GCC branch prediction hints on generated if statements.
|
||||
|
||||
**** Fix bad simulation when same function called twice in same expression.
|
||||
**** Fixed bad simulation when same function called twice in same expression.
|
||||
|
||||
**** Fix preprocessor substitution of quoted parameterized defines.
|
||||
**** Fixed preprocessor substitution of quoted parameterized defines.
|
||||
|
||||
* Verilator 3.464 8/24/2005 Stable
|
||||
|
||||
|
@ -393,7 +395,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** Add --stats option to dump design statistics.
|
||||
|
||||
**** Fix core dump with clock inversion optimizations.
|
||||
**** Fixed core dump with clock inversion optimizations.
|
||||
|
||||
* Verilator 3.463 8/5/2005 Stable
|
||||
|
||||
|
@ -401,15 +403,15 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.462 8/3/2005 Stable
|
||||
|
||||
*** Fix reordering of delayed assignments to same memory index. [Wim Michiels]
|
||||
*** Fixed reordering of delayed assignments to same memory index. [Wim Michiels]
|
||||
|
||||
**** Fix compile error with Flex 2.5.1. [Jens Arm]
|
||||
**** Fixed compile error with Flex 2.5.1. [Jens Arm]
|
||||
|
||||
**** Fix multiply-instantiated public tasks generating non-compilable code.
|
||||
**** Fixed multiply-instantiated public tasks generating non-compilable code.
|
||||
|
||||
* Verilator 3.461 7/28/2005 Beta
|
||||
|
||||
**** Fix compile error with older versions of bison. [Jeff Dutton]
|
||||
**** Fixed compile error with older versions of bison. [Jeff Dutton]
|
||||
|
||||
* Verilator 3.460 7/27/2005 Beta
|
||||
|
||||
|
@ -422,13 +424,13 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** When issuing unoptimizable warning, show an example path.
|
||||
|
||||
**** Fix false warning when a clock is constant.
|
||||
**** Fixed false warning when a clock is constant.
|
||||
|
||||
**** Fix X/Z in decimal numbers. [Wim Michiels]
|
||||
**** Fixed X/Z in decimal numbers. [Wim Michiels]
|
||||
|
||||
**** Fix genvar statements in non-named generate blocks.
|
||||
**** Fixed genvar statements in non-named generate blocks.
|
||||
|
||||
**** Fix core dump when missing newline in `define. [David van der bokke]
|
||||
**** Fixed core dump when missing newline in `define. [David van der bokke]
|
||||
|
||||
**** Internal tree dumps now indicate edit number that changed the node.
|
||||
|
||||
|
@ -445,7 +447,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
*** Add support for SystemVerilog keywords $bits, $countones, $isunknown,
|
||||
$onehot, $onehot0, always_comb, always_ff, always_latch, finish.
|
||||
|
||||
**** Fix "=== 1'bx" to always be false, instead of random.
|
||||
**** Fixed "=== 1'bx" to always be false, instead of random.
|
||||
|
||||
* Verilator 3.440 6/28/2005 Stable
|
||||
|
||||
|
@ -453,7 +455,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.431 6/24/2005 Stable
|
||||
|
||||
*** Fix selection bugs introduced in 3.430 beta.
|
||||
*** Fixed selection bugs introduced in 3.430 beta.
|
||||
|
||||
* Verilator 3.430 6/22/2005 Beta
|
||||
|
||||
|
@ -1085,7 +1087,7 @@ of input ports exists for tracing.
|
|||
|
||||
** [Versions 0 to 1.8 were by Paul Wasson]
|
||||
|
||||
**** Fix single bit in concat from instance output incorrect offset bug.
|
||||
**** Fixed single bit in concat from instance output incorrect offset bug.
|
||||
|
||||
* Verilator 1.7 5/20/1996
|
||||
|
||||
|
@ -1100,7 +1102,7 @@ of input ports exists for tracing.
|
|||
*** Pass structure pointer into translated code,
|
||||
so multiple instances can use same functions.
|
||||
|
||||
**** Fix static value concat on casex items.
|
||||
**** Fixed static value concat on casex items.
|
||||
|
||||
* Verilator 1.1 3/30/1995
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
|
|||
// Called on all major tree changers.
|
||||
// Only for use for those really nasty bugs relating to internals
|
||||
// Note this may be null.
|
||||
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<endl;
|
||||
//if (debug()) {
|
||||
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
|
||||
// v3Global.rootp()->dumpTree(cout,"-treeChange: ");
|
||||
|
@ -586,11 +587,29 @@ void AstNode::deleteTree() {
|
|||
// unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this.
|
||||
if (!this) return;
|
||||
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
|
||||
this->debugTreeChange("-delete: ", __LINE__, true);
|
||||
this->debugTreeChange("-delTree: ", __LINE__, true);
|
||||
// MUST be depth first!
|
||||
deleteTreeIter();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Memory checks
|
||||
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
void* AstNode::operator new(size_t size) {
|
||||
AstNode* objp = static_cast<AstNode*>(::operator new(size));
|
||||
V3Broken::addNewed(objp);
|
||||
return objp;
|
||||
}
|
||||
|
||||
void AstNode::operator delete(void* objp, size_t size) {
|
||||
if (!objp) return;
|
||||
AstNode* nodep = static_cast<AstNode*>(objp);
|
||||
V3Broken::deleted(nodep);
|
||||
::operator delete(objp);
|
||||
}
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// Iterators
|
||||
|
||||
|
|
|
@ -538,6 +538,10 @@ public:
|
|||
|
||||
// CONSTRUCTORS
|
||||
virtual ~AstNode();
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
static void* operator new(size_t size);
|
||||
static void operator delete(void* obj, size_t size);
|
||||
#endif
|
||||
|
||||
// CONSTANT ACCESSORS
|
||||
static int instrCountBranch() { return 4; } ///< Instruction cycles to branch
|
||||
|
|
118
src/V3Broken.cpp
118
src/V3Broken.cpp
|
@ -32,7 +32,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3Broken.h"
|
||||
|
@ -45,19 +45,100 @@ class BrokenTable : public AstNVisitor {
|
|||
private:
|
||||
// MEMBERS
|
||||
// For each node, we keep if it exists or not.
|
||||
typedef set<const AstNode*> NodeSet;
|
||||
static NodeSet s_nodes; // Set of all nodes that exist
|
||||
typedef map<const AstNode*,int> NodeMap;
|
||||
static NodeMap s_nodes; // Set of all nodes that exist
|
||||
// BITMASK
|
||||
static const int FLAG_ALLOCATED = 0x01; // new() and not delete()ed
|
||||
static const int FLAG_IN_TREE = 0x02; // Is in netlist tree
|
||||
static const int FLAG_LINKABLE = 0x04; // Is in netlist tree, can be linked to
|
||||
static const int FLAG_LEAKED = 0x08; // Known to have been leaked
|
||||
public:
|
||||
// METHODS
|
||||
static void add(const AstNode* nodep) {
|
||||
s_nodes.insert(nodep);
|
||||
static void deleted(const AstNode* nodep) {
|
||||
// Called by operator delete on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
|
||||
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n");
|
||||
}
|
||||
if (iter!=s_nodes.end()) s_nodes.erase(iter);
|
||||
}
|
||||
static bool exists(const AstNode* nodep) {
|
||||
NodeSet::iterator iter = s_nodes.find(nodep);
|
||||
return (iter != s_nodes.end());
|
||||
static void addNewed(const AstNode* nodep) {
|
||||
// Called by operator new on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
|
||||
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n");
|
||||
}
|
||||
if (iter == s_nodes.end()) {
|
||||
s_nodes.insert(make_pair(nodep,FLAG_ALLOCATED));
|
||||
}
|
||||
}
|
||||
static void clear() {
|
||||
static void addInTree(AstNode* nodep, bool linkable) {
|
||||
#ifndef VL_LEAK_CHECKS
|
||||
if (!linkable) return; // save some time, else the map will get huge!
|
||||
#endif
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter == s_nodes.end()) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
|
||||
#endif
|
||||
} else {
|
||||
if (!(iter->second & FLAG_ALLOCATED)) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
|
||||
#endif
|
||||
}
|
||||
if (iter->second & FLAG_IN_TREE) {
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location\n");
|
||||
}
|
||||
}
|
||||
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
|
||||
if (iter == s_nodes.end()) {
|
||||
s_nodes.insert(make_pair(nodep,or_flags));
|
||||
} else {
|
||||
iter->second |= or_flags;
|
||||
}
|
||||
}
|
||||
static bool okIfLinkedTo(const AstNode* nodep) {
|
||||
// Someone has a pointer to this node. Is it kosher?
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter == s_nodes.end()) return false;
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
if (!(iter->second & FLAG_ALLOCATED)) return false;
|
||||
#endif
|
||||
if (!(iter->second & FLAG_IN_TREE)) return false;
|
||||
if (!(iter->second & FLAG_LINKABLE)) return false;
|
||||
return true;
|
||||
}
|
||||
static void prepForTree() {
|
||||
#ifndef VL_LEAK_CHECKS
|
||||
s_nodes.clear();
|
||||
#endif
|
||||
for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
|
||||
it->second &= ~FLAG_IN_TREE;
|
||||
it->second &= ~FLAG_LINKABLE;
|
||||
}
|
||||
}
|
||||
static void doneWithTree() {
|
||||
for (int backs=0; backs<2; backs++) { // Those with backp() are probably under one leaking without
|
||||
for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
|
||||
if ((it->second & FLAG_ALLOCATED)
|
||||
&& !(it->second & FLAG_IN_TREE)
|
||||
&& !(it->second & FLAG_LEAKED)
|
||||
&& (it->first->backp() ? backs==1 : backs==0)) {
|
||||
// Use only AstNode::dump instead of the virtual one, as there
|
||||
// may be varp() and other cross links that are bad.
|
||||
if (debug()) {
|
||||
cout<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
|
||||
((AstNode*)(it->first))->AstNode::dump(cout);
|
||||
cout<<endl;
|
||||
V3Error::incErrors();
|
||||
}
|
||||
it->second |= FLAG_LEAKED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
|
@ -65,11 +146,11 @@ public:
|
|||
virtual ~BrokenTable() {}
|
||||
};
|
||||
|
||||
BrokenTable::NodeSet BrokenTable::s_nodes;
|
||||
BrokenTable::NodeMap BrokenTable::s_nodes;
|
||||
|
||||
bool AstNode::brokeExists() const {
|
||||
// Called by node->broken() routines to do table lookup
|
||||
return BrokenTable::exists(this);
|
||||
return BrokenTable::okIfLinkedTo(this);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
@ -82,9 +163,7 @@ private:
|
|||
// // so userp and friends may not be used
|
||||
// VISITORS
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
if (nodep->maybePointedTo()) {
|
||||
BrokenTable::add(nodep);
|
||||
}
|
||||
BrokenTable::addInTree(nodep, nodep->maybePointedTo());
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
|
@ -127,8 +206,15 @@ public:
|
|||
|
||||
void V3Broken::brokenAll(AstNetlist* nodep) {
|
||||
//UINFO(9,__FUNCTION__<<": "<<endl);
|
||||
BrokenTable::clear();
|
||||
BrokenTable::prepForTree();
|
||||
BrokenMarkVisitor mvisitor (nodep);
|
||||
BrokenCheckVisitor cvisitor (nodep);
|
||||
BrokenTable::clear();
|
||||
BrokenTable::doneWithTree();
|
||||
}
|
||||
|
||||
void V3Broken::addNewed(AstNode* nodep) {
|
||||
BrokenTable::addNewed(nodep);
|
||||
}
|
||||
void V3Broken::deleted(AstNode* nodep) {
|
||||
BrokenTable::deleted(nodep);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
class V3Broken {
|
||||
public:
|
||||
static void brokenAll(AstNetlist* nodep);
|
||||
static void addNewed(AstNode* nodep);
|
||||
static void deleted(AstNode* nodep);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
@ -218,7 +218,10 @@ private:
|
|||
a++, b++) {
|
||||
if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
|
||||
}
|
||||
if (same) return tree0p;
|
||||
if (same) {
|
||||
tree1p->deleteTree(); tree1p=NULL;
|
||||
return tree0p;
|
||||
}
|
||||
|
||||
// Must have differing logic, so make a selection
|
||||
|
||||
|
@ -245,8 +248,7 @@ private:
|
|||
// CASEx(cexpr,....
|
||||
// -> tree of IF(msb, IF(msb-1, 11, 10)
|
||||
// IF(msb-1, 01, 00))
|
||||
AstNode* cexprp = nodep->exprp();
|
||||
cexprp->unlinkFrBack();
|
||||
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
|
||||
|
||||
if (debug()>=9) {
|
||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
||||
|
@ -264,6 +266,8 @@ private:
|
|||
|
||||
if (ifrootp) nodep->replaceWith(ifrootp);
|
||||
else nodep->unlinkFrBack();
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
cexprp->deleteTree(); cexprp=NULL;
|
||||
if (debug()>=9) ifrootp->dumpTree(cout," _simp: ");
|
||||
}
|
||||
|
||||
|
@ -304,6 +308,7 @@ private:
|
|||
and2p = new AstAnd(itemp->fileline(),
|
||||
new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
} else {
|
||||
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
|
||||
and1p = cexprp->cloneTree(false);
|
||||
|
@ -320,6 +325,7 @@ private:
|
|||
itemp->condsp(ifexprp);
|
||||
}
|
||||
}
|
||||
cexprp->deleteTree(); cexprp=NULL;
|
||||
if (!hadDefault) {
|
||||
// If there was no default, add a empty one, this greatly simplifies below code
|
||||
// and constant propagation will just eliminate it for us later.
|
||||
|
|
|
@ -384,6 +384,8 @@ private:
|
|||
int shift1 = shift1p->castConst()->asInt(); if (lhsp->castShiftR()) shift1=-shift1;
|
||||
int shift2 = shift2p->castConst()->asInt(); if (nodep->castShiftR()) shift2=-shift2;
|
||||
int newshift = shift1+shift2;
|
||||
shift1p->deleteTree(); shift1p=NULL;
|
||||
shift2p->deleteTree(); shift1p=NULL;
|
||||
AstNode* newp;
|
||||
V3Number mask1 (nodep->fileline(), nodep->width());
|
||||
V3Number ones (nodep->fileline(), nodep->width());
|
||||
|
@ -524,7 +526,8 @@ private:
|
|||
if (debug()>=9) asn1p->dumpTree(cout," _new: ");
|
||||
if (debug()>=9) asn2p->dumpTree(cout," _new: ");
|
||||
// Cleanup
|
||||
nodep->unlinkFrBack()->deleteTree();
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
conp->deleteTree(); conp=NULL;
|
||||
// Further reduce, either node may have more reductions.
|
||||
return true;
|
||||
}
|
||||
|
@ -637,6 +640,7 @@ private:
|
|||
// If bp was a concat, then we have this exact same form again!
|
||||
// Recurse rather then calling node->iterate to prevent 2^n recursion!
|
||||
if (operandConcatMove(abConcp)) moveConcat(abConcp);
|
||||
bcConcp->deleteTree(); bcConcp=NULL;
|
||||
} else {
|
||||
AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack();
|
||||
AstNode* ap = abConcp->lhsp()->unlinkFrBack();
|
||||
|
@ -647,6 +651,7 @@ private:
|
|||
nodep->lhsp(ap);
|
||||
nodep->rhsp(bcConcp);
|
||||
if (operandConcatMove(bcConcp)) moveConcat(bcConcp);
|
||||
abConcp->deleteTree(); abConcp=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,6 +682,8 @@ private:
|
|||
if (lsb1p->castConst() && lsb2p->castConst()) {
|
||||
newlsbp = new AstConst(lsb1p->fileline(),
|
||||
lsb1p->castConst()->asInt() + lsb2p->castConst()->asInt());
|
||||
lsb1p->deleteTree(); lsb1p=NULL;
|
||||
lsb2p->deleteTree(); lsb2p=NULL;
|
||||
} else {
|
||||
// Width is important, we need the width of the fromp's
|
||||
// expression, not the potentially smaller lsb1p's width
|
||||
|
@ -860,7 +867,7 @@ private:
|
|||
new AstAssign(nodep->fileline(),
|
||||
varrefp, exprp));
|
||||
m_modp->addStmtp(newinitp);
|
||||
nodep->unlinkFrBack(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
// Set the initial value right in the variable so we can constant propagate
|
||||
AstNode* initvaluep = exprp->cloneTree(false);
|
||||
varrefp->varp()->initp(initvaluep);
|
||||
|
|
|
@ -110,18 +110,6 @@ private:
|
|||
}
|
||||
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) {
|
||||
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
|
||||
AstRange* rangep = NULL;
|
||||
if (width==0) {
|
||||
rangep = new AstRange(oldvarscp->fileline(),
|
||||
oldvarscp->varp()->msb(),
|
||||
oldvarscp->varp()->lsb());
|
||||
} else if (width==1) {
|
||||
rangep = NULL;
|
||||
} else {
|
||||
rangep = new AstRange(oldvarscp->fileline(),
|
||||
width-1, 0);
|
||||
}
|
||||
|
||||
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
|
||||
AstVar* varp;
|
||||
AstModule* addmodp = oldvarscp->scopep()->modp();
|
||||
|
@ -131,6 +119,17 @@ private:
|
|||
// Created module's AstVar earlier under some other scope
|
||||
varp = iter->second;
|
||||
} else {
|
||||
AstRange* rangep = NULL;
|
||||
if (width==0) {
|
||||
rangep = new AstRange(oldvarscp->fileline(),
|
||||
oldvarscp->varp()->msb(),
|
||||
oldvarscp->varp()->lsb());
|
||||
} else if (width==1) {
|
||||
rangep = NULL;
|
||||
} else {
|
||||
rangep = new AstRange(oldvarscp->fileline(),
|
||||
width-1, 0);
|
||||
}
|
||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep);
|
||||
if (width==0) varp->widthSignedFrom(oldvarscp);
|
||||
addmodp->addStmtp(varp);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <set>
|
||||
#include "V3Error.h"
|
||||
#ifndef _V3ERROR_NO_GLOBAL_
|
||||
# include "V3Ast.h"
|
||||
|
@ -170,6 +171,46 @@ void FileLine::v3errorEnd(ostringstream& str) {
|
|||
V3Error::v3errorEnd(str);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
typedef set<FileLine*> FileLineCheckSet;
|
||||
FileLineCheckSet fileLineLeakChecks;
|
||||
|
||||
void* FileLine::operator new(size_t size) {
|
||||
FileLine* objp = static_cast<FileLine*>(::operator new(size));
|
||||
fileLineLeakChecks.insert(objp);
|
||||
return objp;
|
||||
}
|
||||
|
||||
void FileLine::operator delete(void* objp, size_t size) {
|
||||
if (!objp) return;
|
||||
FileLine* flp = static_cast<FileLine*>(objp);
|
||||
FileLineCheckSet::iterator it = fileLineLeakChecks.find(flp);
|
||||
if (it != fileLineLeakChecks.end()) {
|
||||
fileLineLeakChecks.erase(it);
|
||||
} else {
|
||||
flp->v3fatalSrc("Deleting FileLine object that was never tracked\n");
|
||||
}
|
||||
::operator delete(objp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void FileLine::deleteAllRemaining() {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
// FileLines are allocated, but never nicely freed, as it's much faster
|
||||
// that way. Unfortunately this makes our leak checking a big mess, so
|
||||
// only when leak checking we'll track them all and cleanup.
|
||||
while (1) {
|
||||
FileLineCheckSet::iterator it=fileLineLeakChecks.begin();
|
||||
if (it==fileLineLeakChecks.end()) break;
|
||||
delete *it;
|
||||
// Operator delete will remove the iterated object from the list.
|
||||
// Eventually the list will be empty and terminate the loop.
|
||||
}
|
||||
fileLineLeakChecks.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// V3Error class functions
|
||||
|
||||
|
|
|
@ -117,8 +117,6 @@ class V3Error {
|
|||
static ostringstream s_errorStr; // Error string being formed
|
||||
static V3ErrorCode s_errorCode; // Error string being formed will abort
|
||||
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
|
||||
static void incErrors();
|
||||
static void incWarnings();
|
||||
|
||||
V3Error() { cerr<<("Static class"); abort(); }
|
||||
|
||||
|
@ -132,6 +130,8 @@ class V3Error {
|
|||
static int warnCount() { return s_warnCount; }
|
||||
static int errorOrWarnCount() { return errorCount()+warnCount(); }
|
||||
// METHODS
|
||||
static void incErrors();
|
||||
static void incWarnings();
|
||||
static void init();
|
||||
static void abortIfErrors();
|
||||
static void abortIfWarnings();
|
||||
|
@ -199,9 +199,14 @@ protected:
|
|||
void incLineno() { m_lineno++; }
|
||||
FileLine* copyOrSameFileLine();
|
||||
public:
|
||||
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff;}
|
||||
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff;};
|
||||
FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; } // Only for static constructor
|
||||
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff; }
|
||||
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff; }
|
||||
FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; }
|
||||
~FileLine() { }
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
static void* operator new(size_t size);
|
||||
static void operator delete(void* obj, size_t size);
|
||||
#endif
|
||||
static FileLine& defaultFileLine() { return s_defaultFileLine; }
|
||||
int lineno () const { return m_lineno; }
|
||||
string ascii() const;
|
||||
|
@ -218,6 +223,8 @@ public:
|
|||
|
||||
void v3errorEnd(ostringstream& str);
|
||||
inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); }
|
||||
|
||||
static void deleteAllRemaining();
|
||||
};
|
||||
ostream& operator<<(ostream& os, FileLine* fileline);
|
||||
|
||||
|
|
|
@ -531,6 +531,8 @@ private:
|
|||
rhsp, lsb)));
|
||||
}
|
||||
}
|
||||
rhsp->deleteTree(); rhsp=NULL;
|
||||
destp->deleteTree(); destp=NULL;
|
||||
} else {
|
||||
UINFO(8," ASSIGNSEL(const,narrow) "<<nodep<<endl);
|
||||
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
|
||||
|
|
|
@ -151,7 +151,7 @@ private:
|
|||
// Remove the cell
|
||||
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
|
||||
nodep->unlinkFrBack();
|
||||
nodep = NULL;
|
||||
pushDeletep(nodep); nodep = NULL;
|
||||
if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); }
|
||||
}
|
||||
}
|
||||
|
@ -332,14 +332,14 @@ private:
|
|||
} else {
|
||||
m_modp->user(1);
|
||||
}
|
||||
nodep->unlinkFrBack(); nodep=NULL; // Remove so don't propagate to upper cell...
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
|
||||
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
|
||||
if (!m_modp) {
|
||||
nodep->v3error("Inline pragma not under a module");
|
||||
} else {
|
||||
cantInline("Pragma NO_INLINE_MODULE");
|
||||
}
|
||||
nodep->unlinkFrBack(); nodep=NULL; // Remove so don't propagate to upper cell...
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
|
||||
} else {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ private:
|
|||
if ((findvarp->isIO() && nodep->isSignal())
|
||||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
nodep->unlinkFrBack(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
} else {
|
||||
nodep->v3error("Duplicate declaration of signal: "<<nodep->prettyName());
|
||||
findvarp->v3error("... Location of original declaration");
|
||||
|
|
|
@ -155,6 +155,9 @@ public:
|
|||
void movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp); // Mark one vertex as finished, remove from ready list if done
|
||||
// STATIC MEMBERS (for lookup)
|
||||
static void clear() {
|
||||
for (DomScopeMap::iterator it=s_dsMap.begin(); it!=s_dsMap.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
s_dsMap.clear();
|
||||
}
|
||||
V3List<OrderMoveVertex*>& readyVertices() { return m_readyVertices; }
|
||||
|
@ -426,15 +429,18 @@ private:
|
|||
m_finder.main(m_topScopep);
|
||||
// ProcessDomainsIterate will use these when it needs to move
|
||||
// something to a combodomain. This saves a ton of find() operations.
|
||||
AstSenTree comb (nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
||||
new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
|
||||
m_comboDomainp = m_finder.getSenTree(nodep->fileline(), &comb);
|
||||
AstSenTree settle (nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
||||
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
||||
m_settleDomainp = m_finder.getSenTree(nodep->fileline(), &settle);
|
||||
AstSenTree* combp = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
||||
new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
|
||||
m_comboDomainp = m_finder.getSenTree(nodep->fileline(), combp);
|
||||
pushDeletep(combp); // Cleanup when done
|
||||
AstSenTree* settlep = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
||||
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
||||
m_settleDomainp = m_finder.getSenTree(nodep->fileline(), settlep);
|
||||
pushDeletep(settlep); // Cleanup when done
|
||||
// Fake AstSenTree we set domainp to indicate needs deletion
|
||||
m_deleteDomainp = new AstSenTree (nodep->fileline(),
|
||||
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
||||
pushDeletep(m_deleteDomainp); // Cleanup when done
|
||||
UINFO(5," DeleteDomain = "<<m_deleteDomainp<<endl);
|
||||
// Base vertices
|
||||
m_activeSenVxp = NULL;
|
||||
|
|
|
@ -57,10 +57,10 @@ protected:
|
|||
s_preprocp->debug(debug());
|
||||
// Default defines
|
||||
FileLine* prefl = new FileLine("INTERNAL_VERILATOR_DEFINE",0);
|
||||
s_preprocp->define(prefl,"verilator", "1");
|
||||
s_preprocp->define(prefl,"verilator3", "1");
|
||||
s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/");
|
||||
s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/");
|
||||
s_preprocp->define(prefl,"verilator", "1"); // LEAK_OK
|
||||
s_preprocp->define(prefl,"verilator3", "1"); // LEAK_OK
|
||||
s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/"); // LEAK_OK
|
||||
s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); // LEAK_OK
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,19 @@ void V3Read::statePop() { s_readp->m_lexerp->statePop(); }
|
|||
//######################################################################
|
||||
// Read class functions
|
||||
|
||||
V3Read::~V3Read() {
|
||||
for (deque<string*>::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
m_stringps.clear();
|
||||
for (deque<V3Number*>::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
m_numberps.clear();
|
||||
if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; }
|
||||
parserClear();
|
||||
}
|
||||
|
||||
void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
|
||||
string modname = V3Options::filenameNonExt(modfilename);
|
||||
|
||||
|
|
12
src/V3Read.h
12
src/V3Read.h
|
@ -110,16 +110,8 @@ public:
|
|||
m_inBeginKwd = 0;
|
||||
m_lastVerilogState = stateVerilogRecent();
|
||||
}
|
||||
~V3Read() {
|
||||
for (deque<string*>::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
m_stringps.clear();
|
||||
for (deque<V3Number*>::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
m_numberps.clear();
|
||||
}
|
||||
~V3Read();
|
||||
void parserClear();
|
||||
|
||||
// METHODS
|
||||
// Preprocess and read the Verilog file specified into the netlist database
|
||||
|
|
|
@ -349,6 +349,7 @@ private:
|
|||
// Connect to this exact variable
|
||||
AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope");
|
||||
portp->user2p(localVscp);
|
||||
pushDeletep(pinp);
|
||||
} else {
|
||||
pinp->v3warn(TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
|
||||
}
|
||||
|
|
|
@ -95,6 +95,8 @@ private:
|
|||
|| (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) {
|
||||
V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1));
|
||||
newp = new AstConst (nodep->fileline(), num);
|
||||
lhsp->deleteTree(); lhsp=NULL;
|
||||
rhsp->deleteTree(); rhsp=NULL;
|
||||
} else {
|
||||
if (nodep->castEqCase())
|
||||
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
|
||||
|
@ -221,6 +223,7 @@ private:
|
|||
if (debug()>=9) newref1p->dumpTree(cout," _new: ");
|
||||
if (debug()>=9) newvarp->dumpTree(cout," _new: ");
|
||||
if (debug()>=9) newinitp->dumpTree(cout," _new: ");
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ private:
|
|||
constInitp->num(),
|
||||
condBip, constStopp->num(),
|
||||
incInstrp, constIncp->num()); nodep = NULL;
|
||||
// Cleanup
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -229,7 +230,6 @@ private:
|
|||
loopValue.opAssign(numInit);
|
||||
|
||||
AstNode* newbodysp = NULL;
|
||||
AstNode* clonedIncsp = NULL; // Last cloned incp() statements
|
||||
m_statLoops++;
|
||||
if (stmtsp) {
|
||||
int times = 0;
|
||||
|
@ -244,25 +244,8 @@ private:
|
|||
// Replace iterator values with constant.
|
||||
AstNode* oneloopp = stmtsp->cloneTree(true);
|
||||
|
||||
// A nicer way to propage the loop constant would be to set the variable to the value
|
||||
// and call a constant-propagator like V3Table, so temp values
|
||||
// that are calculated propagate down.
|
||||
// If we do this, we can remove the below
|
||||
if (nodep->castWhile() && incp) {
|
||||
if (clonedIncsp) {
|
||||
// Previous iteration of loop set the variable.
|
||||
// This set is redundant with this next iteration and can be removed.
|
||||
if (clonedIncsp == newbodysp) { // Increment was only thing in list
|
||||
newbodysp = NULL;
|
||||
} else {
|
||||
clonedIncsp->unlinkFrBack();
|
||||
}
|
||||
clonedIncsp->deleteTree();
|
||||
}
|
||||
clonedIncsp = incp->clonep(); if (!clonedIncsp) nodep->v3fatalSrc("inc failed");
|
||||
}
|
||||
|
||||
m_varValuep = new AstConst(nodep->fileline(), loopValue);
|
||||
|
||||
m_varModeReplace = true;
|
||||
oneloopp->iterateAndNext(*this);
|
||||
m_varModeReplace = false;
|
||||
|
@ -280,6 +263,8 @@ private:
|
|||
V3Number newnum(nodep->fileline(), m_forVarp->width()); // Can't increment in-place
|
||||
incInstrp->numberOperate(newnum, loopValue, numInc);
|
||||
loopValue.opAssign(newnum);
|
||||
|
||||
pushDeletep(m_varValuep); m_varValuep=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,6 +272,9 @@ private:
|
|||
// Replace the FOR()
|
||||
if (newbodysp) nodep->replaceWith(newbodysp);
|
||||
else nodep->unlinkFrBack();
|
||||
if (bodysp) { pushDeletep(bodysp); bodysp=NULL; }
|
||||
if (precondsp) { pushDeletep(precondsp); precondsp=NULL; }
|
||||
if (initp) { pushDeletep(initp); initp=NULL; }
|
||||
if (debug()>=9) newbodysp->dumpTree(cout,"- _new: ");
|
||||
}
|
||||
|
||||
|
@ -311,7 +299,7 @@ private:
|
|||
if (forUnrollCheck(nodep, initp,
|
||||
nodep->precondsp(), nodep->condp(),
|
||||
incp, nodep->bodysp())) {
|
||||
nodep=NULL; // Did replacement
|
||||
pushDeletep(nodep); nodep=NULL; // Did replacement
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +316,7 @@ private:
|
|||
if (forUnrollCheck(nodep, nodep->initsp(),
|
||||
NULL, nodep->condp(),
|
||||
nodep->incsp(), nodep->bodysp())) {
|
||||
nodep=NULL; // Did replacement
|
||||
pushDeletep(nodep); nodep=NULL; // Did replacement
|
||||
} else {
|
||||
nodep->v3error("For loop doesn't have genvar index, or is misformed");
|
||||
}
|
||||
|
@ -373,6 +361,7 @@ private:
|
|||
&& !nodep->lvalue()) {
|
||||
AstNode* newconstp = m_varValuep->cloneTree(false);
|
||||
nodep->replaceWith(newconstp);
|
||||
pushDeletep(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -760,6 +760,7 @@ void WidthVisitor::fixWidthExtend (AstNode* nodep, int expWidth) {
|
|||
AstNode* newp = new AstConst(nodep->fileline(), num);
|
||||
newp->signedFrom(constp);
|
||||
constp->replaceWith(newp);
|
||||
pushDeletep(constp); constp=NULL;
|
||||
nodep=newp;
|
||||
} else if (expWidth<nodep->width()) {
|
||||
// Trunc - Extract
|
||||
|
|
|
@ -552,6 +552,7 @@ int main(int argc, char** argv, char** env) {
|
|||
// Cleanup memory for valgrind leak analysis
|
||||
v3Global.clear();
|
||||
#endif
|
||||
FileLine::deleteAllRemaining();
|
||||
|
||||
UINFO(1,"Done, Exiting...\n");
|
||||
}
|
||||
|
|
|
@ -66,6 +66,10 @@ public:
|
|||
nodep->addNext(new AstStop(fileline));
|
||||
return nodep;
|
||||
}
|
||||
static void setRange(AstRange* rangep) {
|
||||
if (s_varRangep) { s_varRangep->deleteTree(); s_varRangep=NULL; } // It was cloned, so this is safe.
|
||||
s_varRangep = rangep;
|
||||
}
|
||||
static string deQuote(FileLine* fileline, string text);
|
||||
};
|
||||
|
||||
|
@ -88,7 +92,7 @@ AstCase* V3Parse::s_caseAttrp = NULL;
|
|||
#define VARDECL(type) { V3Parse::s_varDecl = AstVarType::type; }
|
||||
#define VARIO(type) { V3Parse::s_varIO = AstVarType::type; }
|
||||
#define VARSIGNED(value) { V3Parse::s_varSigned = value; }
|
||||
#define VARRANGE(range) { V3Parse::s_varRangep=(range); }
|
||||
#define VARRANGE(rangep) { V3Parse::setRange(rangep); }
|
||||
|
||||
#define INSTPREP(modname,paramsp) { V3Parse::s_impliedDecl = true; V3Parse::s_instModule = modname; V3Parse::s_instParamp = paramsp; }
|
||||
|
||||
|
@ -858,8 +862,8 @@ stmt: ';' { $$ = NULL; }
|
|||
| yD_ERROR parenE ';' { $$ = V3Parse::createDisplayError($1); }
|
||||
| yD_ERROR '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); }
|
||||
| yD_FATAL parenE ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
|
||||
| yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
|
||||
| yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); }
|
||||
| yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
|
||||
| yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
|
||||
|
||||
| yD_READMEMB '(' expr ',' varRefMem ')' ';' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); }
|
||||
| yD_READMEMB '(' expr ',' varRefMem ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); }
|
||||
|
@ -1314,6 +1318,11 @@ pslExpr: exprPsl { $$ = new AstPslBool($1->fileline(), $1); }
|
|||
//**********************************************************************
|
||||
%%
|
||||
|
||||
void V3Read::parserClear() {
|
||||
// Clear up any dynamic memory V3Parser required
|
||||
V3Parse::setRange(NULL);
|
||||
}
|
||||
|
||||
AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) {
|
||||
FileLine* newfl = new FileLine (fileline);
|
||||
newfl->warnOff(V3ErrorCode::WIDTH, true);
|
||||
|
@ -1328,6 +1337,7 @@ AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) {
|
|||
AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* arrayp) {
|
||||
AstVarType type = V3Parse::s_varIO;
|
||||
AstRange* rangep = V3Parse::s_varRangep;
|
||||
AstRange* cleanup_rangep = NULL;
|
||||
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<V3Parse::s_varDecl.ascii()<<" io="<<V3Parse::s_varIO.ascii()<<endl);
|
||||
if (type == AstVarType::UNKNOWN) type = V3Parse::s_varDecl;
|
||||
if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared");
|
||||
|
@ -1335,7 +1345,8 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
|
|||
if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER
|
||||
|| type == AstVarType::GENVAR) {
|
||||
if (rangep) fileline->v3error("Integers may not be ranged: "<<name);
|
||||
rangep = new AstRange(fileline, 31, 0); // Integer == REG[31:0]
|
||||
cleanup_rangep = new AstRange(fileline, 31, 0); // Integer == REG[31:0]
|
||||
rangep = cleanup_rangep;
|
||||
}
|
||||
if (type == AstVarType::GENVAR) {
|
||||
if (arrayp) fileline->v3error("Genvars may not be arrayed: "<<name);
|
||||
|
@ -1363,6 +1374,7 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
|
|||
|
||||
// Remember the last variable created, so we can attach attributes to it in later parsing
|
||||
V3Parse::s_varAttrp = nodep;
|
||||
if (cleanup_rangep) { cleanup_rangep->deleteTree(); cleanup_rangep=NULL; }
|
||||
return nodep;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue