int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); /*QSettings test("test.ini", QSettings::IniFormat); test.beginGroup("compiler"); test.setValue("test-value", "asd"); test.setValue("other-value", "val"); test.endGroup(); test.beginGroup("opt"); test.setValue("test-value2", "asd2"); test.setValue("other-value2", "val2"); test.endGroup(); test.sync(); return 0;*/ QTime bigTimer; bigTimer.start(); QStringList params = a.arguments(); if (params.size() != 2) { qCritical() << "Expecting file to compile"; return 0; } ErrorHandler errHandler; Settings settings; bool success = false; success = settings.loadDefaults(); if (!success) { errHandler.error(ErrorCodes::ecSettingsLoadingFailed, errHandler.tr("Loading the default settings \"%1\" failed").arg(settings.loadPath()), CodePoint()); return ErrorCodes::ecSettingsLoadingFailed; } Lexer lexer; QObject::connect(&lexer, &Lexer::error, &errHandler, &ErrorHandler::error); QObject::connect(&lexer, &Lexer::warning, &errHandler, &ErrorHandler::warning); QTime timer; timer.start(); if (lexer.tokenizeFile(params[1], settings) == Lexer::Success) { qDebug() << "Lexical analysing took " << timer.elapsed() << "ms"; #ifdef DEBUG_OUTPUT lexer.writeTokensToFile("tokens.txt"); #endif } else { errHandler.error(ErrorCodes::ecLexicalAnalysingFailed, errHandler.tr("Lexical analysing failed"), CodePoint(lexer.files().first().first)); return ErrorCodes::ecLexicalAnalysingFailed; } Parser parser; QObject::connect(&parser, &Parser::error, &errHandler, &ErrorHandler::error); QObject::connect(&parser, &Parser::warning, &errHandler, &ErrorHandler::warning); timer.start(); ast::Program *program = parser.parse(lexer.tokens(), settings); qDebug() << "Parsing took " << timer.elapsed() << "ms"; if (!parser.success()) { errHandler.error(ErrorCodes::ecParsingFailed, errHandler.tr("Parsing failed \"%1\"").arg(params[1]), CodePoint()); return ErrorCodes::ecParsingFailed; } #ifdef DEBUG_OUTPUT if (program) { QFile file("ast.txt"); if (file.open(QFile::WriteOnly)) { QTextStream stream(&file); program->write(stream); file.close(); } } #endif CodeGenerator codeGenerator; //QObject::connect(&codeGenerator, &CodeGenerator::error, &errHandler, &ErrorHandler::error); //QObject::connect(&codeGenerator, &CodeGenerator::warning, &errHandler, &ErrorHandler::warning); QObject::connect(&codeGenerator, &CodeGenerator::error, &errHandler, &ErrorHandler::error); QObject::connect(&codeGenerator, &CodeGenerator::warning, &errHandler, &ErrorHandler::warning); timer.start(); if (!codeGenerator.initialize(settings)) { return ErrorCodes::ecCodeGeneratorInitializationFailed; } qDebug() << "Code generator initialization took " << timer.elapsed() << "ms"; timer.start(); if (!codeGenerator.generate(program)) { errHandler.error(ErrorCodes::ecCodeGenerationFailed, errHandler.tr("Code generation failed"), CodePoint()); return ErrorCodes::ecCodeGenerationFailed; } qDebug() << "Code generation took" << timer.elapsed() << "ms"; qDebug() << "LLVM-IR generated"; timer.start(); codeGenerator.createExecutable(settings.defaultOutputFile()); qDebug() << "Executable generation took " << timer.elapsed() << "ms"; qDebug() << "The whole compilation took " << bigTimer.elapsed() << "ms"; return 0; }
nmethod* Compiler::compile() { NewBackendGuard guard; if ((PrintProgress > 0) && (nofCompilations % PrintProgress == 0)) std->print("."); const char* compiling; if (DeltaProcess::active()->isUncommon()) { compiling = recompilee ? "Uncommon-Recompiling " : "Uncommon-Compiling "; } else { if (_uses_inlining_database) { compiling = recompilee ? "Recompiling (database)" : "Compiling (database)"; } else { compiling = recompilee ? "Recompiling " : "Compiling "; } } EventMarker em("%s%#lx %#lx", compiling, key->selector(), NULL); // don't use uncommon traps when recompiling because of trap useUncommonTraps = DeferUncommonBranches && !is_uncommon_compile(); if (is_uncommon_compile()) reporter->report_uncommon(false); if (recompilee && recompilee->isUncommonRecompiled()) reporter->report_uncommon(true); // don't use counters when compiling from DB FlagSetting fs(UseRecompilation, UseRecompilation && !is_database_compile()); bool should_trace = _uses_inlining_database ? PrintInliningDatabaseCompilation : PrintCompilation; TraceTime t(compiling, should_trace); if (should_trace || PrintCode) { print_key(std); if (PrintCode || PrintInlining) std->print("\n"); } topScope->genCode(); fixupNLRTestPoints(); buildBBs(); if (PrintCode) print_code(false); if (verifyOften) bbIterator->verify(); // compute escaping blocks and up-level accessed vars bbIterator->computeEscapingBlocks(); bbIterator->computeUplevelAccesses(); if (verifyOften) bbIterator->verify(); //if (PrintCode) print_code(false); // construct def & use information bbIterator->makeUses(); if (verifyOften) bbIterator->verify(); //if (PrintCode) print_code(false); if (LocalCopyPropagate) { bbIterator->localCopyPropagate(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (GlobalCopyPropagate) { bbIterator->globalCopyPropagate(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (BruteForcePropagate) { bbIterator->bruteForceCopyPropagate(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (EliminateUnneededNodes) { bbIterator->eliminateUnneededResults(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (OptimizeIntegerLoops) { // run after copy propagation so that loop increment is easier to recognize // also run after eliminateUnneededResults so that cpInfo is set for eliminated PRegs topScope->optimizeLoops(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); // compute existence & format of run-time context objects and blocks computeBlockInfo(); // allocate floats _totalNofFloatTemporaries = topScope->allocateFloatTemporaries(0); // HACK: Fix preallocation // Necessary because a few primitives (allocateContext/Closure) need self or // the previous context after calling a primitive; i.e., self or the previous // context should not be allocated to a register. Currently not working correctly // -> allocated to stack as a temporary fix for the problem. theAllocator->preAllocate(topScope->self()->preg()); bbIterator->localAlloc(); // allocate regs within basic blocks theAllocator->allocate(bbIterator->globals); if (PrintCode) print_code(false); #ifdef ASSERT bbIterator->verify(); #endif if (PrintDebugInfoGeneration) { std->cr(); std->cr(); std->print_cr("Start of debugging info."); } topScope->generateDebugInfo(); // must come before gen to set scopeInfo topScope->generateDebugInfoForNonInlinedBlocks(); // generate machine code theMacroAssm = new MacroAssembler(_code); if (UseNewBackend) { PRegMapping* mapping = new PRegMapping(theMacroAssm, topScope->nofArguments(), 6, topScope->nofTemporaries()); CodeGenerator* cgen = new CodeGenerator(theMacroAssm, mapping); cgen->initialize(topScope); bbIterator->apply(cgen); cgen->finalize(topScope); } else { // use a node visitor to generate code OldCodeGenerator* cgen = new OldCodeGenerator(); bbIterator->apply(cgen); } theMacroAssm->finalize(); theMacroAssm = NULL; #ifndef ASSERT if (verifyOften) { #endif bool ok = bbIterator->verifyLabels(); if (!ok) print_code(false); #ifndef ASSERT } #endif rec->generate(); // write debugging info nmethod* nm = new_nmethod(this); // construct new nmethod em.event.args[1] = nm; if (PrintAssemblyCode) Disassembler::decode(nm); reporter->finish_reporting(); if (should_trace) { lprintf(": %#lx (%d bytes; level %ld v%d)\n", nm, nm->instsLen(), nm->level(), nm->version()); flush_logFile(); } if (verifyOften) nm->verify(); if (PrintDebugInfo) nm->print_inlining(std, true); return nm; }