/// Add the complete set of target-independent postISel code generator passes.
///
/// This can be read as the standard order of major LLVM CodeGen stages. Stages
/// with nontrivial configuration or multiple passes are broken out below in
/// add%Stage routines.
///
/// Any TargetPassConfig::addXX routine may be overriden by the Target. The
/// addPre/Post methods with empty header implementations allow injecting
/// target-specific fixups just before or after major stages. Additionally,
/// targets have the flexibility to change pass order within a stage by
/// overriding default implementation of add%Stage routines below. Each
/// technique has maintainability tradeoffs because alternate pass orders are
/// not well supported. addPre/Post works better if the target pass is easily
/// tied to a common pass. But if it has subtle dependencies on multiple passes,
/// the target should override the stage instead.
///
/// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
/// before/after any target-independent pass. But it's currently overkill.
void TargetPassConfig::addMachinePasses() {
  AddingMachinePasses = true;

  // Insert a machine instr printer pass after the specified pass.
  if (!StringRef(PrintMachineInstrs.getValue()).equals("") &&
      !StringRef(PrintMachineInstrs.getValue()).equals("option-unspecified")) {
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    const PassInfo *TPI = PR->getPassInfo(PrintMachineInstrs.getValue());
    const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer"));
    assert (TPI && IPI && "Pass ID not registered!");
    const char *TID = (const char *)(TPI->getTypeInfo());
    const char *IID = (const char *)(IPI->getTypeInfo());
    insertPass(TID, IID);
  }

  // Print the instruction selected machine code...
  printAndVerify("After Instruction Selection");

  if (TM->Options.EnableIPRA)
    addPass(createRegUsageInfoPropPass());

  // Expand pseudo-instructions emitted by ISel.
  addPass(&ExpandISelPseudosID);

  // Add passes that optimize machine instructions in SSA form.
  if (getOptLevel() != CodeGenOpt::None) {
    addMachineSSAOptimization();
  } else {
    // If the target requests it, assign local variables to stack slots relative
    // to one another and simplify frame index references where possible.
    addPass(&LocalStackSlotAllocationID, false);
  }

  // Run pre-ra passes.
  addPreRegAlloc();

  // Run register allocation and passes that are tightly coupled with it,
  // including phi elimination and scheduling.
  if (getOptimizeRegAlloc())
    addOptimizedRegAlloc(createRegAllocPass(true));
  else
    addFastRegAlloc(createRegAllocPass(false));

  // Run post-ra passes.
  addPostRegAlloc();

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  if (getOptLevel() != CodeGenOpt::None)
    addPass(&ShrinkWrapID);

  // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
  // do so if it hasn't been disabled, substituted, or overridden.
  if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
      addPass(createPrologEpilogInserterPass(TM));

  /// Add passes that optimize machine instructions after register allocation.
  if (getOptLevel() != CodeGenOpt::None)
    addMachineLateOptimization();

  // Expand pseudo instructions before second scheduling pass.
  addPass(&ExpandPostRAPseudosID);

  // Run pre-sched2 passes.
  addPreSched2();

  if (EnableImplicitNullChecks)
    addPass(&ImplicitNullChecksID);

  // Second pass scheduler.
  // Let Target optionally insert this pass by itself at some other
  // point.
  if (getOptLevel() != CodeGenOpt::None &&
      !TM->targetSchedulesPostRAScheduling()) {
    if (MISchedPostRA)
      addPass(&PostMachineSchedulerID);
    else
      addPass(&PostRASchedulerID);
  }

  // GC
  if (addGCPasses()) {
    if (PrintGCInfo)
      addPass(createGCInfoPrinter(dbgs()), false, false);
  }

  // Basic block placement.
  if (getOptLevel() != CodeGenOpt::None)
    addBlockPlacement();

  addPreEmitPass();

  if (TM->Options.EnableIPRA)
    // Collect register usage information and produce a register mask of
    // clobbered registers, to be used to optimize call sites.
    addPass(createRegUsageInfoCollector());

  addPass(&FuncletLayoutID, false);

  addPass(&StackMapLivenessID, false);
  addPass(&LiveDebugValuesID, false);

  addPass(&XRayInstrumentationID, false);
  addPass(&PatchableFunctionID, false);

  AddingMachinePasses = false;
}
Beispiel #2
0
int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
#endif

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  cl::ParseCommandLineOptions(argc, argv,
                              "LLVM automatic testcase reducer. See\nhttp://"
                              "llvm.org/cmds/bugpoint.html"
                              " for more information.\n");
#ifndef DEBUG_BUGPOINT
  sys::SetInterruptFunction(BugpointInterruptFunction);
#endif

  LLVMContext& Context = getGlobalContext();
  // If we have an override, set it and then track the triple we want Modules
  // to use.
  if (!OverrideTriple.empty()) {
    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  }

  if (MemoryLimit < 0) {
    // Set the default MemoryLimit.  Be sure to update the flag's description if
    // you change this.
    if (sys::RunningOnValgrind() || UseValgrind)
      MemoryLimit = 800;
    else
      MemoryLimit = 300;
  }

  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit,
              UseValgrind, Context);
  if (D.addSources(InputFilenames)) return 1;

  AddToDriver PM(D);

  if (StandardLinkOpts) {
    PassManagerBuilder Builder;
    Builder.Inliner = createFunctionInliningPass();
    Builder.populateLTOPassManager(PM);
  }

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    PassManagerBuilder Builder;
    if (OptLevelO1)
      Builder.Inliner = createAlwaysInlinerPass();
    else if (OptLevelO2)
      Builder.Inliner = createFunctionInliningPass(225);
    else
      Builder.Inliner = createFunctionInliningPass(275);

    // Note that although clang/llvm-gcc use two separate passmanagers
    // here, it shouldn't normally make a difference.
    Builder.populateFunctionPassManager(PM);
    Builder.populateModulePassManager(PM);
  }

  for (std::vector<const PassInfo*>::iterator I = PassList.begin(),
         E = PassList.end();
       I != E; ++I) {
    const PassInfo* PI = *I;
    D.addPass(PI->getPassArgument());
  }

  // Bugpoint has the ability of generating a plethora of core files, so to
  // avoid filling up the disk, we prevent it
#ifndef DEBUG_BUGPOINT
  sys::Process::PreventCoreFiles();
#endif

  std::string Error;
  bool Failure = D.run(Error);
  if (!Error.empty()) {
    errs() << Error;
    return 1;
  }
  return Failure;
}
int main(int argc_, const char **argv_) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc_, argv_);

  if (llvm::sys::Process::FixupStandardFileDescriptors())
    return 1;

  SmallVector<const char *, 256> argv;
  llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
  std::error_code EC = llvm::sys::Process::GetArgumentVector(
      argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator);
  if (EC) {
    llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
    return 1;
  }

  std::string ProgName = normalizeProgramName(argv[0]);
  const DriverSuffix *DS = parseDriverSuffix(ProgName);

  llvm::BumpPtrAllocator A;
  llvm::StringSaver Saver(A);

  // Parse response files using the GNU syntax, unless we're in CL mode. There
  // are two ways to put clang in CL compatibility mode: argv[0] is either
  // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
  // command line parsing can't happen until after response file parsing, so we
  // have to manually search for a --driver-mode=cl argument the hard way.
  // Finally, our -cc1 tools don't care which tokenization mode we use because
  // response files written by clang will tokenize the same way in either mode.
  llvm::cl::TokenizerCallback Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
  if ((DS && DS->ModeFlag && strcmp(DS->ModeFlag, "--driver-mode=cl") == 0) ||
      std::find_if(argv.begin(), argv.end(), [](const char *F) {
        return F && strcmp(F, "--driver-mode=cl") == 0;
      }) != argv.end()) {
    Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
  }

  // Determines whether we want nullptr markers in argv to indicate response
  // files end-of-lines. We only use this for the /LINK driver argument.
  bool MarkEOLs = true;
  if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
    MarkEOLs = false;
  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs);

  // Separate out templight and clang flags.  templight flags are "-Xtemplight <templight_flag>"
  SmallVector<const char *, 256> templight_argv, clang_argv;
  templight_argv.push_back(argv[0]);
  clang_argv.push_back(argv[0]);
  for (int i = 1, size = argv.size(); i < size; /* in loop */ ) {
    if ((argv[i] != nullptr) &&
        (strcmp(argv[i], "-Xtemplight") == 0)) {
      while( i < size - 1 && argv[++i] == nullptr ) /* skip EOLs */ ;
      templight_argv.push_back(argv[i]);   // the word after -Xtemplight
      if( i == size - 1 ) // was this the last argument?
        break;
      while( i < size - 1 && argv[++i] == nullptr ) /* skip EOLs */ ;
    } else {
      if ((argv[i] != nullptr) &&
          ((strcmp(argv[i], "-help") == 0) ||
           (strcmp(argv[i], "--help") == 0))) {
        // Print the help for the templight options:
        PrintTemplightHelp();
      }
      clang_argv.push_back(argv[i++]);  // also leave -help to driver (to print its help info too)
    }
  }

  cl::ParseCommandLineOptions(
      templight_argv.size(), &templight_argv[0],
      "A tool to profile template instantiations in C++ code.\n");

  bool CanonicalPrefixes = true;
  for (int i = 1, size = clang_argv.size(); i < size; ++i) {
    // Skip end-of-line response file markers
    if (clang_argv[i] == nullptr)
      continue;
    if (StringRef(clang_argv[i]) == "-no-canonical-prefixes") {
      CanonicalPrefixes = false;
      break;
    }
  }

  std::string Path = GetExecutablePath(clang_argv[0], CanonicalPrefixes);

  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
      CreateAndPopulateDiagOpts(clang_argv);

  TextDiagnosticPrinter *DiagClient
    = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
  FixupDiagPrefixExeName(DiagClient, Path);

  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());

  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);

  if (!DiagOpts->DiagnosticSerializationFile.empty()) {
    auto SerializedConsumer =
        clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile,
                                        &*DiagOpts, /*MergeChildRecords=*/true);
    Diags.setClient(new ChainedDiagnosticConsumer(
        Diags.takeClient(), std::move(SerializedConsumer)));
  }

  ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);

  // Prepare a variable for the return value:
  int Res = 0;

  void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;

  llvm::InitializeAllTargets();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmPrinters();
  llvm::InitializeAllAsmParsers();

#ifdef LINK_POLLY_INTO_TOOLS
  llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
  polly::initializePollyPasses(Registry);
#endif

  // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
  // file.
  auto FirstArg = std::find_if(clang_argv.begin() + 1, clang_argv.end(),
                               [](const char *A) { return A != nullptr; });
  bool invokeCC1 = (FirstArg != clang_argv.end() && StringRef(*FirstArg).startswith("-cc1"));
  if (invokeCC1) {
    // If -cc1 came from a response file, remove the EOL sentinels.
    if (MarkEOLs) {
      auto newEnd = std::remove(clang_argv.begin(), clang_argv.end(), nullptr);
      clang_argv.resize(newEnd - clang_argv.begin());
    }

    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());

    Res = !CompilerInvocation::CreateFromArgs(
        Clang->getInvocation(), clang_argv.begin() + 2, clang_argv.end(), Diags);

    // Infer the builtin include path if unspecified.
    if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
        Clang->getHeaderSearchOpts().ResourceDir.empty())
      Clang->getHeaderSearchOpts().ResourceDir =
        CompilerInvocation::GetResourcesPath(clang_argv[0], GetExecutablePathVP);

    // Create the compilers actual diagnostics engine.
    Clang->createDiagnostics();
    if (!Clang->hasDiagnostics()) {
      Res = 1;
      goto cleanup;
    }

    LocalOutputFilename = OutputFilename;

    // Execute the frontend actions.
    Res = ExecuteTemplightInvocation(Clang.get());

    // When running with -disable-free, don't do any destruction or shutdown.
    if (Clang->getFrontendOpts().DisableFree) {
      if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats)
        llvm::PrintStatistics();
      BuryPointer(std::move(Clang));
    }

  } else {

    Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
    TheDriver.setTitle("templight");
    SetInstallDir(clang_argv, TheDriver);

    std::set<std::string> SavedStrings;
    insertArgsFromProgramName(ProgName, DS, clang_argv, SavedStrings);

    SetBackdoorDriverOutputsFromEnvVars(TheDriver);

    std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(clang_argv));
    if(!C.get()) {
      Res = 1;
      goto cleanup;
    }

    SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
    for (auto &J : C->getJobs())
      ExecuteTemplightCommand(TheDriver, Diags, *C, J, clang_argv[0], FailingCommands);

    // Merge all the temp files into a single output file:
    if ( ! TempOutputFiles.empty() ) {
      if ( OutputFilename.empty() )
        OutputFilename = "a";
      std::string FinalOutputFilename = TemplightAction::CreateOutputFilename(
        nullptr, OutputFilename,
        InstProfiler, OutputToStdOut, MemoryProfile);
      if ( ( !FinalOutputFilename.empty() ) && ( FinalOutputFilename != "-" ) ) {
        std::error_code error;
        llvm::raw_fd_ostream TraceOS(FinalOutputFilename, error, llvm::sys::fs::F_None);
        if ( error ) {
          llvm::errs() <<
            "Error: [Templight] Can not open file to write trace of template instantiations: "
            << FinalOutputFilename << " Error: " << error.message();
        } else {
          for ( SmallVector< std::string, 32 >::iterator it = TempOutputFiles.begin(),
                it_end = TempOutputFiles.end(); it != it_end; ++it) {
            llvm::ErrorOr< std::unique_ptr<llvm::MemoryBuffer> >
              file_epbuf = llvm::MemoryBuffer::getFile(llvm::Twine(*it));
            if(file_epbuf && file_epbuf.get()) {
              TraceOS << StringRef(file_epbuf.get()->getBufferStart(),
                file_epbuf.get()->getBufferEnd() - file_epbuf.get()->getBufferStart())
                << '\n';
            }
          }
        }
      }
    }

    // Remove temp files.
    C->CleanupFileList(C->getTempFiles());

    // If the command succeeded, the number of failing commands should zero:
    Res = FailingCommands.size();

    // Otherwise, remove result files and print extra information about abnormal
    // failures.
    for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it =
          FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) {
      int FailRes = it->first;
      const Command *FailingCommand = it->second;

      // Remove result files if we're not saving temps.
      if (!C->getArgs().hasArg(options::OPT_save_temps)) {
        const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
        C->CleanupFileMap(C->getResultFiles(), JA, true);

        // Failure result files are valid unless we crashed.
        if (FailRes < 0)
          C->CleanupFileMap(C->getFailureResultFiles(), JA, true);
      }

      // Print extra information about abnormal failures, if possible.
      const Tool &FailingTool = FailingCommand->getCreator();

      if (!FailingCommand->getCreator().hasGoodDiagnostics() || FailRes != 1) {
        if (FailRes < 0)
          Diags.Report(clang::diag::err_drv_command_signalled)
            << FailingTool.getShortName();
        else
          Diags.Report(clang::diag::err_drv_command_failed)
            << FailingTool.getShortName() << FailRes;
      }
    }

  }

