xref: /llvm-project/polly/lib/Transform/CodePreparation.cpp (revision bd93df937a6441db4aff67191ca0bb486554c34b)
119523ed2SAndreas Simbuerger //===---- CodePreparation.cpp - Code preparation for Scop Detection -------===//
219523ed2SAndreas Simbuerger //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
619523ed2SAndreas Simbuerger //
719523ed2SAndreas Simbuerger //===----------------------------------------------------------------------===//
819523ed2SAndreas Simbuerger //
9af4e809cSTobias Grosser // The Polly code preparation pass is executed before SCoP detection. Its
10af4e809cSTobias Grosser // currently only splits the entry block of the SCoP to make room for alloc
11af4e809cSTobias Grosser // instructions as they are generated during code generation.
1219523ed2SAndreas Simbuerger //
1319523ed2SAndreas Simbuerger // XXX: In the future, we should remove the need for this pass entirely and
14af4e809cSTobias Grosser // instead add this spitting to the code generation pass.
1519523ed2SAndreas Simbuerger //
1619523ed2SAndreas Simbuerger //===----------------------------------------------------------------------===//
1719523ed2SAndreas Simbuerger 
18a70e2649SPhilip Pfaffe #include "polly/CodePreparation.h"
1919523ed2SAndreas Simbuerger #include "polly/LinkAllPasses.h"
2019523ed2SAndreas Simbuerger #include "polly/Support/ScopHelper.h"
218ca36815SMatt Arsenault #include "llvm/Analysis/DominanceFrontier.h"
2219523ed2SAndreas Simbuerger #include "llvm/Analysis/LoopInfo.h"
2319523ed2SAndreas Simbuerger #include "llvm/Analysis/RegionInfo.h"
2419523ed2SAndreas Simbuerger #include "llvm/Analysis/ScalarEvolution.h"
2505da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
2619523ed2SAndreas Simbuerger 
2719523ed2SAndreas Simbuerger using namespace llvm;
2819523ed2SAndreas Simbuerger using namespace polly;
2919523ed2SAndreas Simbuerger 
3019523ed2SAndreas Simbuerger namespace {
3164b95123STobias Grosser 
32c80d6979STobias Grosser /// Prepare the IR for the scop detection.
3319523ed2SAndreas Simbuerger ///
34*bd93df93SMichael Kruse class CodePreparation final : public FunctionPass {
35c4d7bc3fSDavid Blaikie   CodePreparation(const CodePreparation &) = delete;
36c3fe35dfSTobias Grosser   const CodePreparation &operator=(const CodePreparation &) = delete;
3719523ed2SAndreas Simbuerger 
3819523ed2SAndreas Simbuerger   LoopInfo *LI;
3919523ed2SAndreas Simbuerger   ScalarEvolution *SE;
4019523ed2SAndreas Simbuerger 
4119523ed2SAndreas Simbuerger   void clear();
4219523ed2SAndreas Simbuerger 
4319523ed2SAndreas Simbuerger public:
4419523ed2SAndreas Simbuerger   static char ID;
4519523ed2SAndreas Simbuerger 
CodePreparation()4619523ed2SAndreas Simbuerger   explicit CodePreparation() : FunctionPass(ID) {}
4719523ed2SAndreas Simbuerger   ~CodePreparation();
4819523ed2SAndreas Simbuerger 
4919523ed2SAndreas Simbuerger   /// @name FunctionPass interface.
5019523ed2SAndreas Simbuerger   //@{
515d31d09fSLogan Smith   void getAnalysisUsage(AnalysisUsage &AU) const override;
525d31d09fSLogan Smith   void releaseMemory() override;
535d31d09fSLogan Smith   bool runOnFunction(Function &F) override;
545d31d09fSLogan Smith   void print(raw_ostream &OS, const Module *) const override;
5519523ed2SAndreas Simbuerger   //@}
5619523ed2SAndreas Simbuerger };
57522478d2STobias Grosser } // namespace
5819523ed2SAndreas Simbuerger 
run(Function & F,FunctionAnalysisManager & FAM)59a70e2649SPhilip Pfaffe PreservedAnalyses CodePreparationPass::run(Function &F,
60a70e2649SPhilip Pfaffe                                            FunctionAnalysisManager &FAM) {
61a70e2649SPhilip Pfaffe 
62a70e2649SPhilip Pfaffe   // Find first non-alloca instruction. Every basic block has a non-alloca
63a70e2649SPhilip Pfaffe   // instruction, as every well formed basic block has a terminator.
64a70e2649SPhilip Pfaffe   auto &EntryBlock = F.getEntryBlock();
65a70e2649SPhilip Pfaffe   BasicBlock::iterator I = EntryBlock.begin();
66a70e2649SPhilip Pfaffe   while (isa<AllocaInst>(I))
67a70e2649SPhilip Pfaffe     ++I;
68a70e2649SPhilip Pfaffe 
69a70e2649SPhilip Pfaffe   auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
70a70e2649SPhilip Pfaffe   auto &LI = FAM.getResult<LoopAnalysis>(F);
71a70e2649SPhilip Pfaffe 
72a70e2649SPhilip Pfaffe   // splitBlock updates DT, LI and RI.
73a70e2649SPhilip Pfaffe   splitEntryBlockForAlloca(&EntryBlock, &DT, &LI, nullptr);
74a70e2649SPhilip Pfaffe 
75a70e2649SPhilip Pfaffe   PreservedAnalyses PA;
76a70e2649SPhilip Pfaffe   PA.preserve<DominatorTreeAnalysis>();
77a70e2649SPhilip Pfaffe   PA.preserve<LoopAnalysis>();
78a70e2649SPhilip Pfaffe   return PA;
79a70e2649SPhilip Pfaffe }
80a70e2649SPhilip Pfaffe 
clear()8119523ed2SAndreas Simbuerger void CodePreparation::clear() {}
8219523ed2SAndreas Simbuerger 
~CodePreparation()8319523ed2SAndreas Simbuerger CodePreparation::~CodePreparation() { clear(); }
8419523ed2SAndreas Simbuerger 
getAnalysisUsage(AnalysisUsage & AU) const8519523ed2SAndreas Simbuerger void CodePreparation::getAnalysisUsage(AnalysisUsage &AU) const {
86f557987bSChandler Carruth   AU.addRequired<LoopInfoWrapperPass>();
87c5bcf246STobias Grosser   AU.addRequired<ScalarEvolutionWrapperPass>();
8819523ed2SAndreas Simbuerger 
89f557987bSChandler Carruth   AU.addPreserved<LoopInfoWrapperPass>();
908ca36815SMatt Arsenault   AU.addPreserved<RegionInfoPass>();
9119523ed2SAndreas Simbuerger   AU.addPreserved<DominatorTreeWrapperPass>();
92defd0986SHongbin Zheng   AU.addPreserved<DominanceFrontierWrapperPass>();
9319523ed2SAndreas Simbuerger }
9419523ed2SAndreas Simbuerger 
runOnFunction(Function & F)9519523ed2SAndreas Simbuerger bool CodePreparation::runOnFunction(Function &F) {
96de1b318dSEli Friedman   if (skipFunction(F))
97de1b318dSEli Friedman     return false;
98de1b318dSEli Friedman 
99f557987bSChandler Carruth   LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
100c5bcf246STobias Grosser   SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
10119523ed2SAndreas Simbuerger 
10219523ed2SAndreas Simbuerger   splitEntryBlockForAlloca(&F.getEntryBlock(), this);
10319523ed2SAndreas Simbuerger 
104de1b318dSEli Friedman   return true;
10519523ed2SAndreas Simbuerger }
10619523ed2SAndreas Simbuerger 
releaseMemory()10719523ed2SAndreas Simbuerger void CodePreparation::releaseMemory() { clear(); }
10819523ed2SAndreas Simbuerger 
print(raw_ostream & OS,const Module *) const10919523ed2SAndreas Simbuerger void CodePreparation::print(raw_ostream &OS, const Module *) const {}
11019523ed2SAndreas Simbuerger 
11119523ed2SAndreas Simbuerger char CodePreparation::ID = 0;
11219523ed2SAndreas Simbuerger char &polly::CodePreparationID = CodePreparation::ID;
11319523ed2SAndreas Simbuerger 
createCodePreparationPass()11419523ed2SAndreas Simbuerger Pass *polly::createCodePreparationPass() { return new CodePreparation(); }
11519523ed2SAndreas Simbuerger 
11619523ed2SAndreas Simbuerger INITIALIZE_PASS_BEGIN(CodePreparation, "polly-prepare",
11719523ed2SAndreas Simbuerger                       "Polly - Prepare code for polly", false, false)
118f557987bSChandler Carruth INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
11919523ed2SAndreas Simbuerger INITIALIZE_PASS_END(CodePreparation, "polly-prepare",
12019523ed2SAndreas Simbuerger                     "Polly - Prepare code for polly", false, false)
121