1*09d30697STobias Grosser //===------ CodeGeneration.cpp - Code generate the Scops using ISL. ----======// 2*09d30697STobias Grosser // 3*09d30697STobias Grosser // The LLVM Compiler Infrastructure 4*09d30697STobias Grosser // 5*09d30697STobias Grosser // This file is distributed under the University of Illinois Open Source 6*09d30697STobias Grosser // License. See LICENSE.TXT for details. 7*09d30697STobias Grosser // 8*09d30697STobias Grosser //===----------------------------------------------------------------------===// 9*09d30697STobias Grosser // 10*09d30697STobias Grosser // The CodeGeneration pass takes a Scop created by ScopInfo and translates it 11*09d30697STobias Grosser // back to LLVM-IR using the ISL code generator. 12*09d30697STobias Grosser // 13*09d30697STobias Grosser // The Scop describes the high level memory behaviour of a control flow region. 14*09d30697STobias Grosser // Transformation passes can update the schedule (execution order) of statements 15*09d30697STobias Grosser // in the Scop. ISL is used to generate an abstract syntax tree that reflects 16*09d30697STobias Grosser // the updated execution order. This clast is used to create new LLVM-IR that is 17*09d30697STobias Grosser // computationally equivalent to the original control flow region, but executes 18*09d30697STobias Grosser // its code in the new execution order defined by the changed schedule. 19*09d30697STobias Grosser // 20*09d30697STobias Grosser //===----------------------------------------------------------------------===// 21*09d30697STobias Grosser 22*09d30697STobias Grosser #include "polly/CodeGen/IslNodeBuilder.h" 23*09d30697STobias Grosser #include "polly/CodeGen/IslAst.h" 24*09d30697STobias Grosser #include "polly/CodeGen/Utils.h" 25*09d30697STobias Grosser #include "polly/DependenceInfo.h" 26*09d30697STobias Grosser #include "polly/LinkAllPasses.h" 27*09d30697STobias Grosser #include "polly/ScopInfo.h" 28*09d30697STobias Grosser #include "polly/Support/ScopHelper.h" 29*09d30697STobias Grosser #include "polly/TempScopInfo.h" 30*09d30697STobias Grosser #include "llvm/IR/Module.h" 31*09d30697STobias Grosser #include "llvm/IR/Verifier.h" 32*09d30697STobias Grosser #include "llvm/Support/Debug.h" 33*09d30697STobias Grosser 34*09d30697STobias Grosser using namespace polly; 35*09d30697STobias Grosser using namespace llvm; 36*09d30697STobias Grosser 37*09d30697STobias Grosser #define DEBUG_TYPE "polly-codegen" 38*09d30697STobias Grosser 39*09d30697STobias Grosser namespace { 40*09d30697STobias Grosser class CodeGeneration : public ScopPass { 41*09d30697STobias Grosser public: 42*09d30697STobias Grosser static char ID; 43*09d30697STobias Grosser 44*09d30697STobias Grosser CodeGeneration() : ScopPass(ID) {} 45*09d30697STobias Grosser 46*09d30697STobias Grosser /// @brief The datalayout used 47*09d30697STobias Grosser const DataLayout *DL; 48*09d30697STobias Grosser 49*09d30697STobias Grosser /// @name The analysis passes we need to generate code. 50*09d30697STobias Grosser /// 51*09d30697STobias Grosser ///{ 52*09d30697STobias Grosser LoopInfo *LI; 53*09d30697STobias Grosser IslAstInfo *AI; 54*09d30697STobias Grosser DominatorTree *DT; 55*09d30697STobias Grosser ScalarEvolution *SE; 56*09d30697STobias Grosser ///} 57*09d30697STobias Grosser 58*09d30697STobias Grosser /// @brief The loop annotator to generate llvm.loop metadata. 59*09d30697STobias Grosser ScopAnnotator Annotator; 60*09d30697STobias Grosser 61*09d30697STobias Grosser /// @brief Build the runtime condition. 62*09d30697STobias Grosser /// 63*09d30697STobias Grosser /// Build the condition that evaluates at run-time to true iff all 64*09d30697STobias Grosser /// assumptions taken for the SCoP hold, and to false otherwise. 65*09d30697STobias Grosser /// 66*09d30697STobias Grosser /// @return A value evaluating to true/false if execution is save/unsafe. 67*09d30697STobias Grosser Value *buildRTC(PollyIRBuilder &Builder, IslExprBuilder &ExprBuilder) { 68*09d30697STobias Grosser Builder.SetInsertPoint(Builder.GetInsertBlock()->getTerminator()); 69*09d30697STobias Grosser Value *RTC = ExprBuilder.create(AI->getRunCondition()); 70*09d30697STobias Grosser if (!RTC->getType()->isIntegerTy(1)) 71*09d30697STobias Grosser RTC = Builder.CreateIsNotNull(RTC); 72*09d30697STobias Grosser return RTC; 73*09d30697STobias Grosser } 74*09d30697STobias Grosser 75*09d30697STobias Grosser bool verifyGeneratedFunction(Scop &S, Function &F) { 76*09d30697STobias Grosser if (!verifyFunction(F)) 77*09d30697STobias Grosser return false; 78*09d30697STobias Grosser 79*09d30697STobias Grosser DEBUG({ 80*09d30697STobias Grosser errs() << "== ISL Codegen created an invalid function ==\n\n== The " 81*09d30697STobias Grosser "SCoP ==\n"; 82*09d30697STobias Grosser S.print(errs()); 83*09d30697STobias Grosser errs() << "\n== The isl AST ==\n"; 84*09d30697STobias Grosser AI->printScop(errs(), S); 85*09d30697STobias Grosser errs() << "\n== The invalid function ==\n"; 86*09d30697STobias Grosser F.print(errs()); 87*09d30697STobias Grosser errs() << "\n== The errors ==\n"; 88*09d30697STobias Grosser verifyFunction(F, &errs()); 89*09d30697STobias Grosser }); 90*09d30697STobias Grosser 91*09d30697STobias Grosser return true; 92*09d30697STobias Grosser } 93*09d30697STobias Grosser 94*09d30697STobias Grosser bool runOnScop(Scop &S) override { 95*09d30697STobias Grosser AI = &getAnalysis<IslAstInfo>(); 96*09d30697STobias Grosser 97*09d30697STobias Grosser // Check if we created an isl_ast root node, otherwise exit. 98*09d30697STobias Grosser isl_ast_node *AstRoot = AI->getAst(); 99*09d30697STobias Grosser if (!AstRoot) 100*09d30697STobias Grosser return false; 101*09d30697STobias Grosser 102*09d30697STobias Grosser LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 103*09d30697STobias Grosser DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 104*09d30697STobias Grosser SE = &getAnalysis<ScalarEvolution>(); 105*09d30697STobias Grosser DL = &S.getRegion().getEntry()->getParent()->getParent()->getDataLayout(); 106*09d30697STobias Grosser 107*09d30697STobias Grosser assert(!S.getRegion().isTopLevelRegion() && 108*09d30697STobias Grosser "Top level regions are not supported"); 109*09d30697STobias Grosser 110*09d30697STobias Grosser Annotator.buildAliasScopes(S); 111*09d30697STobias Grosser 112*09d30697STobias Grosser BasicBlock *EnteringBB = simplifyRegion(&S, this); 113*09d30697STobias Grosser PollyIRBuilder Builder = createPollyIRBuilder(EnteringBB, Annotator); 114*09d30697STobias Grosser 115*09d30697STobias Grosser IslNodeBuilder NodeBuilder(Builder, Annotator, this, *DL, *LI, *SE, *DT, S); 116*09d30697STobias Grosser 117*09d30697STobias Grosser // Only build the run-time condition and parameters _after_ having 118*09d30697STobias Grosser // introduced the conditional branch. This is important as the conditional 119*09d30697STobias Grosser // branch will guard the original scop from new induction variables that 120*09d30697STobias Grosser // the SCEVExpander may introduce while code generating the parameters and 121*09d30697STobias Grosser // which may introduce scalar dependences that prevent us from correctly 122*09d30697STobias Grosser // code generating this scop. 123*09d30697STobias Grosser BasicBlock *StartBlock = 124*09d30697STobias Grosser executeScopConditionally(S, this, Builder.getTrue()); 125*09d30697STobias Grosser auto SplitBlock = StartBlock->getSinglePredecessor(); 126*09d30697STobias Grosser Builder.SetInsertPoint(SplitBlock->getTerminator()); 127*09d30697STobias Grosser NodeBuilder.addParameters(S.getContext()); 128*09d30697STobias Grosser Value *RTC = buildRTC(Builder, NodeBuilder.getExprBuilder()); 129*09d30697STobias Grosser SplitBlock->getTerminator()->setOperand(0, RTC); 130*09d30697STobias Grosser Builder.SetInsertPoint(StartBlock->begin()); 131*09d30697STobias Grosser 132*09d30697STobias Grosser NodeBuilder.create(AstRoot); 133*09d30697STobias Grosser 134*09d30697STobias Grosser assert(!verifyGeneratedFunction(S, *EnteringBB->getParent()) && 135*09d30697STobias Grosser "Verification of generated function failed"); 136*09d30697STobias Grosser return true; 137*09d30697STobias Grosser } 138*09d30697STobias Grosser 139*09d30697STobias Grosser void printScop(raw_ostream &, Scop &) const override {} 140*09d30697STobias Grosser 141*09d30697STobias Grosser void getAnalysisUsage(AnalysisUsage &AU) const override { 142*09d30697STobias Grosser AU.addRequired<DominatorTreeWrapperPass>(); 143*09d30697STobias Grosser AU.addRequired<IslAstInfo>(); 144*09d30697STobias Grosser AU.addRequired<RegionInfoPass>(); 145*09d30697STobias Grosser AU.addRequired<ScalarEvolution>(); 146*09d30697STobias Grosser AU.addRequired<ScopDetection>(); 147*09d30697STobias Grosser AU.addRequired<ScopInfo>(); 148*09d30697STobias Grosser AU.addRequired<LoopInfoWrapperPass>(); 149*09d30697STobias Grosser 150*09d30697STobias Grosser AU.addPreserved<DependenceInfo>(); 151*09d30697STobias Grosser 152*09d30697STobias Grosser AU.addPreserved<LoopInfoWrapperPass>(); 153*09d30697STobias Grosser AU.addPreserved<DominatorTreeWrapperPass>(); 154*09d30697STobias Grosser AU.addPreserved<IslAstInfo>(); 155*09d30697STobias Grosser AU.addPreserved<ScopDetection>(); 156*09d30697STobias Grosser AU.addPreserved<ScalarEvolution>(); 157*09d30697STobias Grosser 158*09d30697STobias Grosser // FIXME: We do not yet add regions for the newly generated code to the 159*09d30697STobias Grosser // region tree. 160*09d30697STobias Grosser AU.addPreserved<RegionInfoPass>(); 161*09d30697STobias Grosser AU.addPreserved<TempScopInfo>(); 162*09d30697STobias Grosser AU.addPreserved<ScopInfo>(); 163*09d30697STobias Grosser AU.addPreservedID(IndependentBlocksID); 164*09d30697STobias Grosser } 165*09d30697STobias Grosser }; 166*09d30697STobias Grosser } 167*09d30697STobias Grosser 168*09d30697STobias Grosser char CodeGeneration::ID = 1; 169*09d30697STobias Grosser 170*09d30697STobias Grosser Pass *polly::createCodeGenerationPass() { return new CodeGeneration(); } 171*09d30697STobias Grosser 172*09d30697STobias Grosser INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen", 173*09d30697STobias Grosser "Polly - Create LLVM-IR from SCoPs", false, false); 174*09d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(DependenceInfo); 175*09d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); 176*09d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); 177*09d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); 178*09d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(ScalarEvolution); 179*09d30697STobias Grosser INITIALIZE_PASS_DEPENDENCY(ScopDetection); 180*09d30697STobias Grosser INITIALIZE_PASS_END(CodeGeneration, "polly-codegen", 181*09d30697STobias Grosser "Polly - Create LLVM-IR from SCoPs", false, false) 182