cleanup:

  // If any timers were active but haven't been destroyed yet, print their
  // results now.  This happens in -disable-free mode.
  llvm::TimerGroup::printAll(llvm::errs());

  llvm::llvm_shutdown();

#ifdef LLVM_ON_WIN32
  // Exit status should not be negative on Win32, unless abnormal termination.
  // Once abnormal termiation was caught, negative status should not be
  // propagated.
  if (Res < 0)
    Res = 1;
#endif

  // If we have multiple failing commands, we return the result of the first
  // failing command.
  return Res;
}
Beispiel #4
0
int main(int argc, char **argv, char **envp) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeTarget(Registry);

  // Initial global variable above for convenience printing of program name.
  progname = sys::path::stem(argv[0]);

  // Parse the command line options
  cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");

#if defined(_WIN32) || defined(__CYGWIN__)
  if (!LinkAsLibrary) {
    // Default to "a.exe" instead of "a.out".
    if (OutputFilename.getNumOccurrences() == 0)
      OutputFilename = "a.exe";

    // If there is no suffix add an "exe" one.
    if (sys::path::extension(OutputFilename).empty())
      OutputFilename.append(".exe");
  }
#endif

  // Generate the bitcode for the optimized module.
  // If -b wasn't specified, use the name specified
  // with -o to construct BitcodeOutputFilename.
  if (BitcodeOutputFilename.empty()) {
    BitcodeOutputFilename = OutputFilename;
    if (!LinkAsLibrary) BitcodeOutputFilename += ".bc";
  }

  // Arrange for the bitcode output file to be deleted on any errors.
  BitcodeOutputRemover.setFile(BitcodeOutputFilename);
  sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename));

  // Arrange for the output file to be deleted on any errors.
  if (!LinkAsLibrary) {
    OutputRemover.setFile(OutputFilename);
    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
  }

  // Construct a Linker (now that Verbose is set)
  Linker TheLinker(progname, OutputFilename, Context, Verbose);

  // Keep track of the native link items (versus the bitcode items)
  Linker::ItemList NativeLinkItems;

  // Add library paths to the linker
  TheLinker.addPaths(LibPaths);
  TheLinker.addSystemPaths();

  // Remove any consecutive duplicates of the same library...
  Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                  Libraries.end());

  if (LinkAsLibrary) {
    std::vector<sys::Path> Files;
    for (unsigned i = 0; i < InputFilenames.size(); ++i )
      Files.push_back(sys::Path(InputFilenames[i]));
    if (TheLinker.LinkInFiles(Files))
      return 1; // Error already printed

    // The libraries aren't linked in but are noted as "dependent" in the
    // module.
    for (cl::list<std::string>::const_iterator I = Libraries.begin(),
         E = Libraries.end(); I != E ; ++I) {
      TheLinker.getModule()->addLibrary(*I);
    }
  } else {
    // Build a list of the items from our command line
    Linker::ItemList Items;
    BuildLinkItems(Items, InputFilenames, Libraries);

    // Link all the items together
    if (TheLinker.LinkInItems(Items, NativeLinkItems) )
      return 1; // Error already printed
  }

  std::auto_ptr<Module> Composite(TheLinker.releaseModule());

  // Optimize the module
  Optimize(Composite.get());

  // Generate the bitcode output.
  GenerateBitcode(Composite.get(), BitcodeOutputFilename);

  // If we are not linking a library, generate either a native executable
  // or a JIT shell script, depending upon what the user wants.
  if (!LinkAsLibrary) {
    // If the user wants to run a post-link optimization, run it now.
    if (!PostLinkOpts.empty()) {
      std::vector<std::string> opts = PostLinkOpts;
      for (std::vector<std::string>::iterator I = opts.begin(),
           E = opts.end(); I != E; ++I) {
        sys::Path prog(*I);
        if (!prog.canExecute()) {
          prog = sys::Program::FindProgramByName(*I);
          if (prog.isEmpty())
            PrintAndExit(std::string("Optimization program '") + *I +
                         "' is not found or not executable.", Composite.get());
        }
        // Get the program arguments
        sys::Path tmp_output("opt_result");
        std::string ErrMsg;
        if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg))
          PrintAndExit(ErrMsg, Composite.get());

        const char* args[4];
        args[0] = I->c_str();
        args[1] = BitcodeOutputFilename.c_str();
        args[2] = tmp_output.c_str();
        args[3] = 0;
        if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) {
          if (tmp_output.isBitcodeFile()) {
            sys::Path target(BitcodeOutputFilename);
            target.eraseFromDisk();
            if (tmp_output.renamePathOnDisk(target, &ErrMsg))
              PrintAndExit(ErrMsg, Composite.get(), 2);
          } else
            PrintAndExit("Post-link optimization output is not bitcode",
                         Composite.get());
        } else {
          PrintAndExit(ErrMsg, Composite.get());
        }
      }
    }

    // If the user wants to generate a native executable, compile it from the
    // bitcode file.
    //
    // Otherwise, create a script that will run the bitcode through the JIT.
    if (Native) {
      // Name of the Assembly Language output file
      sys::Path AssemblyFile ( OutputFilename);
      AssemblyFile.appendSuffix("s");

      // Mark the output files for removal.
      FileRemover AssemblyFileRemover(AssemblyFile.str());
      sys::RemoveFileOnSignal(AssemblyFile);

      // Determine the locations of the llc and gcc programs.
      sys::Path llc = PrependMainExecutablePath("llc", argv[0],
                                                (void *)(intptr_t)&Optimize);
      if (llc.isEmpty())
        PrintAndExit("Failed to find llc", Composite.get());

      sys::Path gcc = sys::Program::FindProgramByName("gcc");
      if (gcc.isEmpty())
        PrintAndExit("Failed to find gcc", Composite.get());

      // Generate an assembly language file for the bitcode.
      std::string ErrMsg;
      if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename,
          llc, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());

      if (0 != GenerateNative(OutputFilename, AssemblyFile.str(),
                              NativeLinkItems, gcc, envp, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());
    } else if (NativeCBE) {
      sys::Path CFile (OutputFilename);
      CFile.appendSuffix("cbe.c");

      // Mark the output files for removal.
      FileRemover CFileRemover(CFile.str());
      sys::RemoveFileOnSignal(CFile);

      // Determine the locations of the llc and gcc programs.
      sys::Path llc = PrependMainExecutablePath("llc", argv[0],
                                                (void *)(intptr_t)&Optimize);
      if (llc.isEmpty())
        PrintAndExit("Failed to find llc", Composite.get());

      sys::Path gcc = sys::Program::FindProgramByName("gcc");
      if (gcc.isEmpty())
        PrintAndExit("Failed to find gcc", Composite.get());

      // Generate an assembly language file for the bitcode.
      std::string ErrMsg;
      if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());

      if (GenerateNative(OutputFilename, CFile.str(),
                         NativeLinkItems, gcc, envp, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());
    } else {
      EmitShellScript(argv, Composite.get());
    }

    // Make the script executable...
    std::string ErrMsg;
    if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg))
      PrintAndExit(ErrMsg, Composite.get());

    // Make the bitcode file readable and directly executable in LLEE as well
    if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg))
      PrintAndExit(ErrMsg, Composite.get());

    if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg))
      PrintAndExit(ErrMsg, Composite.get());
  }

  // Operations which may fail are now complete.
  BitcodeOutputRemover.releaseFile();
  if (!LinkAsLibrary)
    OutputRemover.releaseFile();

  // Graceful exit
  return 0;
}
Beispiel #5
0
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);

  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  LLVMContext Context;

  //InitializeAllTargets();
  //InitializeAllTargetMCs();

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  //initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  initializeSoaapPass(Registry);

  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);

  if (!M.get()) {
    Err.print(argv[0], errs());
    return 1;
  }
  
  // Warn if M doesn't have debug info
  if (M->getNamedMetadata("llvm.dbg.cu") == NULL) {
    errs() << "**********************************************************\n";
    errs() << "WARNING: Input IR file does not contain debug information\n";
    errs() << "**********************************************************\n";
  }
  
  // Figure out what stream we are supposed to write to...
  std::unique_ptr<tool_output_file> Out;
  if (!OutputFilename.empty()) {
    std::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      return 1;
    }
  }

  // Create a PassManager to hold and optimize the collection of passes we are
  // about to build.
  //
  legacy::PassManager Passes;
  Passes.add(new soaap::Soaap);

  // Check that the module is well formed on completion of optimization
  if (!OutputFilename.empty()) {
    if (Verify)
      Passes.add(createVerifierPass());

    // Pass to create output
    if (OutputAssembly)
      Passes.add(createPrintModulePass(Out->os()));
    else
      Passes.add(createBitcodeWriterPass(Out->os()));
  }

  // Now that we have all of the passes ready, run them.
  Passes.run(*M.get());

  // Declare success.
  if (!OutputFilename.empty()) {
    Out->keep();
  }

  return 0;
}
Beispiel #6
0
int main(int argc, char* argv[])
{
  std::string programName = argv[0];

    try
      {
	cl::ParseCommandLineOptions( argc, argv );
	SMDiagnostic Err;

        // Load the input module.
	std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context));
        if (M.get() == 0)
	  {
	    Err.Print(argv[0], errs());
            return (1);
	  }
	if (!DisableVerify) {
	  std::string Err;
	  if (verifyModule(*M.get(), ReturnStatusAction, &Err)) {
	    errs() << argv[0]
		   << ": assembly parsed, but does not verify as correct!\n";
	    errs() << Err;
	    return (1);
	  }
	}
	std::ostream *Out = new std::ofstream(OutputFilename.c_str(),
					      std::ios::out | std::ios::trunc
					      | std::ios::binary);
        if (!Out->good())
	  {
	    std::cerr << programName << ": Error opening " << OutputFilename
		      << "!\n";
            return (1);
	  }


	if (DumpAsm)
	  errs() << "Here's the assembly:\n" << *M.get();

	PassManager Passes;

	raw_os_ostream L(*Out);

        // Add an appropriate TargetData instance for this module.
        Passes.add(new TargetData("onfuscator"));

        Passes.add(new MakeDispatcherPass());

	// Passes.add(new WriteBytecodePass(Out, true));
	Passes.add(createPrintModulePass(&L));
	Passes.run( *M.get() );
      }
    catch( std::exception e )
      {
	std::cerr << programName << ": " << e.what() << "\n";
        return (1);
      }
    catch( const std::string& msg )
      {
	std::cerr << programName << ": " << msg << "\n";
        return (1);
      }
    catch( ... )
      {
	std::cerr << programName << ": Unexpected exception occurred.\n";
        return (1);
      }

  return (0);
}
int LLVMFuzzerInitialize(int *argc, char ***argv) {
  // The command line is unusual compared to other fuzzers due to the need to
  // specify the target. Options like -triple, -mcpu, and -mattr work like
  // their counterparts in llvm-mc, while -fuzzer-args collects options for the
  // fuzzer itself.
  //
  // Examples:
  //
  // Fuzz the big-endian MIPS32R6 disassembler using 100,000 inputs of up to
  // 4-bytes each and use the contents of ./corpus as the test corpus:
  //   llvm-mc-fuzzer -triple mips-linux-gnu -mcpu=mips32r6 -disassemble \
  //       -fuzzer-args -max_len=4 -runs=100000 ./corpus
  //
  // Infinitely fuzz the little-endian MIPS64R2 disassembler with the MSA
  // feature enabled using up to 64-byte inputs:
  //   llvm-mc-fuzzer -triple mipsel-linux-gnu -mcpu=mips64r2 -mattr=msa \
  //       -disassemble -fuzzer-args ./corpus
  //
  // If your aim is to find instructions that are not tested, then it is
  // advisable to constrain the maximum input size to a single instruction
  // using -max_len as in the first example. This results in a test corpus of
  // individual instructions that test unique paths. Without this constraint,
  // there will be considerable redundancy in the corpus.

  char **OriginalArgv = *argv;

  LLVMInitializeAllTargetInfos();
  LLVMInitializeAllTargetMCs();
  LLVMInitializeAllAsmParsers();

  cl::ParseCommandLineOptions(*argc, OriginalArgv);

  // Rebuild the argv without the arguments llvm-mc-fuzzer consumed so that
  // the driver can parse its arguments.
  //
  // FuzzerArgs cannot provide the non-const pointer that OriginalArgv needs.
  // Re-use the strings from OriginalArgv instead of copying FuzzerArg to a
  // non-const buffer to avoid the need to clean up when the fuzzer terminates.
  ModifiedArgv.push_back(OriginalArgv[0]);
  for (const auto &FuzzerArg : FuzzerArgs) {
    for (int i = 1; i < *argc; ++i) {
      if (FuzzerArg == OriginalArgv[i])
        ModifiedArgv.push_back(OriginalArgv[i]);
    }
  }
  *argc = ModifiedArgv.size();
  *argv = ModifiedArgv.data();

  // Package up features to be passed to target/subtarget
  // We have to pass it via a global since the callback doesn't
  // permit any user data.
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  if (TripleName.empty())
    TripleName = sys::getDefaultTargetTriple();

  return 0;
}
Beispiel #8
0
//===----------------------------------------------------------------------===//
// main for instrument
//
int main(int argc, char **argv) {
  llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
  LLVMContext &Context = getGlobalContext();
  try {
    cl::ParseCommandLineOptions(argc, argv,
      "zoltar .bc -> .bc instrumenter and mutator\n");
    sys::PrintStackTraceOnErrorSignal();

    // Allocate a full target machine description only if necessary.
    // FIXME: The choice of target should be controllable on the command line.
    std::auto_ptr<TargetMachine> target;

    std::string ErrorMessage;

    // Load the input module...
    std::auto_ptr<Module> M;
    if (MemoryBuffer *Buffer
          = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
      M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage));
      delete Buffer;
    }

    if (M.get() == 0) {
      errs() << argv[0] << ": ";
      if (ErrorMessage.size())
        errs() << ErrorMessage << "\n";
      else
        errs() << "bitcode didn't read correctly.\n";
      return 1;
    }

    // Figure out what stream we are supposed to write to...
    // FIXME: outs() is not binary!
    raw_ostream *Out = &outs();  // Default to printing to stdout...
    if (OutputFilename != "-") {
      std::string ErrorInfo;
      /*TODO: solve this problem */
      //Out = new raw_fd_ostream(OutputFilename.c_str(), /*Binary=*/true,
       //                        Force, ErrorInfo);
      Out = new raw_fd_ostream(OutputFilename.c_str(),ErrorInfo,0);
      if (!ErrorInfo.empty()) {
        errs() << ErrorInfo << '\n';
        if (!Force)
          errs() << "Use -f command line argument to force output\n";
        delete Out;
        return 1;
      }

      // Make sure that the Output file gets unlinked from the disk if we get a
      // SIGINT
      sys::RemoveFileOnSignal(sys::Path(OutputFilename));
    }

    // If the output is set to be emitted to standard out, and standard out is a
    // console, print out a warning message and refuse to do it.  We don't
    // impress anyone by spewing tons of binary goo to a terminal.
    if (!Force && !NoOutput && CheckBitcodeOutputToConsole(*Out,!Quiet)) {
      NoOutput = true;
    }

    // Create a PassManager to hold and optimize the collection of passes we are
    // about to build...
    //
    PassManager Passes;

    // Add an appropriate TargetData instance for this module...
    Passes.add(new TargetData(M.get()));

    // Create a new instrumentation pass for each one specified on the command line
    for (unsigned i = 0; i < PassList.size(); ++i) {
      
      const PassInfo *PassInf = PassList[i];
      Pass *P = 0;
      if (PassInf->getNormalCtor())
        P = PassInf->getNormalCtor()();
      else
        errs() << argv[0] << ": cannot create pass: "******"\n";
      if (P) {
        Passes.add(P);
      }
    }
    
    // Enable the specified mutation operators
    if (!MutOps) {
      OperatorManager* OM = OperatorManager::getInstance();
      OperatorInfoList::iterator oit;
      for (oit = OM->getRegistered().begin(); oit != OM->getRegistered().end(); oit++) {
        (*oit)->setEnabled(true);
      }
    } else {    
        for (unsigned i = 0; i < OperatorList.size(); ++i) {
          
          OperatorInfo *OInf = OperatorList[i];
          
          OInf->setEnabled(true);
        }
    }
    //Passes.add(createPrintModulePass(&errs()));
    // Check that the module is well formed on completion of optimization
    Passes.add(createVerifierPass());

    // Write bitcode out to disk or outs() as the last step...
    if (!NoOutput)
      Passes.add(createBitcodeWriterPass(*Out));

    // Now that we have all of the passes ready, run them.
    Passes.run(*M.get());

    // Delete the raw_fd_ostream.
    if (Out != &outs())
      delete Out;
    
    // Write the context.dat file of zoltar
    ContextManager::print();

    return 0;

  } catch (const std::string& msg) {
    errs() << argv[0] << ": " << msg << "\n";
  } catch (...) {
    errs() << argv[0] << ": Unexpected unknown exception occurred.\n";
  }
  llvm_shutdown();
  return 1;
}
Beispiel #9
0
void WorklessInstrument::InstrumentWorkless0Star1(Module * pModule, Loop * pLoop)
{
	Function * pMain = NULL;

	if(strMainName != "" )
	{
		pMain = pModule->getFunction(strMainName.c_str());
	}
	else
	{
		pMain = pModule->getFunction("main");
	}

	LoadInst * pLoad;
	BinaryOperator* pAdd = NULL;
	StoreInst * pStore = NULL;

	for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) 
	{
		if(BB->getName().equals("entry"))
		{
			CallInst * pCall;
			StoreInst * pStore;

			Instruction * II = BB->begin();
			pCall = CallInst::Create(this->InitHooks, "", II);
			pCall->setCallingConv(CallingConv::C);
			pCall->setTailCall(false);
			AttributeSet emptySet;
			pCall->setAttributes(emptySet);

			pCall = CallInst::Create(this->getenv, this->SAMPLE_RATE_ptr, "", II);
			pCall->setCallingConv(CallingConv::C);
			pCall->setTailCall(false);
			AttributeSet AS;
			{
				SmallVector<AttributeSet, 4> Attrs;
				AttributeSet PAS;
				{
					AttrBuilder B;
					B.addAttribute(Attribute::NoUnwind);
					PAS = AttributeSet::get(pModule->getContext(), ~0U, B);
				}
				Attrs.push_back(PAS);
				AS = AttributeSet::get(pModule->getContext(), Attrs);
			}
			pCall->setAttributes(AS);

			pCall = CallInst::Create(this->function_atoi, pCall, "", II);
			pCall->setCallingConv(CallingConv::C);
			pCall->setTailCall(false);
			{
  				SmallVector<AttributeSet, 4> Attrs;
   				AttributeSet PAS;
    			{
    	 			AttrBuilder B;
     				B.addAttribute(Attribute::NoUnwind);
     				B.addAttribute(Attribute::ReadOnly);
     				PAS = AttributeSet::get(pModule->getContext(), ~0U, B);
    			}
   
   				Attrs.push_back(PAS);
   				AS = AttributeSet::get(pModule->getContext(), Attrs);
   
  			}
  			pCall->setAttributes(AS);

  			pStore = new StoreInst(pCall, this->SAMPLE_RATE, false, II);
  			pStore->setAlignment(4);

  			pCall = CallInst::Create(this->geo, pCall, "", II);
  			pCall->setCallingConv(CallingConv::C);
  			pCall->setTailCall(false);
  			pCall->setAttributes(emptySet);

  			CastInst * pCast = CastInst::CreateIntegerCast(pCall, this->LongType, true, "", II);
  			pStore = new StoreInst(pCast, this->CURRENT_SAMPLE, false, II);
  			pStore->setAlignment(8);

  			vector<Value *> vecParam;
  			vecParam.push_back(this->Output_Format_String);
  			vecParam.push_back(pCall);
  			pCall = CallInst::Create(this->printf, vecParam, "", II);
  			pCall->setCallingConv(CallingConv::C);
  			pCall->setTailCall(false);
  			pCall->setAttributes(emptySet);
  			break;
		}
	}

	for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) 
	{		
		for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) 
		{
			if (isa<ReturnInst>(Ins) || isa<ResumeInst>(Ins)) 
			{
				vector<Value*> vecParams;
				pLoad = new LoadInst(numIterations, "", false, Ins); 
				pLoad->setAlignment(8); 
				vecParams.push_back(pLoad);
				pLoad = new LoadInst(numInstances, "", false, Ins); 
				pLoad->setAlignment(8);
				vecParams.push_back(pLoad);
				
				CallInst* pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins);
				pCall->setCallingConv(CallingConv::C);
				pCall->setTailCall(false);
				AttributeSet aSet;
				pCall->setAttributes(aSet);
			}
			else if(isa<CallInst>(Ins) || isa<InvokeInst>(Ins))
			{
				CallSite cs(Ins);
				Function * pCalled = cs.getCalledFunction();

				if(pCalled == NULL)
				{
					continue;
				}

				if(pCalled->getName() == "exit" || pCalled->getName() == "_ZL9mysql_endi")
				{
					vector<Value*> vecParams;
					pLoad = new LoadInst(numIterations, "", false, Ins); 
					pLoad->setAlignment(8); 
					vecParams.push_back(pLoad);
					pLoad = new LoadInst(numInstances, "", false, Ins); 
					pLoad->setAlignment(8);
					vecParams.push_back(pLoad);
				
					CallInst* pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins);
					pCall->setCallingConv(CallingConv::C);
					pCall->setTailCall(false);
					AttributeSet aSet;
					pCall->setAttributes(aSet);
				}
			}
		}
	}



	BasicBlock * pHeader = pLoop->getHeader();
	set<BasicBlock *> setExitBlock;
	CollectExitBlock(pLoop, setExitBlock);

	vector<BasicBlock *> vecAdded;
	CreateIfElseBlock(pLoop, vecAdded);

	ValueToValueMapTy  VMap;
	set<BasicBlock *> setCloned;
	CloneInnerLoop(pLoop, vecAdded, VMap, setCloned);

	BasicBlock * pPreHeader = vecAdded[1];
	pLoad = new LoadInst(this->numIterations, "", false, pPreHeader->getTerminator());
	pLoad->setAlignment(8);

	BasicBlock * pClonedHeader = cast<BasicBlock>(VMap[pHeader]);

	set<BasicBlock *> setPredBlocks;

	for(pred_iterator PI = pred_begin(pClonedHeader), E = pred_end(pClonedHeader); PI != E; ++PI)
	{
		setPredBlocks.insert(*PI);
	}

	PHINode * pNew = PHINode::Create(pLoad->getType(), setPredBlocks.size(), "numIterations", pClonedHeader->getFirstInsertionPt());
	pAdd = BinaryOperator::Create(Instruction::Add, pNew, this->ConstantLong1, "add", pClonedHeader->getFirstInsertionPt());

	set<BasicBlock *>::iterator itSetBegin = setPredBlocks.begin();
	set<BasicBlock *>::iterator itSetEnd   = setPredBlocks.end();

	for(; itSetBegin != itSetEnd; itSetBegin ++ )
	{
		if((*itSetBegin) == pPreHeader)
		{
			pNew->addIncoming(pLoad, pPreHeader);
		}
		else
		{
			pNew->addIncoming(pAdd, *itSetBegin);
		}
	}


	itSetBegin = setExitBlock.begin();
	itSetEnd   = setExitBlock.end();

	for(; itSetBegin != itSetEnd; itSetBegin ++ )
	{
		SmallVector<BasicBlock*, 8> LoopBlocks;

		for(pred_iterator PI = pred_begin(*itSetBegin), E = pred_end(*itSetBegin); PI != E; ++PI)
		{
			if(setCloned.find(*PI) != setCloned.end())
			{
				LoopBlocks.push_back(*PI);
			}
		}

		BasicBlock * NewExitBB = SplitBlockPredecessors(*itSetBegin, LoopBlocks, ".WL.loopexit", this);

		pStore = new StoreInst(pAdd, this->numIterations, false, NewExitBB->getFirstInsertionPt());
		pStore->setAlignment(8);
	}

	pPreHeader->getParent()->dump();

}
Beispiel #10
0
int ObjectGenerator::process(Module *module) {
    cerr << "Starting object generation" << endl;
    cerr.flush();
//    if (false) {
        //
        // Initialize targets first, so that --version shows registered targets.
        //
        InitializeAllTargets();
        InitializeAllAsmPrinters();

        //
        // Load the module to be compiled...
        //
        SMDiagnostic Err;
        Module &mod = *module;

        //
        // If we are supposed to override the target triple, do so now.
        //
        if (! TargetTriple.empty())
            mod.setTargetTriple(TargetTriple);

        Triple TheTriple(mod.getTargetTriple());
        if (TheTriple.getTriple().empty())
            TheTriple.setTriple(sys::getHostTriple());

        //
        // Allocate target machine.  First, check whether the user has explicitly
        // specified an architecture to compile for. If so we have to look it up by
        // name, because it might be a backend that has no mapping to a target triple.
        //
        const Target *TheTarget = 0;
        if (! MArch.empty()) {
            for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) {
                if (MArch == it -> getName()) {
                    TheTarget = &*it;
                    break;
                }
            }

            if (! TheTarget) {
                errs() << "RoseToLLVM" /*argv[0]*/ << ": error: invalid target '" << MArch << "'.\n";
                return 1;
            }

            //
            // Adjust the triple to match (if known), otherwise stick with the
            // module/host triple.
            //
            Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
            if (Type != Triple::UnknownArch)
                TheTriple.setArch(Type);
        } else {

        std::string Err;
        TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
        if (TheTarget == 0) {
            errs() << "RoseToLLVM" /*argv[0]*/ << ": error auto-selecting target for module '"
                   << Err << "'.  Please use the -march option to explicitly "
                   << "pick a target.\n";
            return 1;
        }
    }

    //
    // Package up features to be passed to target/subtarget
    //
    std::string FeaturesStr;
    if (MCPU.size() || MAttrs.size()) {
        SubtargetFeatures Features;
        Features.setCPU(MCPU);
        for (unsigned i = 0; i != MAttrs.size(); ++i)
            Features.AddFeature(MAttrs[i]);
        FeaturesStr = Features.getString();
    }

    std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr));
    assert(target.get() && "Could not allocate target machine!");
    TargetMachine &Target = *target.get();

    //
    // Figure out where we are going to send the output...
    //
    formatted_raw_ostream *Out = GetOutputStream(TheTarget -> getName(), "RoseToLLVM"/*argv[0]*/);
    if (Out == 0) return 1;

    CodeGenOpt::Level OLvl = CodeGenOpt::Default;
    switch (OptLevel) {
        default:
cerr << "The optimization level is " << OptLevel << endl;
cerr.flush();
            errs() << "RoseToLLVM" /*argv[0]*/ << ": invalid optimization level.\n";
            return 1;
        case ' ': break;
        case '0': OLvl = CodeGenOpt::None; break;
        case '1': OLvl = CodeGenOpt::Less; break;
        case '2': OLvl = CodeGenOpt::Default; break;
        case '3': OLvl = CodeGenOpt::Aggressive; break;
    }

    //
    // Request that addPassesToEmitFile run the Verifier after running
    // passes which modify the IR.
    //
