19248fde5SEugene Zelenko //===- CodeGeneration.cpp - Code generate the Scops using ISL. ---------======// 209d30697STobias Grosser // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609d30697STobias Grosser // 709d30697STobias Grosser //===----------------------------------------------------------------------===// 809d30697STobias Grosser // 909d30697STobias Grosser // The CodeGeneration pass takes a Scop created by ScopInfo and translates it 1009d30697STobias Grosser // back to LLVM-IR using the ISL code generator. 1109d30697STobias Grosser // 12a6d48f59SMichael Kruse // The Scop describes the high level memory behavior of a control flow region. 1309d30697STobias Grosser // Transformation passes can update the schedule (execution order) of statements 1409d30697STobias Grosser // in the Scop. ISL is used to generate an abstract syntax tree that reflects 1509d30697STobias Grosser // the updated execution order. This clast is used to create new LLVM-IR that is 1609d30697STobias Grosser // computationally equivalent to the original control flow region, but executes 1709d30697STobias Grosser // its code in the new execution order defined by the changed schedule. 1809d30697STobias Grosser // 1909d30697STobias Grosser //===----------------------------------------------------------------------===// 2009d30697STobias Grosser 2178ae52f0SPhilip Pfaffe #include "polly/CodeGen/CodeGeneration.h" 229248fde5SEugene Zelenko #include "polly/CodeGen/IRBuilder.h" 2309d30697STobias Grosser #include "polly/CodeGen/IslAst.h" 245624d3c9STobias Grosser #include "polly/CodeGen/IslNodeBuilder.h" 2565371af2STobias Grosser #include "polly/CodeGen/PerfMonitor.h" 2609d30697STobias Grosser #include "polly/CodeGen/Utils.h" 2709d30697STobias Grosser #include "polly/DependenceInfo.h" 2809d30697STobias Grosser #include "polly/LinkAllPasses.h" 2958e58544STobias Grosser #include "polly/Options.h" 309248fde5SEugene Zelenko #include "polly/ScopDetectionDiagnostic.h" 3109d30697STobias Grosser #include "polly/ScopInfo.h" 3209d30697STobias Grosser #include "polly/Support/ScopHelper.h" 339248fde5SEugene Zelenko #include "llvm/ADT/Statistic.h" 3466ef16b2SChandler Carruth #include "llvm/Analysis/AliasAnalysis.h" 3566ef16b2SChandler Carruth #include "llvm/Analysis/BasicAliasAnalysis.h" 3666ef16b2SChandler Carruth #include "llvm/Analysis/GlobalsModRef.h" 3778ae52f0SPhilip Pfaffe #include "llvm/Analysis/LoopInfo.h" 389248fde5SEugene Zelenko #include "llvm/Analysis/RegionInfo.h" 3966ef16b2SChandler Carruth #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 409248fde5SEugene Zelenko #include "llvm/IR/BasicBlock.h" 419248fde5SEugene Zelenko #include "llvm/IR/Dominators.h" 429248fde5SEugene Zelenko #include "llvm/IR/Function.h" 439248fde5SEugene Zelenko #include "llvm/IR/Instruction.h" 449248fde5SEugene Zelenko #include "llvm/IR/IntrinsicInst.h" 459248fde5SEugene Zelenko #include "llvm/IR/Intrinsics.h" 46c2bb0cbeSTobias Grosser #include "llvm/IR/Module.h" 4778ae52f0SPhilip Pfaffe #include "llvm/IR/PassManager.h" 48c2bb0cbeSTobias Grosser #include "llvm/IR/Verifier.h" 499248fde5SEugene Zelenko #include "llvm/Pass.h" 509248fde5SEugene Zelenko #include "llvm/Support/Casting.h" 519248fde5SEugene Zelenko #include "llvm/Support/CommandLine.h" 52c2bb0cbeSTobias Grosser #include "llvm/Support/Debug.h" 539248fde5SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 549248fde5SEugene Zelenko #include "llvm/Support/raw_ostream.h" 559248fde5SEugene Zelenko #include "isl/ast.h" 569248fde5SEugene Zelenko #include <cassert> 579248fde5SEugene Zelenko #include <utility> 5809d30697STobias Grosser 5909d30697STobias Grosser using namespace llvm; 609248fde5SEugene Zelenko using namespace polly; 6109d30697STobias Grosser 6209d30697STobias Grosser #define DEBUG_TYPE "polly-codegen" 6309d30697STobias Grosser 6458e58544STobias Grosser static cl::opt<bool> Verify("polly-codegen-verify", 6558e58544STobias Grosser cl::desc("Verify the function generated by Polly"), 66f1372217STobias Grosser cl::Hidden, cl::init(false), cl::ZeroOrMore, 6758e58544STobias Grosser cl::cat(PollyCategory)); 6858e58544STobias Grosser 697b9f5ca2SSiddharth Bhat bool polly::PerfMonitoring; 709248fde5SEugene Zelenko 717b9f5ca2SSiddharth Bhat static cl::opt<bool, true> 727b9f5ca2SSiddharth Bhat XPerfMonitoring("polly-codegen-perf-monitoring", 7365371af2STobias Grosser cl::desc("Add run-time performance monitoring"), cl::Hidden, 747b9f5ca2SSiddharth Bhat cl::location(polly::PerfMonitoring), cl::init(false), 757b9f5ca2SSiddharth Bhat cl::ZeroOrMore, cl::cat(PollyCategory)); 7665371af2STobias Grosser 7706ed5292SMichael Kruse STATISTIC(ScopsProcessed, "Number of SCoP processed"); 7806ed5292SMichael Kruse STATISTIC(CodegenedScops, "Number of successfully generated SCoPs"); 7906ed5292SMichael Kruse STATISTIC(CodegenedAffineLoops, 8006ed5292SMichael Kruse "Number of original affine loops in SCoPs that have been generated"); 8106ed5292SMichael Kruse STATISTIC(CodegenedBoxedLoops, 8206ed5292SMichael Kruse "Number of original boxed loops in SCoPs that have been generated"); 8306ed5292SMichael Kruse 8471dfb3ebSSiddharth Bhat namespace polly { 859248fde5SEugene Zelenko 8671dfb3ebSSiddharth Bhat /// Mark a basic block unreachable. 8771dfb3ebSSiddharth Bhat /// 8871dfb3ebSSiddharth Bhat /// Marks the basic block @p Block unreachable by equipping it with an 8971dfb3ebSSiddharth Bhat /// UnreachableInst. 9071dfb3ebSSiddharth Bhat void markBlockUnreachable(BasicBlock &Block, PollyIRBuilder &Builder) { 9171dfb3ebSSiddharth Bhat auto *OrigTerminator = Block.getTerminator(); 9271dfb3ebSSiddharth Bhat Builder.SetInsertPoint(OrigTerminator); 9371dfb3ebSSiddharth Bhat Builder.CreateUnreachable(); 9471dfb3ebSSiddharth Bhat OrigTerminator->eraseFromParent(); 9571dfb3ebSSiddharth Bhat } 9671dfb3ebSSiddharth Bhat } // namespace polly 9771dfb3ebSSiddharth Bhat 9878ae52f0SPhilip Pfaffe static void verifyGeneratedFunction(Scop &S, Function &F, IslAstInfo &AI) { 99d439911fSTobias Grosser if (!Verify || !verifyFunction(F, &errs())) 10058e58544STobias Grosser return; 10109d30697STobias Grosser 102349506a9SNicola Zaghen LLVM_DEBUG({ 10309d30697STobias Grosser errs() << "== ISL Codegen created an invalid function ==\n\n== The " 10409d30697STobias Grosser "SCoP ==\n"; 105cd4c977bSMichael Kruse errs() << S; 10609d30697STobias Grosser errs() << "\n== The isl AST ==\n"; 10778ae52f0SPhilip Pfaffe AI.print(errs()); 10809d30697STobias Grosser errs() << "\n== The invalid function ==\n"; 10909d30697STobias Grosser F.print(errs()); 11009d30697STobias Grosser }); 11109d30697STobias Grosser 11258e58544STobias Grosser llvm_unreachable("Polly generated function could not be verified. Add " 11358e58544STobias Grosser "-polly-codegen-verify=false to disable this assertion."); 11409d30697STobias Grosser } 11509d30697STobias Grosser 1169c483c58SMichael Kruse // CodeGeneration adds a lot of BBs without updating the RegionInfo 1179c483c58SMichael Kruse // We make all created BBs belong to the scop's parent region without any 1189c483c58SMichael Kruse // nested structure to keep the RegionInfo verifier happy. 11978ae52f0SPhilip Pfaffe static void fixRegionInfo(Function &F, Region &ParentRegion, RegionInfo &RI) { 12078ae52f0SPhilip Pfaffe for (BasicBlock &BB : F) { 12178ae52f0SPhilip Pfaffe if (RI.getRegionFor(&BB)) 1229c483c58SMichael Kruse continue; 1239c483c58SMichael Kruse 12478ae52f0SPhilip Pfaffe RI.setRegionFor(&BB, &ParentRegion); 1259c483c58SMichael Kruse } 1269c483c58SMichael Kruse } 1279c483c58SMichael Kruse 128895f5d80SMichael Kruse /// Remove all lifetime markers (llvm.lifetime.start, llvm.lifetime.end) from 129895f5d80SMichael Kruse /// @R. 130895f5d80SMichael Kruse /// 131895f5d80SMichael Kruse /// CodeGeneration does not copy lifetime markers into the optimized SCoP, 132895f5d80SMichael Kruse /// which would leave the them only in the original path. This can transform 133895f5d80SMichael Kruse /// code such as 134895f5d80SMichael Kruse /// 135895f5d80SMichael Kruse /// llvm.lifetime.start(%p) 136895f5d80SMichael Kruse /// llvm.lifetime.end(%p) 137895f5d80SMichael Kruse /// 138895f5d80SMichael Kruse /// into 139895f5d80SMichael Kruse /// 140895f5d80SMichael Kruse /// if (RTC) { 141895f5d80SMichael Kruse /// // generated code 142895f5d80SMichael Kruse /// } else { 143895f5d80SMichael Kruse /// // original code 144895f5d80SMichael Kruse /// llvm.lifetime.start(%p) 145895f5d80SMichael Kruse /// } 146895f5d80SMichael Kruse /// llvm.lifetime.end(%p) 147895f5d80SMichael Kruse /// 148895f5d80SMichael Kruse /// The current StackColoring algorithm cannot handle if some, but not all, 149895f5d80SMichael Kruse /// paths from the end marker to the entry block cross the start marker. Same 150895f5d80SMichael Kruse /// for start markers that do not always cross the end markers. We avoid any 151895f5d80SMichael Kruse /// issues by removing all lifetime markers, even from the original code. 152895f5d80SMichael Kruse /// 153895f5d80SMichael Kruse /// A better solution could be to hoist all llvm.lifetime.start to the split 154895f5d80SMichael Kruse /// node and all llvm.lifetime.end to the merge node, which should be 155895f5d80SMichael Kruse /// conservatively correct. 15678ae52f0SPhilip Pfaffe static void removeLifetimeMarkers(Region *R) { 157895f5d80SMichael Kruse for (auto *BB : R->blocks()) { 158895f5d80SMichael Kruse auto InstIt = BB->begin(); 159895f5d80SMichael Kruse auto InstEnd = BB->end(); 160895f5d80SMichael Kruse 161895f5d80SMichael Kruse while (InstIt != InstEnd) { 162895f5d80SMichael Kruse auto NextIt = InstIt; 163895f5d80SMichael Kruse ++NextIt; 164895f5d80SMichael Kruse 165895f5d80SMichael Kruse if (auto *IT = dyn_cast<IntrinsicInst>(&*InstIt)) { 166895f5d80SMichael Kruse switch (IT->getIntrinsicID()) { 1679248fde5SEugene Zelenko case Intrinsic::lifetime_start: 1689248fde5SEugene Zelenko case Intrinsic::lifetime_end: 169895f5d80SMichael Kruse BB->getInstList().erase(InstIt); 170895f5d80SMichael Kruse break; 171895f5d80SMichael Kruse default: 172895f5d80SMichael Kruse break; 173895f5d80SMichael Kruse } 174895f5d80SMichael Kruse } 175895f5d80SMichael Kruse 176895f5d80SMichael Kruse InstIt = NextIt; 177895f5d80SMichael Kruse } 178895f5d80SMichael Kruse } 179895f5d80SMichael Kruse } 180895f5d80SMichael Kruse 18178ae52f0SPhilip Pfaffe static bool CodeGen(Scop &S, IslAstInfo &AI, LoopInfo &LI, DominatorTree &DT, 18278ae52f0SPhilip Pfaffe ScalarEvolution &SE, RegionInfo &RI) { 1830e370cf1SMichael Kruse // Check whether IslAstInfo uses the same isl_ctx. Since -polly-codegen 1840e370cf1SMichael Kruse // reports itself to preserve DependenceInfo and IslAstInfo, we might get 1850e370cf1SMichael Kruse // those analysis that were computed by a different ScopInfo for a different 1860e370cf1SMichael Kruse // Scop structure. When the ScopInfo/Scop object is freed, there is a high 1870e370cf1SMichael Kruse // probability that the new ScopInfo/Scop object will be created at the same 1880e370cf1SMichael Kruse // heap position with the same address. Comparing whether the Scop or ScopInfo 1890e370cf1SMichael Kruse // address is the expected therefore is unreliable. 1900e370cf1SMichael Kruse // Instead, we compare the address of the isl_ctx object. Both, DependenceInfo 1910e370cf1SMichael Kruse // and IslAstInfo must hold a reference to the isl_ctx object to ensure it is 1920e370cf1SMichael Kruse // not freed before the destruction of those analyses which might happen after 1930e370cf1SMichael Kruse // the destruction of the Scop/ScopInfo they refer to. Hence, the isl_ctx 1940e370cf1SMichael Kruse // will not be freed and its space not reused as long there is a 1950e370cf1SMichael Kruse // DependenceInfo or IslAstInfo around. 1960e370cf1SMichael Kruse IslAst &Ast = AI.getIslAst(); 1970e370cf1SMichael Kruse if (Ast.getSharedIslCtx() != S.getSharedIslCtx()) { 198349506a9SNicola Zaghen LLVM_DEBUG(dbgs() << "Got an IstAst for a different Scop/isl_ctx\n"); 1990e370cf1SMichael Kruse return false; 2000e370cf1SMichael Kruse } 2010e370cf1SMichael Kruse 20209d30697STobias Grosser // Check if we created an isl_ast root node, otherwise exit. 2030e370cf1SMichael Kruse isl_ast_node *AstRoot = Ast.getAst(); 20409d30697STobias Grosser if (!AstRoot) 20509d30697STobias Grosser return false; 20609d30697STobias Grosser 20706ed5292SMichael Kruse // Collect statistics. Do it before we modify the IR to avoid having it any 20806ed5292SMichael Kruse // influence on the result. 20906ed5292SMichael Kruse auto ScopStats = S.getStatistics(); 21006ed5292SMichael Kruse ScopsProcessed++; 21106ed5292SMichael Kruse 21278ae52f0SPhilip Pfaffe auto &DL = S.getFunction().getParent()->getDataLayout(); 21322370884SMichael Kruse Region *R = &S.getRegion(); 21422370884SMichael Kruse assert(!R->isTopLevelRegion() && "Top level regions are not supported"); 21509d30697STobias Grosser 216d78616f9STobias Grosser ScopAnnotator Annotator; 21709d30697STobias Grosser 21878ae52f0SPhilip Pfaffe simplifyRegion(R, &DT, &LI, &RI); 21922370884SMichael Kruse assert(R->isSimple()); 220ef74443cSJohannes Doerfert BasicBlock *EnteringBB = S.getEnteringBlock(); 22122370884SMichael Kruse assert(EnteringBB); 22209d30697STobias Grosser PollyIRBuilder Builder = createPollyIRBuilder(EnteringBB, Annotator); 22309d30697STobias Grosser 22409d30697STobias Grosser // Only build the run-time condition and parameters _after_ having 22509d30697STobias Grosser // introduced the conditional branch. This is important as the conditional 22609d30697STobias Grosser // branch will guard the original scop from new induction variables that 22709d30697STobias Grosser // the SCEVExpander may introduce while code generating the parameters and 22809d30697STobias Grosser // which may introduce scalar dependences that prevent us from correctly 22909d30697STobias Grosser // code generating this scop. 230256070d8SAndreas Simbuerger BBPair StartExitBlocks = 23103346c27SSiddharth Bhat std::get<0>(executeScopConditionally(S, Builder.getTrue(), DT, RI, LI)); 232256070d8SAndreas Simbuerger BasicBlock *StartBlock = std::get<0>(StartExitBlocks); 233dbb0ef8eSAndreas Simbuerger BasicBlock *ExitBlock = std::get<1>(StartExitBlocks); 234256070d8SAndreas Simbuerger 235895f5d80SMichael Kruse removeLifetimeMarkers(R); 236bfb6a968STobias Grosser auto *SplitBlock = StartBlock->getSinglePredecessor(); 23709e3697fSJohannes Doerfert 23878ae52f0SPhilip Pfaffe IslNodeBuilder NodeBuilder(Builder, Annotator, DL, LI, SE, DT, S, StartBlock); 239acf80064SEli Friedman 240214deb79SMichael Kruse // All arrays must have their base pointers known before 241214deb79SMichael Kruse // ScopAnnotator::buildAliasScopes. 242b738ffa8SMichael Kruse NodeBuilder.allocateNewArrays(StartExitBlocks); 243214deb79SMichael Kruse Annotator.buildAliasScopes(S); 244214deb79SMichael Kruse 24565371af2STobias Grosser if (PerfMonitoring) { 24607bee290SSiddharth Bhat PerfMonitor P(S, EnteringBB->getParent()->getParent()); 24765371af2STobias Grosser P.initialize(); 24865371af2STobias Grosser P.insertRegionStart(SplitBlock->getTerminator()); 24965371af2STobias Grosser 250dbb0ef8eSAndreas Simbuerger BasicBlock *MergeBlock = ExitBlock->getUniqueSuccessor(); 25165371af2STobias Grosser P.insertRegionEnd(MergeBlock->getTerminator()); 25265371af2STobias Grosser } 25365371af2STobias Grosser 25409e3697fSJohannes Doerfert // First generate code for the hoisted invariant loads and transitively the 25509e3697fSJohannes Doerfert // parameters they reference. Afterwards, for the remaining parameters that 25609e3697fSJohannes Doerfert // might reference the hoisted loads. Finally, build the runtime check 25709e3697fSJohannes Doerfert // that might reference both hoisted loads as well as parameters. 258c4898504SJohannes Doerfert // If the hoisting fails we have to bail and execute the original code. 25909d30697STobias Grosser Builder.SetInsertPoint(SplitBlock->getTerminator()); 260c4898504SJohannes Doerfert if (!NodeBuilder.preloadInvariantLoads()) { 261bfb6a968STobias Grosser // Patch the introduced branch condition to ensure that we always execute 262bfb6a968STobias Grosser // the original SCoP. 263c4898504SJohannes Doerfert auto *FalseI1 = Builder.getFalse(); 26437977076SJohannes Doerfert auto *SplitBBTerm = Builder.GetInsertBlock()->getTerminator(); 26537977076SJohannes Doerfert SplitBBTerm->setOperand(0, FalseI1); 2661dd6e37aSJohannes Doerfert 267bfb6a968STobias Grosser // Since the other branch is hence ignored we mark it as unreachable and 268bfb6a968STobias Grosser // adjust the dominator tree accordingly. 269bfb6a968STobias Grosser auto *ExitingBlock = StartBlock->getUniqueSuccessor(); 270bfb6a968STobias Grosser assert(ExitingBlock); 271bfb6a968STobias Grosser auto *MergeBlock = ExitingBlock->getUniqueSuccessor(); 272bfb6a968STobias Grosser assert(MergeBlock); 273bfb6a968STobias Grosser markBlockUnreachable(*StartBlock, Builder); 274bfb6a968STobias Grosser markBlockUnreachable(*ExitingBlock, Builder); 275ef74443cSJohannes Doerfert auto *ExitingBB = S.getExitingBlock(); 276bfb6a968STobias Grosser assert(ExitingBB); 27778ae52f0SPhilip Pfaffe DT.changeImmediateDominator(MergeBlock, ExitingBB); 27878ae52f0SPhilip Pfaffe DT.eraseNode(ExitingBlock); 279bfb6a968STobias Grosser 280bfb6a968STobias Grosser isl_ast_node_free(AstRoot); 2811dd6e37aSJohannes Doerfert } else { 2828ea1fc19STobias Grosser NodeBuilder.addParameters(S.getContext().release()); 28378ae52f0SPhilip Pfaffe Value *RTC = NodeBuilder.createRTC(AI.getRunCondition()); 284404a0f81SJohannes Doerfert 2853717aa5dSTobias Grosser Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC); 286b738ffa8SMichael Kruse 287b738ffa8SMichael Kruse // Explicitly set the insert point to the end of the block to avoid that a 288b738ffa8SMichael Kruse // split at the builder's current 289b738ffa8SMichael Kruse // insert position would move the malloc calls to the wrong BasicBlock. 290b738ffa8SMichael Kruse // Ideally we would just split the block during allocation of the new 291b738ffa8SMichael Kruse // arrays, but this would break the assumption that there are no blocks 292b738ffa8SMichael Kruse // between polly.start and polly.exiting (at this point). 293b738ffa8SMichael Kruse Builder.SetInsertPoint(StartBlock->getTerminator()); 2943717aa5dSTobias Grosser 2953717aa5dSTobias Grosser NodeBuilder.create(AstRoot); 2968ed5e599STobias Grosser NodeBuilder.finalize(); 29778ae52f0SPhilip Pfaffe fixRegionInfo(*EnteringBB->getParent(), *R->getParent(), RI); 29806ed5292SMichael Kruse 29906ed5292SMichael Kruse CodegenedScops++; 30006ed5292SMichael Kruse CodegenedAffineLoops += ScopStats.NumAffineLoops; 30106ed5292SMichael Kruse CodegenedBoxedLoops += ScopStats.NumBoxedLoops; 3021dd6e37aSJohannes Doerfert } 303ecff11dcSJohannes Doerfert 3046a6a671cSJohannes Doerfert Function *F = EnteringBB->getParent(); 30578ae52f0SPhilip Pfaffe verifyGeneratedFunction(S, *F, AI); 306a9dc5294SJohannes Doerfert for (auto *SubF : NodeBuilder.getParallelSubfunctions()) 30778ae52f0SPhilip Pfaffe verifyGeneratedFunction(S, *SubF, AI); 308652f7808STobias Grosser 3094c86a1d9SMichael Kruse // Mark the function such that we run additional cleanup passes on this 3104c86a1d9SMichael Kruse // function (e.g. mem2reg to rediscover phi nodes). 3114c86a1d9SMichael Kruse F->addFnAttr("polly-optimized"); 31209d30697STobias Grosser return true; 31309d30697STobias Grosser } 31409d30697STobias Grosser 3159248fde5SEugene Zelenko namespace { 3169248fde5SEugene Zelenko 31778ae52f0SPhilip Pfaffe class CodeGeneration : public ScopPass { 31878ae52f0SPhilip Pfaffe public: 31978ae52f0SPhilip Pfaffe static char ID; 32078ae52f0SPhilip Pfaffe 321a6d48f59SMichael Kruse /// The data layout used. 32278ae52f0SPhilip Pfaffe const DataLayout *DL; 32378ae52f0SPhilip Pfaffe 32478ae52f0SPhilip Pfaffe /// @name The analysis passes we need to generate code. 32578ae52f0SPhilip Pfaffe /// 32678ae52f0SPhilip Pfaffe ///{ 32778ae52f0SPhilip Pfaffe LoopInfo *LI; 32878ae52f0SPhilip Pfaffe IslAstInfo *AI; 32978ae52f0SPhilip Pfaffe DominatorTree *DT; 33078ae52f0SPhilip Pfaffe ScalarEvolution *SE; 33178ae52f0SPhilip Pfaffe RegionInfo *RI; 33278ae52f0SPhilip Pfaffe ///} 33378ae52f0SPhilip Pfaffe 3349248fde5SEugene Zelenko CodeGeneration() : ScopPass(ID) {} 3359248fde5SEugene Zelenko 33678ae52f0SPhilip Pfaffe /// Generate LLVM-IR for the SCoP @p S. 33778ae52f0SPhilip Pfaffe bool runOnScop(Scop &S) override { 33802ca346eSSingapuram Sanjay Srivallabh // Skip SCoPs in case they're already code-generated by PPCGCodeGeneration. 33902ca346eSSingapuram Sanjay Srivallabh if (S.isToBeSkipped()) 34002ca346eSSingapuram Sanjay Srivallabh return false; 34102ca346eSSingapuram Sanjay Srivallabh 34278ae52f0SPhilip Pfaffe AI = &getAnalysis<IslAstInfoWrapperPass>().getAI(); 34378ae52f0SPhilip Pfaffe LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 34478ae52f0SPhilip Pfaffe DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 34578ae52f0SPhilip Pfaffe SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 34678ae52f0SPhilip Pfaffe DL = &S.getFunction().getParent()->getDataLayout(); 34778ae52f0SPhilip Pfaffe RI = &getAnalysis<RegionInfoPass>().getRegionInfo(); 34878ae52f0SPhilip Pfaffe return CodeGen(S, *AI, *LI, *DT, *SE, *RI); 34978ae52f0SPhilip Pfaffe } 35078ae52f0SPhilip Pfaffe 351c80d6979STobias Grosser /// Register all analyses and transformation required. 35209d30697STobias Grosser void getAnalysisUsage(AnalysisUsage &AU) const override { 353a4f447c2SMichael Kruse ScopPass::getAnalysisUsage(AU); 354a4f447c2SMichael Kruse 35509d30697STobias Grosser AU.addRequired<DominatorTreeWrapperPass>(); 3562b852e2eSPhilip Pfaffe AU.addRequired<IslAstInfoWrapperPass>(); 35709d30697STobias Grosser AU.addRequired<RegionInfoPass>(); 358c5bcf246STobias Grosser AU.addRequired<ScalarEvolutionWrapperPass>(); 3595cc87e3aSPhilip Pfaffe AU.addRequired<ScopDetectionWrapperPass>(); 36099191c78SJohannes Doerfert AU.addRequired<ScopInfoRegionPass>(); 36109d30697STobias Grosser AU.addRequired<LoopInfoWrapperPass>(); 36209d30697STobias Grosser 36309d30697STobias Grosser AU.addPreserved<DependenceInfo>(); 3642b852e2eSPhilip Pfaffe AU.addPreserved<IslAstInfoWrapperPass>(); 36509d30697STobias Grosser 36609d30697STobias Grosser // FIXME: We do not yet add regions for the newly generated code to the 36709d30697STobias Grosser // region tree. 36809d30697STobias Grosser } 36909d30697STobias Grosser }; 370522478d2STobias Grosser } // namespace 37109d30697STobias Grosser 3729248fde5SEugene Zelenko PreservedAnalyses CodeGenerationPass::run(Scop &S, ScopAnalysisManager &SAM, 3739248fde5SEugene Zelenko ScopStandardAnalysisResults &AR, 3749248fde5SEugene Zelenko SPMUpdater &U) { 37578ae52f0SPhilip Pfaffe auto &AI = SAM.getResult<IslAstAnalysis>(S, AR); 376f43e7c2eSPhilip Pfaffe if (CodeGen(S, AI, AR.LI, AR.DT, AR.SE, AR.RI)) { 377f43e7c2eSPhilip Pfaffe U.invalidateScop(S); 37878ae52f0SPhilip Pfaffe return PreservedAnalyses::none(); 379f43e7c2eSPhilip Pfaffe } 38078ae52f0SPhilip Pfaffe 38178ae52f0SPhilip Pfaffe return PreservedAnalyses::all(); 38278ae52f0SPhilip Pfaffe } 38378ae52f0SPhilip Pfaffe 38409d30697STobias Grosser char CodeGeneration::ID = 1; 38509d30697STobias Grosser 38609d30697STobias Grosser Pass *polly::createCodeGenerationPass() { return new CodeGeneration(); } 38709d30697STobias Grosser 38809d30697STobias Grosser INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen", 38909d30697STobias Grosser "Polly - Create LLVM-IR from SCoPs", false, false); 39009d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(DependenceInfo); 39109d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); 39209d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); 39309d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); 394c5bcf246STobias Grosser INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); 3955cc87e3aSPhilip Pfaffe INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass); 39609d30697STobias Grosser INITIALIZE_PASS_END(CodeGeneration, "polly-codegen", 39709d30697STobias Grosser "Polly - Create LLVM-IR from SCoPs", false, false) 398