// BuildLinkItems -- This function generates a LinkItemList for the LinkItems
// linker function by combining the Files and Libraries in the order they were
// declared on the command line.
static void BuildLinkItems(
  Linker::ItemList& Items,
  const cl::list<std::string>& Files,
  const cl::list<std::string>& Libraries) {

  // Build the list of linkage items for LinkItems.

  cl::list<std::string>::const_iterator fileIt = Files.begin();
  cl::list<std::string>::const_iterator libIt  = Libraries.begin();

  int libPos = -1, filePos = -1;
  while ( libIt != Libraries.end() || fileIt != Files.end() ) {
    if (libIt != Libraries.end())
      libPos = Libraries.getPosition(libIt - Libraries.begin());
    else
      libPos = -1;
    if (fileIt != Files.end())
      filePos = Files.getPosition(fileIt - Files.begin());
    else
      filePos = -1;

    if (filePos != -1 && (libPos == -1 || filePos < libPos)) {
      // Add a source file
      Items.push_back(std::make_pair(*fileIt++, false));
    } else if (libPos != -1 && (filePos == -1 || libPos < filePos)) {
      // Add a library
      Items.push_back(std::make_pair(*libIt++, true));
    }
  }
}
// Helper function used by Build().
// Traverses initial portions of the toolchains (up to the first Join node).
// This function is also responsible for handling the -x option.
void CompilationGraph::BuildInitial (InputLanguagesSet& InLangs,
                                     const sys::Path& TempDir) {
    // This is related to -x option handling.
    cl::list<std::string>::const_iterator xIter = Languages.begin(),
                                          xBegin = xIter, xEnd = Languages.end();
    bool xEmpty = true;
    const std::string* xLanguage = 0;
    unsigned xPos = 0, xPosNext = 0, filePos = 0;

    if (xIter != xEnd) {
        xEmpty = false;
        xPos = Languages.getPosition(xIter - xBegin);
        cl::list<std::string>::const_iterator xNext = llvm::next(xIter);
        xPosNext = (xNext == xEnd) ? std::numeric_limits<unsigned>::max()
                   : Languages.getPosition(xNext - xBegin);
        xLanguage = (*xIter == "none") ? 0 : &(*xIter);
    }

    // For each input file:
    for (cl::list<std::string>::const_iterator B = InputFilenames.begin(),
            CB = B, E = InputFilenames.end(); B != E; ++B) {
        sys::Path In = sys::Path(*B);

        // Code for handling the -x option.
        // Output: std::string* xLanguage (can be NULL).
        if (!xEmpty) {
            filePos = InputFilenames.getPosition(B - CB);

            if (xPos < filePos) {
                if (filePos < xPosNext) {
                    xLanguage = (*xIter == "none") ? 0 : &(*xIter);
                }
                else { // filePos >= xPosNext
                    // Skip xIters while filePos > xPosNext
                    while (filePos > xPosNext) {
                        ++xIter;
                        xPos = xPosNext;

                        cl::list<std::string>::const_iterator xNext = llvm::next(xIter);
                        if (xNext == xEnd)
                            xPosNext = std::numeric_limits<unsigned>::max();
                        else
                            xPosNext = Languages.getPosition(xNext - xBegin);
                        xLanguage = (*xIter == "none") ? 0 : &(*xIter);
                    }
                }
            }
        }

        // Find the toolchain corresponding to this file.
        const Node* N = FindToolChain(In, xLanguage, InLangs);
        // Pass file through the chain starting at head.
        PassThroughGraph(In, N, InLangs, TempDir);
    }
}
Exemple #3
0
//////////////////////////////////////////////////////////////////////////////////////////
// This function runs optimization passes based on command line arguments.
// Returns true if any optimization passes were invoked.
bool ldc_optimize_module(llvm::Module* m)
{
    if (!optimize())
        return false;

    PassManager pm;

    if (verifyEach) pm.add(createVerifierPass());

#if LDC_LLVM_VER >= 302
    addPass(pm, new DataLayout(m));
#else
    addPass(pm, new TargetData(m));
#endif

    bool optimize = optimizeLevel != 0 || doInline();

    unsigned optPos = optimizeLevel != 0
                    ? optimizeLevel.getPosition()
                    : enableInlining.getPosition();

    for (size_t i = 0; i < passList.size(); i++) {
        // insert -O<N> / -enable-inlining in right position
        if (optimize && optPos < passList.getPosition(i)) {
            addPassesForOptLevel(pm);
            optimize = false;
        }

        const PassInfo* pass = passList[i];
        if (PassInfo::NormalCtor_t ctor = pass->getNormalCtor()) {
            addPass(pm, ctor());
        } else {
            const char* arg = pass->getPassArgument(); // may return null
            if (arg)
                error("Can't create pass '-%s' (%s)", arg, pass->getPassName());
            else
                error("Can't create pass (%s)", pass->getPassName());
            assert(0);  // Should be unreachable; root.h:error() calls exit()
        }
    }
    // insert -O<N> / -enable-inlining if specified at the end,
    if (optimize)
        addPassesForOptLevel(pm);

    pm.run(*m);

    verifyModule(m);

    return true;
}
//===----------------------------------------------------------------------===//
// 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);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  // @LOCALMOD-BEGIN
  initializeAddPNaClExternalDeclsPass(Registry);
  initializeCanonicalizeMemIntrinsicsPass(Registry);
  initializeExpandArithWithOverflowPass(Registry);
  initializeExpandByValPass(Registry);
  initializeExpandConstantExprPass(Registry);
  initializeExpandCtorsPass(Registry);
  initializeExpandGetElementPtrPass(Registry);
  initializeExpandSmallArgumentsPass(Registry);
  initializeExpandStructRegsPass(Registry);
  initializeExpandTlsConstantExprPass(Registry);
  initializeExpandTlsPass(Registry);
  initializeExpandVarArgsPass(Registry);
  initializeFlattenGlobalsPass(Registry);
  initializeGlobalCleanupPass(Registry);
  initializeInsertDivideCheckPass(Registry);
  initializePNaClABIVerifyFunctionsPass(Registry);
  initializePNaClABIVerifyModulePass(Registry);
  initializePNaClSjLjEHPass(Registry);
  initializePromoteI1OpsPass(Registry);
  initializePromoteIntegersPass(Registry);
  initializeRemoveAsmMemoryPass(Registry);
  initializeReplacePtrsWithIntsPass(Registry);
  initializeResolveAliasesPass(Registry);
  initializeResolvePNaClIntrinsicsPass(Registry);
  initializeRewriteAtomicsPass(Registry);
  initializeRewriteLLVMIntrinsicsPass(Registry);
  initializeRewritePNaClLibraryCallsPass(Registry);
  initializeStripAttributesPass(Registry);
  initializeStripMetadataPass(Registry);
  initializeExpandI64Pass(Registry);
  // @LOCALMOD-END

  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,
                                   raw_fd_ostream::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 (PrintBreakpoints) {
    // Default to standard output.
    if (!Out) {
      if (OutputFilename.empty())
        OutputFilename = "-";

      std::string ErrorInfo;
      Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                                     raw_fd_ostream::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;
    }

    // @LOCALMOD-BEGIN
    if (PNaClABISimplifyPreOpt &&
        PNaClABISimplifyPreOpt.getPosition() < PassList.getPosition(i)) {
      PNaClABISimplifyAddPreOptPasses(Passes);
      PNaClABISimplifyPreOpt = false;
    }

    if (PNaClABISimplifyPostOpt &&
        PNaClABISimplifyPostOpt.getPosition() < PassList.getPosition(i)) {
      PNaClABISimplifyAddPostOptPasses(Passes);
      PNaClABISimplifyPostOpt = false;
    }
    // @LOCALMOD-END

    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();
  }

  // @LOCALMOD-BEGIN
  if (PNaClABISimplifyPreOpt)
    PNaClABISimplifyAddPreOptPasses(Passes);

  if (PNaClABISimplifyPostOpt)
    PNaClABISimplifyAddPostOptPasses(Passes);
  // @LOCALMOD-END

  // 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()));
    // @LOCALMOD
  }

  // 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());