#ifndef NDEBUG
    bool DisableVerify = false;
#else
    bool DisableVerify = true;
#endif

    //
    // If this target requires addPassesToEmitWholeFile, do it now.  This is
    // used by strange things like the C backend.
    //
    if (Target.WantsWholeFile()) {
        PassManager PM;

        //
        // Add the target data from the target machine, if it exists, or the module.
        //
        if (const TargetData *TD = Target.getTargetData())
             PM.add(new TargetData(*TD));
        else PM.add(new TargetData(&mod));

        if (! NoVerify)
            PM.add(createVerifierPass());

        //
        // Ask the target to add backend passes as necessary.
        //
	//        if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl, DisableVerify)) {
        if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl)) {
            errs() << "RoseToLLVM" /*argv[0]*/ << ": target does not support generation of this"
                   << " file type!\n";
            if (Out != &fouts()) delete Out;
            // And the Out file is empty and useless, so remove it now.
            sys::Path(OutputFilename).eraseFromDisk();
            return 1;
        }
        PM.run(mod);
    }
    else {
        //
        // Build up all of the passes that we want to do to the module.
        //
        FunctionPassManager Passes(module);

        //
        // Add the target data from the target machine, if it exists, or the module.
        //
        if (const TargetData *TD = Target.getTargetData())
             Passes.add(new TargetData(*TD));
        else Passes.add(new TargetData(&mod));

#ifndef NDEBUG
        if (! NoVerify)
            Passes.add(createVerifierPass());
#endif

        //
        // Override default to generate verbose assembly.
        //
        Target.setAsmVerbosityDefault(true);

cerr << "The file type is " << FileType << endl;
cerr.flush();
//        if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl, DisableVerify)) {
        if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) {
            errs() << "RoseToLLVM" /*argv[0]*/ << ": target does not support generation of this" << " file type!\n";
            if (Out != &fouts()) delete Out;
            // And the Out file is empty and useless, so remove it now.
            sys::Path(OutputFilename).eraseFromDisk();
            return 1;
        }

        Passes.doInitialization();

        //
        // Run our queue of passes all at once now, efficiently.
        // TODO: this could lazily stream functions out of the module.
        //
        for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
            if (! I -> isDeclaration()) {
                if (DisableRedZone)
                    I -> addFnAttr(Attribute::NoRedZone);
                if (NoImplicitFloats)
                    I -> addFnAttr(Attribute::NoImplicitFloat);
                Passes.run(*I);
            }

            Passes.doFinalization();
        }

        //
        // Delete the ostream if it's not a stdout stream
        //
        if (Out != &fouts()) delete Out;
