// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: https://verilator.org // //************************************************************************* // // Copyright 2003-2019 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include "V3Global.h" #include "V3String.h" #include "V3Os.h" #include "V3Options.h" #include "V3Error.h" #include "V3File.h" #include "V3PreShell.h" #include #include #ifndef _WIN32 # include #endif #include #include #include #include #include #include #include #include "config_rev.h" //###################################################################### // V3 Internal state class V3OptionsImp { public: // TYPES typedef std::map > DirMap; // Directory listing // STATE std::list m_allArgs; // List of every argument encountered std::list m_incDirUsers; // Include directories (ordered) std::set m_incDirUserSet; // Include directories (for removing duplicates) std::list m_incDirFallbacks; // Include directories (ordered) std::set m_incDirFallbackSet; // Include directories (for removing duplicates) std::map m_langExts; // Language extension map std::list m_libExtVs; // Library extensions (ordered) std::set m_libExtVSet; // Library extensions (for removing duplicates) DirMap m_dirMap; // Directory listing // ACCESSOR METHODS void addIncDirUser(const string& incdir) { if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { m_incDirUserSet.insert(incdir); m_incDirUsers.push_back(incdir); m_incDirFallbacks.remove(incdir); // User has priority over Fallback m_incDirFallbackSet.erase(incdir); // User has priority over Fallback } } void addIncDirFallback(const string& incdir) { if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { // User has priority over Fallback if (m_incDirFallbackSet.find(incdir) == m_incDirFallbackSet.end()) { m_incDirFallbackSet.insert(incdir); m_incDirFallbacks.push_back(incdir); } } } void addLangExt(const string& langext, const V3LangCode& lc) { // New language extension replaces any pre-existing one. (void)m_langExts.erase(langext); m_langExts[langext] = lc; } void addLibExtV(const string& libext) { if (m_libExtVSet.find(libext) == m_libExtVSet.end()) { m_libExtVSet.insert(libext); m_libExtVs.push_back(libext); } } V3OptionsImp() {} ~V3OptionsImp() {} }; void V3Options::addIncDirUser(const string& incdir) { m_impp->addIncDirUser(incdir); } void V3Options::addIncDirFallback(const string& incdir) { m_impp->addIncDirFallback(incdir); } void V3Options::addLangExt(const string& langext, const V3LangCode& lc) { m_impp->addLangExt(langext, lc); } void V3Options::addLibExtV(const string& libext) { m_impp->addLibExtV(libext); } void V3Options::addDefine(const string& defline, bool allowPlus) { // Split +define+foo=value into the appropriate parts and parse // Optional + says to allow multiple defines on the line // + is not quotable, as other simulators do not allow that string left = defline; while (left != "") { string def = left; string::size_type pos; if (allowPlus && ((pos = left.find('+')) != string::npos)) { left = left.substr(pos+1); def.erase(pos); } else { left = ""; } string value; if ((pos = def.find('=')) != string::npos) { value = def.substr(pos+1); def.erase(pos); } V3PreShell::defineCmdLine(def, value); } } void V3Options::addParameter(const string& paramline, bool allowPlus) { // Split +define+foo=value into the appropriate parts and parse // Optional + says to allow multiple defines on the line // + is not quotable, as other simulators do not allow that string left = paramline; while (left != "") { string param = left; string::size_type pos; if (allowPlus && ((pos = left.find('+')) != string::npos)) { left = left.substr(pos+1); param.erase(pos); } else { left = ""; } string value; if ((pos = param.find('=')) != string::npos) { value = param.substr(pos+1); param.erase(pos); } UINFO(4,"Add parameter"<second; m_parameters.erase(m_parameters.find(name)); return value; } void V3Options::checkParameters() { if (!m_parameters.empty()) { std::stringstream msg; msg << "Parameters from the command line were not found in the design:"; for (std::map::iterator it = m_parameters.begin(); it != m_parameters.end(); ++it) { msg << " " << it->first; } v3error(msg.str()); } } void V3Options::addCppFile(const string& filename) { if (m_cppFiles.find(filename) == m_cppFiles.end()) { m_cppFiles.insert(filename); } } void V3Options::addCFlags(const string& filename) { m_cFlags.push_back(filename); } void V3Options::addLdLibs(const string& filename) { m_ldLibs.push_back(filename); } void V3Options::addFuture(const string& flag) { if (m_futures.find(flag) == m_futures.end()) { m_futures.insert(flag); } } bool V3Options::isFuture(const string& flag) const { return m_futures.find(flag) != m_futures.end(); } bool V3Options::isLibraryFile(const string& filename) const { return m_libraryFiles.find(filename) != m_libraryFiles.end(); } void V3Options::addLibraryFile(const string& filename) { if (m_libraryFiles.find(filename) == m_libraryFiles.end()) { m_libraryFiles.insert(filename); } } bool V3Options::isClocker(const string& signame) const { return m_clockers.find(signame) != m_clockers.end(); } void V3Options::addClocker(const string& signame) { if (m_clockers.find(signame) == m_clockers.end()) { m_clockers.insert(signame); } } bool V3Options::isNoClocker(const string& signame) const { return m_noClockers.find(signame) != m_noClockers.end(); } void V3Options::addNoClocker(const string& signame) { if (m_noClockers.find(signame) == m_noClockers.end()) { m_noClockers.insert(signame); } } void V3Options::addVFile(const string& filename) { // We use a list for v files, because it's legal to have includes // in a specific order and multiple of them. m_vFiles.push_back(filename); } void V3Options::addForceInc(const string& filename) { m_forceIncs.push_back(filename); } void V3Options::addArg(const string& arg) { m_impp->m_allArgs.push_back(arg); } string V3Options::allArgsString() { string out; for (std::list::iterator it=m_impp->m_allArgs.begin(); it != m_impp->m_allArgs.end(); ++it) { if (out != "") out += " "; out += *it; } return out; } //###################################################################### // V3LangCode class functions V3LangCode::V3LangCode(const char* textp) { // Return code for given string, or ERROR, which is a bad code for (int codei=V3LangCode::L_ERROR; codei0) ::close(fd); } } string V3Options::fileExists(const string& filename) { // Surprisingly, for VCS and other simulators, this process // is quite slow; presumably because of re-reading each directory // many times. So we read a whole dir at once and cache it string dir = V3Os::filenameDir(filename); string basename = V3Os::filenameNonDir(filename); V3OptionsImp::DirMap::iterator diriter = m_impp->m_dirMap.find(dir); if (diriter == m_impp->m_dirMap.end()) { // Read the listing m_impp->m_dirMap.insert(std::make_pair(dir, std::set() )); diriter = m_impp->m_dirMap.find(dir); std::set* setp = &(diriter->second); if (DIR* dirp = opendir(dir.c_str())) { while (struct dirent* direntp = readdir(dirp)) { setp->insert(direntp->d_name); } closedir(dirp); } } // Find it std::set* filesetp = &(diriter->second); std::set::iterator fileiter = filesetp->find(basename); if (fileiter == filesetp->end()) { return ""; // Not found } // Check if it is a directory, ignore if so string filenameOut = V3Os::filenameFromDirBase(dir, basename); if (!fileStatNormal(filenameOut)) return ""; // Directory return filenameOut; } string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) { for (std::list::iterator extIter=m_impp->m_libExtVs.begin(); extIter != m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(dirname, modname+*extIter); string exists = fileExists(fn); if (exists!="") { // Strip ./, it just looks ugly if (exists.substr(0, 2)=="./") exists.erase(0, 2); return exists; } } return ""; } string V3Options::filePath(FileLine* fl, const string& modname, const string& lastpath, const string& errmsg) { // Error prefix or "" to suppress error // Find a filename to read the specified module name, // using the incdir and libext's. // Return "" if not found. for (std::list::iterator dirIter=m_impp->m_incDirUsers.begin(); dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) { string exists = filePathCheckOneDir(modname, *dirIter); if (exists!="") return exists; } for (std::list::iterator dirIter=m_impp->m_incDirFallbacks.begin(); dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) { string exists = filePathCheckOneDir(modname, *dirIter); if (exists!="") return exists; } if (m_relativeIncludes) { string exists = filePathCheckOneDir(modname, lastpath); if (exists!="") return V3Os::filenameRealPath(exists); } // Warn and return not found if (errmsg != "") { fl->v3error(errmsg+modname); filePathLookedMsg(fl, modname); } return ""; } void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) { static bool shown_notfound_msg = false; if (!shown_notfound_msg) { shown_notfound_msg = true; if (m_impp->m_incDirUsers.empty()) { fl->v3error("This may be because there's no search path specified with -I."<::iterator dirIter=m_impp->m_incDirUsers.begin(); dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) { for (std::list::iterator extIter=m_impp->m_libExtVs.begin(); extIter != m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(*dirIter, modname+*extIter); std::cerr<::iterator dirIter=m_impp->m_incDirFallbacks.begin(); dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) { for (std::list::iterator extIter=m_impp->m_libExtVs.begin(); extIter != m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(*dirIter, modname+*extIter); std::cerr<::iterator it = m_impp->m_langExts.find(ext); if (it != m_impp->m_langExts.end()) { return it->second; } } return m_defaultLanguage; } //###################################################################### // Environment string V3Options::getenvBuiltins(const string& var) { if (var == "PERL") return getenvPERL(); else if (var == "SYSTEMC") return getenvSYSTEMC(); else if (var == "SYSTEMC_ARCH") return getenvSYSTEMC_ARCH(); else if (var == "SYSTEMC_INCLUDE") return getenvSYSTEMC_INCLUDE(); else if (var == "SYSTEMC_LIBDIR") return getenvSYSTEMC_LIBDIR(); else if (var == "VERILATOR_ROOT") return getenvVERILATOR_ROOT(); else { return V3Os::getenvStr(var, ""); } } string V3Options::getenvPERL() { return V3Os::getenvStr("PERL", "perl"); } string V3Options::getenvSYSTEMC() { string var = V3Os::getenvStr("SYSTEMC", ""); if (var == "" && string(DEFENV_SYSTEMC) != "") { var = DEFENV_SYSTEMC; V3Os::setenvStr("SYSTEMC", var, "Hardcoded at build time"); } return var; } string V3Options::getenvSYSTEMC_ARCH() { string var = V3Os::getenvStr("SYSTEMC_ARCH", ""); if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") { var = DEFENV_SYSTEMC_ARCH; V3Os::setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time"); } if (var == "") { #if defined (__MINGW32__) // Hardcoded with MINGW current version. Would like a better way. string sysname = "MINGW32_NT-5.0"; var = "mingw32"; #elif defined (_WIN32) string sysname = "WIN32"; var = "win32"; #else // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) struct utsname uts; uname(&uts); string sysname = VString::downcase(uts.sysname); // aka 'uname -s' if (VString::wildmatch(sysname.c_str(), "*solaris*")) { var = "gccsparcOS5"; } else if (VString::wildmatch(sysname.c_str(), "*cygwin*")) { var = "cygwin"; } else { var = "linux"; } #endif V3Os::setenvStr("SYSTEMC_ARCH", var, "From sysname '"+sysname+"'"); } return var; } string V3Options::getenvSYSTEMC_INCLUDE() { string var = V3Os::getenvStr("SYSTEMC_INCLUDE", ""); if (var == "" && string(DEFENV_SYSTEMC_INCLUDE) != "") { var = DEFENV_SYSTEMC_INCLUDE; V3Os::setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time"); } if (var == "") { string sc = getenvSYSTEMC(); if (sc != "") var = sc+"/include"; } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemCLibs()) { if (var == "") { v3fatal("Need $SYSTEMC_INCLUDE in environment or when Verilator configured\n" "Probably System-C isn't installed, see http://www.systemc.org\n"); } } return var; } string V3Options::getenvSYSTEMC_LIBDIR() { string var = V3Os::getenvStr("SYSTEMC_LIBDIR", ""); if (var == "" && string(DEFENV_SYSTEMC_LIBDIR) != "") { var = DEFENV_SYSTEMC_LIBDIR; V3Os::setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time"); } if (var == "") { string sc = getenvSYSTEMC(); string arch = getenvSYSTEMC_ARCH(); if (sc != "" && arch != "") var = sc+"/lib-"+arch; } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemCLibs()) { if (var == "") { v3fatal("Need $SYSTEMC_LIBDIR in environment or when Verilator configured\n" "Probably System-C isn't installed, see http://www.systemc.org\n"); } } return var; } string V3Options::getenvVERILATOR_ROOT() { string var = V3Os::getenvStr("VERILATOR_ROOT", ""); if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") { var = DEFENV_VERILATOR_ROOT; V3Os::setenvStr("VERILATOR_ROOT", var, "Hardcoded at build time"); } if (var == "") { v3fatal("$VERILATOR_ROOT needs to be in environment\n"); } return var; } //###################################################################### // V3 Options notification methods void V3Options::notify() { // Notify that all arguments have been passed and final modification can be made. if (!outFormatOk() && !cdc() && !dpiHdrOnly() && !lintOnly() && !preprocOnly() && !xmlOnly()) { v3fatal("verilator: Need --cc, --sc, --cdc, --dpi-hdr-only, --lint-only, --xml-only or --E option"); } // Make sure at least one make system is enabled if (!m_gmake && !m_cmake) { m_gmake = true; } if (protectIds()) { FileLine* cmdfl = new FileLine(FileLine::commandLineFilename()); if (allPublic()) { // We always call protect() on names, we don't check if public or not // Hence any external references wouldn't be able to find the refed public object. cmdfl->v3error("Unsupported: Using --protect-ids with --public\n" +V3Error::warnMore()+"... Suggest remove --public."); } if (trace()) { cmdfl->v3warn(INSECURE, "Using --protect-ids with --trace may expose private design details\n" +V3Error::warnMore()+"... Suggest remove --trace."); } if (vpi()) { cmdfl->v3warn(INSECURE, "Using --protect-ids with --vpi may expose private design details\n" +V3Error::warnMore()+"... Suggest remove --vpi."); } } // Default some options if not turned on or off if (v3Global.opt.skipIdentical().isDefault()) { v3Global.opt.m_skipIdentical.setTrueOrFalse( !v3Global.opt.cdc() && !v3Global.opt.dpiHdrOnly() && !v3Global.opt.lintOnly() && !v3Global.opt.preprocOnly() && !v3Global.opt.xmlOnly()); } if (v3Global.opt.makeDepend().isDefault()) { v3Global.opt.m_makeDepend.setTrueOrFalse( !v3Global.opt.cdc() && !v3Global.opt.dpiHdrOnly() && !v3Global.opt.lintOnly() && !v3Global.opt.preprocOnly() && !v3Global.opt.xmlOnly()); } } //###################################################################### // V3 Options accessors string V3Options::version() { string ver = DTVERSION; ver += " rev "+cvtToStr(DTVERSION_rev); return ver; } string V3Options::protectKeyDefaulted() { if (m_protectKey.empty()) { // Create a key with a human-readable symbol-like name. // This conversion drops ~2 bits of entropy out of 256, shouldn't matter. VHashSha256 digest (V3Os::trueRandom(32)); m_protectKey = "VL-KEY-"+digest.digestSymbol(); } return m_protectKey; } void V3Options::throwSigsegv() { #if !(defined(VL_CPPCHECK) || defined(__clang_analyzer__)) char* zp=NULL; *zp=0; // Intentional core dump, ignore warnings here #endif } //###################################################################### // V3 Options utilities string V3Options::argString(int argc, char** argv) { // Return list of arguments as simple string string opts; for (int i=0; i=1) { m_prefix = string("V")+V3Os::filenameNonExt(*(vFilesList.begin())); } if (modPrefix()=="") m_modPrefix = prefix(); // Find files in makedir addIncDirFallback(makeDir()); } //====================================================================== bool V3Options::onoff(const char* sw, const char* arg, bool& flag) { // if sw==arg, then return true (found it), and flag=true // if sw=="-no-arg", then return true (found it), and flag=false // if sw=="-noarg", then return true (found it), and flag=false // else return false if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash"); if (0==strcmp(sw, arg)) { flag = true; return true; } else if (0==strncmp(sw, "-no", 3) && (0==strcmp(sw+3, arg+1))) { flag = false; return true; } else if (0==strncmp(sw, "-no-", 4) && (0==strcmp(sw+4, arg+1))) { flag = false; return true; } return false; } bool V3Options::onoffb(const char* sw, const char* arg, VOptionBool& bflag) { bool flag; if (onoff(sw, arg, flag/*ref*/)) { bflag.setTrueOrFalse(flag); return true; } else { return false; } } bool V3Options::suffixed(const string& sw, const char* arg) { if (strlen(arg) > sw.length()) return false; return (0==strcmp(sw.c_str()+sw.length()-strlen(arg), arg)); } void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char** argv) { // Parse parameters // Note argc and argv DO NOT INCLUDE the filename in [0]!!! // May be called recursively when there are -f files. for (int i=0; iv3fatal("Invalid Option: "<v3fatal("Unknown --make system specified: '"<v3fatal("Unknown language specified: "<m_outputSplitCFuncs)) { m_outputSplitCTrace = m_outputSplitCFuncs; } } else if (!strcmp(sw, "-output-split-ctrace")) { // Undocumented optimization tweak shift; m_outputSplitCTrace = atoi(argv[i]); } else if (!strcmp(sw, "-protect-lib") && (i+1)v3fatal("Unknown warning specified: "<v3fatal("Unknown warning specified: "<v3fatal("Unknown warning specified: "<v3fatal("Unknown setting for --compiler: "< 65) fl->v3fatal("--pins-bv maximum is 65: "<v3fatal("--threads must be >= 0: "<v3fatal("Unknown setting for --threads-dpi: "<v3fatal("--threads-max-mtasks must be >= 1: "<v3fatal("Unknown setting for --x-assign: "<v3fatal("Unknown setting for --x-initial: "<v3fatal("Invalid Option: "< ifp (V3File::new_ifstream(filename)); if (ifp->fail()) { fl->v3error("Cannot open -f command file: "+filename); return; } string whole_file; bool inCmt = false; while (!ifp->eof()) { string line = V3Os::getline(*ifp); // Strip simple comments string oline; // cppcheck-suppress StlMissingComparison char lastch = ' '; for (string::const_iterator pos = line.begin(); pos != line.end(); lastch = *pos++) { if (inCmt) { if (*pos=='*' && *(pos+1)=='/') { inCmt = false; ++pos; } } else if (*pos=='/' && *(pos+1)=='/' && (pos == line.begin() || isspace(lastch))) { // But allow /file//path break; // Ignore to EOL } else if (*pos=='/' && *(pos+1)=='*') { inCmt = true; // cppcheck-suppress StlMissingComparison ++pos; } else { oline += *pos; } } whole_file += oline + " "; } whole_file += "\n"; // So string match below is simplified if (inCmt) fl->v3error("Unterminated /* comment inside -f file."); fl = new FileLine(filename); // Split into argument list and process // Note we try to respect escaped char, double/simple quoted strings // Other simulators don't respect a common syntax... // Strip off arguments and parse into words std::vector args; // Parse file using a state machine, taking into account quoted strings and escaped chars enum state {ST_IN_OPTION, ST_ESCAPED_CHAR, ST_IN_QUOTED_STR, ST_IN_DOUBLE_QUOTED_STR}; state st = ST_IN_OPTION; state last_st = ST_IN_OPTION; string arg; for (string::size_type pos = 0; pos < whole_file.length(); ++pos) { char curr_char = whole_file[pos]; switch (st) { case ST_IN_OPTION: // Get all chars up to a white space or a "=" if (isspace(curr_char)) { // End of option if (!arg.empty()) { // End of word args.push_back(arg); } arg = ""; break; } if (curr_char == '\\') { // Escape char, we wait for next char last_st = st; // Memorize current state st = ST_ESCAPED_CHAR; break; } if (curr_char == '\'') { // Find begin of quoted string // Examine next char in order to decide between // a string or a base specifier for integer literal ++pos; if (pos < whole_file.length()) curr_char = whole_file[pos]; if (curr_char == '"') { // String st = ST_IN_QUOTED_STR; } else { // Base specifier arg += '\''; } arg += curr_char; break; } if (curr_char == '"') { // Find begin of double quoted string // Doesn't insert the quote st = ST_IN_DOUBLE_QUOTED_STR; break; } arg += curr_char; break; case ST_IN_QUOTED_STR: // Just store all chars inside string if (curr_char != '\'') { arg += curr_char; } else { // End of quoted string st = ST_IN_OPTION; } break; case ST_IN_DOUBLE_QUOTED_STR: // Take into account escaped chars if (curr_char != '"') { if (curr_char == '\\') { last_st = st; st = ST_ESCAPED_CHAR; } else { arg += curr_char; } } else { // End of double quoted string st = ST_IN_OPTION; } break; case ST_ESCAPED_CHAR: // Just add the escaped char arg += curr_char; st = last_st; break; } } if (!arg.empty()) { // Add last word args.push_back(arg); } // Path string optdir = (rel ? V3Os::filenameDir(filename) : "."); // Convert to argv style arg list and parse them char* argv [args.size()+1]; for (unsigned i=0; i(args[i].c_str()); } parseOptsList(fl, optdir, args.size(), argv); } //====================================================================== string V3Options::parseFileArg(const string& optdir, const string& relfilename) { string filename = V3Os::filenameSubstitute(relfilename); if (optdir != "." && V3Os::filenameIsRel(filename)) { filename = optdir + "/" + filename; } return filename; } //====================================================================== //! Utility to see if we have a language extension argument and if so add it. bool V3Options::parseLangExt(const char* swp, //!< argument text const char* langswp, //!< option to match const V3LangCode& lc) { //!< language code int len = strlen(langswp); if (!strncmp(swp, langswp, len)) { addLangExt(swp + len, lc); return true; } else { return false; } } //====================================================================== void V3Options::showVersion(bool verbose) { cout <second = level; } else { m_debugSrcs.insert(make_pair(srcfile, level)); } } int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) { // For simplicity, calling functions can just use __FILE__ for srcfile. // That means though we need to cleanup the filename from ../Foo.cpp -> Foo string srcfile = V3Os::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile); if (iter!=m_debugSrcs.end()) { return iter->second; } else { return default_level; } } void V3Options::setDumpTreeLevel(const string& srcfile, int level) { DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); if (iter!=m_dumpTrees.end()) { iter->second = level; } else { m_dumpTrees.insert(make_pair(srcfile, level)); } } int V3Options::dumpTreeLevel(const string& srcfile_path) { // For simplicity, calling functions can just use __FILE__ for srcfile. // That means though we need to cleanup the filename from ../Foo.cpp -> Foo string srcfile = V3Os::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); if (iter!=m_dumpTrees.end()) { return iter->second; } else { return m_dumpTree; } } void V3Options::optimize(int level) { // Set all optimizations to on/off bool flag = level > 0; m_oAcycSimp = flag; m_oCase = flag; m_oCombine = flag; m_oConst = flag; m_oExpand = flag; m_oGate = flag; m_oInline = flag; m_oLife = flag; m_oLifePost = flag; m_oLocalize = flag; m_oReloop = flag; m_oReorder = flag; m_oSplit = flag; m_oSubst = flag; m_oSubstConst = flag; m_oTable = flag; m_oDedupe = flag; m_oAssemble = flag; // And set specific optimization levels if (level >= 3) { m_inlineMult = -1; // Maximum inlining } }