Пример #1
0
// Primary pass pipeline description parsing routine.
// FIXME: Should this routine accept a TargetMachine or require the caller to
// pre-populate the analysis managers with target-specific stuff?
bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
                             bool VerifyEachPass) {
  // Look at the first entry to figure out which layer to start parsing at.
  if (PipelineText.startswith("module("))
    return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
           PipelineText.empty();
  if (PipelineText.startswith("function(")) {
    FunctionPassManager FPM;
    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
        !PipelineText.empty())
      return false;
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
    return true;
  }

  // This isn't a direct pass manager name, look for the end of a pass name.
  StringRef FirstName =
      PipelineText.substr(0, PipelineText.find_first_of(",)"));
  if (isModulePassName(FirstName))
    return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
           PipelineText.empty();

  if (isFunctionPassName(FirstName)) {
    FunctionPassManager FPM;
    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
        !PipelineText.empty())
      return false;
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
    return true;
  }

  return false;
}
Пример #2
0
// Primary pass pipeline description parsing routine.
// FIXME: Should this routine accept a TargetMachine or require the caller to
// pre-populate the analysis managers with target-specific stuff?
bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
                                    StringRef PipelineText, bool VerifyEachPass,
                                    bool DebugLogging) {
  // By default, try to parse the pipeline as-if it were within an implicit
  // 'module(...)' pass pipeline. If this will parse at all, it needs to
  // consume the entire string.
  if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
    return PipelineText.empty();

  // This isn't parsable as a module pipeline, look for the end of a pass name
  // and directly drop down to that layer.
  StringRef FirstName =
      PipelineText.substr(0, PipelineText.find_first_of(",)"));
  assert(!isModulePassName(FirstName) &&
         "Already handled all module pipeline options.");

  // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
  // pipeline.
  if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
    CGSCCPassManager CGPM(DebugLogging);
    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
                                DebugLogging) ||
        !PipelineText.empty())
      return false;
    MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
    return true;
  }

  // Similarly, if this looks like a Function pass, parse the whole thing as
  // a Function pipelien.
  if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
    FunctionPassManager FPM(DebugLogging);
    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
                                   DebugLogging) ||
        !PipelineText.empty())
      return false;
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
    return true;
  }

  // If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
  if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
    LoopPassManager LPM(DebugLogging);
    if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
                               DebugLogging) ||
        !PipelineText.empty())
      return false;
    FunctionPassManager FPM(DebugLogging);
    FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
    return true;
  }


  return false;
}
Пример #3
0
static bool parseModulePassPipeline(ModulePassManager &MPM,
                                    StringRef &PipelineText,
                                    bool VerifyEachPass) {
  for (;;) {
    // Parse nested pass managers by recursing.
    if (PipelineText.startswith("module(")) {
      ModulePassManager NestedMPM;

      // Parse the inner pipeline into the nested manager.
      PipelineText = PipelineText.substr(strlen("module("));
      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
          PipelineText.empty())
        return false;
      assert(PipelineText[0] == ')');
      PipelineText = PipelineText.substr(1);

      // Now add the nested manager as a module pass.
      MPM.addPass(std::move(NestedMPM));
    } else if (PipelineText.startswith("function(")) {
      FunctionPassManager NestedFPM;

      // Parse the inner pipeline inte the nested manager.
      PipelineText = PipelineText.substr(strlen("function("));
      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
          PipelineText.empty())
        return false;
      assert(PipelineText[0] == ')');
      PipelineText = PipelineText.substr(1);

      // Add the nested pass manager with the appropriate adaptor.
      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
    } else {
      // Otherwise try to parse a pass name.
      size_t End = PipelineText.find_first_of(",)");
      if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
        return false;
      if (VerifyEachPass)
        MPM.addPass(VerifierPass());

      PipelineText = PipelineText.substr(End);
    }

    if (PipelineText.empty() || PipelineText[0] == ')')
      return true;

    assert(PipelineText[0] == ',');
    PipelineText = PipelineText.substr(1);
  }
}
Пример #4
0
static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
  if (Name == "no-op-module") {
    MPM.addPass(NoOpModulePass());
    return true;
  }
  if (Name == "print") {
    MPM.addPass(PrintModulePass(dbgs()));
    return true;
  }
  if (Name == "print-cg") {
    MPM.addPass(LazyCallGraphPrinterPass(dbgs()));
    return true;
  }
  return false;
}
Пример #5
0
void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM,
                                        OptimizationLevel Level,
                                        bool DebugLogging) {
  // FIXME: Finish fleshing this out to match the legacy LTO pipelines.
  FunctionPassManager LateFPM(DebugLogging);
  LateFPM.addPass(InstCombinePass());
  LateFPM.addPass(SimplifyCFGPass());

  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));
}
Пример #6
0
static void runNewCustomLtoPasses(Module &M, TargetMachine &TM) {
  PassBuilder PB(&TM);

  AAManager AA;

  // Parse a custom AA pipeline if asked to.
  if (!PB.parseAAPipeline(AA, Config->LtoAAPipeline)) {
    error("Unable to parse AA pipeline description: " + Config->LtoAAPipeline);
    return;
  }

  LoopAnalysisManager LAM;
  FunctionAnalysisManager FAM;
  CGSCCAnalysisManager CGAM;
  ModuleAnalysisManager MAM;

  // Register the AA manager first so that our version is the one used.
  FAM.registerPass([&] { return std::move(AA); });

  // Register all the basic analyses with the managers.
  PB.registerModuleAnalyses(MAM);
  PB.registerCGSCCAnalyses(CGAM);
  PB.registerFunctionAnalyses(FAM);
  PB.registerLoopAnalyses(LAM);
  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);

  ModulePassManager MPM;
  if (!Config->DisableVerify)
    MPM.addPass(VerifierPass());

  // Now, add all the passes we've been requested to.
  if (!PB.parsePassPipeline(MPM, Config->LtoNewPmPasses)) {
    error("unable to parse pass pipeline description: " +
          Config->LtoNewPmPasses);
    return;
  }

  if (!Config->DisableVerify)
    MPM.addPass(VerifierPass());
  MPM.run(M, MAM);
}
Пример #7
0
bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
                                          ArrayRef<PipelineElement> Pipeline,
                                          bool VerifyEachPass,
                                          bool DebugLogging) {
  for (const auto &Element : Pipeline) {
    if (!parseModulePass(MPM, Element, VerifyEachPass, DebugLogging))
      return false;
    if (VerifyEachPass)
      MPM.addPass(VerifierPass());
  }
  return true;
}
Пример #8
0
void PassBuilder::addPerModuleDefaultPipeline(ModulePassManager &MPM,
                                              OptimizationLevel Level,
                                              bool DebugLogging) {
  // FIXME: Finish fleshing this out to match the legacy pipelines.
  FunctionPassManager EarlyFPM(DebugLogging);
  EarlyFPM.addPass(SimplifyCFGPass());
  EarlyFPM.addPass(SROA());
  EarlyFPM.addPass(EarlyCSEPass());
  EarlyFPM.addPass(LowerExpectIntrinsicPass());

  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
}
Пример #9
0
bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
                           tool_output_file *Out, StringRef PassPipeline,
                           OutputKind OK, VerifierKind VK) {
  FunctionAnalysisManager FAM;
  ModuleAnalysisManager MAM;

  // FIXME: Lift this registration of analysis passes into a .def file adjacent
  // to the one used to associate names with passes.
  MAM.registerPass(LazyCallGraphAnalysis());

  // Cross register the analysis managers through their proxies.
  MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
  FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));

  ModulePassManager MPM;
  if (VK > VK_NoVerifier)
    MPM.addPass(VerifierPass());

  if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) {
    errs() << Arg0 << ": unable to parse pass pipeline description.\n";
    return false;
  }

  if (VK > VK_NoVerifier)
    MPM.addPass(VerifierPass());

  // Add any relevant output pass at the end of the pipeline.
  switch (OK) {
  case OK_NoOutput:
    break; // No output pass needed.
  case OK_OutputAssembly:
    MPM.addPass(PrintModulePass(Out->os()));
    break;
  case OK_OutputBitcode:
    MPM.addPass(BitcodeWriterPass(Out->os()));
    break;
  }

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

  // Now that we have all of the passes ready, run them.
  MPM.run(&M, &MAM);

  // Declare success.
  if (OK != OK_NoOutput)
    Out->keep();
  return true;
}
Пример #10
0
bool PassBuilder::parseModulePass(ModulePassManager &MPM,
                                  const PipelineElement &E, bool VerifyEachPass,
                                  bool DebugLogging) {
  auto &Name = E.Name;
  auto &InnerPipeline = E.InnerPipeline;

  // First handle complex passes like the pass managers which carry pipelines.
  if (!InnerPipeline.empty()) {
    if (Name == "module") {
      ModulePassManager NestedMPM(DebugLogging);
      if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass,
                                   DebugLogging))
        return false;
      MPM.addPass(std::move(NestedMPM));
      return true;
    }
    if (Name == "cgscc") {
      CGSCCPassManager CGPM(DebugLogging);
      if (!parseCGSCCPassPipeline(CGPM, InnerPipeline, VerifyEachPass,
                                  DebugLogging))
        return false;
      MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM),
                                                          DebugLogging));
      return true;
    }
    if (Name == "function") {
      FunctionPassManager FPM(DebugLogging);
      if (!parseFunctionPassPipeline(FPM, InnerPipeline, VerifyEachPass,
                                     DebugLogging))
        return false;
      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
      return true;
    }
    if (auto Count = parseRepeatPassName(Name)) {
      ModulePassManager NestedMPM(DebugLogging);
      if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass,
                                   DebugLogging))
        return false;
      MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM)));
      return true;
    }
    // Normal passes can't have pipelines.
    return false;
  }

  // Manually handle aliases for pre-configured pipeline fragments.
  if (Name.startswith("default") || Name.startswith("lto")) {
    SmallVector<StringRef, 3> Matches;
    if (!DefaultAliasRegex.match(Name, &Matches))
      return false;
    assert(Matches.size() == 3 && "Must capture two matched strings!");

    OptimizationLevel L = StringSwitch<OptimizationLevel>(Matches[2])
        .Case("O0", O0)
        .Case("O1", O1)
        .Case("O2", O2)
        .Case("O3", O3)
        .Case("Os", Os)
        .Case("Oz", Oz);
    if (L == O0)
      // At O0 we do nothing at all!
      return true;

    if (Matches[1] == "default") {
      MPM.addPass(buildPerModuleDefaultPipeline(L, DebugLogging));
    } else if (Matches[1] == "lto-pre-link") {
      MPM.addPass(buildLTOPreLinkDefaultPipeline(L, DebugLogging));
    } else {
      assert(Matches[1] == "lto" && "Not one of the matched options!");
      MPM.addPass(buildLTODefaultPipeline(L, DebugLogging));
    }
    return true;
  }

  // Finally expand the basic registered passes from the .inc file.