//    }
    cerr << "Done with object generation" << endl;
    cerr.flush();
}
Beispiel #11
0
formatted_raw_ostream *ObjectGenerator::GetOutputStream(const char *TargetName, const char *ProgName) {
    if (OutputFilename != "") {
        if (OutputFilename == "-")
            return &fouts();

        //
        // Make sure that the Out file gets unlinked from the disk if we get a
        // SIGINT
        //
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));

        std::string error;
        raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error, raw_fd_ostream::F_Binary);
        if (! error.empty()) {
            errs() << error << '\n';
            delete FDOut;
            return 0;
        }
        formatted_raw_ostream *Out = new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);

        return Out;
    }

    if (InputFilename == "-") {
        OutputFilename = "-";
        return &fouts();
    }

    OutputFilename = GetFileNameRoot(InputFilename);

    bool Binary = false;
    switch (FileType) {
        default: assert(0 && "Unknown file type");
        case TargetMachine::CGFT_AssemblyFile:
            if (TargetName[0] == 'c') {
                if (TargetName[1] == 0)
                     OutputFilename += ".cbe.c";
                else if (TargetName[1] == 'p' && TargetName[2] == 'p')
                     OutputFilename += ".cpp";
                else OutputFilename += ".s";
            }
            else OutputFilename += ".s";
            break;
        case TargetMachine::CGFT_ObjectFile:
            OutputFilename += ".o";
            Binary = true;
            break;
	    //        case TargetMachine::CGFT_Null:
	    //            OutputFilename += ".null";
	    //            Binary = true;
	    //            break;
    }

    //
    // Make sure that the Out file gets unlinked from the disk if we get a
    // SIGINT
    //
    sys::RemoveFileOnSignal(sys::Path(OutputFilename));

    std::string error;
    unsigned OpenFlags = 0;
    if (Binary) OpenFlags |= raw_fd_ostream::F_Binary;
    raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error, OpenFlags);
    if (!error.empty()) {
        errs() << error << '\n';
        delete FDOut;
        return 0;
    }

    formatted_raw_ostream *Out = new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);

    return Out;
}
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.


  cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");

  std::string ErrorMessage;
  std::auto_ptr<Module> M;

  {
    OwningPtr<MemoryBuffer> BufferPtr;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
      ErrorMessage = ec.message();
    else
      M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
  }

  if (M.get() == 0) {
    errs() << argv[0] << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "bitcode didn't read correctly.\n";
    return 1;
  }

  // Just use stdout.  We won't actually print anything on it.
  if (DontPrint)
    OutputFilename = "-";

  if (OutputFilename.empty()) { // Unspecified output, infer it.
    if (InputFilename == "-") {
      OutputFilename = "-";
    } else {
      const std::string &IFN = InputFilename;
      int Len = IFN.length();
      // If the source ends in .bc, strip it off.
      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c')
        OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
      else
        OutputFilename = IFN+".ll";
    }
  }

  std::string ErrorInfo;
  OwningPtr<tool_output_file>
  Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                           raw_fd_ostream::F_Binary));
  if (!ErrorInfo.empty()) {
    errs() << ErrorInfo << '\n';
    return 1;
  }

  OwningPtr<AssemblyAnnotationWriter> Annotator;
  if (ShowAnnotations)
    Annotator.reset(new CommentWriter());

  // All that llvm-dis does is write the assembly to a file.
  if (!DontPrint)
    M->print(Out->os(), Annotator.get());

  // Declare success.
  Out->keep();

  return 0;
}
Beispiel #13
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  try {
    cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");

    std::ostream *Out = &std::cout;  // Default to printing to stdout.
    std::string ErrorMessage;

    std::auto_ptr<Module> M;
   
    if (MemoryBuffer *Buffer
           = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
      M.reset(ParseBitcodeFile(Buffer, &ErrorMessage));
      delete Buffer;
    }

    if (M.get() == 0) {
      cerr << argv[0] << ": ";
      if (ErrorMessage.size())
        cerr << ErrorMessage << "\n";
      else
        cerr << "bitcode didn't read correctly.\n";
      return 1;
    }
    
    if (DontPrint) {
      // Just use stdout.  We won't actually print anything on it.
    } else if (OutputFilename != "") {   // Specified an output filename?
      if (OutputFilename != "-") { // Not stdout?
        if (!Force && std::ifstream(OutputFilename.c_str())) {
          // If force is not specified, make sure not to overwrite a file!
          cerr << argv[0] << ": error opening '" << OutputFilename
               << "': file exists! Sending to standard output.\n";
        } else {
          Out = new std::ofstream(OutputFilename.c_str());
        }
      }
    } else {
      if (InputFilename == "-") {
        OutputFilename = "-";
      } else {
        std::string IFN = InputFilename;
        int Len = IFN.length();
        if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
          // Source ends in .bc
          OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
        } else {
          OutputFilename = IFN+".ll";
        }

        if (!Force && std::ifstream(OutputFilename.c_str())) {
          // If force is not specified, make sure not to overwrite a file!
          cerr << argv[0] << ": error opening '" << OutputFilename
               << "': file exists! Sending to standard output.\n";
        } else {
          Out = new std::ofstream(OutputFilename.c_str());

          // Make sure that the Out file gets unlinked from the disk if we get a
          // SIGINT
          sys::RemoveFileOnSignal(sys::Path(OutputFilename));
        }
      }
    }

    if (!Out->good()) {
      cerr << argv[0] << ": error opening " << OutputFilename
           << ": sending to stdout instead!\n";
      Out = &std::cout;
    }

    // All that llvm-dis does is write the assembly to a file.
    if (!DontPrint) {
      PassManager Passes;
      raw_os_ostream L(*Out);
      Passes.add(createPrintModulePass(&L));
      Passes.run(*M.get());
    }

    if (Out != &std::cout) {
      ((std::ofstream*)Out)->close();
      delete Out;
    }
    return 0;
  } catch (const std::string& msg) {
    cerr << argv[0] << ": " << msg << "\n";
  } catch (...) {
    cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
  }

  return 1;
}
/// Return true if the default global register allocator is in use and
/// has not be overriden on the command line with '-regalloc=...'
bool TargetPassConfig::usingDefaultRegAlloc() const {
  return RegAlloc.getNumOccurrences() == 0;
}
Beispiel #15
0
//Command line decoder control
void startCmdLine(){
    LLVMContext &Context = getGlobalContext();

    for (unsigned int i =0 ; i < PassList.size(); i++ ){
        cout << "Pass added: "<< PassList[i]->getPassName() << endl;
        cout << "Argument name :" << PassList[i]->getPassArgument() << endl;
    }

    clock_t timer = clock();

    //Parsing XDF file
    std::cout << "Parsing file " << XDFFile.getValue() << "." << endl;

    XDFParser xdfParser(Verbose);
    Network* network = xdfParser.parseFile(XDFFile, Context);

    cout << "Network parsed in : "<< (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms, start engine" << endl;

    //Parsing XCF file if needed
    if(XCFFile != "") {
        std::cout << "Parsing file " << XCFFile.getValue() << "." << endl;

        XCFParser xcfParser(Verbose);
        map<string, string>* mapping = xcfParser.parseFile(XCFFile);
        network->setMapping(mapping);
    }

    if (enableTrace){
        setTraces(network);
    }

    //Load network
    engine->load(network);

    // Optimizing decoder
    if (optLevel > 0){
        engine->optimize(network, optLevel);
    }

    // Verify the given decoder if needed
    if (Verify){
        engine->verify(network, "error.txt");
    }

    // Set input file
    input_file = (char*)VidFile.c_str();

    // Print the given decoder if needed
    if (OutputDir != ""){
        engine->print(network);
    }

    //Run network
    engine->run(network);

    cout << "End of Jade" << endl;
    cout << "Total time: " << (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    if(XCFFile != "") {
        cout << "Note: This execution time is calculated from CPU clock. When more than 1 thread were run, "
                "the value displayed is higher than the real execution time." << endl;
    }
}
Beispiel #16
0
void WorklessInstrument::InstrumentWorkless0Or1Star(Module * pModule, Loop * pLoop, set<string> & setWorkingBlocks)
{
	LoadInst * pLoad0 = NULL;
	LoadInst * pLoad1 = NULL;
	//BinaryOperator* pAdd = NULL;
	StoreInst * pStore = NULL;
	CallInst * pCall = NULL;

	Function * pMain = NULL;

	if(strMainName != "" )
	{
		pMain = pModule->getFunction(strMainName.c_str());
	}
	else
	{
		pMain = pModule->getFunction("main");
	}

	for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) 
	{
		if(BB->getName().equals("entry"))
		{
			CallInst * pCall;
			StoreInst * pStore;

			Instruction * II = BB->begin();
			pCall = CallInst::Create(this->InitHooks, "", II);
			pCall->setCallingConv(CallingConv::C);
			pCall->setTailCall(false);
			AttributeSet emptySet;
			pCall->setAttributes(emptySet);

			pCall = CallInst::Create(this->getenv, this->SAMPLE_RATE_ptr, "", II);
			pCall->setCallingConv(CallingConv::C);
			pCall->setTailCall(false);
			AttributeSet AS;
			{
				SmallVector<AttributeSet, 4> Attrs;
				AttributeSet PAS;
				{
					AttrBuilder B;
					B.addAttribute(Attribute::NoUnwind);
					PAS = AttributeSet::get(pModule->getContext(), ~0U, B);
				}
				Attrs.push_back(PAS);
				AS = AttributeSet::get(pModule->getContext(), Attrs);
			}
			pCall->setAttributes(AS);

			pCall = CallInst::Create(this->function_atoi, pCall, "", II);
			pCall->setCallingConv(CallingConv::C);
			pCall->setTailCall(false);
			{
  				SmallVector<AttributeSet, 4> Attrs;
   				AttributeSet PAS;
    			{
    	 			AttrBuilder B;
     				B.addAttribute(Attribute::NoUnwind);
     				B.addAttribute(Attribute::ReadOnly);
     				PAS = AttributeSet::get(pModule->getContext(), ~0U, B);
    			}
   
   				Attrs.push_back(PAS);
   				AS = AttributeSet::get(pModule->getContext(), Attrs);
   
  			}
  			pCall->setAttributes(AS);

  			pStore = new StoreInst(pCall, this->SAMPLE_RATE, false, II);
  			pStore->setAlignment(4);

  			pCall = CallInst::Create(this->geo, pCall, "", II);
  			pCall->setCallingConv(CallingConv::C);
  			pCall->setTailCall(false);
  			pCall->setAttributes(emptySet);

  			CastInst * pCast = CastInst::CreateIntegerCast(pCall, this->LongType, true, "", II);
  			pStore = new StoreInst(pCast, this->CURRENT_SAMPLE, false, II);
  			pStore->setAlignment(8);

  			vector<Value *> vecParam;
  			vecParam.push_back(this->Output_Format_String);
  			vecParam.push_back(pCall);
  			pCall = CallInst::Create(this->printf, vecParam, "", II);
  			pCall->setCallingConv(CallingConv::C);
  			pCall->setTailCall(false);
  			pCall->setAttributes(emptySet);
  			break;
		}
	}

	for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) 
	{
		for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) 
		{
			if (isa<ReturnInst>(Ins) || isa<ResumeInst>(Ins)) 
			{
				vector<Value*> vecParams;
				pLoad0 = new LoadInst(numIterations, "", false, Ins); 
				pLoad0->setAlignment(8); 
				vecParams.push_back(pLoad0);
				pLoad1 = new LoadInst(numInstances, "", false, Ins); 
				pLoad1->setAlignment(8);
				vecParams.push_back(pLoad1);
				
				pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins);
				pCall->setCallingConv(CallingConv::C);
				pCall->setTailCall(false);
				AttributeSet aSet;
				pCall->setAttributes(aSet);

				vecParams.clear();
				pLoad0 = new LoadInst(numIterations, "", false, Ins); 
				pLoad0->setAlignment(8); 
				vecParams.push_back(pLoad0);
				pLoad1 = new LoadInst(numWorkingIterations, "", false, Ins); 
				pLoad1->setAlignment(8);
				vecParams.push_back(pLoad1);


				pCall = CallInst::Create(PrintWorkingRatio, vecParams, "", Ins);
				pCall->setCallingConv(CallingConv::C);
				pCall->setTailCall(false);
				pCall->setAttributes(aSet);

			}
			else if(isa<CallInst>(Ins) || isa<InvokeInst>(Ins))
			{
				CallSite cs(Ins);
				Function * pCalled = cs.getCalledFunction();

				if(pCalled == NULL)
				{
					continue;
				}

				if(pCalled->getName() == "exit" || pCalled->getName() == "_ZL9mysql_endi")
				{
					vector<Value*> vecParams;
					pLoad0 = new LoadInst(numIterations, "", false, Ins);
					pLoad0->setAlignment(8); 
					vecParams.push_back(pLoad0);
					pLoad1 = new LoadInst(numInstances, "", false, Ins); 
					pLoad1->setAlignment(8);
					vecParams.push_back(pLoad1);

					pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins);
					pCall->setCallingConv(CallingConv::C);
					pCall->setTailCall(false);
					AttributeSet aSet;
					pCall->setAttributes(aSet);

					vecParams.clear();
					pLoad0 = new LoadInst(numIterations, "", false, Ins); 
					pLoad0->setAlignment(8); 
					vecParams.push_back(pLoad0);
					pLoad1 = new LoadInst(numWorkingIterations, "", false, Ins); 
					pLoad1->setAlignment(8);
					vecParams.push_back(pLoad1);

					pCall = CallInst::Create(PrintWorkingRatio, vecParams, "", Ins);
					pCall->setCallingConv(CallingConv::C);
					pCall->setTailCall(false);
					pCall->setAttributes(aSet);
				}
			}
		}
	}

	Function * pFunction = pLoop->getHeader()->getParent();
	BasicBlock * pEntry = &(pFunction->getEntryBlock());

	AllocaInst * pAlloc = new AllocaInst(this->LongType, "bWorkingIteration.local", pEntry->getFirstInsertionPt());

	vector<BasicBlock *> vecWorkingBlock;
	
	for(Function::iterator BB = pFunction->begin(); BB != pFunction->end(); ++ BB)
	{
		if(setWorkingBlocks.find(BB->getName()) != setWorkingBlocks.end() )
		{
			vecWorkingBlock.push_back(BB);
		}
	}

	errs() << "working block number: " << vecWorkingBlock.size() << "\n";

	BasicBlock * pHeader = pLoop->getHeader();
	set<BasicBlock *> setExitBlock;
	CollectExitBlock(pLoop, setExitBlock);

	vector<BasicBlock *> vecAdded;
	CreateIfElseBlock(pLoop, vecAdded);

	ValueToValueMapTy  VMap;
	set<BasicBlock *> setCloned;
	CloneInnerLoop(pLoop, vecAdded, VMap, setCloned);

	//BasicBlock * pPreHeader = vecAdded[0];
	BasicBlock * pElseBody = vecAdded[1];
	
	vector<BasicBlock *>::iterator itVecBegin = vecWorkingBlock.begin();
	vector<BasicBlock *>::iterator itVecEnd   = vecWorkingBlock.end();

	for(; itVecBegin != itVecEnd; itVecBegin++ )
	{
		BasicBlock * pClonedBlock = cast<BasicBlock>(VMap[*itVecBegin]);
		pStore = new StoreInst(this->ConstantLong1, pAlloc, false, pClonedBlock->getFirstInsertionPt());
		pStore->setAlignment(8);
		pClonedBlock->dump();
	}


	pStore = new StoreInst(this->ConstantLong0, pAlloc, false, pElseBody->getTerminator());
	pStore->setAlignment(8);

	pLoad0 = new LoadInst(this->numIterations, "", false, pElseBody->getTerminator());
	pLoad0->setAlignment(8);

	pLoad1 = new LoadInst(this->numWorkingIterations, "", false, pElseBody->getTerminator());
	pLoad1->setAlignment(8);  

	BasicBlock * pClonedHeader = cast<BasicBlock>(VMap[pHeader]);

	set<BasicBlock *> setPredBlocks;

	for(pred_iterator PI = pred_begin(pClonedHeader), E = pred_end(pClonedHeader); PI != E; ++PI)
	{
		setPredBlocks.insert(*PI);
	}

	BasicBlock::iterator itInsert = pClonedHeader->getFirstInsertionPt();

	PHINode * pNewIterations = PHINode::Create(pLoad0->getType(), setPredBlocks.size(), "numIterations.2", itInsert);
	PHINode * pNewWorkingIterations = PHINode::Create(pLoad1->getType(), setPredBlocks.size(), "WorkingIterations.2", itInsert);

	BinaryOperator * pIterationAdd = BinaryOperator::Create(Instruction::Add, pNewIterations, this->ConstantLong1, "Iterations.add.2", itInsert);

	set<BasicBlock *>::iterator itSetBegin = setPredBlocks.begin();
	set<BasicBlock *>::iterator itSetEnd   = setPredBlocks.end();

	for(; itSetBegin != itSetEnd; itSetBegin ++ )
	{
		if((*itSetBegin) == pElseBody)
		{
			pNewIterations->addIncoming(pLoad0, pElseBody);
		}
		else
		{
			pNewIterations->addIncoming(pIterationAdd, *itSetBegin);
		}
	}

	pLoad0 = new LoadInst(pAlloc, "", false, itInsert);
	BinaryOperator * pWorkingAdd = 	BinaryOperator::Create(Instruction::Add, pNewWorkingIterations, pLoad0, "Working.add.2", itInsert);

	itSetBegin = setPredBlocks.begin();
	itSetEnd   = setPredBlocks.end();

	for(; itSetBegin != itSetEnd; itSetBegin ++ )
	{
		if((*itSetBegin) == pElseBody)
		{
			pNewWorkingIterations->addIncoming(pLoad1, pElseBody);
		}
		else
		{
			pNewWorkingIterations->addIncoming(pWorkingAdd, *itSetBegin);
		}
	}

	pStore = new StoreInst(this->ConstantLong0, pAlloc, false, itInsert);
	pStore->setAlignment(8);


	itSetBegin = setExitBlock.begin();
	itSetEnd   = setExitBlock.end();

	for(; itSetBegin != itSetEnd; itSetBegin ++ )
	{
		SmallVector<BasicBlock*, 8> LoopBlocks;

		for(pred_iterator PI = pred_begin(*itSetBegin), E = pred_end(*itSetBegin); PI != E; ++PI)
		{
			if(setCloned.find(*PI) != setCloned.end())
			{
				LoopBlocks.push_back(*PI);
			}
		}

		BasicBlock * NewExitBB = SplitBlockPredecessors(*itSetBegin, LoopBlocks, ".WL.loopexit", this);

		pStore = new StoreInst(pIterationAdd, this->numIterations, false, NewExitBB->getFirstInsertionPt());
		pStore->setAlignment(8);

		pStore = new StoreInst(pWorkingAdd, this->numWorkingIterations, false, NewExitBB->getFirstInsertionPt());
		pStore->setAlignment(8);
	}

	//pFunction->dump();

	DominatorTree * DT = &(getAnalysis<DominatorTree>(*pFunction));
	vector<AllocaInst *> vecAlloc;
	vecAlloc.push_back(pAlloc);
	PromoteMemToReg(vecAlloc, *DT);

	pFunction->dump();
}
Beispiel #17
0
// Scatter sections in all directions!
// Remaps section addresses for -verify mode. The following command line options
// can be used to customize the layout of the memory within the phony target's
// address space:
// -target-addr-start <s> -- Specify where the phony target addres range starts.
// -target-addr-end   <e> -- Specify where the phony target address range ends.
// -target-section-sep <d> -- Specify how big a gap should be left between the
//                            end of one section and the start of the next.
//                            Defaults to zero. Set to something big
//                            (e.g. 1 << 32) to stress-test stubs, GOTs, etc.
//
static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
                                    TrivialMemoryManager &MemMgr,
                                    RuntimeDyldChecker &Checker) {

  // Set up a work list (section addr/size pairs).
  typedef std::list<std::pair<void*, uint64_t>> WorklistT;
  WorklistT Worklist;

  for (const auto& CodeSection : MemMgr.FunctionMemory)
    Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size()));
  for (const auto& DataSection : MemMgr.DataMemory)
    Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size()));

  // Apply any section-specific mappings that were requested on the command
  // line.
  typedef std::map<void*, uint64_t> AppliedMappingsT;
  AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker);

  // Keep an "already allocated" mapping of section target addresses to sizes.
  // Sections whose address mappings aren't specified on the command line will
  // allocated around the explicitly mapped sections while maintaining the
  // minimum separation.
  std::map<uint64_t, uint64_t> AlreadyAllocated;

  // Move the previously applied mappings into the already-allocated map.
  for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
       I != E;) {
    WorklistT::iterator Tmp = I;
    ++I;
    AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first);

    if (AI != AppliedMappings.end()) {
      AlreadyAllocated[AI->second] = Tmp->second;
      Worklist.erase(Tmp);
    }
  }

  // If the -target-addr-end option wasn't explicitly passed, then set it to a
  // sensible default based on the target triple.
  if (TargetAddrEnd.getNumOccurrences() == 0) {
    if (TargetTriple.isArch16Bit())
      TargetAddrEnd = (1ULL << 16) - 1;
    else if (TargetTriple.isArch32Bit())
      TargetAddrEnd = (1ULL << 32) - 1;
    // TargetAddrEnd already has a sensible default for 64-bit systems, so
    // there's nothing to do in the 64-bit case.
  }

  // Process any elements remaining in the worklist.
  while (!Worklist.empty()) {
    std::pair<void*, uint64_t> CurEntry = Worklist.front();
    Worklist.pop_front();

    uint64_t NextSectionAddr = TargetAddrStart;

    for (const auto &Alloc : AlreadyAllocated)
      if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first)
        break;
      else
        NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep;

    AlreadyAllocated[NextSectionAddr] = CurEntry.second;
    Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr);
  }

  // Add dummy symbols to the memory manager.
  for (const auto &Mapping : DummySymbolMappings) {
    size_t EqualsIdx = Mapping.find_first_of("=");

    if (EqualsIdx == StringRef::npos)
      report_fatal_error("Invalid dummy symbol specification '" + Mapping +
                         "'. Should be '<symbol name>=<addr>'");

    std::string Symbol = Mapping.substr(0, EqualsIdx);
    std::string AddrStr = Mapping.substr(EqualsIdx + 1);

    uint64_t Addr;
    if (StringRef(AddrStr).getAsInteger(0, Addr))
      report_fatal_error("Invalid symbol mapping '" + Mapping + "'.");

    MemMgr.addDummySymbol(Symbol, Addr);
  }
}
Beispiel #18
0
/// Determine if it is profitable to duplicate this block.
bool
TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF,
                                       bool IsSimple,
                                       MachineBasicBlock &TailBB) {
  // Only duplicate blocks that end with unconditional branches.
  if (TailBB.canFallThrough())
    return false;

  // Don't try to tail-duplicate single-block loops.
  if (TailBB.isSuccessor(&TailBB))
    return false;

  // Set the limit on the cost to duplicate. When optimizing for size,
  // duplicate only one, because one branch instruction can be eliminated to
  // compensate for the duplication.
  unsigned MaxDuplicateCount;
  if (TailDuplicateSize.getNumOccurrences() == 0 &&
      // FIXME: Use Function::optForSize().
      MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize))
    MaxDuplicateCount = 1;
  else
    MaxDuplicateCount = TailDuplicateSize;

  // If the target has hardware branch prediction that can handle indirect
  // branches, duplicating them can often make them predictable when there
  // are common paths through the code.  The limit needs to be high enough
  // to allow undoing the effects of tail merging and other optimizations
  // that rearrange the predecessors of the indirect branch.

  bool HasIndirectbr = false;
  if (!TailBB.empty())
    HasIndirectbr = TailBB.back().isIndirectBranch();

  if (HasIndirectbr && PreRegAlloc)
    MaxDuplicateCount = 20;

  // Check the instructions in the block to determine whether tail-duplication
  // is invalid or unlikely to be profitable.
  unsigned InstrCount = 0;
  for (MachineInstr &MI : TailBB) {
    // Non-duplicable things shouldn't be tail-duplicated.
    if (MI.isNotDuplicable())
      return false;

    // Do not duplicate 'return' instructions if this is a pre-regalloc run.
    // A return may expand into a lot more instructions (e.g. reload of callee
    // saved registers) after PEI.
    if (PreRegAlloc && MI.isReturn())
      return false;

    // Avoid duplicating calls before register allocation. Calls presents a
    // barrier to register allocation so duplicating them may end up increasing
    // spills.
    if (PreRegAlloc && MI.isCall())
      return false;

    if (!MI.isPHI() && !MI.isDebugValue())
      InstrCount += 1;

    if (InstrCount > MaxDuplicateCount)
      return false;
  }

  if (HasIndirectbr && PreRegAlloc)
    return true;

  if (IsSimple)
    return true;

  if (!PreRegAlloc)
    return true;

  return canCompletelyDuplicateBB(TailBB);
}
/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
/// frame indexes with appropriate references.
///
bool PEI::runOnMachineFunction(MachineFunction &Fn) {
  const Function* F = Fn.getFunction();
  const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
  const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();

  assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs");

  RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr;
  FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);

  // Calculate the MaxCallFrameSize and AdjustsStack variables for the
  // function's frame information. Also eliminates call frame pseudo
  // instructions.
  calculateCallsInformation(Fn);

  // Determine which of the registers in the callee save list should be saved.
  BitVector SavedRegs;
  TFI->determineCalleeSaves(Fn, SavedRegs, RS);

  // Insert spill code for any callee saved registers that are modified.
  assignCalleeSavedSpillSlots(Fn, SavedRegs);

  // Determine placement of CSR spill/restore code:
  // place all spills in the entry block, all restores in return blocks.
  calculateSets(Fn);

  // Add the code to save and restore the callee saved registers.
  if (!F->hasFnAttribute(Attribute::Naked))
    insertCSRSpillsAndRestores(Fn);

  // Allow the target machine to make final modifications to the function
  // before the frame layout is finalized.
  TFI->processFunctionBeforeFrameFinalized(Fn, RS);

  // Calculate actual frame offsets for all abstract stack objects...
  calculateFrameObjectOffsets(Fn);

  // Add prolog and epilog code to the function.  This function is required
  // to align the stack frame as necessary for any stack variables or
  // called functions.  Because of this, calculateCalleeSavedRegisters()
  // must be called before this function in order to set the AdjustsStack
  // and MaxCallFrameSize variables.
  if (!F->hasFnAttribute(Attribute::Naked))
    insertPrologEpilogCode(Fn);

  // Replace all MO_FrameIndex operands with physical register references
  // and actual offsets.
  //
  replaceFrameIndices(Fn);

  // If register scavenging is needed, as we've enabled doing it as a
  // post-pass, scavenge the virtual registers that frame index elimination
  // inserted.
  if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging)
    scavengeFrameVirtualRegs(Fn);

  // Clear any vregs created by virtual scavenging.
  Fn.getRegInfo().clearVirtRegs();

  // Warn on stack size when we exceeds the given limit.
  MachineFrameInfo *MFI = Fn.getFrameInfo();
  uint64_t StackSize = MFI->getStackSize();
  if (WarnStackSize.getNumOccurrences() > 0 && WarnStackSize < StackSize) {
    DiagnosticInfoStackSize DiagStackSize(*F, StackSize);
    F->getContext().diagnose(DiagStackSize);
  }

  delete RS;
  SaveBlocks.clear();
  RestoreBlocks.clear();
  MFI->setSavePoint(nullptr);
  MFI->setRestorePoint(nullptr);
  return true;
}
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.


  cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");

  std::string ErrorMessage;
  OwningPtr<Module> M;

  // Use the bitcode streaming interface
  DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage);
  if (streamer) {
    std::string DisplayFilename;
    if (InputFilename == "-")
      DisplayFilename = "<stdin>";
    else
      DisplayFilename = InputFilename;

    // @LOCALMOD-BEGIN
    switch (InputFileFormat) {
      case LLVMFormat:
        M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context,
                                         &ErrorMessage));
        break;
      case PNaClFormat:
        M.reset(getNaClStreamedBitcodeModule(DisplayFilename, streamer, Context,
                                             &ErrorMessage));
        break;
      default:
        ErrorMessage = "Don't understand specified bitcode format";
        break;
    }
    // @LOCALMOD-END
    if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) {
      M.reset();
    }
  }

  if (M.get() == 0) {
    errs() << argv[0] << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "bitcode didn't read correctly.\n";
    return 1;
  }

  // Just use stdout.  We won't actually print anything on it.
  if (DontPrint)
    OutputFilename = "-";

  if (OutputFilename.empty()) { // Unspecified output, infer it.
    if (InputFilename == "-" || DumpMetadata) { // @LOCALMOD
      OutputFilename = "-";
    } else {
      const std::string &IFN = InputFilename;
      int Len = IFN.length();
      // If the source ends in .bc, strip it off.
      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c')
        OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
      else
        OutputFilename = IFN+".ll";
    }
  }

  std::string ErrorInfo;
  OwningPtr<tool_output_file>
  Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                           raw_fd_ostream::F_Binary));
  if (!ErrorInfo.empty()) {
    errs() << ErrorInfo << '\n';
    return 1;
  }

  // @LOCALMOD-BEGIN
  if (DumpMetadata) {
    M->dumpMeta(Out->os());
    Out->keep();
    return 0;
  }
  // @LOCALMOD-END

  OwningPtr<AssemblyAnnotationWriter> Annotator;
  if (ShowAnnotations)
    Annotator.reset(new CommentWriter());

  // All that llvm-dis does is write the assembly to a file.
  if (!DontPrint)
    M->print(Out->os(), Annotator.get());

  // Declare success.
  Out->keep();

  return 0;
}
Beispiel #21
0
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM
/// bitcode file for the program.
static void EmitShellScript(char **argv, Module *M) {
  if (Verbose)
    errs() << "Emitting Shell Script\n";
#if defined(_WIN32)
  // Windows doesn't support #!/bin/sh style shell scripts in .exe files.  To
  // support windows systems, we copy the llvm-stub.exe executable from the
  // build tree to the destination file.
  std::string ErrMsg;
  sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0],
                                                 (void *)(intptr_t)&Optimize);
  if (llvmstub.isEmpty())
    PrintAndExit("Could not find llvm-stub.exe executable!", M);

  if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg))
    PrintAndExit(ErrMsg, M);

  return;
