[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