//===---- CodePreparation.cpp - Code preparation for Scop Detection -------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // The Polly code preparation pass is executed before SCoP detection. Its // currently only splits the entry block of the SCoP to make room for alloc // instructions as they are generated during code generation. // // XXX: In the future, we should remove the need for this pass entirely and // instead add this spitting to the code generation pass. // //===----------------------------------------------------------------------===// #include "polly/CodePreparation.h" #include "polly/LinkAllPasses.h" #include "polly/Support/ScopHelper.h" #include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/InitializePasses.h" using namespace llvm; using namespace polly; static bool runCodePreprationImpl(Function &F, 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. auto &EntryBlock = F.getEntryBlock(); BasicBlock::iterator I = EntryBlock.begin(); while (isa(I)) ++I; // Abort if not necessary to split if (I->isTerminator() && isa(I) && cast(I)->isUnconditional()) return false; // splitBlock updates DT, LI and RI. splitEntryBlockForAlloca(&EntryBlock, DT, LI, RI); return true; } namespace { /// Prepare the IR for the scop detection. /// class CodePreparation final : public FunctionPass { CodePreparation(const CodePreparation &) = delete; const CodePreparation &operator=(const CodePreparation &) = delete; void clear(); public: static char ID; explicit CodePreparation() : FunctionPass(ID) {} ~CodePreparation(); /// @name FunctionPass interface. //@{ void getAnalysisUsage(AnalysisUsage &AU) const override; void releaseMemory() override; bool runOnFunction(Function &F) override; void print(raw_ostream &OS, const Module *) const override; //@} }; } // namespace PreservedAnalyses CodePreparationPass::run(Function &F, FunctionAnalysisManager &FAM) { auto &DT = FAM.getResult(F); auto &LI = FAM.getResult(F); bool Changed = runCodePreprationImpl(F, &DT, &LI, nullptr); if (!Changed) return PreservedAnalyses::all(); PreservedAnalyses PA; PA.preserve(); PA.preserve(); return PA; } void CodePreparation::clear() {} CodePreparation::~CodePreparation() { clear(); } void CodePreparation::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); } bool CodePreparation::runOnFunction(Function &F) { if (skipFunction(F)) return false; DominatorTree *DT = &getAnalysis().getDomTree(); LoopInfo *LI = &getAnalysis().getLoopInfo(); RegionInfo *RI = &getAnalysis().getRegionInfo(); runCodePreprationImpl(F, DT, LI, RI); return true; } void CodePreparation::releaseMemory() { clear(); } void CodePreparation::print(raw_ostream &OS, const Module *) const {} char CodePreparation::ID = 0; char &polly::CodePreparationID = CodePreparation::ID; Pass *polly::createCodePreparationPass() { return new CodePreparation(); } INITIALIZE_PASS_BEGIN(CodePreparation, "polly-prepare", "Polly - Prepare code for polly", false, false) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_END(CodePreparation, "polly-prepare", "Polly - Prepare code for polly", false, false)