#endif

  // Output the script to start the program...
  std::string ErrorInfo;
  tool_output_file Out2(OutputFilename.c_str(), ErrorInfo);
  if (!ErrorInfo.empty())
    PrintAndExit(ErrorInfo, M);

  Out2.os() << "#!/bin/sh\n";
  // Allow user to setenv LLVMINTERP if lli is not in their PATH.
  Out2.os() << "lli=${LLVMINTERP-lli}\n";
  Out2.os() << "exec $lli \\\n";
  // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib.
  LibPaths.push_back("/lib");
  LibPaths.push_back("/usr/lib");
  LibPaths.push_back("/usr/X11R6/lib");
  // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a
  // shared object at all! See RH 8: plain text.
  std::vector<std::string>::iterator libc =
    std::find(Libraries.begin(), Libraries.end(), "c");
  if (libc != Libraries.end()) Libraries.erase(libc);
  // List all the shared object (native) libraries this executable will need
  // on the command line, so that we don't have to do this manually!
  for (std::vector<std::string>::iterator i = Libraries.begin(),
         e = Libraries.end(); i != e; ++i) {
    // try explicit -L arguments first:
    sys::Path FullLibraryPath;
    for (cl::list<std::string>::const_iterator P = LibPaths.begin(),
           E = LibPaths.end(); P != E; ++P) {
      FullLibraryPath = *P;
      FullLibraryPath.appendComponent("lib" + *i);
      FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix());
      if (!FullLibraryPath.isEmpty()) {
        if (!FullLibraryPath.isDynamicLibrary()) {
          // Not a native shared library; mark as invalid
          FullLibraryPath = sys::Path();
        } else break;
      }
    }
    if (FullLibraryPath.isEmpty())
      FullLibraryPath = sys::Path::FindLibrary(*i);
    if (!FullLibraryPath.isEmpty())
      Out2.os() << "    -load=" << FullLibraryPath.str() << " \\\n";
  }
  Out2.os() << "    "  << BitcodeOutputFilename << " ${1+\"$@\"}\n";
  Out2.keep();
}
Beispiel #22
0
// parseCommandLine - Parse the command line options as presented and return the
// operation specified. Process all modifiers and check to make sure that
// constraints on modifier/operation pairs have not been violated.
ArchiveOperation parseCommandLine() {

  // Keep track of number of operations. We can only specify one
  // per execution.
  unsigned NumOperations = 0;

  // Keep track of the number of positional modifiers (a,b,i). Only
  // one can be specified.
  unsigned NumPositional = 0;

  // Keep track of which operation was requested
  ArchiveOperation Operation = NoOperation;

  for(unsigned i=0; i<Options.size(); ++i) {
    switch(Options[i]) {
    case 'd': ++NumOperations; Operation = Delete; break;
    case 'm': ++NumOperations; Operation = Move ; break;
    case 'p': ++NumOperations; Operation = Print; break;
    case 'q': ++NumOperations; Operation = QuickAppend; break;
    case 'r': ++NumOperations; Operation = ReplaceOrInsert; break;
    case 't': ++NumOperations; Operation = DisplayTable; break;
    case 'x': ++NumOperations; Operation = Extract; break;
    case 'c': Create = true; break;
    case 'f': TruncateNames = true; break;
    case 'k': DontSkipBitcode = true; break;
    case 'l': /* accepted but unused */ break;
    case 'o': OriginalDates = true; break;
    case 'P': FullPath = true; break;
    case 'R': RecurseDirectories = true; break;
    case 's': SymTable = true; break;
    case 'S': SymTable = false; break;
    case 'u': OnlyUpdate = true; break;
    case 'v': Verbose = true; break;
    case 'V': Verbose = ReallyVerbose = true; break;
    case 'a':
      getRelPos();
      AddAfter = true;
      NumPositional++;
      break;
    case 'b':
      getRelPos();
      AddBefore = true;
      NumPositional++;
      break;
    case 'i':
      getRelPos();
      InsertBefore = true;
      NumPositional++;
      break;
    case 'N':
      getCount();
      UseCount = true;
      break;
    default:
      cl::PrintHelpMessage();
    }
  }

  // At this point, the next thing on the command line must be
  // the archive name.
  getArchive();

  // Everything on the command line at this point is a member.
  getMembers();

  // Perform various checks on the operation/modifier specification
  // to make sure we are dealing with a legal request.
  if (NumOperations == 0)
    throw "You must specify at least one of the operations";
  if (NumOperations > 1)
    throw "Only one operation may be specified";
  if (NumPositional > 1)
    throw "You may only specify one of a, b, and i modifiers";
  if (AddAfter || AddBefore || InsertBefore)
    if (Operation != Move && Operation != ReplaceOrInsert)
      throw "The 'a', 'b' and 'i' modifiers can only be specified with "
            "the 'm' or 'r' operations";
  if (RecurseDirectories && Operation != ReplaceOrInsert)
    throw "The 'R' modifiers is only applicabe to the 'r' operation";
  if (OriginalDates && Operation != Extract)
    throw "The 'o' modifier is only applicable to the 'x' operation";
  if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert)
    throw "The 'f' modifier is only applicable to the 'q' and 'r' operations";
  if (OnlyUpdate && Operation != ReplaceOrInsert)
    throw "The 'u' modifier is only applicable to the 'r' operation";
  if (Count > 1 && Members.size() > 1)
    throw "Only one member name may be specified with the 'N' modifier";

  // Return the parsed operation to the caller
  return Operation;
}
int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
#endif

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  // @LOCALMOD-BEGIN
  initializeAddPNaClExternalDeclsPass(Registry);
  initializeAllocateDataSegmentPass(Registry);
  initializeBackendCanonicalizePass(Registry);
  initializeCanonicalizeMemIntrinsicsPass(Registry);
  initializeCleanupUsedGlobalsMetadataPass(Registry);
  initializeConstantInsertExtractElementIndexPass(Registry);
  initializeExpandAllocasPass(Registry);
  initializeExpandArithWithOverflowPass(Registry);
  initializeExpandByValPass(Registry);
  initializeExpandConstantExprPass(Registry);
  initializeExpandCtorsPass(Registry);
  initializeExpandGetElementPtrPass(Registry);
  initializeExpandIndirectBrPass(Registry);
  initializeExpandLargeIntegersPass(Registry);
  initializeExpandShuffleVectorPass(Registry);
  initializeExpandSmallArgumentsPass(Registry);
  initializeExpandStructRegsPass(Registry);
  initializeExpandTlsConstantExprPass(Registry);
  initializeExpandTlsPass(Registry);
  initializeExpandVarArgsPass(Registry);
  initializeFixVectorLoadStoreAlignmentPass(Registry);
  initializeFlattenGlobalsPass(Registry);
  initializeGlobalCleanupPass(Registry);
  initializeGlobalizeConstantVectorsPass(Registry);
  initializeInsertDivideCheckPass(Registry);
  initializeInternalizeUsedGlobalsPass(Registry);
  initializeNormalizeAlignmentPass(Registry);
  initializePNaClABIVerifyFunctionsPass(Registry);
  initializePNaClABIVerifyModulePass(Registry);
  initializePNaClSjLjEHPass(Registry);
  initializePromoteI1OpsPass(Registry);
  initializePromoteIntegersPass(Registry);
  initializeRemoveAsmMemoryPass(Registry);
  initializeRenameEntryPointPass(Registry);
  initializeReplacePtrsWithIntsPass(Registry);
  initializeResolveAliasesPass(Registry);
  initializeResolvePNaClIntrinsicsPass(Registry);
  initializeRewriteAtomicsPass(Registry);
  initializeRewriteLLVMIntrinsicsPass(Registry);
  initializeRewritePNaClLibraryCallsPass(Registry);
  initializeSandboxIndirectCallsPass(Registry);
  initializeSandboxMemoryAccessesPass(Registry);
  initializeSimplifyAllocasPass(Registry);
  initializeSimplifyStructRegSignaturesPass(Registry);
  initializeStripAttributesPass(Registry);
  initializeStripMetadataPass(Registry);
  initializeStripModuleFlagsPass(Registry);
  initializeStripTlsPass(Registry);
  initializeSubstituteUndefsPass(Registry);
  // Emscripten passes:
  initializeExpandI64Pass(Registry);
  initializeExpandInsertExtractElementPass(Registry);
  initializeLowerEmAsyncifyPass(Registry);
  initializeLowerEmExceptionsPass(Registry);
  initializeLowerEmSetjmpPass(Registry);
  initializeNoExitRuntimePass(Registry);
  // Emscripten passes end.
  // @LOCALMOD-END
  
  cl::ParseCommandLineOptions(argc, argv,
                              "LLVM automatic testcase reducer. See\nhttp://"
                              "llvm.org/cmds/bugpoint.html"
                              " for more information.\n");
