| /* |
| Copyright 2019 Alain Dargelas |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /* |
| * File: Compiler.cpp |
| * Author: alain |
| * |
| * Created on March 4, 2017, 5:16 PM |
| */ |
| #include "../CommandLine/CommandLineParser.hpp" |
| #include "../ErrorReporting/ErrorContainer.h" |
| #include "SymbolTable.h" |
| #include "CompilationUnit.h" |
| #include "PreprocessFile.h" |
| #include "CompilationUnit.h" |
| #include "CompileSourceFile.h" |
| #include "Compiler.h" |
| #include "CheckCompile.h" |
| #include "antlr4-runtime.h" |
| #include "../DesignCompile/CompileDesign.h" |
| #include "AnalyzeFile.h" |
| #include "../Library/ParseLibraryDef.h" |
| #include "../Utils/FileUtils.h" |
| #include "../Package/Precompiled.h" |
| #include "../Utils/StringUtils.h" |
| #include "../Utils/Timer.h" |
| #include "math.h" |
| using namespace antlr4; |
| |
| #include "../API/PythonAPI.h" |
| #include "CheckCompile.h" |
| #include <mutex> |
| #include <thread> |
| #include <vector> |
| using namespace SURELOG; |
| |
| Compiler::Compiler (CommandLineParser* commandLineParser, ErrorContainer* errors, SymbolTable* symbolTable) : |
| m_commandLineParser (commandLineParser), m_errors (errors), m_symbolTable (symbolTable), m_commonCompilationUnit (NULL) |
| { |
| m_design = NULL; |
| #ifdef USETBB |
| if (getCommandLineParser ()->useTbb () && (getCommandLineParser ()->getNbMaxTreads () > 0)) |
| tbb::task_scheduler_init init (getCommandLineParser ()->getNbMaxTreads ()); |
| #endif |
| } |
| |
| Compiler::Compiler (const Compiler& orig) { } |
| |
| Compiler::~Compiler () |
| { |
| std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr; |
| for (itr = m_antlrPpMap.begin (); itr != m_antlrPpMap.end (); itr++) |
| { |
| delete (*itr).second; |
| } |
| if (m_commonCompilationUnit) |
| { |
| delete m_commonCompilationUnit; |
| } |
| cleanup_ (); |
| } |
| |
| struct FunctorCompileOneFile |
| { |
| |
| FunctorCompileOneFile (CompileSourceFile* compileSource, CompileSourceFile::Action action) : |
| m_compileSourceFile (compileSource), m_action (action) { } |
| |
| int operator() () const |
| { |
| if (m_compileSourceFile->getCommandLineParser ()->pythonListener () |
| || m_compileSourceFile->getCommandLineParser ()->pythonEvalScriptPerFile ()) |
| { |
| PyThreadState* interpState = PythonAPI::initNewInterp (); |
| m_compileSourceFile->setPythonInterp (interpState); |
| } |
| return m_compileSourceFile->compile (m_action); |
| } |
| |
| private: |
| CompileSourceFile* m_compileSourceFile; |
| CompileSourceFile::Action m_action; |
| }; |
| |
| bool |
| Compiler::compileOneFile_ (CompileSourceFile* compiler, CompileSourceFile::Action action) |
| { |
| bool status = compiler->compile (action); |
| return status; |
| } |
| |
| bool Compiler::isLibraryFile (SymbolId id) { |
| if (m_libraryFiles.find(id) == m_libraryFiles.end()) |
| { |
| return false; |
| } |
| else |
| { |
| return true; |
| } |
| } |
| |
| bool |
| Compiler::ppinit_ () |
| { |
| if (!m_commandLineParser->fileunit ()) |
| { |
| m_commonCompilationUnit = new CompilationUnit (false); |
| } |
| |
| CompilationUnit* comp_unit = m_commonCompilationUnit; |
| |
| // Source files (.v, .sv on the command line) |
| std::set<SymbolId> sourceFiles; |
| unsigned int size = m_commandLineParser->getSourceFiles ().size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| SymbolTable* symbols = m_symbolTable; |
| if (m_commandLineParser->fileunit ()) |
| { |
| comp_unit = new CompilationUnit (true); |
| m_compilationUnits.push_back (comp_unit); |
| symbols = new SymbolTable (*m_commandLineParser->getSymbolTable ()); |
| m_symbolTables.push_back (symbols); |
| } |
| ErrorContainer* errors = new ErrorContainer (symbols); |
| m_errorContainers.push_back (errors); |
| errors->regiterCmdLine (m_commandLineParser); |
| |
| SymbolId id = m_commandLineParser->getSourceFiles ()[i]; |
| |
| std::string fileName = m_commandLineParser->getSymbolTable ()->getSymbol (id); |
| std::string fullPath = FileUtils::getFullPath (fileName); |
| SymbolId fullPathId = m_commandLineParser->getSymbolTable ()->registerSymbol(fullPath); |
| Library* library = m_librarySet->getLibrary (fullPathId); |
| sourceFiles.insert(fullPathId); |
| |
| CompileSourceFile* compiler = new CompileSourceFile (m_commandLineParser->getSourceFiles ()[i], |
| m_commandLineParser, errors, this, symbols, comp_unit, library); |
| m_compilers.push_back (compiler); |
| } |
| |
| // Library files |
| std::set<SymbolId> libFiles; |
| // (-v <file>) |
| size = m_commandLineParser->getLibraryFiles ().size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| SymbolId id = m_commandLineParser->getLibraryFiles ()[i]; |
| libFiles.insert(id); |
| } |
| // (-y <path> +libext+<ext>) |
| for (auto path : m_commandLineParser->getLibraryPaths ()) |
| { |
| for (auto ext : m_commandLineParser->getLibraryExtensions ()) |
| { |
| auto files = FileUtils::collectFiles (path, ext, m_commandLineParser->getSymbolTable ()); |
| for (auto file : files) |
| { |
| libFiles.insert(file); |
| } |
| } |
| } |
| for (auto id : libFiles) |
| { |
| SymbolTable* symbols = m_symbolTable; |
| if (m_commandLineParser->fileunit ()) |
| { |
| comp_unit = new CompilationUnit (true); |
| m_compilationUnits.push_back (comp_unit); |
| symbols = new SymbolTable (*m_commandLineParser->getSymbolTable ()); |
| m_symbolTables.push_back (symbols); |
| } |
| ErrorContainer* errors = new ErrorContainer (symbols); |
| m_errorContainers.push_back (errors); |
| errors->regiterCmdLine (m_commandLineParser); |
| |
| std::string fullPath = FileUtils::getFullPath (m_commandLineParser->getSymbolTable ()->getSymbol (id)); |
| |
| // This line registers the file in the "work" library: |
| SymbolId fullPathId = m_commandLineParser->getSymbolTable ()->registerSymbol(fullPath); |
| /*Library* library = */ m_librarySet->getLibrary (fullPathId); |
| m_libraryFiles.insert(id); |
| m_libraryFiles.insert(fullPathId); |
| // No need to register a compiler |
| //CompileSourceFile* compiler = new CompileSourceFile (m_commandLineParser->getLibraryFiles ()[i], |
| // m_commandLineParser, errors, this, symbols, comp_unit, library); |
| //m_compilers.push_back (compiler); |
| } |
| |
| |
| // Libraries (.map) |
| for (auto& lib : m_librarySet->getLibraries ()) |
| { |
| for (auto id: lib.getFiles ()) |
| { |
| std::string fileName = lib.getSymbols()->getSymbol (id); |
| if (sourceFiles.find(id) != sourceFiles.end()) |
| { |
| // These files are already included in the command line |
| continue; |
| } |
| |
| if (strstr(fileName.c_str(), ".map")) |
| { |
| // .map files are not parsed with the regular parser |
| continue; |
| } |
| SymbolTable* symbols = m_symbolTable; |
| if (m_commandLineParser->fileunit ()) |
| { |
| comp_unit = new CompilationUnit (true); |
| m_compilationUnits.push_back (comp_unit); |
| symbols = new SymbolTable (*m_commandLineParser->getSymbolTable ()); |
| m_symbolTables.push_back (symbols); |
| } |
| ErrorContainer* errors = new ErrorContainer (symbols); |
| m_errorContainers.push_back (errors); |
| errors->regiterCmdLine (m_commandLineParser); |
| |
| CompileSourceFile* compiler = new CompileSourceFile (id, |
| m_commandLineParser, errors, this, symbols, comp_unit, &lib); |
| m_compilers.push_back (compiler); |
| } |
| } |
| |
| |
| return true; |
| } |
| |
| bool |
| Compiler::parseinit_ () |
| { |
| Precompiled* prec = Precompiled::getSingleton (); |
| // Single out the large files. |
| // Small files are going to be scheduled in multiple threads based on size. |
| // Large files are going to be compiled in a different batch in multithread |
| |
| if (!m_commandLineParser->fileunit ()) |
| { |
| unsigned int size = m_symbolTables.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| delete m_symbolTables[i]; |
| } |
| size = m_errorContainers.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| delete m_errorContainers[i]; |
| } |
| m_symbolTables.clear (); |
| m_errorContainers.clear (); |
| } |
| |
| std::vector<CompileSourceFile*> tmp_compilers; |
| unsigned int size = m_compilers.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| std::string fileName = m_compilers[i]->getSymbolTable ()->getSymbol(m_compilers[i]->getPpOutputFileId ()); |
| std::string origFile = m_compilers[i]->getSymbolTable ()->getSymbol(m_compilers[i]->getFileId ()); |
| unsigned int nbThreads = m_commandLineParser->getNbMaxTreads (); |
| std::string root = fileName; |
| root = StringUtils::getRootFileName (root); |
| if (prec->isFilePrecompiled (root)) |
| { |
| nbThreads = 0; |
| } |
| int effectiveNbThreads = 0; |
| if (nbThreads > 4) |
| effectiveNbThreads = (int) (log (((float) nbThreads + 1.0) / 4.0) * 10.0); |
| else |
| effectiveNbThreads = nbThreads; |
| |
| AnalyzeFile* fileAnalyzer = new AnalyzeFile(m_commandLineParser, m_design, fileName, origFile, effectiveNbThreads); |
| fileAnalyzer->analyze(); |
| m_compilers[i]->setFileAnalyzer (fileAnalyzer); |
| if (fileAnalyzer->getSplitFiles ().size() > 1) |
| { |
| // Schedule parent |
| m_compilersParentFiles.push_back (m_compilers[i]); |
| m_compilers[i]->initParser (); |
| |
| if (!m_commandLineParser->fileunit ()) |
| { |
| SymbolTable* symbols = new SymbolTable (*m_commandLineParser->getSymbolTable ()); |
| m_symbolTables.push_back (symbols); |
| m_compilers[i]->setSymbolTable (symbols); |
| // fileContent->setSymbolTable(symbols); |
| ErrorContainer* errors = new ErrorContainer (symbols); |
| m_errorContainers.push_back (errors); |
| errors->regiterCmdLine (m_commandLineParser); |
| m_compilers[i]->setErrorContainer (errors); |
| } |
| |
| FileContent* fileContent = new FileContent(m_compilers[i]->getParser()->getFileId(0), |
| m_compilers[i]->getParser()->getLibrary (), |
| m_compilers[i]->getSymbolTable(), |
| m_compilers[i]->getErrorContainer (), |
| NULL, 0); |
| m_compilers[i]->getParser()->setFileContent(fileContent); |
| |
| int j = 0; |
| for (auto chunk : fileAnalyzer->getSplitFiles ()) |
| { |
| SymbolTable* symbols = new SymbolTable (*m_commandLineParser->getSymbolTable ()); |
| m_symbolTables.push_back (symbols); |
| SymbolId ppId = symbols->registerSymbol(chunk); |
| symbols->registerSymbol(m_compilers[i]->getParser()->getFileName (LINE1)); |
| CompileSourceFile* chunkCompiler = new CompileSourceFile(m_compilers[i], ppId, |
| fileAnalyzer->getLineOffsets ()[j]); |
| // Schedule chunk |
| tmp_compilers.push_back(chunkCompiler); |
| |
| |
| chunkCompiler->setSymbolTable (symbols); |
| ErrorContainer* errors = new ErrorContainer (symbols); |
| m_errorContainers.push_back (errors); |
| errors->regiterCmdLine (m_commandLineParser); |
| chunkCompiler->setErrorContainer (errors); |
| //chunkCompiler->getParser ()->setFileContent (fileContent); |
| |
| FileContent* fileContent = new FileContent(m_compilers[i]->getParser()->getFileId(0), |
| m_compilers[i]->getParser()->getLibrary(), |
| symbols, errors, NULL, ppId); |
| chunkCompiler->getParser()->setFileContent(fileContent); |
| getDesign()->addFileContent(m_compilers[i]->getParser()->getFileId(0), fileContent); |
| |
| j++; |
| } |
| } |
| else |
| { |
| |
| if (!m_commandLineParser->fileunit ()) |
| { |
| SymbolTable* symbols = new SymbolTable (*m_commandLineParser->getSymbolTable ()); |
| m_symbolTables.push_back (symbols); |
| m_compilers[i]->setSymbolTable (symbols); |
| ErrorContainer* errors = new ErrorContainer (symbols); |
| m_errorContainers.push_back (errors); |
| errors->regiterCmdLine (m_commandLineParser); |
| m_compilers[i]->setErrorContainer (errors); |
| } |
| |
| tmp_compilers.push_back (m_compilers[i]); |
| } |
| } |
| m_compilers = tmp_compilers; |
| |
| return true; |
| } |
| |
| bool |
| Compiler::pythoninit_ () |
| { |
| return parseinit_(); |
| } |
| |
| ErrorContainer::Stats |
| Compiler::getErrorStats () |
| { |
| ErrorContainer::Stats stats; |
| unsigned int size = m_errorContainers.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| ErrorContainer::Stats tmp; |
| tmp = m_errorContainers[i]->getErrorStats (); |
| stats += tmp; |
| } |
| |
| return stats; |
| } |
| |
| bool |
| Compiler::cleanup_ () |
| { |
| unsigned int size = m_compilers.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| delete m_compilers[i]; |
| } |
| size = m_compilationUnits.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| delete m_compilationUnits[i]; |
| } |
| size = m_symbolTables.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| delete m_symbolTables[i]; |
| } |
| size = m_errorContainers.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| delete m_errorContainers[i]; |
| } |
| return true; |
| } |
| |
| bool |
| Compiler::compileFileSet_ (CompileSourceFile::Action action, bool allowMultithread, std::vector<CompileSourceFile*>& container) |
| { |
| unsigned short maxThreadCount = m_commandLineParser->getNbMaxTreads (); |
| if (allowMultithread == false) |
| { |
| maxThreadCount = 0; |
| } |
| |
| if (maxThreadCount == 0) |
| { |
| // Single thread |
| unsigned int size = container.size (); |
| for (unsigned int i = 0; i < size; i++) |
| { |
| container[i]->setPythonInterp (PythonAPI::getMainInterp ()); |
| bool status = compileOneFile_ (container[i], action); |
| m_errors->appendErrors (*container[i]->getErrorContainer ()); |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| if ((!status) || container[i]->getErrorContainer ()->hasFatalErrors ()) |
| return false; |
| } |
| } |
| else if (getCommandLineParser ()->useTbb () && (action != CompileSourceFile::Action::Parse)) |
| { |
| #ifdef USETBB |
| // TBB Thread management |
| int maxThreadCount = m_commandLineParser->getNbMaxTreads (); |
| if (allowMultithread == false) |
| { |
| maxThreadCount = 0; |
| } |
| unsigned int size = container.size (); |
| if (maxThreadCount) |
| { |
| for (unsigned int i = 0; i < size; i++) |
| { |
| m_taskGroup.run (FunctorCompileOneFile (container[i], action)); |
| } |
| m_taskGroup.wait (); |
| bool fatalErrors = false; |
| for (unsigned int i = 0; i < size; i++) |
| { |
| // Promote report to master error container |
| m_errors->appendErrors (*container[i]->getErrorContainer ()); |
| if (container[i]->getErrorContainer ()->hasFatalErrors ()) |
| { |
| fatalErrors = true; |
| } |
| if (getCommandLineParser ()->pythonListener ()) |
| { |
| container[i]->shutdownPythonInterp (); |
| } |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| } |
| if (fatalErrors) |
| return false; |
| } |
| else |
| { |
| for (unsigned int i = 0; i < size; i++) |
| { |
| container[i]->setPythonInterp (PythonAPI::getMainInterp ()); |
| bool status = compileOneFile_ (container[i], action); |
| m_errors->appendErrors (*container[i]->getErrorContainer ()); |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| if ((!status) || container[i]->getErrorContainer ()->hasFatalErrors ()) |
| return false; |
| |
| } |
| } |
| #endif |
| } |
| else |
| { |
| // Custom Thread management |
| |
| // Optimize the load balance, try to even out the work in each thread by the size of the files |
| std::vector<std::vector < CompileSourceFile*>> jobArray (maxThreadCount); |
| |
| std::vector<unsigned long> jobSize(maxThreadCount); |
| |
| for (unsigned short i = 0; i < maxThreadCount; i++) |
| jobSize[i] = 0; |
| |
| for (unsigned int i = 0; i < container.size (); i++) |
| { |
| unsigned int size = container[i]->getJobSize(action); |
| unsigned int newJobIndex = 0; |
| unsigned long minJobQueue = ULLONG_MAX; |
| for (unsigned short ii = 0; ii < maxThreadCount; ii++) |
| { |
| if (jobSize[ii] < minJobQueue) |
| { |
| newJobIndex = ii; |
| minJobQueue = jobSize[ii]; |
| } |
| } |
| |
| jobSize[newJobIndex] += size; |
| jobArray[newJobIndex].push_back (container[i]); |
| |
| } |
| |
| if (getCommandLineParser ()->profile()) |
| { |
| if(action == CompileSourceFile::Preprocess) |
| std::cout << "Preprocessing task\n"; |
| else if(action == CompileSourceFile::Parse) |
| std::cout << "Parsing task\n"; |
| else |
| std::cout << "Misc Task\n"; |
| for (unsigned short i = 0; i < maxThreadCount; i++) |
| { |
| |
| std::cout << "Thread " << i << " : \n"; |
| int sum = 0; |
| for (unsigned int j = 0; j < jobArray[i].size (); j++) |
| { |
| std::string fileName; |
| if (jobArray[i][j]->getPreprocessor ()) |
| fileName = jobArray[i][j]->getPreprocessor ()->getFileName (0); |
| if (jobArray[i][j]->getParser ()) |
| fileName = jobArray[i][j]->getParser ()->getFileName (0); |
| sum += jobArray[i][j]->getJobSize (action); |
| std::cout << jobArray[i][j]->getJobSize (action) << " " << fileName << "\n"; |
| } |
| std::cout << ", Total: " << sum << std::endl << std::flush; |
| } |
| } |
| |
| // Create the threads with their respective workloads |
| std::vector<std::thread*> threads; |
| for (unsigned short i = 0; i < maxThreadCount; i++) |
| { |
| std::thread* th = new std::thread ([ = ]{ |
| |
| for (unsigned int j = 0; j < jobArray[i].size(); j++) |
| { |
| if (getCommandLineParser ()->pythonListener () |
| || getCommandLineParser ()->pythonEvalScriptPerFile ()) |
| { |
| PyThreadState* interpState = PythonAPI::initNewInterp (); |
| jobArray[i][j]->setPythonInterp (interpState); |
| } |
| |
| jobArray[i][j]->compile(action); |
| |
| if (getCommandLineParser ()->pythonListener () |
| || getCommandLineParser ()->pythonEvalScriptPerFile ()) |
| { |
| jobArray[i][j]->shutdownPythonInterp (); |
| } |
| } |
| }); |
| threads.push_back(th); |
| } |
| |
| // Sync the threads |
| for (unsigned int th = 0; th < threads.size (); th++) |
| { |
| threads[th]->join (); |
| } |
| |
| // Delete the threads |
| for (unsigned int th = 0; th < threads.size (); th++) |
| { |
| delete threads[th]; |
| } |
| |
| // Promote report to master error container |
| bool fatalErrors = false; |
| for (unsigned int j = 0; j < container.size (); j++) |
| { |
| m_errors->appendErrors (*container[j]->getErrorContainer ()); |
| if (container[j]->getErrorContainer ()->hasFatalErrors ()) |
| fatalErrors = true; |
| } |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| |
| if (fatalErrors) |
| return false; |
| } |
| return true; |
| } |
| |
| bool |
| Compiler::compile () |
| { |
| |
| std::string profile; |
| Timer tmr; |
| Timer tmrTotal; |
| // Scan the libraries definition |
| if (!parseLibrariesDef_()) return false; |
| |
| if (m_commandLineParser->profile()) |
| { |
| std::string msg = "Scan libraries took " + StringUtils::to_string(tmr.elapsed_rounded ()) + "s\n"; |
| std::cout << msg << std::endl; |
| profile += msg; |
| tmr.reset(); |
| } |
| |
| // Preprocess |
| ppinit_ (); |
| if (!compileFileSet_ (CompileSourceFile::Preprocess, m_commandLineParser->fileunit (), m_compilers)) return false; |
| |
| // Single thread post Preprocess |
| if (!compileFileSet_ (CompileSourceFile::PostPreprocess, false, m_compilers)) return false; |
| |
| if (m_commandLineParser->profile()) |
| { |
| std::string msg = "Preprocessing took " + StringUtils::to_string(tmr.elapsed_rounded ()) + "s\n"; |
| std::cout << msg << std::endl; |
| profile += msg; |
| tmr.reset(); |
| } |
| |
| // Parse |
| bool parserInitialized = false; |
| if (m_commandLineParser->parse () |
| || m_commandLineParser->pythonListener () |
| || m_commandLineParser->pythonEvalScriptPerFile () |
| || m_commandLineParser->pythonEvalScript()) |
| { |
| parseinit_ (); |
| parserInitialized = true; |
| if (!compileFileSet_ (CompileSourceFile::Parse, true, m_compilers)) return false; // Small files and large file chunks |
| if (!compileFileSet_ (CompileSourceFile::Parse, true, m_compilersParentFiles)) return false; // Recombine chunks |
| } |
| |
| if (m_commandLineParser->profile()) |
| { |
| std::string msg = "Parsing took " + StringUtils::to_string(tmr.elapsed_rounded()) + "s\n"; |
| for (unsigned int i = 0; i < m_compilersParentFiles.size(); i++) |
| { |
| msg += m_compilersParentFiles[i]->getParser ()->getProfileInfo (); |
| } |
| for (unsigned int i = 0; i < m_compilers.size(); i++) |
| { |
| msg += m_compilers[i]->getParser ()->getProfileInfo (); |
| } |
| |
| std::cout << msg << std::endl; |
| profile += msg; |
| tmr.reset(); |
| } |
| |
| // Check Parsing |
| CheckCompile* checkComp = new CheckCompile (this); |
| checkComp->check (); |
| delete checkComp; |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| |
| // Python Listener |
| if (m_commandLineParser->pythonListener () |
| || m_commandLineParser->pythonEvalScriptPerFile ()) |
| { |
| |
| if (!parserInitialized) |
| pythoninit_ (); |
| if (!compileFileSet_ (CompileSourceFile::PythonAPI, true, m_compilers)) return false; |
| if (!compileFileSet_ (CompileSourceFile::PythonAPI, true, m_compilersParentFiles)) return false; |
| |
| if (m_commandLineParser->profile ()) |
| { |
| std::string msg = "Python file processing took " + StringUtils::to_string(tmr.elapsed_rounded ()) + "s\n"; |
| std::cout << msg << std::endl; |
| profile += msg; |
| tmr.reset(); |
| } |
| |
| } |
| |
| if (m_commandLineParser->compile()) |
| { |
| // Compile Design, has its own thread management |
| CompileDesign* compileDesign = new CompileDesign (this); |
| compileDesign->compile (); |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| |
| if (m_commandLineParser->profile ()) |
| { |
| std::string msg = "Compilation took " + StringUtils::to_string (tmr.elapsed_rounded ()) + "s\n"; |
| std::cout << msg << std::endl; |
| profile += msg; |
| tmr.reset (); |
| } |
| |
| if (m_commandLineParser->elaborate ()) |
| { |
| compileDesign->elaborate (); |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| |
| if (m_commandLineParser->profile ()) |
| { |
| std::string msg = "Elaboration took " + StringUtils::to_string (tmr.elapsed_rounded ()) + "s\n"; |
| std::cout << msg << std::endl; |
| profile += msg; |
| tmr.reset (); |
| } |
| |
| if (m_commandLineParser->pythonEvalScript ()) |
| { |
| PythonAPI::evalScript (m_commandLineParser->getSymbolTable ()->getSymbol (m_commandLineParser->pythonEvalScriptId ()), |
| m_design); |
| if (m_commandLineParser->profile ()) |
| { |
| std::string msg = "Python design processing took " + StringUtils::to_string (tmr.elapsed_rounded ()) + "s\n"; |
| profile += msg; |
| std::cout << msg << std::endl; |
| tmr.reset (); |
| } |
| } |
| m_errors->printMessages (m_commandLineParser->muteStdout ()); |
| } |
| |
| |
| delete compileDesign; |
| } |
| if (m_commandLineParser->profile ()) |
| { |
| std::string msg = "Total time " + StringUtils::to_string (tmrTotal.elapsed_rounded ()) + "s\n"; |
| profile += msg; |
| profile = std::string ("==============\n") + "PROFILE\n" + std::string ("==============\n") + profile + "==============\n"; |
| std::cout << profile << std::endl; |
| m_errors->printToLogFile (profile); |
| } |
| return true; |
| } |
| |
| void |
| Compiler::registerAntlrPpHandlerForId (SymbolId id, PreprocessFile::AntlrParserHandler* pp) |
| { |
| std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr = m_antlrPpMap.find (id); |
| if (itr != m_antlrPpMap.end ()) |
| { |
| delete (*itr).second; |
| m_antlrPpMap.erase (itr); |
| m_antlrPpMap.insert (std::make_pair (id, pp)); |
| return; |
| } |
| m_antlrPpMap.insert (std::make_pair (id, pp)); |
| } |
| |
| PreprocessFile::AntlrParserHandler* |
| Compiler::getAntlrPpHandlerForId (SymbolId id) |
| { |
| std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr = m_antlrPpMap.find (id); |
| if (itr != m_antlrPpMap.end ()) |
| { |
| PreprocessFile::AntlrParserHandler* ptr = (*itr).second; |
| return ptr; |
| } |
| return NULL; |
| } |
| |
| bool Compiler::parseLibrariesDef_() { |
| m_librarySet = new LibrarySet(); |
| m_configSet = new ConfigSet(); |
| m_design = new Design (this, m_librarySet, m_configSet); |
| ParseLibraryDef* libParser = new ParseLibraryDef(m_commandLineParser,m_errors,m_symbolTable,m_librarySet, m_configSet); |
| return libParser->parseLibrariesDefinition (); |
| } |
| |
| |