brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.5 KiB · a430bee Raw
682 lines · cpp
1//===------ RegisterPasses.cpp - Add the Polly Passes to default passes  --===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file composes the individual LLVM-IR passes provided by Polly to a10// functional polyhedral optimizer. The polyhedral optimizer is automatically11// made available to LLVM based compilers by loading the Polly shared library12// into such a compiler.13//14// The Polly optimizer is made available by executing a static constructor that15// registers the individual Polly passes in the LLVM pass manager builder. The16// passes are registered such that the default behaviour of the compiler is not17// changed, but that the flag '-polly' provided at optimization level '-O3'18// enables additional polyhedral optimizations.19//===----------------------------------------------------------------------===//20 21#include "polly/RegisterPasses.h"22#include "polly/Canonicalization.h"23#include "polly/CodeGen/CodeGeneration.h"24#include "polly/CodeGen/IslAst.h"25#include "polly/CodePreparation.h"26#include "polly/DeLICM.h"27#include "polly/DeadCodeElimination.h"28#include "polly/DependenceInfo.h"29#include "polly/ForwardOpTree.h"30#include "polly/JSONExporter.h"31#include "polly/MaximalStaticExpansion.h"32#include "polly/Options.h"33#include "polly/Pass/PollyFunctionPass.h"34#include "polly/PruneUnprofitable.h"35#include "polly/ScheduleOptimizer.h"36#include "polly/ScopDetection.h"37#include "polly/ScopGraphPrinter.h"38#include "polly/ScopInfo.h"39#include "polly/ScopInliner.h"40#include "polly/Simplify.h"41#include "polly/Support/DumpFunctionPass.h"42#include "polly/Support/DumpModulePass.h"43#include "llvm/Analysis/CFGPrinter.h"44#include "llvm/Config/llvm-config.h" // for LLVM_VERSION_STRING45#include "llvm/IR/LegacyPassManager.h"46#include "llvm/IR/PassManager.h"47#include "llvm/IR/Verifier.h"48#include "llvm/Passes/PassBuilder.h"49#include "llvm/Passes/PassPlugin.h"50#include "llvm/Support/CommandLine.h"51#include "llvm/Support/Error.h"52#include "llvm/Support/TargetSelect.h"53#include "llvm/Transforms/IPO.h"54 55using namespace llvm;56using namespace polly;57 58namespace cl = llvm::cl;59using namespace polly;60 61using llvm::FunctionPassManager;62using llvm::OptimizationLevel;63using llvm::PassBuilder;64using llvm::PassInstrumentationCallbacks;65 66cl::OptionCategory PollyCategory("Polly Options",67                                 "Configure the polly loop optimizer");68 69namespace polly {70static cl::opt<bool>71    PollyEnabled("polly",72                 cl::desc("Enable the polly optimizer (with -O1, -O2 or -O3)"),73                 cl::cat(PollyCategory));74 75static cl::opt<bool> PollyDetectOnly(76    "polly-only-scop-detection",77    cl::desc("Only run scop detection, but no other optimizations"),78    cl::cat(PollyCategory));79 80enum PassPositionChoice { POSITION_EARLY, POSITION_BEFORE_VECTORIZER };81 82enum OptimizerChoice { OPTIMIZER_NONE, OPTIMIZER_ISL };83 84static cl::opt<PassPositionChoice> PassPosition(85    "polly-position", cl::desc("Where to run polly in the pass pipeline"),86    cl::values(clEnumValN(POSITION_EARLY, "early", "Before everything"),87               clEnumValN(POSITION_BEFORE_VECTORIZER, "before-vectorizer",88                          "Right before the vectorizer")),89    cl::Hidden, cl::init(POSITION_BEFORE_VECTORIZER), cl::cat(PollyCategory));90 91static cl::opt<OptimizerChoice>92    Optimizer("polly-optimizer", cl::desc("Select the scheduling optimizer"),93              cl::values(clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"),94                         clEnumValN(OPTIMIZER_ISL, "isl",95                                    "The isl scheduling optimizer")),96              cl::Hidden, cl::init(OPTIMIZER_ISL), cl::cat(PollyCategory));97 98enum CodeGenChoice { CODEGEN_FULL, CODEGEN_AST, CODEGEN_NONE };99static cl::opt<CodeGenChoice> CodeGeneration(100    "polly-code-generation", cl::desc("How much code-generation to perform"),101    cl::values(clEnumValN(CODEGEN_FULL, "full", "AST and IR generation"),102               clEnumValN(CODEGEN_AST, "ast", "Only AST generation"),103               clEnumValN(CODEGEN_NONE, "none", "No code generation")),104    cl::Hidden, cl::init(CODEGEN_FULL), cl::cat(PollyCategory));105 106VectorizerChoice PollyVectorizerChoice;107 108static cl::opt<VectorizerChoice, true> Vectorizer(109    "polly-vectorizer", cl::desc("Select the vectorization strategy"),110    cl::values(111        clEnumValN(VECTORIZER_NONE, "none", "No Vectorization"),112        clEnumValN(113            VECTORIZER_STRIPMINE, "stripmine",114            "Strip-mine outer loops for the loop-vectorizer to trigger")),115    cl::location(PollyVectorizerChoice), cl::init(VECTORIZER_NONE),116    cl::cat(PollyCategory));117 118static cl::opt<bool> ImportJScop(119    "polly-import",120    cl::desc("Import the polyhedral description of the detected Scops"),121    cl::Hidden, cl::cat(PollyCategory));122 123static cl::opt<bool> FullyIndexedStaticExpansion(124    "polly-enable-mse",125    cl::desc("Fully expand the memory accesses of the detected Scops"),126    cl::Hidden, cl::cat(PollyCategory));127 128static cl::opt<bool> ExportJScop(129    "polly-export",130    cl::desc("Export the polyhedral description of the detected Scops"),131    cl::Hidden, cl::cat(PollyCategory));132 133static cl::opt<bool> DeadCodeElim("polly-run-dce",134                                  cl::desc("Run the dead code elimination"),135                                  cl::Hidden, cl::cat(PollyCategory));136 137static cl::opt<bool> PollyViewer(138    "polly-show",139    cl::desc("Highlight the code regions that will be optimized in a "140             "(CFG BBs and LLVM-IR instructions)"),141    cl::cat(PollyCategory));142 143static cl::opt<bool> PollyOnlyViewer(144    "polly-show-only",145    cl::desc("Highlight the code regions that will be optimized in "146             "a (CFG only BBs)"),147    cl::init(false), cl::cat(PollyCategory));148 149static cl::opt<bool>150    PollyPrinter("polly-dot", cl::desc("Enable the Polly DOT printer in -O3"),151                 cl::Hidden, cl::value_desc("Run the Polly DOT printer at -O3"),152                 cl::init(false), cl::cat(PollyCategory));153 154static cl::opt<bool> PollyOnlyPrinter(155    "polly-dot-only",156    cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), cl::Hidden,157    cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"),158    cl::init(false), cl::cat(PollyCategory));159 160static cl::opt<bool>161    CFGPrinter("polly-view-cfg",162               cl::desc("Show the Polly CFG right after code generation"),163               cl::Hidden, cl::init(false), cl::cat(PollyCategory));164 165static cl::opt<bool>166    EnableForwardOpTree("polly-enable-optree",167                        cl::desc("Enable operand tree forwarding"), cl::Hidden,168                        cl::init(true), cl::cat(PollyCategory));169 170static cl::opt<bool>171    DumpBefore("polly-dump-before",172               cl::desc("Dump module before Polly transformations into a file "173                        "suffixed with \"-before\""),174               cl::init(false), cl::cat(PollyCategory));175 176static cl::list<std::string> DumpBeforeFile(177    "polly-dump-before-file",178    cl::desc("Dump module before Polly transformations to the given file"),179    cl::cat(PollyCategory));180 181static cl::opt<bool>182    DumpAfter("polly-dump-after",183              cl::desc("Dump module after Polly transformations into a file "184                       "suffixed with \"-after\""),185              cl::init(false), cl::cat(PollyCategory));186 187static cl::list<std::string> DumpAfterFile(188    "polly-dump-after-file",189    cl::desc("Dump module after Polly transformations to the given file"),190    cl::cat(PollyCategory));191 192static cl::opt<bool>193    EnableDeLICM("polly-enable-delicm",194                 cl::desc("Eliminate scalar loop carried dependences"),195                 cl::Hidden, cl::init(true), cl::cat(PollyCategory));196 197static cl::opt<bool>198    EnableSimplify("polly-enable-simplify",199                   cl::desc("Simplify SCoP after optimizations"),200                   cl::init(true), cl::cat(PollyCategory));201 202static cl::opt<bool> EnablePruneUnprofitable(203    "polly-enable-prune-unprofitable",204    cl::desc("Bail out on unprofitable SCoPs before rescheduling"), cl::Hidden,205    cl::init(true), cl::cat(PollyCategory));206 207static cl::opt<bool>208    PollyPrintDetect("polly-print-detect",209                     cl::desc("Polly - Print static control parts (SCoPs)"),210                     cl::cat(PollyCategory));211 212static cl::opt<bool>213    PollyPrintScops("polly-print-scops",214                    cl::desc("Print polyhedral description of all regions"),215                    cl::cat(PollyCategory));216 217static cl::opt<bool> PollyPrintDeps("polly-print-deps",218                                    cl::desc("Polly - Print dependences"),219                                    cl::cat(PollyCategory));220 221static bool shouldEnablePollyForOptimization() { return PollyEnabled; }222 223static bool shouldEnablePollyForDiagnostic() {224  // FIXME: PollyTrackFailures is user-controlled, should not be set225  // programmatically.226  if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer)227    PollyTrackFailures = true;228 229  return PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||230         ExportJScop;231}232 233/// Parser of parameters for LoopVectorize pass.234static llvm::Expected<PollyPassOptions> parsePollyOptions(StringRef Params,235                                                          bool IsCustom) {236  PassPhase PrevPhase = PassPhase::None;237 238  bool EnableDefaultOpts = !IsCustom;239  bool EnableEnd2End = !IsCustom;240  std::optional<bool>241      PassEnabled[static_cast<size_t>(PassPhase::PassPhaseLast) + 1];242  PassPhase StopAfter = PassPhase::None;243 244  // Passes enabled using command-line flags (can be overridden using245  // 'polly<no-pass>')246  if (PollyPrintDetect)247    PassEnabled[static_cast<size_t>(PassPhase::PrintDetect)] = true;248  if (PollyPrintScops)249    PassEnabled[static_cast<size_t>(PassPhase::PrintScopInfo)] = true;250  if (PollyPrintDeps)251    PassEnabled[static_cast<size_t>(PassPhase::PrintDependences)] = true;252 253  if (PollyViewer)254    PassEnabled[static_cast<size_t>(PassPhase::ViewScops)] = true;255  if (PollyOnlyViewer)256    PassEnabled[static_cast<size_t>(PassPhase::ViewScopsOnly)] = true;257  if (PollyPrinter)258    PassEnabled[static_cast<size_t>(PassPhase::DotScops)] = true;259  if (PollyOnlyPrinter)260    PassEnabled[static_cast<size_t>(PassPhase::DotScopsOnly)] = true;261  if (!EnableSimplify)262    PassEnabled[static_cast<size_t>(PassPhase::Simplify0)] = false;263  if (!EnableForwardOpTree)264    PassEnabled[static_cast<size_t>(PassPhase::Optree)] = false;265  if (!EnableDeLICM)266    PassEnabled[static_cast<size_t>(PassPhase::DeLICM)] = false;267  if (!EnableSimplify)268    PassEnabled[static_cast<size_t>(PassPhase::Simplify1)] = false;269  if (ImportJScop)270    PassEnabled[static_cast<size_t>(PassPhase::ImportJScop)] = true;271  if (DeadCodeElim)272    PassEnabled[static_cast<size_t>(PassPhase::DeadCodeElimination)] = true;273  if (FullyIndexedStaticExpansion)274    PassEnabled[static_cast<size_t>(PassPhase::MaximumStaticExtension)] = true;275  if (!EnablePruneUnprofitable)276    PassEnabled[static_cast<size_t>(PassPhase::PruneUnprofitable)] = false;277  switch (Optimizer) {278  case OPTIMIZER_NONE:279    // explicitly switched off280    PassEnabled[static_cast<size_t>(PassPhase::Optimization)] = false;281    break;282  case OPTIMIZER_ISL:283    // default: enabled284    break;285  }286  if (ExportJScop)287    PassEnabled[static_cast<size_t>(PassPhase::ExportJScop)] = true;288  switch (CodeGeneration) {289  case CODEGEN_AST:290    PassEnabled[static_cast<size_t>(PassPhase::AstGen)] = true;291    PassEnabled[static_cast<size_t>(PassPhase::CodeGen)] = false;292    break;293  case CODEGEN_FULL:294    // default: ast and codegen enabled295    break;296  case CODEGEN_NONE:297    PassEnabled[static_cast<size_t>(PassPhase::AstGen)] = false;298    PassEnabled[static_cast<size_t>(PassPhase::CodeGen)] = false;299    break;300  }301 302  while (!Params.empty()) {303    StringRef Param;304    std::tie(Param, Params) = Params.split(';');305    auto [ParamName, ParamVal] = Param.split('=');306 307    if (ParamName == "stopafter") {308      StopAfter = parsePhase(ParamVal);309      if (StopAfter == PassPhase::None)310        return make_error<StringError>(311            formatv("invalid stopafter parameter value '{0}'", ParamVal).str(),312            inconvertibleErrorCode());313      continue;314    }315 316    if (!ParamVal.empty())317      return make_error<StringError>(318          formatv("parameter '{0}' does not take value", ParamName).str(),319          inconvertibleErrorCode());320 321    bool Enabled = true;322    if (ParamName.starts_with("no-")) {323      Enabled = false;324      ParamName = ParamName.drop_front(3);325    }326 327    if (ParamName == "default-opts") {328      EnableDefaultOpts = Enabled;329      continue;330    }331 332    if (ParamName == "end2end") {333      EnableEnd2End = Enabled;334      continue;335    }336 337    PassPhase Phase;338 339    // Shortcut for both simplifys at the same time340    if (ParamName == "simplify") {341      PassEnabled[static_cast<size_t>(PassPhase::Simplify0)] = Enabled;342      PassEnabled[static_cast<size_t>(PassPhase::Simplify1)] = Enabled;343      Phase = PassPhase::Simplify0;344    } else {345      Phase = parsePhase(ParamName);346      if (Phase == PassPhase::None)347        return make_error<StringError>(348            formatv("invalid Polly parameter/phase name '{0}'", ParamName)349                .str(),350            inconvertibleErrorCode());351 352      if (PrevPhase >= Phase)353        return make_error<StringError>(354            formatv("phases must not be repeated and enumerated in-order: "355                    "'{0}' listed before '{1}'",356                    getPhaseName(PrevPhase), getPhaseName(Phase))357                .str(),358            inconvertibleErrorCode());359 360      PassEnabled[static_cast<size_t>(Phase)] = Enabled;361    }362    PrevPhase = Phase;363  }364 365  PollyPassOptions Opts;366  Opts.ViewAll = ViewAll;367  Opts.ViewFilter = ViewFilter;368  Opts.PrintDepsAnalysisLevel = OptAnalysisLevel;369 370  // Implicitly enable dependent phases first. May be overriden explicitly371  // on/off later.372  for (PassPhase P : llvm::enum_seq_inclusive(PassPhase::PassPhaseFirst,373                                              PassPhase::PassPhaseLast)) {374    bool Enabled = PassEnabled[static_cast<size_t>(P)].value_or(false);375    if (!Enabled)376      continue;377 378    if (static_cast<size_t>(PassPhase::Detection) < static_cast<size_t>(P))379      Opts.setPhaseEnabled(PassPhase::Detection);380 381    if (static_cast<size_t>(PassPhase::ScopInfo) < static_cast<size_t>(P))382      Opts.setPhaseEnabled(PassPhase::ScopInfo);383 384    if (dependsOnDependenceInfo(P))385      Opts.setPhaseEnabled(PassPhase::Dependences);386 387    if (static_cast<size_t>(PassPhase::AstGen) < static_cast<size_t>(P))388      Opts.setPhaseEnabled(PassPhase::AstGen);389  }390 391  if (EnableEnd2End)392    Opts.enableEnd2End();393 394  if (EnableDefaultOpts)395    Opts.enableDefaultOpts();396 397  for (PassPhase P : llvm::enum_seq_inclusive(PassPhase::PassPhaseFirst,398                                              PassPhase::PassPhaseLast)) {399    std::optional<bool> Enabled = PassEnabled[static_cast<size_t>(P)];400 401    // Apply only if set explicitly.402    if (Enabled.has_value())403      Opts.setPhaseEnabled(P, *Enabled);404  }405 406  if (StopAfter != PassPhase::None)407    Opts.disableAfter(StopAfter);408 409  if (Error CheckResult = Opts.checkConsistency())410    return CheckResult;411 412  return Opts;413}414 415static llvm::Expected<PollyPassOptions>416parsePollyDefaultOptions(StringRef Params) {417  return parsePollyOptions(Params, false);418}419 420static llvm::Expected<PollyPassOptions>421parsePollyCustomOptions(StringRef Params) {422  return parsePollyOptions(Params, true);423}424 425/// Register Polly passes such that they form a polyhedral optimizer.426///427/// The individual Polly passes are registered in the pass manager such that428/// they form a full polyhedral optimizer. The flow of the optimizer starts with429/// a set of preparing transformations that canonicalize the LLVM-IR such that430/// the LLVM-IR is easier for us to understand and to optimizes. On the431/// canonicalized LLVM-IR we first run the ScopDetection pass, which detects432/// static control flow regions. Those regions are then translated by the433/// ScopInfo pass into a polyhedral representation. As a next step, a scheduling434/// optimizer is run on the polyhedral representation and finally the optimized435/// polyhedral representation is code generated back to LLVM-IR.436///437/// Besides this core functionality, we optionally schedule passes that provide438/// a graphical view of the scops (Polly[Only]Viewer, Polly[Only]Printer), that439/// allow the export/import of the polyhedral representation440/// (JSCON[Exporter|Importer]) or that show the cfg after code generation.441///442/// For certain parts of the Polly optimizer, several alternatives are provided:443///444/// As scheduling optimizer we support the isl scheduling optimizer445/// (http://freecode.com/projects/isl).446/// It is also possible to run Polly with no optimizer. This mode is mainly447/// provided to analyze the run and compile time changes caused by the448/// scheduling optimizer.449///450/// Polly supports the isl internal code generator.451 452/// Add the pass sequence required for Polly to the New Pass Manager.453///454/// @param PM           The pass manager itself.455/// @param Level        The optimization level. Used for the cleanup of Polly's456///                     output.457/// @param EnableForOpt Whether to add Polly IR transformations. If False, only458///                     the analysis passes are added, skipping Polly itself.459///                     The IR may still be modified.460static void buildCommonPollyPipeline(FunctionPassManager &PM,461                                     OptimizationLevel Level,462                                     bool EnableForOpt) {463  PassBuilder PB;464 465  ExitOnError Err("Inconsistent Polly configuration: ");466  PollyPassOptions &&Opts =467      Err(parsePollyOptions(StringRef(), /*IsCustom=*/false));468  PM.addPass(PollyFunctionPass(Opts));469 470  PM.addPass(PB.buildFunctionSimplificationPipeline(471      Level, llvm::ThinOrFullLTOPhase::None)); // Cleanup472 473  if (CFGPrinter)474    PM.addPass(llvm::CFGPrinterPass());475}476 477static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,478                                    llvm::OptimizationLevel Level) {479  bool EnableForOpt =480      shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();481  if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)482    return;483 484  FunctionPassManager FPM = buildCanonicalicationPassesForNPM(MPM, Level);485 486  if (DumpBefore || !DumpBeforeFile.empty()) {487    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));488 489    if (DumpBefore)490      MPM.addPass(DumpModulePass("-before", true));491    for (auto &Filename : DumpBeforeFile)492      MPM.addPass(DumpModulePass(Filename, false));493 494    FPM = FunctionPassManager();495  }496 497  buildCommonPollyPipeline(FPM, Level, EnableForOpt);498  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));499 500  if (DumpAfter)501    MPM.addPass(DumpModulePass("-after", true));502  for (auto &Filename : DumpAfterFile)503    MPM.addPass(DumpModulePass(Filename, false));504}505 506static void buildLatePollyPipeline(FunctionPassManager &PM,507                                   llvm::OptimizationLevel Level) {508  bool EnableForOpt =509      shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();510  if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)511    return;512 513  if (DumpBefore)514    PM.addPass(DumpFunctionPass("-before"));515  if (!DumpBeforeFile.empty())516    llvm::report_fatal_error(517        "Option -polly-dump-before-file at -polly-position=late "518        "not supported with NPM",519        false);520 521  buildCommonPollyPipeline(PM, Level, EnableForOpt);522 523  if (DumpAfter)524    PM.addPass(DumpFunctionPass("-after"));525  if (!DumpAfterFile.empty())526    llvm::report_fatal_error(527        "Option -polly-dump-after-file at -polly-position=late "528        "not supported with NPM",529        false);530}531 532static llvm::Expected<std::monostate> parseNoOptions(StringRef Params) {533  if (!Params.empty())534    return make_error<StringError>(535        formatv("'{0}' passed to pass that does not take any options", Params)536            .str(),537        inconvertibleErrorCode());538 539  return std::monostate{};540}541 542static llvm::Expected<bool>543parseCGPipeline(StringRef Name, llvm::CGSCCPassManager &CGPM,544                PassInstrumentationCallbacks *PIC,545                ArrayRef<PassBuilder::PipelineElement> Pipeline) {546#define CGSCC_PASS(NAME, CREATE_PASS, PARSER)                                  \547  if (PassBuilder::checkParametrizedPassName(Name, NAME)) {                    \548    auto Params = PassBuilder::parsePassParameters(PARSER, Name, NAME);        \549    if (!Params)                                                               \550      return Params.takeError();                                               \551    CGPM.addPass(CREATE_PASS);                                                 \552    return true;                                                               \553  }554#include "PollyPasses.def"555 556  return false;557}558 559static llvm::Expected<bool>560parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,561                      PassInstrumentationCallbacks *PIC,562                      ArrayRef<PassBuilder::PipelineElement> Pipeline) {563 564#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER)                               \565  if (PassBuilder::checkParametrizedPassName(Name, NAME)) {                    \566    auto ExpectedOpts = PassBuilder::parsePassParameters(PARSER, Name, NAME);  \567    if (!ExpectedOpts)                                                         \568      return ExpectedOpts.takeError();                                         \569    auto &&Opts = *ExpectedOpts;                                               \570    (void)Opts;                                                                \571    FPM.addPass(CREATE_PASS);                                                  \572    return true;                                                               \573  }574 575#include "PollyPasses.def"576  return false;577}578 579static llvm::Expected<bool>580parseModulePipeline(StringRef Name, llvm::ModulePassManager &MPM,581                    PassInstrumentationCallbacks *PIC,582                    ArrayRef<PassBuilder::PipelineElement> Pipeline) {583#define MODULE_PASS(NAME, CREATE_PASS, PARSER)                                 \584  if (PassBuilder::checkParametrizedPassName(Name, NAME)) {                    \585    auto ExpectedOpts = PassBuilder::parsePassParameters(PARSER, Name, NAME);  \586    if (!ExpectedOpts)                                                         \587      return ExpectedOpts.takeError();                                         \588    auto &&Opts = *ExpectedOpts;                                               \589    (void)Opts;                                                                \590    MPM.addPass(CREATE_PASS);                                                  \591    return true;                                                               \592  }593 594#include "PollyPasses.def"595 596  return false;597}598 599/// Register Polly to be available as an optimizer600///601///602/// We can currently run Polly at two different points int the pass manager.603/// a) very early, b) right before the vectorizer.604///605/// The default is currently a), to register Polly such that it runs as early as606/// possible. This has several implications:607///608///   1) We need to schedule more canonicalization passes609///610///   As nothing is run before Polly, it is necessary to run a set of preparing611///   transformations before Polly to canonicalize the LLVM-IR and to allow612///   Polly to detect and understand the code.613///614///   2) We get the full -O3 optimization sequence after Polly615///616///   The LLVM-IR that is generated by Polly has been optimized on a high level,617///   but it may be rather inefficient on the lower/scalar level. By scheduling618///   Polly before all other passes, we have the full sequence of -O3619///   optimizations behind us, such that inefficiencies on the low level can620///   be optimized away.621///622/// We are currently evaluating the benefit or running Polly at b). b) is nice623/// as everything is fully inlined and canonicalized, but we need to be able to624/// handle LICMed code to make it useful.625void registerPollyPasses(PassBuilder &PB) {626  PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();627 628#define MODULE_PASS(NAME, CREATE_PASS, PARSER)                                 \629  {                                                                            \630    std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts;              \631    (void)Opts;                                                                \632    PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);              \633  }634#define CGSCC_PASS(NAME, CREATE_PASS, PARSER)                                  \635  {                                                                            \636    std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts;              \637    (void)Opts;                                                                \638    PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);              \639  }640#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER)                               \641  {                                                                            \642    std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts;              \643    (void)Opts;                                                                \644    PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);              \645  }646#include "PollyPasses.def"647 648  PB.registerPipelineParsingCallback(649      [PIC](StringRef Name, FunctionPassManager &FPM,650            ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {651        ExitOnError Err("Unable to parse Polly module pass: ");652        return Err(parseFunctionPipeline(Name, FPM, PIC, Pipeline));653      });654  PB.registerPipelineParsingCallback(655      [PIC](StringRef Name, CGSCCPassManager &CGPM,656            ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {657        ExitOnError Err("Unable to parse Polly call graph pass: ");658        return Err(parseCGPipeline(Name, CGPM, PIC, Pipeline));659      });660  PB.registerPipelineParsingCallback(661      [PIC](StringRef Name, ModulePassManager &MPM,662            ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {663        ExitOnError Err("Unable to parse Polly module pass: ");664        return Err(parseModulePipeline(Name, MPM, PIC, Pipeline));665      });666 667  switch (PassPosition) {668  case POSITION_EARLY:669    PB.registerPipelineStartEPCallback(buildEarlyPollyPipeline);670    break;671  case POSITION_BEFORE_VECTORIZER:672    PB.registerVectorizerStartEPCallback(buildLatePollyPipeline);673    break;674  }675}676} // namespace polly677 678llvm::PassPluginLibraryInfo getPollyPluginInfo() {679  return {LLVM_PLUGIN_API_VERSION, "Polly", LLVM_VERSION_STRING,680          polly::registerPollyPasses};681}682