#ifndef DEBUG_BUGPOINT
  sys::SetInterruptFunction(BugpointInterruptFunction);
#endif

  LLVMContext& Context = getGlobalContext();
  // If we have an override, set it and then track the triple we want Modules
  // to use.
  if (!OverrideTriple.empty()) {
    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  }

  if (MemoryLimit < 0) {
    // Set the default MemoryLimit.  Be sure to update the flag's description if
    // you change this.
    if (sys::RunningOnValgrind() || UseValgrind)
      MemoryLimit = 800;
    else
      MemoryLimit = 300;
  }

  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit,
              UseValgrind, Context);
  if (D.addSources(InputFilenames)) return 1;

  AddToDriver PM(D);

  if (StandardLinkOpts) {
    PassManagerBuilder Builder;
    Builder.Inliner = createFunctionInliningPass();
    Builder.populateLTOPassManager(PM);
  }

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    PassManagerBuilder Builder;
    if (OptLevelO1)
      Builder.Inliner = createAlwaysInlinerPass();
    else if (OptLevelO2)
      Builder.Inliner = createFunctionInliningPass(225);
    else
      Builder.Inliner = createFunctionInliningPass(275);

    // Note that although clang/llvm-gcc use two separate passmanagers
    // here, it shouldn't normally make a difference.
    Builder.populateFunctionPassManager(PM);
    Builder.populateModulePassManager(PM);
  }

  for (std::vector<const PassInfo*>::iterator I = PassList.begin(),
         E = PassList.end();
       I != E; ++I) {
    const PassInfo* PI = *I;
    D.addPass(PI->getPassArgument());
  }

  // Bugpoint has the ability of generating a plethora of core files, so to
  // avoid filling up the disk, we prevent it