#define MODULE_PASS(NAME, CREATE_PASS)                                         \
  if (Name == NAME) {                                                          \
    MPM.addPass(CREATE_PASS);                                                  \
    return true;                                                               \
  }
#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
  if (Name == "require<" NAME ">") {                                           \
    MPM.addPass(                                                               \
        RequireAnalysisPass<                                                   \
            std::remove_reference<decltype(CREATE_PASS)>::type, Module>());    \
    return true;                                                               \
  }                                                                            \
  if (Name == "invalidate<" NAME ">") {                                        \
    MPM.addPass(InvalidateAnalysisPass<                                        \
                std::remove_reference<decltype(CREATE_PASS)>::type>());        \
    return true;                                                               \
  }
#include "PassRegistry.def"

  return false;
}
Пример #11
0
/// A clean version of `EmitAssembly` that uses the new pass manager.
///
/// Not all features are currently supported in this system, but where
/// necessary it falls back to the legacy pass manager to at least provide
/// basic functionality.
///
/// This API is planned to have its functionality finished and then to replace
/// `EmitAssembly` at some point in the future when the default switches.
void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
    BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
  setCommandLineOpts();

  // The new pass manager always makes a target machine available to passes
  // during construction.
  CreateTargetMachine(/*MustCreateTM*/ true);
  if (!TM)
    // This will already be diagnosed, just bail.
    return;
  TheModule->setDataLayout(TM->createDataLayout());

  PassBuilder PB(TM.get());

  LoopAnalysisManager LAM;
  FunctionAnalysisManager FAM;
  CGSCCAnalysisManager CGAM;
  ModuleAnalysisManager MAM;

  // Register the AA manager first so that our version is the one used.
  FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });

  // Register all the basic analyses with the managers.
  PB.registerModuleAnalyses(MAM);
  PB.registerCGSCCAnalyses(CGAM);
  PB.registerFunctionAnalyses(FAM);
  PB.registerLoopAnalyses(LAM);
  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);

  ModulePassManager MPM;

  if (!CodeGenOpts.DisableLLVMPasses) {
    if (CodeGenOpts.OptimizationLevel == 0) {
      // Build a minimal pipeline based on the semantics required by Clang,
      // which is just that always inlining occurs.
      MPM.addPass(AlwaysInlinerPass());
    } else {
      // Otherwise, use the default pass pipeline. We also have to map our
      // optimization levels into one of the distinct levels used to configure
      // the pipeline.
      PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);

      MPM = PB.buildPerModuleDefaultPipeline(Level);
    }
  }

  // FIXME: We still use the legacy pass manager to do code generation. We
  // create that pass manager here and use it as needed below.
  legacy::PassManager CodeGenPasses;
  bool NeedCodeGen = false;

  // Append any output we need to the pass manager.
  switch (Action) {
  case Backend_EmitNothing:
    break;

  case Backend_EmitBC:
    MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
                                  CodeGenOpts.EmitSummaryIndex,
                                  CodeGenOpts.EmitSummaryIndex));
    break;

  case Backend_EmitLL:
    MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
    break;

  case Backend_EmitAssembly:
  case Backend_EmitMCNull:
  case Backend_EmitObj:
    NeedCodeGen = true;
    CodeGenPasses.add(
        createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
    if (!AddEmitPasses(CodeGenPasses, Action, *OS))
      // FIXME: Should we handle this error differently?
      return;
    break;
  }

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

  // Now that we have all of the passes ready, run them.
  {
    PrettyStackTraceString CrashInfo("Optimizer");
    MPM.run(*TheModule, MAM);
  }

  // Now if needed, run the legacy PM for codegen.
  if (NeedCodeGen) {
    PrettyStackTraceString CrashInfo("Code generation");
    CodeGenPasses.run(*TheModule);
  }
}