Example #1
0
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;
}
Example #2
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;
}