#ifndef DEBUG_BUGPOINT
  sys::Process::PreventCoreFiles();
#endif

  std::string Error;
  bool Failure = D.run(Error);
  if (!Error.empty()) {
    errs() << Error;
    return 1;
  }
  return Failure;
}
bool TargetSubtargetInfo::useMachineScheduler() const {
  if (BenchMachineSched.getNumOccurrences())
    return BenchMachineSched;
  return enableMachineScheduler();
}
Beispiel #25
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets and assembly printers/parsers.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();
  llvm::InitializeAllDisassemblers();

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
  TripleName = Triple::normalize(TripleName);
  setDwarfDebugFlags(argc, argv);

  setDwarfDebugProducer();

  const char *ProgName = argv[0];
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;
  // Now that GetTarget() has (potentially) replaced TripleName, it's safe to
  // construct the Triple object.
  Triple TheTriple(TripleName);

  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr =
      MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (std::error_code EC = BufferPtr.getError()) {
    errs() << InputFilename << ": " << EC.message() << '\n';
    return 1;
  }
  MemoryBuffer *Buffer = BufferPtr->get();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  assert(MAI && "Unable to create target asm info!");

  MAI->setRelaxELFRelocations(RelaxELFRel);

  if (CompressDebugSections != DebugCompressionType::DCT_None) {
    if (!zlib::isAvailable()) {
      errs() << ProgName
             << ": build tools with zlib to enable -compress-debug-sections";
      return 1;
    }
    MAI->setCompressDebugSections(CompressDebugSections);
  }

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  MCObjectFileInfo MOFI;
  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
  MOFI.InitMCObjectFileInfo(TheTriple, PIC, CMModel, Ctx);

  if (SaveTempLabels)
    Ctx.setAllowTemporaryLabels(false);

  Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
  // Default to 4 for dwarf version.
  unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4;
  if (DwarfVersion < 2 || DwarfVersion > 4) {
    errs() << ProgName << ": Dwarf version " << DwarfVersion
           << " is not supported." << '\n';
    return 1;
  }
  Ctx.setDwarfVersion(DwarfVersion);
  if (!DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
  if (!DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer));
  if (!DebugCompilationDir.empty())
    Ctx.setCompilationDir(DebugCompilationDir);
  else {
    // If no compilation dir is set, try to use the current directory.
    SmallString<128> CWD;
    if (!sys::fs::current_path(CWD))
      Ctx.setCompilationDir(CWD);
  }
  if (!MainFileName.empty())
    Ctx.setMainFileName(MainFileName);

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::unique_ptr<tool_output_file> Out = GetOutputStream();
  if (!Out)
    return 1;

  std::unique_ptr<buffer_ostream> BOS;
  raw_pwrite_stream *OS = &Out->os();
  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));

  MCInstPrinter *IP = nullptr;
  if (FileType == OFT_AssemblyFile) {
    IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant,
                                        *MAI, *MCII, *MRI);

    // Set the display preference for hex vs. decimal immediates.
    IP->setPrintImmHex(PrintImmHex);

    // Set up the AsmStreamer.
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    }
    auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS);
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, std::move(FOut), /*asmverbose*/ true,
        /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));

  } else if (FileType == OFT_Null) {
    Str.reset(TheTarget->createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");

    // Don't waste memory on names of temp labels.
    Ctx.setUseNamesOnTempLabels(false);

    if (!Out->os().supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(Out->os());
      OS = BOS.get();
    }

    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    Str.reset(TheTarget->createMCObjectStreamer(
        TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll,
        MCOptions.MCIncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ false));
    if (NoExecStack)
      Str->InitSections(true);
  }

  int Res = 1;
  bool disassemble = false;
  switch (Action) {
  case AC_AsLex:
    Res = AsLexInput(SrcMgr, *MAI, Out->os());
    break;
  case AC_Assemble:
    Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI,
                        *MCII, MCOptions);
    break;
  case AC_MDisassemble:
    assert(IP && "Expected assembly output");
    IP->setUseMarkup(1);
    disassemble = true;
    break;
  case AC_Disassemble:
    disassemble = true;
    break;
  }
  if (disassemble)
    Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
                                    *Buffer, SrcMgr, Out->os());

  // Keep output if no errors.
  if (Res == 0) Out->keep();
  return Res;
}
Beispiel #26
0
//===----------------------------------------------------------------------===//
// main for opt
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);

  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  LLVMContext &Context = getGlobalContext();

  InitializeAllTargets();
  InitializeAllTargetMCs();

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeDebugIRPass(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  if (AnalyzeOnly && NoOutput) {
    errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
    return 1;
  }

  SMDiagnostic Err;

  // Load the input module...
  OwningPtr<Module> M;
  M.reset(ParseIRFile(InputFilename, Err, Context));

  if (M.get() == 0) {
    Err.print(argv[0], errs());
    return 1;
  }

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    M->setTargetTriple(Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  OwningPtr<tool_output_file> Out;
  if (NoOutput) {
    if (!OutputFilename.empty())
      errs() << "WARNING: The -o (output filename) option is ignored when\n"
                "the --disable-output option is used.\n";
  } else {
    // Default to standard output.
    if (OutputFilename.empty())
      OutputFilename = "-";

    std::string ErrorInfo;
    Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                                   sys::fs::F_Binary));
    if (!ErrorInfo.empty()) {
      errs() << ErrorInfo << '\n';
      return 1;
    }
  }

  // If the output is set to be emitted to standard out, and standard out is a
  // console, print out a warning message and refuse to do it.  We don't
  // impress anyone by spewing tons of binary goo to a terminal.
  if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly)
    if (CheckBitcodeOutputToConsole(Out->os(), !Quiet))
      NoOutput = true;

  // Create a PassManager to hold and optimize the collection of passes we are
  // about to build.
  //
  PassManager Passes;

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (DisableSimplifyLibCalls)
    TLI->disableAllFunctions();
  Passes.add(TLI);

  // Add an appropriate DataLayout instance for this module.
  DataLayout *TD = 0;
  const std::string &ModuleDataLayout = M.get()->getDataLayout();
  if (!ModuleDataLayout.empty())
    TD = new DataLayout(ModuleDataLayout);
  else if (!DefaultDataLayout.empty())
    TD = new DataLayout(DefaultDataLayout);

  if (TD)
    Passes.add(TD);

  Triple ModuleTriple(M->getTargetTriple());
  TargetMachine *Machine = 0;
  if (ModuleTriple.getArch())
    Machine = GetTargetMachine(Triple(ModuleTriple));
  OwningPtr<TargetMachine> TM(Machine);

  // Add internal analysis passes from the target machine.
  if (TM.get())
    TM->addAnalysisPasses(Passes);

  OwningPtr<FunctionPassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses.reset(new FunctionPassManager(M.get()));
    if (TD)
      FPasses->add(new DataLayout(*TD));
    if (TM.get())
      TM->addAnalysisPasses(*FPasses);

  }

  if (PrintBreakpoints) {
    // Default to standard output.
    if (!Out) {
      if (OutputFilename.empty())
        OutputFilename = "-";

      std::string ErrorInfo;
      Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                                     sys::fs::F_Binary));
      if (!ErrorInfo.empty()) {
        errs() << ErrorInfo << '\n';
        return 1;
      }
    }
    Passes.add(new BreakpointPrinter(Out->os()));
    NoOutput = true;
  }

  // If the -strip-debug command line option was specified, add it.  If
  // -std-compile-opts was also specified, it will handle StripDebug.
  if (StripDebug && !StandardCompileOpts)
    addPass(Passes, createStripSymbolsPass(true));

  // Create a new optimization pass for each one specified on the command line
  for (unsigned i = 0; i < PassList.size(); ++i) {
    // Check to see if -std-compile-opts was specified before this option.  If
    // so, handle it.
    if (StandardCompileOpts &&
        StandardCompileOpts.getPosition() < PassList.getPosition(i)) {
      AddStandardCompilePasses(Passes);
      StandardCompileOpts = false;
    }

    if (StandardLinkOpts &&
        StandardLinkOpts.getPosition() < PassList.getPosition(i)) {
      AddStandardLinkPasses(Passes);
      StandardLinkOpts = false;
    }

    if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 1, 0);
      OptLevelO1 = false;
    }

    if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 2, 0);
      OptLevelO2 = false;
    }

    if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 2, 1);
      OptLevelOs = false;
    }

    if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 2, 2);
      OptLevelOz = false;
    }

    if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 3, 0);
      OptLevelO3 = false;
    }

    const PassInfo *PassInf = PassList[i];
    Pass *P = 0;
    if (PassInf->getNormalCtor())
      P = PassInf->getNormalCtor()();
    else
      errs() << argv[0] << ": cannot create pass: "******"\n";
    if (P) {
      PassKind Kind = P->getPassKind();
      addPass(Passes, P);

      if (AnalyzeOnly) {
        switch (Kind) {
        case PT_BasicBlock:
          Passes.add(new BasicBlockPassPrinter(PassInf, Out->os()));
          break;
        case PT_Region:
          Passes.add(new RegionPassPrinter(PassInf, Out->os()));
          break;
        case PT_Loop:
          Passes.add(new LoopPassPrinter(PassInf, Out->os()));
          break;
        case PT_Function:
          Passes.add(new FunctionPassPrinter(PassInf, Out->os()));
          break;
        case PT_CallGraphSCC:
          Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os()));
          break;
        default:
          Passes.add(new ModulePassPrinter(PassInf, Out->os()));
          break;
        }
      }
    }

    if (PrintEachXForm)
      Passes.add(createPrintModulePass(&errs()));
  }

  // If -std-compile-opts was specified at the end of the pass list, add them.
  if (StandardCompileOpts) {
    AddStandardCompilePasses(Passes);
    StandardCompileOpts = false;
  }

  if (StandardLinkOpts) {
    AddStandardLinkPasses(Passes);
    StandardLinkOpts = false;
  }

  if (OptLevelO1)
    AddOptimizationPasses(Passes, *FPasses, 1, 0);

  if (OptLevelO2)
    AddOptimizationPasses(Passes, *FPasses, 2, 0);

  if (OptLevelOs)
    AddOptimizationPasses(Passes, *FPasses, 2, 1);

  if (OptLevelOz)
    AddOptimizationPasses(Passes, *FPasses, 2, 2);

  if (OptLevelO3)
    AddOptimizationPasses(Passes, *FPasses, 3, 0);

  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses->doInitialization();
    for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F)
      FPasses->run(*F);
    FPasses->doFinalization();
  }

  // Check that the module is well formed on completion of optimization
  if (!NoVerify && !VerifyEach)
    Passes.add(createVerifierPass());

  // Write bitcode or assembly to the output as the last step...
  if (!NoOutput && !AnalyzeOnly) {
    if (OutputAssembly)
      Passes.add(createPrintModulePass(&Out->os()));
    else
      Passes.add(createBitcodeWriterPass(Out->os()));
  }

  // Before executing passes, print the final values of the LLVM options.
  cl::PrintOptionValues();

  // Now that we have all of the passes ready, run them.
  Passes.run(*M.get());

  // Declare success.
  if (!NoOutput || PrintBreakpoints)
    Out->keep();

  return 0;
}
Beispiel #27
0
int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsPass(Registry);
  initializeWinEHPreparePass(Registry);
  initializeDwarfEHPreparePass(Registry);
  initializeSjLjEHPreparePass(Registry);

  // Register Swift Only Passes.
  initializeSwiftAAWrapperPassPass(Registry);
  initializeSwiftRCIdentityPass(Registry);
  initializeSwiftARCOptPass(Registry);
  initializeSwiftARCContractPass(Registry);
  initializeSwiftStackPromotionPass(Registry);
  initializeInlineTreePrinterPass(Registry);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  llvm::SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M =
      parseIRFile(InputFilename, Err, getGlobalContext());

  if (!M) {
    Err.print(argv[0], errs());
    return 1;
  }

  if (verifyModule(*M, &errs())) {
    errs() << argv[0] << ": " << InputFilename
           << ": error: input module is broken!\n";
    return 1;
  }

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    M->setTargetTriple(llvm::Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<llvm::tool_output_file> Out;
  // Default to standard output.
  if (OutputFilename.empty())
    OutputFilename = "-";

  std::error_code EC;
  Out.reset(
      new llvm::tool_output_file(OutputFilename, EC, llvm::sys::fs::F_None));
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  llvm::Triple ModuleTriple(M->getTargetTriple());
  std::string CPUStr, FeaturesStr;
  llvm::TargetMachine *Machine = nullptr;
  const llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  if (ModuleTriple.getArch()) {
    CPUStr = getCPUStr();
    FeaturesStr = getFeaturesStr();
    Machine = getTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
  }

  std::unique_ptr<llvm::TargetMachine> TM(Machine);

  // Override function attributes based on CPUStr, FeaturesStr, and command line
  // flags.
  setFunctionAttributes(CPUStr, FeaturesStr, *M);

  if (Optimized) {
    IRGenOptions Opts;
    Opts.Optimize = true;

    // Then perform the optimizations.
    performLLVMOptimizations(Opts, M.get(), TM.get());
  } else {
    runSpecificPasses(argv[0], M.get(), TM.get(), ModuleTriple);
  }

  // Finally dump the output.
  dumpOutput(*M, Out->os());

  return 0;
}
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
  // Read the input file.
  error_code ec;
  MemoryBuffer *MemBuf =
    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), ec);

  if (MemBuf == 0)
    return Error("Error reading '" + InputFilename + "': " + ec.message());

  if (MemBuf->getBufferSize() & 3)
    return Error("Bitcode stream should be a multiple of 4 bytes in length");

  unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart();
  unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize();

  // If we have a wrapper header, parse it and ignore the non-bc file contents.
  // The magic number is 0x0B17C0DE stored in little endian.
  if (isBitcodeWrapper(BufPtr, EndBufPtr))
    if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr))
      return Error("Invalid bitcode wrapper header");

  BitstreamReader StreamFile(BufPtr, EndBufPtr);
  BitstreamCursor Stream(StreamFile);
  StreamFile.CollectBlockInfoNames();

  // Read the stream signature.
  char Signature[6];
  Signature[0] = Stream.Read(8);
  Signature[1] = Stream.Read(8);
  Signature[2] = Stream.Read(4);
  Signature[3] = Stream.Read(4);
  Signature[4] = Stream.Read(4);
  Signature[5] = Stream.Read(4);

  // Autodetect the file contents, if it is one we know.
  CurStreamType = UnknownBitstream;
  if (Signature[0] == 'B' && Signature[1] == 'C' &&
      Signature[2] == 0x0 && Signature[3] == 0xC &&
      Signature[4] == 0xE && Signature[5] == 0xD)
    CurStreamType = LLVMIRBitstream;

  unsigned NumTopBlocks = 0;

  // Parse the top-level structure.  We only allow blocks at the top-level.
  while (!Stream.AtEndOfStream()) {
    unsigned Code = Stream.ReadCode();
    if (Code != bitc::ENTER_SUBBLOCK)
      return Error("Invalid record at top-level");

    if (ParseBlock(Stream, 0))
      return true;
    ++NumTopBlocks;
  }

  if (Dump) errs() << "\n\n";

  uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT;
  // Print a summary of the read file.
  errs() << "Summary of " << InputFilename << ":\n";
  errs() << "         Total size: ";
  PrintSize(BufferSizeBits);
  errs() << "\n";
  errs() << "        Stream type: ";
  switch (CurStreamType) {
  default: assert(0 && "Unknown bitstream type");
  case UnknownBitstream: errs() << "unknown\n"; break;
  case LLVMIRBitstream:  errs() << "LLVM IR\n"; break;
  }
  errs() << "  # Toplevel Blocks: " << NumTopBlocks << "\n";
  errs() << "\n";

  // Emit per-block stats.
  errs() << "Per-block Summary:\n";
  for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
       E = BlockIDStats.end(); I != E; ++I) {
    errs() << "  Block ID #" << I->first;
    if (const char *BlockName = GetBlockName(I->first, StreamFile))
      errs() << " (" << BlockName << ")";
    errs() << ":\n";

    const PerBlockIDStats &Stats = I->second;
    errs() << "      Num Instances: " << Stats.NumInstances << "\n";
    errs() << "         Total Size: ";
    PrintSize(Stats.NumBits);
    errs() << "\n";
    double pct = (Stats.NumBits * 100.0) / BufferSizeBits;
    errs() << "    Percent of file: " << format("%2.4f%%", pct) << "\n";
    if (Stats.NumInstances > 1) {
      errs() << "       Average Size: ";
      PrintSize(Stats.NumBits/(double)Stats.NumInstances);
      errs() << "\n";
      errs() << "  Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
             << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
      errs() << "    Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
             << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
      errs() << "    Tot/Avg Records: " << Stats.NumRecords << "/"
             << Stats.NumRecords/(double)Stats.NumInstances << "\n";
    } else {
      errs() << "      Num SubBlocks: " << Stats.NumSubBlocks << "\n";
      errs() << "        Num Abbrevs: " << Stats.NumAbbrevs << "\n";
      errs() << "        Num Records: " << Stats.NumRecords << "\n";
    }
    if (Stats.NumRecords) {
      double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords;
      errs() << "    Percent Abbrevs: " << format("%2.4f%%", pct) << "\n";
    }
    errs() << "\n";

    // Print a histogram of the codes we see.
    if (!NoHistogram && !Stats.CodeFreq.empty()) {
      std::vector<std::pair<unsigned, unsigned> > FreqPairs;  // <freq,code>
      for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i)
        if (unsigned Freq = Stats.CodeFreq[i].NumInstances)
          FreqPairs.push_back(std::make_pair(Freq, i));
      std::stable_sort(FreqPairs.begin(), FreqPairs.end());
      std::reverse(FreqPairs.begin(), FreqPairs.end());

      errs() << "\tRecord Histogram:\n";
      fprintf(stderr, "\t\t  Count    # Bits   %% Abv  Record Kind\n");
      for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) {
        const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second];

        fprintf(stderr, "\t\t%7d %9llu ", RecStats.NumInstances,
                (unsigned long long)RecStats.TotalBits);

        if (RecStats.NumAbbrev)
          fprintf(stderr, "%7.2f  ",
                  (double)RecStats.NumAbbrev/RecStats.NumInstances*100);
        else
          fprintf(stderr, "         ");

        if (const char *CodeName =
              GetCodeName(FreqPairs[i].second, I->first, StreamFile))
          fprintf(stderr, "%s\n", CodeName);
        else
          fprintf(stderr, "UnknownCode%d\n", FreqPairs[i].second);
      }
      errs() << "\n";

    }
  }
  return 0;
}
Beispiel #29
0
CommonOptionsParser::CommonOptionsParser(
    int &argc, const char **argv, cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
  static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
                            cl::sub(*cl::AllSubCommands));

  static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
                                        cl::Optional, cl::cat(Category),
                                        cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> SourcePaths(
      cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> ArgsAfter(
      "extra-arg",
      cl::desc("Additional argument to append to the compiler command line"),
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> ArgsBefore(
      "extra-arg-before",
      cl::desc("Additional argument to prepend to the compiler command line"),
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  cl::HideUnrelatedOptions(Category);

  std::string ErrorMessage;
  Compilations =
      FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
  if (!Compilations && !ErrorMessage.empty())
    llvm::errs() << ErrorMessage;
  cl::ParseCommandLineOptions(argc, argv, Overview);
  cl::PrintOptionValues();

  SourcePathList = SourcePaths;
  if ((OccurrencesFlag == cl::ZeroOrMore || OccurrencesFlag == cl::Optional) &&
      SourcePathList.empty())
    return;
  if (!Compilations) {
    if (!BuildPath.empty()) {
      Compilations =
          CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage);
    } else {
      Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0],
                                                               ErrorMessage);
    }
    if (!Compilations) {
      llvm::errs() << "Error while trying to load a compilation database:\n"
                   << ErrorMessage << "Running without flags.\n";
      Compilations.reset(
          new FixedCompilationDatabase(".", std::vector<std::string>()));
    }
  }
  auto AdjustingCompilations =
      llvm::make_unique<ArgumentsAdjustingCompilations>(
          std::move(Compilations));
  AdjustingCompilations->appendArgumentsAdjuster(
      getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN));
  AdjustingCompilations->appendArgumentsAdjuster(
      getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));
  Compilations = std::move(AdjustingCompilations);
}
Beispiel #30
0
// Returns true if unroll count was set explicitly.
// Calculates unroll count and writes it to UP.Count.
static bool computeUnrollCount(
    Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT, LoopInfo *LI,
    ScalarEvolution *SE, OptimizationRemarkEmitter *ORE, unsigned &TripCount,
    unsigned MaxTripCount, unsigned &TripMultiple, unsigned LoopSize,
    TargetTransformInfo::UnrollingPreferences &UP, bool &UseUpperBound) {
  // Check for explicit Count.
  // 1st priority is unroll count set by "unroll-count" option.
  bool UserUnrollCount = UnrollCount.getNumOccurrences() > 0;
  if (UserUnrollCount) {
    UP.Count = UnrollCount;
    UP.AllowExpensiveTripCount = true;
    UP.Force = true;
    if (UP.AllowRemainder && getUnrolledLoopSize(LoopSize, UP) < UP.Threshold)
      return true;
  }

  // 2nd priority is unroll count set by pragma.
  unsigned PragmaCount = UnrollCountPragmaValue(L);
  if (PragmaCount > 0) {
    UP.Count = PragmaCount;
    UP.Runtime = true;
    UP.AllowExpensiveTripCount = true;
    UP.Force = true;
    if (UP.AllowRemainder &&
        getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold)
      return true;
  }
  bool PragmaFullUnroll = HasUnrollFullPragma(L);
  if (PragmaFullUnroll && TripCount != 0) {
    UP.Count = TripCount;
    if (getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold)
      return false;
  }

  bool PragmaEnableUnroll = HasUnrollEnablePragma(L);
  bool ExplicitUnroll = PragmaCount > 0 || PragmaFullUnroll ||
                        PragmaEnableUnroll || UserUnrollCount;

  if (ExplicitUnroll && TripCount != 0) {
    // If the loop has an unrolling pragma, we want to be more aggressive with
    // unrolling limits. Set thresholds to at least the PragmaThreshold value
    // which is larger than the default limits.
    UP.Threshold = std::max<unsigned>(UP.Threshold, PragmaUnrollThreshold);
    UP.PartialThreshold =
        std::max<unsigned>(UP.PartialThreshold, PragmaUnrollThreshold);
  }

  // 3rd priority is full unroll count.
  // Full unroll makes sense only when TripCount or its upper bound could be
  // statically calculated.
  // Also we need to check if we exceed FullUnrollMaxCount.
  // If using the upper bound to unroll, TripMultiple should be set to 1 because
  // we do not know when loop may exit.
  // MaxTripCount and ExactTripCount cannot both be non zero since we only
  // compute the former when the latter is zero.
  unsigned ExactTripCount = TripCount;
  assert((ExactTripCount == 0 || MaxTripCount == 0) &&
         "ExtractTripCound and MaxTripCount cannot both be non zero.");
  unsigned FullUnrollTripCount = ExactTripCount ? ExactTripCount : MaxTripCount;
  UP.Count = FullUnrollTripCount;
  if (FullUnrollTripCount && FullUnrollTripCount <= UP.FullUnrollMaxCount) {
    // When computing the unrolled size, note that BEInsns are not replicated
    // like the rest of the loop body.
    if (getUnrolledLoopSize(LoopSize, UP) < UP.Threshold) {
      UseUpperBound = (MaxTripCount == FullUnrollTripCount);
      TripCount = FullUnrollTripCount;
      TripMultiple = UP.UpperBound ? 1 : TripMultiple;
      return ExplicitUnroll;
    } else {
      // The loop isn't that small, but we still can fully unroll it if that
      // helps to remove a significant number of instructions.
      // To check that, run additional analysis on the loop.
      if (Optional<EstimatedUnrollCost> Cost = analyzeLoopUnrollCost(
              L, FullUnrollTripCount, DT, *SE, TTI,
              UP.Threshold * UP.MaxPercentThresholdBoost / 100)) {
        unsigned Boost =
            getFullUnrollBoostingFactor(*Cost, UP.MaxPercentThresholdBoost);
        if (Cost->UnrolledCost < UP.Threshold * Boost / 100) {
          UseUpperBound = (MaxTripCount == FullUnrollTripCount);
          TripCount = FullUnrollTripCount;
          TripMultiple = UP.UpperBound ? 1 : TripMultiple;
          return ExplicitUnroll;
        }
      }
    }
  }

  // 4rd priority is partial unrolling.
  // Try partial unroll only when TripCount could be staticaly calculated.
  if (TripCount) {
    UP.Partial |= ExplicitUnroll;
    if (!UP.Partial) {
      DEBUG(dbgs() << "  will not try to unroll partially because "
                   << "-unroll-allow-partial not given\n");
      UP.Count = 0;
      return false;
    }
    if (UP.Count == 0)
      UP.Count = TripCount;
    if (UP.PartialThreshold != NoThreshold) {
      // Reduce unroll count to be modulo of TripCount for partial unrolling.
      if (getUnrolledLoopSize(LoopSize, UP) > UP.PartialThreshold)
        UP.Count =
            (std::max(UP.PartialThreshold, UP.BEInsns + 1) - UP.BEInsns) /
            (LoopSize - UP.BEInsns);
      if (UP.Count > UP.MaxCount)
        UP.Count = UP.MaxCount;
      while (UP.Count != 0 && TripCount % UP.Count != 0)
        UP.Count--;
      if (UP.AllowRemainder && UP.Count <= 1) {
        // If there is no Count that is modulo of TripCount, set Count to
        // largest power-of-two factor that satisfies the threshold limit.
        // As we'll create fixup loop, do the type of unrolling only if
        // remainder loop is allowed.
        UP.Count = UP.DefaultUnrollRuntimeCount;
        while (UP.Count != 0 &&
               getUnrolledLoopSize(LoopSize, UP) > UP.PartialThreshold)
          UP.Count >>= 1;
      }
      if (UP.Count < 2) {
        if (PragmaEnableUnroll)
          ORE->emit(
              OptimizationRemarkMissed(DEBUG_TYPE, "UnrollAsDirectedTooLarge",
                                       L->getStartLoc(), L->getHeader())
              << "Unable to unroll loop as directed by unroll(enable) pragma "
                 "because unrolled size is too large.");
        UP.Count = 0;
      }
    } else {