// @LOCALMOD-BEGIN
  // Write bitcode to the output.
  if (!NoOutput && !AnalyzeOnly && !OutputAssembly) {
    switch (OutputFileFormat) {
      case LLVMFormat:
        WriteBitcodeToFile(M.get(), Out->os());
        break;
      case PNaClFormat:
        NaClWriteBitcodeToFile(M.get(), Out->os());
        break;
      default:
        errs() << "Don't understand bitcode format for generated bitcode.\n";
        return 1;
    }
  }
// @LOCALMOD-END

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

  return 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();
  InitializeAllAsmPrinters();

  // 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);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsPass(Registry);

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

  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...
  std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);

  if (!M) {
    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...
  std::unique_ptr<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::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\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;

  if (PassPipeline.getNumOccurrences() > 0) {
    OutputKind OK = OK_NoOutput;
    if (!NoOutput)
      OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;

    VerifierKind VK = VK_VerifyInAndOut;
    if (NoVerify)
      VK = VK_NoVerifier;
    else if (VerifyEach)
      VK = VK_VerifyEachPass;

    // The user has asked to use the new pass manager and provided a pipeline
    // string. Hand off the rest of the functionality to the new code for that
    // layer.
    return runPassPipeline(argv[0], Context, *M, Out.get(), PassPipeline,
                           OK, VK)
               ? 0
               : 1;
  }

  // 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.
  const DataLayout *DL = M->getDataLayout();
  if (!DL && !DefaultDataLayout.empty()) {
    M->setDataLayout(DefaultDataLayout);
    DL = M->getDataLayout();
  }

  if (DL)
    Passes.add(new DataLayoutPass());

  Triple ModuleTriple(M->getTargetTriple());
  TargetMachine *Machine = nullptr;
  if (ModuleTriple.getArch())
    Machine = GetTargetMachine(Triple(ModuleTriple));
  std::unique_ptr<TargetMachine> TM(Machine);

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

  std::unique_ptr<FunctionPassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses.reset(new FunctionPassManager(M.get()));
    if (DL)
      FPasses->add(new DataLayoutPass());
    if (TM)
      TM->addAnalysisPasses(*FPasses);

  }

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

      std::error_code EC;
      Out = llvm::make_unique<tool_output_file>(OutputFilename, EC,
                                                sys::fs::F_None);
      if (EC) {
        errs() << EC.message() << '\n';
        return 1;
      }
    }
    Passes.add(createBreakpointPrinter(Out->os()));
    NoOutput = true;
  }

  // If the -strip-debug command line option was specified, add it.
  if (StripDebug)
    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) {
    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 = nullptr;
    if (PassInf->getTargetMachineCtor())
      P = PassInf->getTargetMachineCtor()(TM.get());
    else 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(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Region:
          Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Loop:
          Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Function:
          Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_CallGraphSCC:
          Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet));
          break;
        default:
          Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet));
          break;
        }
      }
    }

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

  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 (Function &F : *M)
      FPasses->run(F);
    FPasses->doFinalization();
  }

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

  // 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);

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

  return 0;
}
Exemple #6
0
//===----------------------------------------------------------------------===//
// main for opt
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);

  if (AnalyzeOnly && NoOutput) {
    errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
    return 1;
  }
  
  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  LLVMContext &Context = getGlobalContext();
  
  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  // 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;

  SMDiagnostic Err;

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

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

  // 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,
                                   raw_fd_ostream::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 TargetData instance for this module...
  TargetData *TD = 0;
  const std::string &ModuleDataLayout = M.get()->getDataLayout();
  if (!ModuleDataLayout.empty())
    TD = new TargetData(ModuleDataLayout);
  else if (!DefaultDataLayout.empty())
    TD = new TargetData(DefaultDataLayout);

  if (TD)
    Passes.add(TD);

  OwningPtr<PassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    FPasses.reset(new PassManager());
    if (TD)
      FPasses->add(new TargetData(*TD));
  }

  // 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);
      OptLevelO1 = false;
    }

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

    if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 3);
      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_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);

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

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

  if (OptLevelO1 || OptLevelO2 || OptLevelO3)
    FPasses->run(*M.get());

  // 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()));
  }

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

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

  return 0;
}
Exemple #7
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();
  InitializeAllAsmPrinters();

  // 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);
  initializeSafeStackPass(Registry);
  initializeSjLjEHPreparePass(Registry);

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

  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;

  Context.setDiscardValueNames(DiscardValueNames);

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

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

  // Strip debug info before running the verifier.
  if (StripDebug)
    StripDebugInfo(*M);

  // Immediately run the verifier to catch any problems before starting up the
  // pass pipelines.  Otherwise we can crash on broken code during
  // doInitialization().
  if (!NoVerify && 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(Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<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::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      return 1;
    }
  }

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

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

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

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

  // 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;

  if (PassPipeline.getNumOccurrences() > 0) {
    OutputKind OK = OK_NoOutput;
    if (!NoOutput)
      OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;

    VerifierKind VK = VK_VerifyInAndOut;
    if (NoVerify)
      VK = VK_NoVerifier;
    else if (VerifyEach)
      VK = VK_VerifyEachPass;

    // The user has asked to use the new pass manager and provided a pipeline
    // string. Hand off the rest of the functionality to the new code for that
    // layer.
    return runPassPipeline(argv[0], Context, *M, TM.get(), Out.get(),
                           PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
                           PreserveBitcodeUseListOrder)
               ? 0
               : 1;
  }

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

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfoImpl TLII(ModuleTriple);

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

  // Add an appropriate DataLayout instance for this module.
  const DataLayout &DL = M->getDataLayout();
  if (DL.isDefault() && !DefaultDataLayout.empty()) {
    M->setDataLayout(DefaultDataLayout);
  }

  // Add internal analysis passes from the target machine.
  Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
                                                     : TargetIRAnalysis()));

  std::unique_ptr<legacy::FunctionPassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses.reset(new legacy::FunctionPassManager(M.get()));
    FPasses->add(createTargetTransformInfoWrapperPass(
        TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis()));
  }

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

      std::error_code EC;
      Out = llvm::make_unique<tool_output_file>(OutputFilename, EC,
                                                sys::fs::F_None);
      if (EC) {
        errs() << EC.message() << '\n';
        return 1;
      }
    }
    Passes.add(createBreakpointPrinter(Out->os()));
    NoOutput = true;
  }

  // Create a new optimization pass for each one specified on the command line
  for (unsigned i = 0; i < PassList.size(); ++i) {
    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 = nullptr;
    if (PassInf->getTargetMachineCtor())
      P = PassInf->getTargetMachineCtor()(TM.get());
    else 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(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Region:
          Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Loop:
          Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Function:
          Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_CallGraphSCC:
          Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet));
          break;
        default:
          Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet));
          break;
        }
      }
    }

    if (PrintEachXForm)
      Passes.add(
          createPrintModulePass(errs(), "", PreserveAssemblyUseListOrder));
  }

  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 (Function &F : *M)
      FPasses->run(F);
    FPasses->doFinalization();
  }

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

  // In run twice mode, we want to make sure the output is bit-by-bit
  // equivalent if we run the pass manager again, so setup two buffers and
  // a stream to write to them. Note that llc does something similar and it
  // may be worth to abstract this out in the future.
  SmallVector<char, 0> Buffer;
  SmallVector<char, 0> CompileTwiceBuffer;
  std::unique_ptr<raw_svector_ostream> BOS;
  raw_ostream *OS = nullptr;

  // Write bitcode or assembly to the output as the last step...
  if (!NoOutput && !AnalyzeOnly) {
    assert(Out);
    OS = &Out->os();
    if (RunTwice) {
      BOS = make_unique<raw_svector_ostream>(Buffer);
      OS = BOS.get();
    }
    if (OutputAssembly) {
      if (EmitSummaryIndex)
        report_fatal_error("Text output is incompatible with -module-summary");
      if (EmitModuleHash)
        report_fatal_error("Text output is incompatible with -module-hash");
      Passes.add(createPrintModulePass(*OS, "", PreserveAssemblyUseListOrder));
    } else
      Passes.add(createBitcodeWriterPass(*OS, PreserveBitcodeUseListOrder,
                                         EmitSummaryIndex, EmitModuleHash));
  }

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

  // If requested, run all passes again with the same pass manager to catch
  // bugs caused by persistent state in the passes
  if (RunTwice) {
      std::unique_ptr<Module> M2(CloneModule(M.get()));
      Passes.run(*M2);
      CompileTwiceBuffer = Buffer;
      Buffer.clear();
  }

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

  // Compare the two outputs and make sure they're the same
  if (RunTwice) {
    assert(Out);
    if (Buffer.size() != CompileTwiceBuffer.size() ||
        (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) !=
         0)) {
      errs() << "Running the pass manager twice changed the output.\n"
                "Writing the result of the second run to the specified output.\n"
                "To generate the one-run comparison binary, just run without\n"
                "the compile-twice option\n";
      Out->os() << BOS->str();
      Out->keep();
      return 1;
    }
    Out->os() << BOS->str();
  }

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

  return 0;
}
Exemple #8
0
//////////////////////////////////////////////////////////////////////////////////////////
// This function runs optimization passes based on command line arguments.
// Returns true if any optimization passes were invoked.
bool ldc_optimize_module(llvm::Module *M)
{
    // Create a PassManager to hold and optimize the collection of
    // per-module passes we are about to build.
#if LDC_LLVM_VER >= 307
    legacy::
#endif
    PassManager mpm;

#if LDC_LLVM_VER >= 307
    // Add an appropriate TargetLibraryInfo pass for the module's triple.
    TargetLibraryInfoImpl *tlii = new TargetLibraryInfoImpl(Triple(M->getTargetTriple()));

    // The -disable-simplify-libcalls flag actually disables all builtin optzns.
    if (disableSimplifyLibCalls)
      tlii->disableAllFunctions();

    mpm.add(new TargetLibraryInfoWrapperPass(*tlii));
#else
    // 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();

    mpm.add(tli);
#endif

    // Add an appropriate DataLayout instance for this module.
#if LDC_LLVM_VER >= 307
    // The DataLayout is already set at the module (in module.cpp,
    // method Module::genLLVMModule())
    // FIXME: Introduce new command line switch default-data-layout to
    // override the module data layout
#elif LDC_LLVM_VER == 306
    mpm.add(new DataLayoutPass());
#elif LDC_LLVM_VER == 305
    const DataLayout *DL = M->getDataLayout();
    assert(DL && "DataLayout not set at module");
    mpm.add(new DataLayoutPass(*DL));
#elif LDC_LLVM_VER >= 302
    mpm.add(new DataLayout(M));
#else
    mpm.add(new TargetData(M));
#endif

#if LDC_LLVM_VER >= 307
    // Add internal analysis passes from the target machine.
    mpm.add(createTargetTransformInfoWrapperPass(gTargetMachine->getTargetIRAnalysis()));
#elif LDC_LLVM_VER >= 305
    // Add internal analysis passes from the target machine.
    gTargetMachine->addAnalysisPasses(mpm);
#endif

    // Also set up a manager for the per-function passes.
#if LDC_LLVM_VER >= 307
    legacy::
#endif
    FunctionPassManager fpm(M);

#if LDC_LLVM_VER >= 307
    // Add internal analysis passes from the target machine.
    fpm.add(createTargetTransformInfoWrapperPass(gTargetMachine->getTargetIRAnalysis()));
#elif LDC_LLVM_VER >= 306
    fpm.add(new DataLayoutPass());
    gTargetMachine->addAnalysisPasses(fpm);
#elif LDC_LLVM_VER == 305
    fpm.add(new DataLayoutPass(M));
    gTargetMachine->addAnalysisPasses(fpm);
#elif LDC_LLVM_VER >= 302
    fpm.add(new DataLayout(M));
#else
    fpm.add(new TargetData(M));
#endif

    // If the -strip-debug command line option was specified, add it before
    // anything else.
    if (stripDebug)
        mpm.add(createStripSymbolsPass(true));

    bool defaultsAdded = false;
    // Create a new optimization pass for each one specified on the command line
    for (unsigned i = 0; i < passList.size(); ++i) {
        if (optimizeLevel && optimizeLevel.getPosition() < passList.getPosition(i)) {
            addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());
            defaultsAdded = true;
        }

        const PassInfo *passInf = passList[i];
        Pass *pass = 0;
        if (passInf->getNormalCtor())
            pass = passInf->getNormalCtor()();
        else {
            const char* arg = passInf->getPassArgument(); // may return null
            if (arg)
                error(Loc(), "Can't create pass '-%s' (%s)", arg, pass->getPassName());
            else
                error(Loc(), "Can't create pass (%s)", pass->getPassName());
            llvm_unreachable("pass creation failed");
        }
        if (pass) {
            addPass(mpm, pass);
        }
    }

    // Add the default passes for the specified optimization level.
    if (!defaultsAdded)
        addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());

    // Run per-function passes.
    fpm.doInitialization();
    for (llvm::Module::iterator F = M->begin(), E = M->end(); F != E; ++F)
        fpm.run(*F);
    fpm.doFinalization();

    // Run per-module passes.
    mpm.run(*M);

    // Verify the resulting module.
    verifyModule(M);

    // Report that we run some passes.
    return true;
}
//===----------------------------------------------------------------------===//
// 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();
  InitializeAllAsmPrinters();

  // 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);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsPass(Registry);
  initializeWinEHPreparePass(Registry);
  initializeDwarfEHPreparePass(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 .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...
  std::unique_ptr<Module> M;

  // XXX EMSCRIPTEN: support for multiple files
  if (InputFilenames.size() == 0)
    M = parseIRFile("-", Err, Context);
  else if (InputFilenames.size() == 1)
    M = parseIRFile(InputFilenames[0], Err, Context);
  else {
    // link them in
    M = nullptr;
    std::unique_ptr<Linker> L;

    for (unsigned i = 0; i < InputFilenames.size(); ++i) {
      std::unique_ptr<Module> MM = parseIRFile(InputFilenames[i], Err, Context);
      if (!MM.get()) {
        errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
        return 1;
      }

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

      if (i == 0) {
        M.swap(MM);
        L = make_unique<Linker>(M.get());
      } else {
        if (L->linkInModule(MM.get()))
          return 1;
      }
    }
  }

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

  // Strip debug info before running the verifier.
  if (StripDebug)
    StripDebugInfo(*M);

  // Immediately run the verifier to catch any problems before starting up the
  // pass pipelines.  Otherwise we can crash on broken code during
  // doInitialization().
  if (!NoVerify && verifyModule(*M, &errs())) {
    errs() << argv[0] << ": "
           << ": 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(Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<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::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      return 1;
    }
  }

  Triple ModuleTriple(M->getTargetTriple());
  TargetMachine *Machine = nullptr;
  if (ModuleTriple.getArch())
    Machine = GetTargetMachine(ModuleTriple);
  std::unique_ptr<TargetMachine> TM(Machine);

  // 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;

  if (PassPipeline.getNumOccurrences() > 0) {
    OutputKind OK = OK_NoOutput;
    if (!NoOutput)
      OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;

    VerifierKind VK = VK_VerifyInAndOut;
    if (NoVerify)
      VK = VK_NoVerifier;
    else if (VerifyEach)
      VK = VK_VerifyEachPass;

    // The user has asked to use the new pass manager and provided a pipeline
    // string. Hand off the rest of the functionality to the new code for that
    // layer.
    return runPassPipeline(argv[0], Context, *M, TM.get(), Out.get(),
                           PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
                           PreserveBitcodeUseListOrder)
               ? 0
               : 1;
  }

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

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfoImpl TLII(ModuleTriple);

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

  // Add an appropriate DataLayout instance for this module.
  const DataLayout &DL = M->getDataLayout();
  if (DL.isDefault() && !DefaultDataLayout.empty()) {
    M->setDataLayout(DefaultDataLayout);
  }

  // Add internal analysis passes from the target machine.
  Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
                                                     : TargetIRAnalysis()));

  std::unique_ptr<legacy::FunctionPassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses.reset(new legacy::FunctionPassManager(M.get()));
    FPasses->add(createTargetTransformInfoWrapperPass(
        TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis()));
  }

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

      std::error_code EC;
      Out = llvm::make_unique<tool_output_file>(OutputFilename, EC,
                                                sys::fs::F_None);
      if (EC) {
        errs() << EC.message() << '\n';
        return 1;
      }
    }
    Passes.add(createBreakpointPrinter(Out->os()));
    NoOutput = true;
  }

  // Create a new optimization pass for each one specified on the command line
  for (unsigned i = 0; i < PassList.size(); ++i) {
    // @LOCALMOD-BEGIN
    if (PNaClABISimplifyPreOpt &&
        PNaClABISimplifyPreOpt.getPosition() < PassList.getPosition(i)) {
      PNaClABISimplifyAddPreOptPasses(&ModuleTriple, Passes);
      PNaClABISimplifyPreOpt = false;
    }
    // @LOCALMOD-END

    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;
    }

    // @LOCALMOD-BEGIN
    if (PNaClABISimplifyPostOpt &&
        PNaClABISimplifyPostOpt.getPosition() < PassList.getPosition(i)) {
      PNaClABISimplifyAddPostOptPasses(&ModuleTriple, Passes);
      PNaClABISimplifyPostOpt = false;
    }

    if (MinSFI && MinSFI.getPosition() < PassList.getPosition(i)) {
      MinSFIPasses(Passes);
      MinSFI = false;
    }
    // @LOCALMOD-END

    const PassInfo *PassInf = PassList[i];
    Pass *P = nullptr;
    if (PassInf->getTargetMachineCtor())
      P = PassInf->getTargetMachineCtor()(TM.get());
    else 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(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Region:
          Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Loop:
          Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Function:
          Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_CallGraphSCC:
          Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet));
          break;
        default:
          Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet));
          break;
        }
      }
    }

    if (PrintEachXForm)
      Passes.add(
          createPrintModulePass(errs(), "", PreserveAssemblyUseListOrder));
  }

  // @LOCALMOD-BEGIN
  if (PNaClABISimplifyPreOpt)
    PNaClABISimplifyAddPreOptPasses(&ModuleTriple, Passes);
  // @LOCALMOD-END

  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 (Function &F : *M)
      FPasses->run(F);
    FPasses->doFinalization();
  }

  // @LOCALMOD-BEGIN
  if (PNaClABISimplifyPostOpt)
    PNaClABISimplifyAddPostOptPasses(&ModuleTriple, Passes);

  if (MinSFI)
     MinSFIPasses(Passes);
  // @LOCALMOD-END

  // 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(), "", PreserveAssemblyUseListOrder));
    else
      // @LOCALMOD-START
      switch (OutputFileFormat) {
      case LLVMFormat:
        Passes.add(createBitcodeWriterPass(Out->os(), PreserveBitcodeUseListOrder));
        break;
      case PNaClFormat:
        Passes.add(createNaClBitcodeWriterPass(Out->os()));
        break;
      case AutodetectFileFormat:
        report_fatal_error("Command can't autodetect file format!");
        break;
      }
      // @LOCALMOD-END
  }

  // 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);

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

  return 0;
}
Exemple #10
0
//////////////////////////////////////////////////////////////////////////////////////////
// This function runs optimization passes based on command line arguments.
// Returns true if any optimization passes were invoked.
bool ldc_optimize_module(llvm::Module* m)
{
    // Create a PassManager to hold and optimize the collection of
    // per-module passes we are about to build.
    PassManager mpm;

    // 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();
    mpm.add(tli);

    // Add an appropriate TargetData instance for this module.
#if LDC_LLVM_VER >= 302
    mpm.add(new DataLayout(m));
#else
    mpm.add(new TargetData(m));
#endif

    // Also set up a manager for the per-function passes.
    FunctionPassManager fpm(m);
#if LDC_LLVM_VER >= 302
    fpm.add(new DataLayout(m));
#else
    fpm.add(new TargetData(m));
#endif

    // If the -strip-debug command line option was specified, add it before
    // anything else.
    if (stripDebug)
        mpm.add(createStripSymbolsPass(true));

    bool defaultsAdded = false;
    // Create a new optimization pass for each one specified on the command line
    for (unsigned i = 0; i < passList.size(); ++i) {
        if (optimizeLevel && optimizeLevel.getPosition() < passList.getPosition(i)) {
            addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());
            defaultsAdded = true;
        }

        const PassInfo *passInf = passList[i];
        Pass *pass = 0;
        if (passInf->getNormalCtor())
            pass = passInf->getNormalCtor()();
        else {
            const char* arg = passInf->getPassArgument(); // may return null
            if (arg)
                error("Can't create pass '-%s' (%s)", arg, pass->getPassName());
            else
                error("Can't create pass (%s)", pass->getPassName());
            llvm_unreachable("pass creation failed");
        }
        if (pass) {
            addPass(mpm, pass);
        }
    }

    // Add the default passes for the specified optimization level.
    if (!defaultsAdded)
        addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());

    // Run per-function passes.
    fpm.doInitialization();
    for (llvm::Module::iterator F = m->begin(), E = m->end(); F != E; ++F)
        fpm.run(*F);
    fpm.doFinalization();

    // Run per-module passes.
    mpm.run(*m);

    // Verify the resulting module.
    verifyModule(m);

    // Report that we run some passes.
    return true;
}
Exemple #11
0
//===----------------------------------------------------------------------===//
// main for opt
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  LLVMContext &Context = getGlobalContext();
  
  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  // 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;

  SMDiagnostic Err;

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

  if (M.get() == 0) {
    Err.Print(argv[0], errs());
    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 != "-") {
    // Make sure that the Output file gets unlinked from the disk if we get a
    // SIGINT
    sys::RemoveFileOnSignal(sys::Path(OutputFilename));

    std::string ErrorInfo;
    Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo,
                             raw_fd_ostream::F_Binary);
    if (!ErrorInfo.empty()) {
      errs() << ErrorInfo << '\n';
      delete Out;
      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 && !OutputAssembly)
    if (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...
  TargetData *TD = 0;
  const std::string &ModuleDataLayout = M.get()->getDataLayout();
  if (!ModuleDataLayout.empty())
    TD = new TargetData(ModuleDataLayout);
  else if (!DefaultDataLayout.empty())
    TD = new TargetData(DefaultDataLayout);

  if (TD)
    Passes.add(TD);

  FunctionPassManager *FPasses = NULL;
  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    FPasses = new FunctionPassManager(new ExistingModuleProvider(M.get()));
    if (TD)
      FPasses->add(new TargetData(*TD));
  }

  // 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);
      OptLevelO1 = false;
    }

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

    if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 3);
      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) {
      bool isBBPass = dynamic_cast<BasicBlockPass*>(P) != 0;
      bool isLPass = !isBBPass && dynamic_cast<LoopPass*>(P) != 0;
      bool isFPass = !isLPass && dynamic_cast<FunctionPass*>(P) != 0;
      bool isCGSCCPass = !isFPass && dynamic_cast<CallGraphSCCPass*>(P) != 0;

      addPass(Passes, P);

      if (AnalyzeOnly) {
        if (isBBPass)
          Passes.add(new BasicBlockPassPrinter(PassInf));
        else if (isLPass)
          Passes.add(new LoopPassPrinter(PassInf));
        else if (isFPass)
          Passes.add(new FunctionPassPrinter(PassInf));
        else if (isCGSCCPass)
          Passes.add(new CallGraphSCCPassPrinter(PassInf));
        else
          Passes.add(new ModulePassPrinter(PassInf));
      }
    }

    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);

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

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

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

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

  // Write bitcode or assembly  out to disk or outs() as the last step...
  if (!NoOutput && !AnalyzeOnly) {
    if (OutputAssembly)
      Passes.add(createPrintModulePass(Out));
    else
      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;
  return 0;
}
Exemple #12
0
//===----------------------------------------------------------------------===//
// main for opt
//
int main(int argc, char **argv) {
    llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
    try {
        cl::ParseCommandLineOptions(argc, argv,
                                    "llvm .bc -> .bc modular optimizer and analysis printer\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, &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;
        }

        // Figure out what stream we are supposed to write to...
        // FIXME: cout is not binary!
        std::ostream *Out = &std::cout;  // Default to printing to stdout...
        if (OutputFilename != "-") {
            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!\n"
                     << "Use -f command line argument to force output\n";
                return 1;
            }
            std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                                         std::ios::binary;
            Out = new std::ofstream(OutputFilename.c_str(), io_mode);

            if (!Out->good()) {
                cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
                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()));

        FunctionPassManager *FPasses = NULL;
        if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
            FPasses = new FunctionPassManager(new ExistingModuleProvider(M.get()));
            FPasses->add(new TargetData(M.get()));
        }

        // 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 (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) {
                AddOptimizationPasses(Passes, *FPasses, 1);
                OptLevelO1 = false;
            }

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

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

            const PassInfo *PassInf = PassList[i];
            Pass *P = 0;
            if (PassInf->getNormalCtor())
                P = PassInf->getNormalCtor()();
            else
                cerr << argv[0] << ": cannot create pass: "******"\n";
            if (P) {
                bool isBBPass = dynamic_cast<BasicBlockPass*>(P) != 0;
                bool isLPass = !isBBPass && dynamic_cast<LoopPass*>(P) != 0;
                bool isFPass = !isLPass && dynamic_cast<FunctionPass*>(P) != 0;
                bool isCGSCCPass = !isFPass && dynamic_cast<CallGraphSCCPass*>(P) != 0;

                addPass(Passes, P);

                if (AnalyzeOnly) {
                    if (isBBPass)
                        Passes.add(new BasicBlockPassPrinter(PassInf));
                    else if (isLPass)
                        Passes.add(new LoopPassPrinter(PassInf));
                    else if (isFPass)
                        Passes.add(new FunctionPassPrinter(PassInf));
                    else if (isCGSCCPass)
                        Passes.add(new CallGraphSCCPassPrinter(PassInf));
                    else
                        Passes.add(new ModulePassPrinter(PassInf));
                }
            }

            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 (OptLevelO1) {
            AddOptimizationPasses(Passes, *FPasses, 1);
        }

        if (OptLevelO2) {
            AddOptimizationPasses(Passes, *FPasses, 2);
        }

        if (OptLevelO3) {
            AddOptimizationPasses(Passes, *FPasses, 3);
        }

        if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
            for (Module::iterator I = M.get()->begin(), E = M.get()->end();
                    I != E; ++I)
                FPasses->run(*I);
        }

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

        // Write bitcode out to disk or cout as the last step...
        if (!NoOutput && !AnalyzeOnly)
            Passes.add(CreateBitcodeWriterPass(*Out));

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

        // Delete the ofstream.
        if (Out != &std::cout)
            delete Out;
        return 0;

    } catch (const std::string& msg) {
        cerr << argv[0] << ": " << msg << "\n";
    } catch (...) {
        cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
    }
    llvm_shutdown();
    return 1;
}