Add creating __inputs.vpp file with --debug (#4177).

This commit is contained in:
Wilson Snyder
2023-05-07 17:58:14 -04:00
parent 444020f7c7
commit d269fbb446
11 changed files with 134 additions and 38 deletions
+50 -21
View File
@@ -35,6 +35,7 @@
#include "V3Os.h"
#include "V3ParseBison.h" // Generated by bison
#include "V3PreShell.h"
#include "V3Stats.h"
#include <sstream>
@@ -247,24 +248,22 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
return got;
}
void V3ParseImp::preprocDumps(std::ostream& os) {
if (v3Global.opt.dumpDefines()) {
V3PreShell::dumpDefines(os);
} else {
const bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine();
for (auto& buf : m_ppBuffers) {
if (noblanks) {
bool blank = true;
for (string::iterator its = buf.begin(); its != buf.end(); ++its) {
if (!std::isspace(*its) && *its != '\n') {
blank = false;
break;
}
void V3ParseImp::preprocDumps(std::ostream& os, bool forInputs) {
bool noblanks = forInputs || (v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine());
bool nolines = forInputs;
for (auto& buf : m_ppBuffers) {
if (noblanks) {
bool blank = true;
for (string::iterator its = buf.begin(); its != buf.end(); ++its) {
if (!std::isspace(*its) && *its != '\n') {
blank = false;
break;
}
if (blank) continue;
}
os << buf;
if (blank) continue;
if (nolines && buf.rfind("`line ", 0) == 0) continue;
}
os << buf;
}
}
@@ -292,7 +291,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
// Create output file with all the preprocessor output we buffered up
const string vppfilename = v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix()
+ "_" + nondirname + ".vpp";
+ "__" + nondirname + ".vpp";
std::ofstream* ofp = nullptr;
std::ostream* osp;
if (v3Global.opt.preprocOnly()) {
@@ -303,15 +302,20 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
if (osp->fail()) {
fileline->v3error("Cannot write preprocessor output: " + vppfilename);
return;
}
if (v3Global.opt.dumpDefines()) {
V3PreShell::dumpDefines(*osp);
} else {
preprocDumps(*osp);
if (ofp) {
ofp->close();
VL_DO_DANGLING(delete ofp, ofp);
}
preprocDumps(*osp, false);
}
if (ofp) {
ofp->close();
VL_DO_DANGLING(delete ofp, ofp);
}
}
if (debug() && modfilename != V3Options::getStdPackagePath()) dumpInputsFile();
// Parse it
if (!v3Global.opt.preprocOnly()) {
lexFile(modfilename);
@@ -320,6 +324,31 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
}
}
void V3ParseImp::dumpInputsFile() {
// Create output file with joined preprocessor output we buffered up,
// Useful for debug to feed back into Verilator
static bool append = false;
const string vppfilename
= v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix() + "__inputs.vpp";
std::ofstream* ofp = V3File::new_ofstream(vppfilename, append);
if (ofp->fail()) {
v3error("Cannot write preprocessor output: " + vppfilename);
return;
}
if (!append) {
append = true;
UINFO(1, "Writing all preprocessed output to " << vppfilename << endl);
*ofp << "// Dump of all post-preprocessor input\n";
*ofp << "// Blank lines and `line directives have been removed\n";
*ofp << "//\n";
V3Stats::infoHeader(*ofp, "// ");
}
*ofp << "\n";
preprocDumps(*ofp, true);
ofp->close();
VL_DO_DANGLING(delete ofp, ofp);
}
void V3ParseImp::lexFile(const string& modname) {
// Prepare for lexing
UINFO(3, "Lexing " << modname << endl);
+2 -1
View File
@@ -295,6 +295,7 @@ public:
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
const string& errmsg);
void dumpInputsFile();
private:
void lexFile(const string& modname);
@@ -305,7 +306,7 @@ private:
size_t tokenPipeScanParam(size_t depth);
size_t tokenPipeScanType(size_t depth);
const V3ParseBisonYYSType* tokenPeekp(size_t depth);
void preprocDumps(std::ostream& os);
void preprocDumps(std::ostream& os, bool forInputs);
};
#endif // Guard
+2
View File
@@ -121,6 +121,8 @@ public:
static void statsFinalAll(AstNetlist* nodep);
/// Called by the top level to dump the statistics
static void statsReport();
/// Called by debug dumps
static void infoHeader(std::ofstream& os, const string& prefix);
};
#endif // Guard
+11 -12
View File
@@ -40,18 +40,8 @@ class StatsReport final {
std::ofstream& os; ///< Output stream
static StatColl s_allStats; ///< All statistics
void header() {
os << "Verilator Statistics Report\n\n";
os << "Information:\n";
os << " " << V3Options::version() << '\n';
os << " Arguments: " << v3Global.opt.allArgsString() << '\n';
os << " Build jobs: " << v3Global.opt.buildJobs() << '\n';
os << " Verilate jobs: " << v3Global.opt.verilateJobs() << '\n';
os << '\n';
}
void sumit() {
os << '\n';
// If sumit is set on a statistic, combine with others of same name
std::multimap<std::string, V3Statistic*> byName;
// * is always first
@@ -179,7 +169,8 @@ public:
// CONSTRUCTORS
explicit StatsReport(std::ofstream* aofp)
: os(*aofp) { // Need () or GCC 4.8 false warning
header();
os << "Verilator Statistics Report\n\n";
V3Stats::infoHeader(os, "");
sumit();
stars();
stages();
@@ -222,6 +213,14 @@ void V3Stats::statsStage(const string& name) {
V3Stats::addStatPerf("Stage, Memory (MB), " + digitName, memory);
}
void V3Stats::infoHeader(std::ofstream& os, const string& prefix) {
os << prefix << "Information:\n";
os << prefix << " " << V3Options::version() << '\n';
os << prefix << " Arguments: " << v3Global.opt.allArgsString() << '\n';
os << prefix << " Build jobs: " << v3Global.opt.buildJobs() << '\n';
os << prefix << " Verilate jobs: " << v3Global.opt.verilateJobs() << '\n';
}
void V3Stats::statsReport() {
UINFO(2, __FUNCTION__ << ": " << endl);