[polly] r309826 - [Polly][PM][WIP] Polly pass registration

Philip Pfaffe via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 2 10:28:04 PDT 2017


Yes, I forgot to clean the commit message again, I'm sorry.

I shouldn't make commits when I'm halfway out the door...

Cheers,
Philip

On Aug 2, 2017 18:58, "Michael Kruse" <llvm-commits at meinersbur.de> wrote:

> Hi Philipp,
>
> before committing Phabricator patches, could remove the tags [Polly]
> and [WIP]? Thank you.
>
> Michael
>
>
>
> 2017-08-02 17:52 GMT+02:00 Philip Pfaffe via llvm-commits
> <llvm-commits at lists.llvm.org>:
> > Author: pfaffe
> > Date: Wed Aug  2 08:52:25 2017
> > New Revision: 309826
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=309826&view=rev
> > Log:
> > [Polly][PM][WIP] Polly pass registration
> >
> > Summary:
> > This patch is a first attempt at registering Polly passes with the LLVM
> tools. Tool plugins are still unsupported, but this registration is usable
> from the tools if Polly is linked into them (albeit requiring minimal
> patches to those tools). Registration requires a small amount of machinery
> (the owning analysis proxies), necessary for injecting ScopAnalysisManager
> objects into the calling tools.
> >
> > This patch is marked WIP because the registration is incomplete. Parsing
> manual pipelines is fully supported, but default pass injection into the O3
> pipeline is lacking, mostly because there is opportunity for some redesign
> here, I believe. The first point of order would be insertion points. I
> think it makes sense to run before the vectorizers. Running Polly Early,
> however, is weird. Mostly because it actually is the default (which to me
> is unexpected), and because Polly runs it's own O1 pipeline. Why not
> instead insert it at an appropriate place somewhere after simplification
> happend? Running after the loop optimizers seems intuitive, but it also
> seems wasteful, since multiple consecutive loops might well be a single
> scop, and we don't need to run for all of them.
> >
> > My second request for comments would be regarding all those smallish
> helper passes we have,  like PollyViewer, PollyPrinter, PollyImportJScop.
> Right now these are controlled by command line options, deciding whether
> they should be part of the Polly pipeline. What is your opinion on treating
> them like real passes, and have the user write an appropriate pipeline if
> they want to use any of them?
> >
> > Reviewers: grosser, Meinersbur, bollu
> >
> > Reviewed By: grosser
> >
> > Subscribers: llvm-commits, pollydev
> >
> > Tags: #polly
> >
> > Differential Revision: https://reviews.llvm.org/D35458
> >
> > Added:
> >     polly/trunk/include/polly/CodePreparation.h
> >     polly/trunk/lib/Support/PollyPasses.def
> > Modified:
> >     polly/trunk/include/polly/ScopPass.h
> >     polly/trunk/include/polly/Support/ScopHelper.h
> >     polly/trunk/lib/Analysis/ScopPass.cpp
> >     polly/trunk/lib/Support/RegisterPasses.cpp
> >     polly/trunk/lib/Support/ScopHelper.cpp
> >     polly/trunk/lib/Transform/CodePreparation.cpp
> >
> > Added: polly/trunk/include/polly/CodePreparation.h
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/poll
> y/CodePreparation.h?rev=309826&view=auto
> > ============================================================
> ==================
> > --- polly/trunk/include/polly/CodePreparation.h (added)
> > +++ polly/trunk/include/polly/CodePreparation.h Wed Aug  2 08:52:25 2017
> > @@ -0,0 +1,13 @@
> > +#ifndef POLLY_CODEPREPARATION_H
> > +#define POLLY_CODEPREPARATION_H
> > +
> > +#include "llvm/IR/PassManager.h"
> > +
> > +namespace polly {
> > +struct CodePreparationPass : public llvm::PassInfoMixin<CodePreparationPass>
> {
> > +  llvm::PreservedAnalyses run(llvm::Function &F,
> > +                              llvm::FunctionAnalysisManager &FAM);
> > +};
> > +}
> > +
> > +#endif /* POLLY_CODEPREPARATION_H */
> >
> > Modified: polly/trunk/include/polly/ScopPass.h
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/poll
> y/ScopPass.h?rev=309826&r1=309825&r2=309826&view=diff
> > ============================================================
> ==================
> > --- polly/trunk/include/polly/ScopPass.h (original)
> > +++ polly/trunk/include/polly/ScopPass.h Wed Aug  2 08:52:25 2017
> > @@ -77,6 +77,21 @@ private:
> >    ScopInfo *SI;
> >  };
> >
> > +// A partial specialization of the require analysis template pass to
> handle
> > +// extra parameters
> > +template <typename AnalysisT>
> > +struct RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
> > +                           ScopStandardAnalysisResults &, SPMUpdater &>
> > +    : PassInfoMixin<
> > +          RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
> > +                              ScopStandardAnalysisResults &, SPMUpdater
> &>> {
> > +  PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM,
> > +                        ScopStandardAnalysisResults &AR, SPMUpdater &) {
> > +    (void)AM.template getResult<AnalysisT>(L, AR);
> > +    return PreservedAnalyses::all();
> > +  }
> > +};
> > +
> >  template <>
> >  InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result
> >  InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
> > @@ -95,6 +110,40 @@ extern template class OuterAnalysisManag
> >  } // namespace llvm
> >
> >  namespace polly {
> > +
> > +template <typename AnalysisManagerT, typename IRUnitT, typename...
> ExtraArgTs>
> > +class OwningInnerAnalysisManagerProxy
> > +    : public InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT> {
> > +public:
> > +  OwningInnerAnalysisManagerProxy()
> > +      : InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>(InnerAM)
> {}
> > +  using Result = typename InnerAnalysisManagerProxy<AnalysisManagerT,
> IRUnitT,
> > +
> ExtraArgTs...>::Result;
> > +  Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
> > +             ExtraArgTs...) {
> > +    return Result(InnerAM);
> > +  }
> > +
> > +  AnalysisManagerT &getManager() { return InnerAM; }
> > +
> > +private:
> > +  friend AnalysisInfoMixin<
> > +      OwningInnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
> > +
> > +  static AnalysisKey Key;
> > +
> > +  AnalysisManagerT InnerAM;
> > +};
> > +
> > +template <>
> > +OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result
> > +OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
> > +    Function &F, FunctionAnalysisManager &FAM);
> > +extern template class OwningInnerAnalysisManagerProx
> y<ScopAnalysisManager,
> > +                                                      Function>;
> > +
> > +using OwningScopAnalysisManagerFunctionProxy =
> > +    OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
> >  using ScopPassManager =
> >      PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults
> &,
> >                  SPMUpdater &>;
> >
> > Modified: polly/trunk/include/polly/Support/ScopHelper.h
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/poll
> y/Support/ScopHelper.h?rev=309826&r1=309825&r2=309826&view=diff
> > ============================================================
> ==================
> > --- polly/trunk/include/polly/Support/ScopHelper.h (original)
> > +++ polly/trunk/include/polly/Support/ScopHelper.h Wed Aug  2 08:52:25
> 2017
> > @@ -315,6 +315,16 @@ void simplifyRegion(llvm::Region *R, llv
> >  ///
> >  void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass
> *P);
> >
> > +/// Split the entry block of a function to store the newly inserted
> > +///        allocations outside of all Scops.
> > +///
> > +/// @param DT DominatorTree to be updated.
> > +/// @param LI LoopInfo to be updated.
> > +/// @param RI RegionInfo to be updated.
> > +void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock,
> > +                              llvm::DominatorTree *DT, llvm::LoopInfo
> *LI,
> > +                              llvm::RegionInfo *RI);
> > +
> >  /// Wrapper for SCEVExpander extended to all Polly features.
> >  ///
> >  /// This wrapper will internally call the SCEVExpander but also makes
> sure that
> >
> > Modified: polly/trunk/lib/Analysis/ScopPass.cpp
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis
> /ScopPass.cpp?rev=309826&r1=309825&r2=309826&view=diff
> > ============================================================
> ==================
> > --- polly/trunk/lib/Analysis/ScopPass.cpp (original)
> > +++ polly/trunk/lib/Analysis/ScopPass.cpp Wed Aug  2 08:52:25 2017
> > @@ -41,6 +41,8 @@ void ScopPass::getAnalysisUsage(Analysis
> >    AU.setPreservesAll();
> >  }
> >
> > +template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager,
> Function>;
> > +
> >  namespace llvm {
> >
> >  template class PassManager<Scop, ScopAnalysisManager,
> > @@ -130,6 +132,12 @@ bool ScopAnalysisManagerFunctionProxy::R
> >  }
> >
> >  template <>
> > +OwningScopAnalysisManagerFunctionProxy::Result
> > +OwningScopAnalysisManagerFunctionProxy::run(Function &F,
> > +                                            FunctionAnalysisManager
> &FAM) {
> > +  return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
> > +}
> > +template <>
> >  ScopAnalysisManagerFunctionProxy::Result
> >  ScopAnalysisManagerFunctionProxy::run(Function &F,
> >                                        FunctionAnalysisManager &FAM) {
> >
> > Added: polly/trunk/lib/Support/PollyPasses.def
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/
> PollyPasses.def?rev=309826&view=auto
> > ============================================================
> ==================
> > --- polly/trunk/lib/Support/PollyPasses.def (added)
> > +++ polly/trunk/lib/Support/PollyPasses.def Wed Aug  2 08:52:25 2017
> > @@ -0,0 +1,29 @@
> > +#ifndef FUNCTION_ANALYSIS
> > +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
> > +#endif
> > +FUNCTION_ANALYSIS("polly-detect", ScopAnalysis())
> > +FUNCTION_ANALYSIS("polly-function-scops", ScopInfoAnalysis())
> > +#undef FUNCTION_ANALYSIS
> > +
> > +#ifndef FUNCTION_PASS
> > +#define FUNCTION_PASS(NAME, CREATE_PASS)
> > +#endif
> > +FUNCTION_PASS("polly-prepare", CodePreparationPass())
> > +FUNCTION_PASS("print<polly-detect>", ScopAnalysisPrinterPass(errs()))
> > +FUNCTION_PASS("print<polly-function-scops>",
> ScopInfoPrinterPass(errs()))
> > +#undef FUNCTION_PASS
> > +
> > +#ifndef SCOP_ANALYSIS
> > +#define SCOP_ANALYSIS(NAME, CREATE_PASS)
> > +#endif
> > +SCOP_ANALYSIS("polly-ast", IslAstAnalysis())
> > +SCOP_ANALYSIS("polly-dependences", DependenceAnalysis())
> > +#undef SCOP_ANALYSIS
> > +
> > +#ifndef SCOP_PASS
> > +#define SCOP_PASS(NAME, CREATE_PASS)
> > +#endif
> > +SCOP_PASS("print<polly-ast>", IslAstPrinterPass(outs()))
> > +SCOP_PASS("print<polly-dependences>", DependenceInfoPrinterPass(outs
> ()))
> > +SCOP_PASS("polly-codegen", CodeGenerationPass())
> > +#undef SCOP_PASS
> >
> > Modified: polly/trunk/lib/Support/RegisterPasses.cpp
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/
> RegisterPasses.cpp?rev=309826&r1=309825&r2=309826&view=diff
> > ============================================================
> ==================
> > --- polly/trunk/lib/Support/RegisterPasses.cpp (original)
> > +++ polly/trunk/lib/Support/RegisterPasses.cpp Wed Aug  2 08:52:25 2017
> > @@ -23,7 +23,9 @@
> >  #include "polly/Canonicalization.h"
> >  #include "polly/CodeGen/CodeGeneration.h"
> >  #include "polly/CodeGen/CodegenCleanup.h"
> > +#include "polly/CodeGen/IslAst.h"
> >  #include "polly/CodeGen/PPCGCodeGeneration.h"
> > +#include "polly/CodePreparation.h"
> >  #include "polly/DeLICM.h"
> >  #include "polly/DependenceInfo.h"
> >  #include "polly/FlattenSchedule.h"
> > @@ -37,6 +39,8 @@
> >  #include "polly/Support/DumpModulePass.h"
> >  #include "llvm/Analysis/CFGPrinter.h"
> >  #include "llvm/IR/LegacyPassManager.h"
> > +#include "llvm/IR/Verifier.h"
> > +#include "llvm/Passes/PassBuilder.h"
> >  #include "llvm/Support/TargetSelect.h"
> >  #include "llvm/Transforms/IPO.h"
> >  #include "llvm/Transforms/IPO/PassManagerBuilder.h"
> > @@ -430,6 +434,69 @@ registerPollyScalarOptimizerLatePasses(c
> >    PM.add(createCodegenCleanupPass());
> >  }
> >
> > +static void buildDefaultPollyPipeline(FunctionPassManager &PM,
> > +                                      PassBuilder::OptimizationLevel
> Level) {
> > +  if (!polly::shouldEnablePolly())
> > +    return;
> > +  PassBuilder PB;
> > +  ScopPassManager SPM;
> > +
> > +  // TODO add utility passes for the various command line options, once
> they're
> > +  // ported
> > +  assert(!DumpBefore && "This option is not implemented");
> > +  assert(DumpBeforeFile.empty() && "This option is not implemented");
> > +
> > +  if (PollyDetectOnly)
> > +    return;
> > +
> > +  assert(!PollyViewer && "This option is not implemented");
> > +  assert(!PollyOnlyViewer && "This option is not implemented");
> > +  assert(!PollyPrinter && "This option is not implemented");
> > +  assert(!PollyOnlyPrinter && "This option is not implemented");
> > +  assert(!EnablePolyhedralInfo && "This option is not implemented");
> > +  assert(!EnableDeLICM && "This option is not implemented");
> > +  assert(!EnableSimplify && "This option is not implemented");
> > +  assert(!ImportJScop && "This option is not implemented");
> > +  assert(!DeadCodeElim && "This option is not implemented");
> > +  assert(!EnablePruneUnprofitable && "This option is not implemented");
> > +  if (Target == TARGET_CPU || Target == TARGET_HYBRID)
> > +    switch (Optimizer) {
> > +    case OPTIMIZER_NONE:
> > +      break; /* Do nothing */
> > +    case OPTIMIZER_ISL:
> > +      assert("ISL optimizer is not implemented");
> > +      break;
> > +    }
> > +
> > +  assert(!ExportJScop && "This option is not implemented");
> > +
> > +  if (Target == TARGET_CPU || Target == TARGET_HYBRID) {
> > +    switch (CodeGeneration) {
> > +    case CODEGEN_FULL:
> > +      SPM.addPass(polly::CodeGenerationPass());
> > +      break;
> > +    case CODEGEN_AST:
> > +    default: // Does it actually make sense to distinguish IslAst
> codegen?
> > +      break;
> > +    }
> > +  }
> > +#ifdef GPU_CODEGEN
> > +  else
> > +    assert("Hybrid Target with GPU support is not implemented");
> > +#endif
> > +
> > +  PM.addPass(CodePreparationPass());
> > +  PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
> > +  PM.addPass(PB.buildFunctionSimplificationPipeline(
> > +      Level, PassBuilder::ThinLTOPhase::None)); // Cleanup
> > +
> > +  assert(!DumpAfter && "This option is not implemented");
> > +  assert(DumpAfterFile.empty() && "This option is not implemented");
> > +
> > +  if (CFGPrinter)
> > +    PM.addPass(llvm::CFGPrinterPass());
> > +}
> > +
> >  /// Register Polly to be available as an optimizer
> >  ///
> >  ///
> > @@ -478,4 +545,140 @@ static llvm::RegisterStandardPasses
> >  static llvm::RegisterStandardPasses RegisterPollyOptimizerScalarLate(
> >      llvm::PassManagerBuilder::EP_VectorizerStart,
> >      registerPollyScalarOptimizerLatePasses);
> > +
> > +static OwningScopAnalysisManagerFunctionProxy
> > +createScopAnalyses(FunctionAnalysisManager &FAM) {
> > +  OwningScopAnalysisManagerFunctionProxy Proxy;
> > +#define SCOP_ANALYSIS(NAME, CREATE_PASS)
>        \
> > +  Proxy.getManager().registerPass([] { return CREATE_PASS; });
> > +
> > +#include "PollyPasses.def"
> > +
> > +  Proxy.getManager().registerPass(
> > +      [&FAM] { return FunctionAnalysisManagerScopProxy(FAM); });
> > +  return Proxy;
> > +}
> > +
> > +static void registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
> > +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
>        \
> > +  FAM.registerPass([] { return CREATE_PASS; });
> > +
> > +#include "PollyPasses.def"
> > +
> > +  FAM.registerPass([&FAM] { return createScopAnalyses(FAM); });
> > +}
> > +
> > +static bool
> > +parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
> > +                      ArrayRef<PassBuilder::PipelineElement> Pipeline)
> {
> > +  if (parseAnalysisUtilityPasses<OwningScopAnalysisManagerFunctio
> nProxy>(
> > +          "polly-scop-analyses", Name, FPM))
> > +    return true;
> > +
> > +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
>        \
> > +  if (parseAnalysisUtilityPasses<
>         \
> > +          std::remove_reference<decltype(CREATE_PASS)>::type>(NAME,
> Name,      \
> > +                                                              FPM))
>         \
> > +    return true;
> > +
> > +#define FUNCTION_PASS(NAME, CREATE_PASS)
>        \
> > +  if (Name == NAME) {
>         \
> > +    FPM.addPass(CREATE_PASS);
>         \
> > +    return true;
>        \
> > +  }
> > +
> > +#include "PollyPasses.def"
> > +  return false;
> > +}
> > +
> > +static bool parseScopPass(StringRef Name, ScopPassManager &SPM) {
> > +#define SCOP_ANALYSIS(NAME, CREATE_PASS)
>        \
> > +  if (parseAnalysisUtilityPasses<
>         \
> > +          std::remove_reference<decltype(CREATE_PASS)>::type>(NAME,
> Name,      \
> > +                                                              SPM))
>         \
> > +    return true;
> > +
> > +#define SCOP_PASS(NAME, CREATE_PASS)
>        \
> > +  if (Name == NAME) {
>         \
> > +    SPM.addPass(CREATE_PASS);
>         \
> > +    return true;
>        \
> > +  }
> > +
> > +#include "PollyPasses.def"
> > +
> > +  return false;
> > +}
> > +
> > +static bool parseScopPipeline(StringRef Name, FunctionPassManager &FPM,
> > +                              ArrayRef<PassBuilder::PipelineElement>
> Pipeline) {
> > +  if (Name != "scop")
> > +    return false;
> > +  if (!Pipeline.empty()) {
> > +    ScopPassManager SPM;
> > +    for (const auto &E : Pipeline)
> > +      if (!parseScopPass(E.Name, SPM))
> > +        return false;
> > +    FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
> > +  }
> > +  return true;
> > +}
> > +
> > +static bool isScopPassName(StringRef Name) {
> > +#define SCOP_ANALYSIS(NAME, CREATE_PASS)
>        \
> > +  if (Name == "require<" NAME ">")
>        \
> > +    return true;
>        \
> > +  if (Name == "invalidate<" NAME ">")
>         \
> > +    return true;
> > +
> > +#define SCOP_PASS(NAME, CREATE_PASS)
>        \
> > +  if (Name == NAME)
>         \
> > +    return true;
> > +
> > +#include "PollyPasses.def"
> > +
> > +  return false;
> > +}
> > +
> > +static bool
> > +parseTopLevelPipeline(ModulePassManager &MPM,
> > +                      ArrayRef<PassBuilder::PipelineElement> Pipeline,
> > +                      bool VerifyEachPass, bool DebugLogging) {
> > +  std::vector<PassBuilder::PipelineElement> FullPipeline;
> > +  StringRef FirstName = Pipeline.front().Name;
> > +
> > +  if (!isScopPassName(FirstName))
> > +    return false;
> > +
> > +  FunctionPassManager FPM(DebugLogging);
> > +  ScopPassManager SPM(DebugLogging);
> > +
> > +  for (auto &Element : Pipeline) {
> > +    auto &Name = Element.Name;
> > +    auto &InnerPipeline = Element.InnerPipeline;
> > +    if (!InnerPipeline.empty()) // Scop passes don't have inner
> pipelines
> > +      return false;
> > +    if (!parseScopPass(Name, SPM))
> > +      return false;
> > +  }
> > +
> > +  FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
> > +  if (VerifyEachPass)
> > +    FPM.addPass(VerifierPass());
> > +  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> > +  if (VerifyEachPass)
> > +    MPM.addPass(VerifierPass());
> > +
> > +  return true;
> > +}
> > +
> > +void RegisterPollyPasses(PassBuilder &PB) {
> > +  PB.registerAnalysisRegistrationCallback(registerFunctionAnalyses);
> > +  PB.registerPipelineParsingCallback(parseFunctionPipeline);
> > +  PB.registerPipelineParsingCallback(parseScopPipeline);
> > +  PB.registerParseTopLevelPipelineCallback(parseTopLevelPipeline);
> > +
> > +  if (PassPosition == POSITION_BEFORE_VECTORIZER)
> > +    PB.registerVectorizerStartEPCallback(buildDefaultPollyPipeline);
> > +  // FIXME else Error?
> > +}
> >  } // namespace polly
> >
> > Modified: polly/trunk/lib/Support/ScopHelper.cpp
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/
> ScopHelper.cpp?rev=309826&r1=309825&r2=309826&view=diff
> > ============================================================
> ==================
> > --- polly/trunk/lib/Support/ScopHelper.cpp (original)
> > +++ polly/trunk/lib/Support/ScopHelper.cpp Wed Aug  2 08:52:25 2017
> > @@ -194,13 +194,19 @@ static BasicBlock *splitBlock(BasicBlock
> >    return NewBlock;
> >  }
> >
> > -void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
> > +void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock,
> DominatorTree *DT,
> > +                                     LoopInfo *LI, RegionInfo *RI) {
> >    // Find first non-alloca instruction. Every basic block has a
> non-alloca
> >    // instruction, as every well formed basic block has a terminator.
> >    BasicBlock::iterator I = EntryBlock->begin();
> >    while (isa<AllocaInst>(I))
> >      ++I;
> >
> > +  // splitBlock updates DT, LI and RI.
> > +  splitBlock(EntryBlock, &*I, DT, LI, RI);
> > +}
> > +
> > +void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
> >    auto *DTWP = P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
> >    auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
> >    auto *LIWP = P->getAnalysisIfAvailable<LoopInfoWrapperPass>();
> > @@ -209,7 +215,7 @@ void polly::splitEntryBlockForAlloca(Bas
> >    RegionInfo *RI = RIP ? &RIP->getRegionInfo() : nullptr;
> >
> >    // splitBlock updates DT, LI and RI.
> > -  splitBlock(EntryBlock, &*I, DT, LI, RI);
> > +  polly::splitEntryBlockForAlloca(EntryBlock, DT, LI, RI);
> >  }
> >
> >  /// The SCEVExpander will __not__ generate any code for an existing
> SDiv/SRem
> >
> > Modified: polly/trunk/lib/Transform/CodePreparation.cpp
> > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transfor
> m/CodePreparation.cpp?rev=309826&r1=309825&r2=309826&view=diff
> > ============================================================
> ==================
> > --- polly/trunk/lib/Transform/CodePreparation.cpp (original)
> > +++ polly/trunk/lib/Transform/CodePreparation.cpp Wed Aug  2 08:52:25
> 2017
> > @@ -16,6 +16,7 @@
> >  //
> >  //===-------------------------------------------------------
> ---------------===//
> >
> > +#include "polly/CodePreparation.h"
> >  #include "polly/LinkAllPasses.h"
> >  #include "polly/ScopDetection.h"
> >  #include "polly/Support/ScopHelper.h"
> > @@ -57,6 +58,28 @@ public:
> >  };
> >  } // namespace
> >
> > +PreservedAnalyses CodePreparationPass::run(Function &F,
> > +                                           FunctionAnalysisManager
> &FAM) {
> > +
> > +  // Find first non-alloca instruction. Every basic block has a
> non-alloca
> > +  // instruction, as every well formed basic block has a terminator.
> > +  auto &EntryBlock = F.getEntryBlock();
> > +  BasicBlock::iterator I = EntryBlock.begin();
> > +  while (isa<AllocaInst>(I))
> > +    ++I;
> > +
> > +  auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
> > +  auto &LI = FAM.getResult<LoopAnalysis>(F);
> > +
> > +  // splitBlock updates DT, LI and RI.
> > +  splitEntryBlockForAlloca(&EntryBlock, &DT, &LI, nullptr);
> > +
> > +  PreservedAnalyses PA;
> > +  PA.preserve<DominatorTreeAnalysis>();
> > +  PA.preserve<LoopAnalysis>();
> > +  return PA;
> > +}
> > +
> >  void CodePreparation::clear() {}
> >
> >  CodePreparation::~CodePreparation() { clear(); }
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170802/c8127f09/attachment.html>


More information about the llvm-commits mailing list