1 //===------ CodeGeneration.cpp - Code generate the Scops. -----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // The CodeGeneration pass takes a Scop created by ScopInfo and translates it 11 // back to LLVM-IR using Cloog. 12 // 13 // The Scop describes the high level memory behaviour of a control flow region. 14 // Transformation passes can update the schedule (execution order) of statements 15 // in the Scop. Cloog is used to generate an abstract syntax tree (clast) that 16 // reflects the updated execution order. This clast is used to create new 17 // LLVM-IR that is computational equivalent to the original control flow region, 18 // but executes its code in the new execution order defined by the changed 19 // scattering. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #include "polly/CodeGen/Cloog.h" 24 #ifdef CLOOG_FOUND 25 26 #define DEBUG_TYPE "polly-codegen" 27 #include "polly/Dependences.h" 28 #include "polly/LinkAllPasses.h" 29 #include "polly/ScopInfo.h" 30 #include "polly/TempScopInfo.h" 31 #include "polly/CodeGen/CodeGeneration.h" 32 #include "polly/CodeGen/BlockGenerators.h" 33 #include "polly/CodeGen/LoopGenerators.h" 34 #include "polly/CodeGen/Utils.h" 35 #include "polly/Support/GICHelper.h" 36 37 #include "llvm/Module.h" 38 #include "llvm/ADT/SetVector.h" 39 #include "llvm/ADT/PostOrderIterator.h" 40 #include "llvm/Analysis/LoopInfo.h" 41 #include "llvm/Analysis/ScalarEvolutionExpander.h" 42 #include "llvm/Support/CommandLine.h" 43 #include "llvm/Support/Debug.h" 44 #include "llvm/Target/TargetData.h" 45 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 46 47 #define CLOOG_INT_GMP 1 48 #include "cloog/cloog.h" 49 #include "cloog/isl/cloog.h" 50 51 #include "isl/aff.h" 52 53 #include <vector> 54 #include <utility> 55 56 using namespace polly; 57 using namespace llvm; 58 59 struct isl_set; 60 61 namespace polly { 62 static cl::opt<bool> 63 OpenMP("enable-polly-openmp", 64 cl::desc("Generate OpenMP parallel code"), cl::Hidden, 65 cl::value_desc("OpenMP code generation enabled if true"), 66 cl::init(false), cl::ZeroOrMore); 67 68 static cl::opt<bool> 69 AtLeastOnce("enable-polly-atLeastOnce", 70 cl::desc("Give polly the hint, that every loop is executed at least" 71 "once"), cl::Hidden, 72 cl::value_desc("OpenMP code generation enabled if true"), 73 cl::init(false), cl::ZeroOrMore); 74 75 typedef DenseMap<const char*, Value*> CharMapT; 76 77 /// Class to generate LLVM-IR that calculates the value of a clast_expr. 78 class ClastExpCodeGen { 79 IRBuilder<> &Builder; 80 const CharMapT &IVS; 81 82 Value *codegen(const clast_name *e, Type *Ty); 83 Value *codegen(const clast_term *e, Type *Ty); 84 Value *codegen(const clast_binary *e, Type *Ty); 85 Value *codegen(const clast_reduction *r, Type *Ty); 86 public: 87 88 // A generator for clast expressions. 89 // 90 // @param B The IRBuilder that defines where the code to calculate the 91 // clast expressions should be inserted. 92 // @param IVMAP A Map that translates strings describing the induction 93 // variables to the Values* that represent these variables 94 // on the LLVM side. 95 ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap); 96 97 // Generates code to calculate a given clast expression. 98 // 99 // @param e The expression to calculate. 100 // @return The Value that holds the result. 101 Value *codegen(const clast_expr *e, Type *Ty); 102 }; 103 104 Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) { 105 CharMapT::const_iterator I = IVS.find(e->name); 106 107 assert(I != IVS.end() && "Clast name not found"); 108 109 return Builder.CreateSExtOrBitCast(I->second, Ty); 110 } 111 112 Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) { 113 APInt a = APInt_from_MPZ(e->val); 114 115 Value *ConstOne = ConstantInt::get(Builder.getContext(), a); 116 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty); 117 118 if (!e->var) 119 return ConstOne; 120 121 Value *var = codegen(e->var, Ty); 122 return Builder.CreateMul(ConstOne, var); 123 } 124 125 Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) { 126 Value *LHS = codegen(e->LHS, Ty); 127 128 APInt RHS_AP = APInt_from_MPZ(e->RHS); 129 130 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP); 131 RHS = Builder.CreateSExtOrBitCast(RHS, Ty); 132 133 switch (e->type) { 134 case clast_bin_mod: 135 return Builder.CreateSRem(LHS, RHS); 136 case clast_bin_fdiv: 137 { 138 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d 139 Value *One = ConstantInt::get(Ty, 1); 140 Value *Zero = ConstantInt::get(Ty, 0); 141 Value *Sum1 = Builder.CreateSub(LHS, RHS); 142 Value *Sum2 = Builder.CreateAdd(Sum1, One); 143 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero); 144 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS); 145 return Builder.CreateSDiv(Dividend, RHS); 146 } 147 case clast_bin_cdiv: 148 { 149 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d 150 Value *One = ConstantInt::get(Ty, 1); 151 Value *Zero = ConstantInt::get(Ty, 0); 152 Value *Sum1 = Builder.CreateAdd(LHS, RHS); 153 Value *Sum2 = Builder.CreateSub(Sum1, One); 154 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero); 155 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2); 156 return Builder.CreateSDiv(Dividend, RHS); 157 } 158 case clast_bin_div: 159 return Builder.CreateSDiv(LHS, RHS); 160 }; 161 162 llvm_unreachable("Unknown clast binary expression type"); 163 } 164 165 Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) { 166 assert(( r->type == clast_red_min 167 || r->type == clast_red_max 168 || r->type == clast_red_sum) 169 && "Clast reduction type not supported"); 170 Value *old = codegen(r->elts[0], Ty); 171 172 for (int i=1; i < r->n; ++i) { 173 Value *exprValue = codegen(r->elts[i], Ty); 174 175 switch (r->type) { 176 case clast_red_min: 177 { 178 Value *cmp = Builder.CreateICmpSLT(old, exprValue); 179 old = Builder.CreateSelect(cmp, old, exprValue); 180 break; 181 } 182 case clast_red_max: 183 { 184 Value *cmp = Builder.CreateICmpSGT(old, exprValue); 185 old = Builder.CreateSelect(cmp, old, exprValue); 186 break; 187 } 188 case clast_red_sum: 189 old = Builder.CreateAdd(old, exprValue); 190 break; 191 } 192 } 193 194 return old; 195 } 196 197 ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap) 198 : Builder(B), IVS(IVMap) {} 199 200 Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) { 201 switch(e->type) { 202 case clast_expr_name: 203 return codegen((const clast_name *)e, Ty); 204 case clast_expr_term: 205 return codegen((const clast_term *)e, Ty); 206 case clast_expr_bin: 207 return codegen((const clast_binary *)e, Ty); 208 case clast_expr_red: 209 return codegen((const clast_reduction *)e, Ty); 210 } 211 212 llvm_unreachable("Unknown clast expression!"); 213 } 214 215 class ClastStmtCodeGen { 216 public: 217 const std::vector<std::string> &getParallelLoops(); 218 219 private: 220 // The Scop we code generate. 221 Scop *S; 222 Pass *P; 223 224 // The Builder specifies the current location to code generate at. 225 IRBuilder<> &Builder; 226 227 // Map the Values from the old code to their counterparts in the new code. 228 ValueMapT ValueMap; 229 230 // clastVars maps from the textual representation of a clast variable to its 231 // current *Value. clast variables are scheduling variables, original 232 // induction variables or parameters. They are used either in loop bounds or 233 // to define the statement instance that is executed. 234 // 235 // for (s = 0; s < n + 3; ++i) 236 // for (t = s; t < m; ++j) 237 // Stmt(i = s + 3 * m, j = t); 238 // 239 // {s,t,i,j,n,m} is the set of clast variables in this clast. 240 CharMapT ClastVars; 241 242 // Codegenerator for clast expressions. 243 ClastExpCodeGen ExpGen; 244 245 // Do we currently generate parallel code? 246 bool parallelCodeGeneration; 247 248 std::vector<std::string> parallelLoops; 249 250 void codegen(const clast_assignment *a); 251 252 void codegen(const clast_assignment *a, ScopStmt *Statement, 253 unsigned Dimension, int vectorDim, 254 std::vector<ValueMapT> *VectorVMap = 0); 255 256 void codegenSubstitutions(const clast_stmt *Assignment, 257 ScopStmt *Statement, int vectorDim = 0, 258 std::vector<ValueMapT> *VectorVMap = 0); 259 260 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL, 261 const char *iterator = NULL, isl_set *scatteringDomain = 0); 262 263 void codegen(const clast_block *b); 264 265 /// @brief Create a classical sequential loop. 266 void codegenForSequential(const clast_for *f); 267 268 /// @brief Create OpenMP structure values. 269 /// 270 /// Create a list of values that has to be stored into the OpenMP subfuncition 271 /// structure. 272 SetVector<Value*> getOMPValues(); 273 274 /// @brief Update the internal structures according to a Value Map. 275 /// 276 /// @param VMap A map from old to new values. 277 /// @param Reverse If true, we assume the update should be reversed. 278 void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap, 279 bool Reverse); 280 281 /// @brief Create an OpenMP parallel for loop. 282 /// 283 /// This loop reflects a loop as if it would have been created by an OpenMP 284 /// statement. 285 void codegenForOpenMP(const clast_for *f); 286 287 /// @brief Check if a loop is parallel 288 /// 289 /// Detect if a clast_for loop can be executed in parallel. 290 /// 291 /// @param f The clast for loop to check. 292 /// 293 /// @return bool Returns true if the incoming clast_for statement can 294 /// execute in parallel. 295 bool isParallelFor(const clast_for *For); 296 297 bool isInnermostLoop(const clast_for *f); 298 299 /// @brief Get the number of loop iterations for this loop. 300 /// @param f The clast for loop to check. 301 int getNumberOfIterations(const clast_for *f); 302 303 /// @brief Create vector instructions for this loop. 304 void codegenForVector(const clast_for *f); 305 306 void codegen(const clast_for *f); 307 308 Value *codegen(const clast_equation *eq); 309 310 void codegen(const clast_guard *g); 311 312 void codegen(const clast_stmt *stmt); 313 314 void addParameters(const CloogNames *names); 315 316 IntegerType *getIntPtrTy(); 317 318 public: 319 void codegen(const clast_root *r); 320 321 ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P); 322 }; 323 } 324 325 IntegerType *ClastStmtCodeGen::getIntPtrTy() { 326 return P->getAnalysis<TargetData>().getIntPtrType(Builder.getContext()); 327 } 328 329 const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() { 330 return parallelLoops; 331 } 332 333 void ClastStmtCodeGen::codegen(const clast_assignment *a) { 334 Value *V= ExpGen.codegen(a->RHS, getIntPtrTy()); 335 ClastVars[a->LHS] = V; 336 } 337 338 void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt, 339 unsigned Dim, int VectorDim, 340 std::vector<ValueMapT> *VectorVMap) { 341 const PHINode *PN; 342 Value *RHS; 343 344 assert(!A->LHS && "Statement assignments do not have left hand side"); 345 346 PN = Stmt->getInductionVariableForDimension(Dim); 347 RHS = ExpGen.codegen(A->RHS, Builder.getInt64Ty()); 348 RHS = Builder.CreateTruncOrBitCast(RHS, PN->getType()); 349 350 if (VectorVMap) 351 (*VectorVMap)[VectorDim][PN] = RHS; 352 353 ValueMap[PN] = RHS; 354 } 355 356 void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment, 357 ScopStmt *Statement, int vectorDim, 358 std::vector<ValueMapT> *VectorVMap) { 359 int Dimension = 0; 360 361 while (Assignment) { 362 assert(CLAST_STMT_IS_A(Assignment, stmt_ass) 363 && "Substitions are expected to be assignments"); 364 codegen((const clast_assignment *)Assignment, Statement, Dimension, 365 vectorDim, VectorVMap); 366 Assignment = Assignment->next; 367 Dimension++; 368 } 369 } 370 371 void ClastStmtCodeGen::codegen(const clast_user_stmt *u, 372 std::vector<Value*> *IVS , const char *iterator, 373 isl_set *Domain) { 374 ScopStmt *Statement = (ScopStmt *)u->statement->usr; 375 376 if (u->substitutions) 377 codegenSubstitutions(u->substitutions, Statement); 378 379 int VectorDimensions = IVS ? IVS->size() : 1; 380 381 if (VectorDimensions == 1) { 382 BlockGenerator::generate(Builder, *Statement, ValueMap, P); 383 return; 384 } 385 386 VectorValueMapT VectorMap(VectorDimensions); 387 388 if (IVS) { 389 assert (u->substitutions && "Substitutions expected!"); 390 int i = 0; 391 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end(); 392 II != IE; ++II) { 393 ClastVars[iterator] = *II; 394 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap); 395 i++; 396 } 397 } 398 399 VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P); 400 } 401 402 void ClastStmtCodeGen::codegen(const clast_block *b) { 403 if (b->body) 404 codegen(b->body); 405 } 406 407 void ClastStmtCodeGen::codegenForSequential(const clast_for *f) { 408 Value *LowerBound, *UpperBound, *IV, *Stride; 409 BasicBlock *AfterBB; 410 Type *IntPtrTy = getIntPtrTy(); 411 412 LowerBound = ExpGen.codegen(f->LB, IntPtrTy); 413 UpperBound = ExpGen.codegen(f->UB, IntPtrTy); 414 Stride = Builder.getInt(APInt_from_MPZ(f->stride)); 415 416 IV = createLoop(LowerBound, UpperBound, Stride, Builder, P, AfterBB); 417 418 // Add loop iv to symbols. 419 ClastVars[f->iterator] = IV; 420 421 if (f->body) 422 codegen(f->body); 423 424 // Loop is finished, so remove its iv from the live symbols. 425 ClastVars.erase(f->iterator); 426 Builder.SetInsertPoint(AfterBB->begin()); 427 } 428 429 SetVector<Value*> ClastStmtCodeGen::getOMPValues() { 430 SetVector<Value*> Values; 431 432 // The clast variables 433 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end(); 434 I != E; I++) 435 Values.insert(I->second); 436 437 // The memory reference base addresses 438 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { 439 ScopStmt *Stmt = *SI; 440 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(), 441 E = Stmt->memacc_end(); I != E; ++I) { 442 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr()); 443 Values.insert((BaseAddr)); 444 } 445 } 446 447 return Values; 448 } 449 450 void ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap, 451 bool Reverse) { 452 std::set<Value*> Inserted; 453 454 if (Reverse) { 455 OMPGenerator::ValueToValueMapTy ReverseMap; 456 457 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end(); 458 I != E; ++I) 459 ReverseMap.insert(std::make_pair(I->second, I->first)); 460 461 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end(); 462 I != E; I++) { 463 ClastVars[I->first] = ReverseMap[I->second]; 464 Inserted.insert(I->second); 465 } 466 467 /// FIXME: At the moment we do not reverse the update of the ValueMap. 468 /// This is incomplet, but the failure should be obvious, such that 469 /// we can fix this later. 470 return; 471 } 472 473 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end(); 474 I != E; I++) { 475 ClastVars[I->first] = VMap[I->second]; 476 Inserted.insert(I->second); 477 } 478 479 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end(); 480 I != E; ++I) { 481 if (Inserted.count(I->first)) 482 continue; 483 484 ValueMap[I->first] = I->second; 485 } 486 } 487 488 static void clearDomtree(Function *F, DominatorTree &DT) { 489 DomTreeNode *N = DT.getNode(&F->getEntryBlock()); 490 std::vector<BasicBlock*> Nodes; 491 for (po_iterator<DomTreeNode*> I = po_begin(N), E = po_end(N); I != E; ++I) 492 Nodes.push_back(I->getBlock()); 493 494 for (std::vector<BasicBlock*>::iterator I = Nodes.begin(), E = Nodes.end(); 495 I != E; ++I) 496 DT.eraseNode(*I); 497 } 498 499 void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) { 500 Value *Stride, *LB, *UB, *IV; 501 BasicBlock::iterator LoopBody; 502 IntegerType *IntPtrTy = getIntPtrTy(); 503 SetVector<Value*> Values; 504 OMPGenerator::ValueToValueMapTy VMap; 505 OMPGenerator OMPGen(Builder, P); 506 507 Stride = Builder.getInt(APInt_from_MPZ(For->stride)); 508 Stride = Builder.CreateSExtOrBitCast(Stride, IntPtrTy); 509 LB = ExpGen.codegen(For->LB, IntPtrTy); 510 UB = ExpGen.codegen(For->UB, IntPtrTy); 511 512 Values = getOMPValues(); 513 514 IV = OMPGen.createParallelLoop(LB, UB, Stride, Values, VMap, &LoopBody); 515 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint(); 516 Builder.SetInsertPoint(LoopBody); 517 518 updateWithValueMap(VMap, /* reverse */ false); 519 ClastVars[For->iterator] = IV; 520 521 if (For->body) 522 codegen(For->body); 523 524 ClastVars.erase(For->iterator); 525 updateWithValueMap(VMap, /* reverse */ true); 526 527 clearDomtree((*LoopBody).getParent()->getParent(), 528 P->getAnalysis<DominatorTree>()); 529 530 Builder.SetInsertPoint(AfterLoop); 531 } 532 533 bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) { 534 const clast_stmt *stmt = f->body; 535 536 while (stmt) { 537 if (!CLAST_STMT_IS_A(stmt, stmt_user)) 538 return false; 539 540 stmt = stmt->next; 541 } 542 543 return true; 544 } 545 546 int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) { 547 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain)); 548 isl_set *tmp = isl_set_copy(loopDomain); 549 550 // Calculate a map similar to the identity map, but with the last input 551 // and output dimension not related. 552 // [i0, i1, i2, i3] -> [i0, i1, i2, o0] 553 isl_space *Space = isl_set_get_space(loopDomain); 554 Space = isl_space_drop_outputs(Space, 555 isl_set_dim(loopDomain, isl_dim_set) - 2, 1); 556 Space = isl_space_map_from_set(Space); 557 isl_map *identity = isl_map_identity(Space); 558 identity = isl_map_add_dims(identity, isl_dim_in, 1); 559 identity = isl_map_add_dims(identity, isl_dim_out, 1); 560 561 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain); 562 map = isl_map_intersect(map, identity); 563 564 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map)); 565 isl_map *lexmin = isl_map_lexmin(map); 566 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin)); 567 568 isl_set *elements = isl_map_range(sub); 569 570 if (!isl_set_is_singleton(elements)) { 571 isl_set_free(elements); 572 return -1; 573 } 574 575 isl_point *p = isl_set_sample_point(elements); 576 577 isl_int v; 578 isl_int_init(v); 579 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v); 580 int numberIterations = isl_int_get_si(v); 581 isl_int_clear(v); 582 isl_point_free(p); 583 584 return (numberIterations) / isl_int_get_si(f->stride) + 1; 585 } 586 587 void ClastStmtCodeGen::codegenForVector(const clast_for *F) { 588 DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";); 589 int VectorWidth = getNumberOfIterations(F); 590 591 Value *LB = ExpGen.codegen(F->LB, getIntPtrTy()); 592 593 APInt Stride = APInt_from_MPZ(F->stride); 594 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType()); 595 Stride = Stride.zext(LoopIVType->getBitWidth()); 596 Value *StrideValue = ConstantInt::get(LoopIVType, Stride); 597 598 std::vector<Value*> IVS(VectorWidth); 599 IVS[0] = LB; 600 601 for (int i = 1; i < VectorWidth; i++) 602 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv"); 603 604 isl_set *Domain = isl_set_from_cloog_domain(F->domain); 605 606 // Add loop iv to symbols. 607 ClastVars[F->iterator] = LB; 608 609 const clast_stmt *Stmt = F->body; 610 611 while (Stmt) { 612 codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator, 613 isl_set_copy(Domain)); 614 Stmt = Stmt->next; 615 } 616 617 // Loop is finished, so remove its iv from the live symbols. 618 isl_set_free(Domain); 619 ClastVars.erase(F->iterator); 620 } 621 622 623 bool ClastStmtCodeGen::isParallelFor(const clast_for *f) { 624 isl_set *Domain = isl_set_from_cloog_domain(f->domain); 625 assert(Domain && "Cannot access domain of loop"); 626 627 Dependences &D = P->getAnalysis<Dependences>(); 628 629 return D.isParallelDimension(isl_set_copy(Domain), isl_set_n_dim(Domain)); 630 } 631 632 void ClastStmtCodeGen::codegen(const clast_for *f) { 633 bool Vector = PollyVectorizerChoice != VECTORIZER_NONE; 634 if ((Vector || OpenMP) && isParallelFor(f)) { 635 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f)) 636 && (getNumberOfIterations(f) <= 16)) { 637 codegenForVector(f); 638 return; 639 } 640 641 if (OpenMP && !parallelCodeGeneration) { 642 parallelCodeGeneration = true; 643 parallelLoops.push_back(f->iterator); 644 codegenForOpenMP(f); 645 parallelCodeGeneration = false; 646 return; 647 } 648 } 649 650 codegenForSequential(f); 651 } 652 653 Value *ClastStmtCodeGen::codegen(const clast_equation *eq) { 654 Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy()); 655 Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy()); 656 CmpInst::Predicate P; 657 658 if (eq->sign == 0) 659 P = ICmpInst::ICMP_EQ; 660 else if (eq->sign > 0) 661 P = ICmpInst::ICMP_SGE; 662 else 663 P = ICmpInst::ICMP_SLE; 664 665 return Builder.CreateICmp(P, LHS, RHS); 666 } 667 668 void ClastStmtCodeGen::codegen(const clast_guard *g) { 669 Function *F = Builder.GetInsertBlock()->getParent(); 670 LLVMContext &Context = F->getContext(); 671 672 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(), 673 Builder.GetInsertPoint(), P); 674 CondBB->setName("polly.cond"); 675 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P); 676 MergeBB->setName("polly.merge"); 677 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F); 678 679 DominatorTree &DT = P->getAnalysis<DominatorTree>(); 680 DT.addNewBlock(ThenBB, CondBB); 681 DT.changeImmediateDominator(MergeBB, CondBB); 682 683 CondBB->getTerminator()->eraseFromParent(); 684 685 Builder.SetInsertPoint(CondBB); 686 687 Value *Predicate = codegen(&(g->eq[0])); 688 689 for (int i = 1; i < g->n; ++i) { 690 Value *TmpPredicate = codegen(&(g->eq[i])); 691 Predicate = Builder.CreateAnd(Predicate, TmpPredicate); 692 } 693 694 Builder.CreateCondBr(Predicate, ThenBB, MergeBB); 695 Builder.SetInsertPoint(ThenBB); 696 Builder.CreateBr(MergeBB); 697 Builder.SetInsertPoint(ThenBB->begin()); 698 699 codegen(g->then); 700 701 Builder.SetInsertPoint(MergeBB->begin()); 702 } 703 704 void ClastStmtCodeGen::codegen(const clast_stmt *stmt) { 705 if (CLAST_STMT_IS_A(stmt, stmt_root)) 706 assert(false && "No second root statement expected"); 707 else if (CLAST_STMT_IS_A(stmt, stmt_ass)) 708 codegen((const clast_assignment *)stmt); 709 else if (CLAST_STMT_IS_A(stmt, stmt_user)) 710 codegen((const clast_user_stmt *)stmt); 711 else if (CLAST_STMT_IS_A(stmt, stmt_block)) 712 codegen((const clast_block *)stmt); 713 else if (CLAST_STMT_IS_A(stmt, stmt_for)) 714 codegen((const clast_for *)stmt); 715 else if (CLAST_STMT_IS_A(stmt, stmt_guard)) 716 codegen((const clast_guard *)stmt); 717 718 if (stmt->next) 719 codegen(stmt->next); 720 } 721 722 void ClastStmtCodeGen::addParameters(const CloogNames *names) { 723 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly"); 724 725 int i = 0; 726 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end(); 727 PI != PE; ++PI) { 728 assert(i < names->nb_parameters && "Not enough parameter names"); 729 730 const SCEV *Param = *PI; 731 Type *Ty = Param->getType(); 732 733 Instruction *insertLocation = --(Builder.GetInsertBlock()->end()); 734 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation); 735 ClastVars[names->parameters[i]] = V; 736 737 ++i; 738 } 739 } 740 741 void ClastStmtCodeGen::codegen(const clast_root *r) { 742 addParameters(r->names); 743 744 parallelCodeGeneration = false; 745 746 const clast_stmt *stmt = (const clast_stmt*) r; 747 if (stmt->next) 748 codegen(stmt->next); 749 } 750 751 ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) : 752 S(scop), P(P), Builder(B), ExpGen(Builder, ClastVars) {} 753 754 namespace { 755 class CodeGeneration : public ScopPass { 756 std::vector<std::string> ParallelLoops; 757 758 public: 759 static char ID; 760 761 CodeGeneration() : ScopPass(ID) {} 762 763 764 bool runOnScop(Scop &S) { 765 ParallelLoops.clear(); 766 767 assert(S.getRegion().isSimple() && "Only simple regions are supported"); 768 769 BasicBlock *StartBlock = executeScopConditionally(S, this); 770 771 IRBuilder<> Builder(StartBlock->begin()); 772 773 ClastStmtCodeGen CodeGen(&S, Builder, this); 774 CloogInfo &C = getAnalysis<CloogInfo>(); 775 CodeGen.codegen(C.getClast()); 776 777 ParallelLoops.insert(ParallelLoops.begin(), 778 CodeGen.getParallelLoops().begin(), 779 CodeGen.getParallelLoops().end()); 780 return true; 781 } 782 783 virtual void printScop(raw_ostream &OS) const { 784 for (std::vector<std::string>::const_iterator PI = ParallelLoops.begin(), 785 PE = ParallelLoops.end(); PI != PE; ++PI) 786 OS << "Parallel loop with iterator '" << *PI << "' generated\n"; 787 } 788 789 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 790 AU.addRequired<CloogInfo>(); 791 AU.addRequired<Dependences>(); 792 AU.addRequired<DominatorTree>(); 793 AU.addRequired<RegionInfo>(); 794 AU.addRequired<ScalarEvolution>(); 795 AU.addRequired<ScopDetection>(); 796 AU.addRequired<ScopInfo>(); 797 AU.addRequired<TargetData>(); 798 799 AU.addPreserved<CloogInfo>(); 800 AU.addPreserved<Dependences>(); 801 802 // FIXME: We do not create LoopInfo for the newly generated loops. 803 AU.addPreserved<LoopInfo>(); 804 AU.addPreserved<DominatorTree>(); 805 AU.addPreserved<ScopDetection>(); 806 AU.addPreserved<ScalarEvolution>(); 807 808 // FIXME: We do not yet add regions for the newly generated code to the 809 // region tree. 810 AU.addPreserved<RegionInfo>(); 811 AU.addPreserved<TempScopInfo>(); 812 AU.addPreserved<ScopInfo>(); 813 AU.addPreservedID(IndependentBlocksID); 814 } 815 }; 816 } 817 818 char CodeGeneration::ID = 1; 819 820 INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen", 821 "Polly - Create LLVM-IR from SCoPs", false, false) 822 INITIALIZE_PASS_DEPENDENCY(CloogInfo) 823 INITIALIZE_PASS_DEPENDENCY(Dependences) 824 INITIALIZE_PASS_DEPENDENCY(DominatorTree) 825 INITIALIZE_PASS_DEPENDENCY(RegionInfo) 826 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) 827 INITIALIZE_PASS_DEPENDENCY(ScopDetection) 828 INITIALIZE_PASS_DEPENDENCY(TargetData) 829 INITIALIZE_PASS_END(CodeGeneration, "polly-codegen", 830 "Polly - Create LLVM-IR from SCoPs", false, false) 831 832 Pass *polly::createCodeGenerationPass() { 833 return new CodeGeneration(); 834 } 835 836 #endif // CLOOG_FOUND 837