1 //===- ScopBuilder.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Create a polyhedral description for a static control flow region. 10 // 11 // The pass creates a polyhedral description of the Scops detected by the SCoP 12 // detection derived from their LLVM-IR code. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "polly/ScopBuilder.h" 17 #include "polly/Options.h" 18 #include "polly/ScopDetection.h" 19 #include "polly/ScopInfo.h" 20 #include "polly/Support/GICHelper.h" 21 #include "polly/Support/ISLTools.h" 22 #include "polly/Support/SCEVValidator.h" 23 #include "polly/Support/ScopHelper.h" 24 #include "polly/Support/VirtualInstruction.h" 25 #include "llvm/ADT/ArrayRef.h" 26 #include "llvm/ADT/EquivalenceClasses.h" 27 #include "llvm/ADT/PostOrderIterator.h" 28 #include "llvm/ADT/Sequence.h" 29 #include "llvm/ADT/SmallSet.h" 30 #include "llvm/ADT/Statistic.h" 31 #include "llvm/Analysis/AliasAnalysis.h" 32 #include "llvm/Analysis/AssumptionCache.h" 33 #include "llvm/Analysis/Loads.h" 34 #include "llvm/Analysis/LoopInfo.h" 35 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 36 #include "llvm/Analysis/RegionInfo.h" 37 #include "llvm/Analysis/RegionIterator.h" 38 #include "llvm/Analysis/ScalarEvolution.h" 39 #include "llvm/Analysis/ScalarEvolutionExpressions.h" 40 #include "llvm/IR/BasicBlock.h" 41 #include "llvm/IR/DataLayout.h" 42 #include "llvm/IR/DebugLoc.h" 43 #include "llvm/IR/DerivedTypes.h" 44 #include "llvm/IR/Dominators.h" 45 #include "llvm/IR/Function.h" 46 #include "llvm/IR/InstrTypes.h" 47 #include "llvm/IR/Instruction.h" 48 #include "llvm/IR/Instructions.h" 49 #include "llvm/IR/Type.h" 50 #include "llvm/IR/Use.h" 51 #include "llvm/IR/Value.h" 52 #include "llvm/Support/CommandLine.h" 53 #include "llvm/Support/Compiler.h" 54 #include "llvm/Support/Debug.h" 55 #include "llvm/Support/ErrorHandling.h" 56 #include "llvm/Support/raw_ostream.h" 57 #include <cassert> 58 59 using namespace llvm; 60 using namespace polly; 61 62 #define DEBUG_TYPE "polly-scops" 63 64 STATISTIC(ScopFound, "Number of valid Scops"); 65 STATISTIC(RichScopFound, "Number of Scops containing a loop"); 66 STATISTIC(InfeasibleScops, 67 "Number of SCoPs with statically infeasible context."); 68 69 bool polly::ModelReadOnlyScalars; 70 71 // The maximal number of dimensions we allow during invariant load construction. 72 // More complex access ranges will result in very high compile time and are also 73 // unlikely to result in good code. This value is very high and should only 74 // trigger for corner cases (e.g., the "dct_luma" function in h264, SPEC2006). 75 static int const MaxDimensionsInAccessRange = 9; 76 77 static cl::opt<bool, true> XModelReadOnlyScalars( 78 "polly-analyze-read-only-scalars", 79 cl::desc("Model read-only scalar values in the scop description"), 80 cl::location(ModelReadOnlyScalars), cl::Hidden, cl::ZeroOrMore, 81 cl::init(true), cl::cat(PollyCategory)); 82 83 static cl::opt<int> 84 OptComputeOut("polly-analysis-computeout", 85 cl::desc("Bound the scop analysis by a maximal amount of " 86 "computational steps (0 means no bound)"), 87 cl::Hidden, cl::init(800000), cl::ZeroOrMore, 88 cl::cat(PollyCategory)); 89 90 static cl::opt<bool> PollyAllowDereferenceOfAllFunctionParams( 91 "polly-allow-dereference-of-all-function-parameters", 92 cl::desc( 93 "Treat all parameters to functions that are pointers as dereferencible." 94 " This is useful for invariant load hoisting, since we can generate" 95 " less runtime checks. This is only valid if all pointers to functions" 96 " are always initialized, so that Polly can choose to hoist" 97 " their loads. "), 98 cl::Hidden, cl::init(false), cl::cat(PollyCategory)); 99 100 static cl::opt<bool> 101 PollyIgnoreInbounds("polly-ignore-inbounds", 102 cl::desc("Do not take inbounds assumptions at all"), 103 cl::Hidden, cl::init(false), cl::cat(PollyCategory)); 104 105 static cl::opt<unsigned> RunTimeChecksMaxArraysPerGroup( 106 "polly-rtc-max-arrays-per-group", 107 cl::desc("The maximal number of arrays to compare in each alias group."), 108 cl::Hidden, cl::ZeroOrMore, cl::init(20), cl::cat(PollyCategory)); 109 110 static cl::opt<int> RunTimeChecksMaxAccessDisjuncts( 111 "polly-rtc-max-array-disjuncts", 112 cl::desc("The maximal number of disjunts allowed in memory accesses to " 113 "to build RTCs."), 114 cl::Hidden, cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory)); 115 116 static cl::opt<unsigned> RunTimeChecksMaxParameters( 117 "polly-rtc-max-parameters", 118 cl::desc("The maximal number of parameters allowed in RTCs."), cl::Hidden, 119 cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory)); 120 121 static cl::opt<bool> UnprofitableScalarAccs( 122 "polly-unprofitable-scalar-accs", 123 cl::desc("Count statements with scalar accesses as not optimizable"), 124 cl::Hidden, cl::init(false), cl::cat(PollyCategory)); 125 126 static cl::opt<std::string> UserContextStr( 127 "polly-context", cl::value_desc("isl parameter set"), 128 cl::desc("Provide additional constraints on the context parameters"), 129 cl::init(""), cl::cat(PollyCategory)); 130 131 static cl::opt<bool> DetectFortranArrays( 132 "polly-detect-fortran-arrays", 133 cl::desc("Detect Fortran arrays and use this for code generation"), 134 cl::Hidden, cl::init(false), cl::cat(PollyCategory)); 135 136 static cl::opt<bool> DetectReductions("polly-detect-reductions", 137 cl::desc("Detect and exploit reductions"), 138 cl::Hidden, cl::ZeroOrMore, 139 cl::init(true), cl::cat(PollyCategory)); 140 141 // Multiplicative reductions can be disabled separately as these kind of 142 // operations can overflow easily. Additive reductions and bit operations 143 // are in contrast pretty stable. 144 static cl::opt<bool> DisableMultiplicativeReductions( 145 "polly-disable-multiplicative-reductions", 146 cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore, 147 cl::init(false), cl::cat(PollyCategory)); 148 149 enum class GranularityChoice { BasicBlocks, ScalarIndependence, Stores }; 150 151 static cl::opt<GranularityChoice> StmtGranularity( 152 "polly-stmt-granularity", 153 cl::desc( 154 "Algorithm to use for splitting basic blocks into multiple statements"), 155 cl::values(clEnumValN(GranularityChoice::BasicBlocks, "bb", 156 "One statement per basic block"), 157 clEnumValN(GranularityChoice::ScalarIndependence, "scalar-indep", 158 "Scalar independence heuristic"), 159 clEnumValN(GranularityChoice::Stores, "store", 160 "Store-level granularity")), 161 cl::init(GranularityChoice::ScalarIndependence), cl::cat(PollyCategory)); 162 163 /// Helper to treat non-affine regions and basic blocks the same. 164 /// 165 ///{ 166 167 /// Return the block that is the representing block for @p RN. 168 static inline BasicBlock *getRegionNodeBasicBlock(RegionNode *RN) { 169 return RN->isSubRegion() ? RN->getNodeAs<Region>()->getEntry() 170 : RN->getNodeAs<BasicBlock>(); 171 } 172 173 /// Return the @p idx'th block that is executed after @p RN. 174 static inline BasicBlock * 175 getRegionNodeSuccessor(RegionNode *RN, Instruction *TI, unsigned idx) { 176 if (RN->isSubRegion()) { 177 assert(idx == 0); 178 return RN->getNodeAs<Region>()->getExit(); 179 } 180 return TI->getSuccessor(idx); 181 } 182 183 static bool containsErrorBlock(RegionNode *RN, const Region &R, LoopInfo &LI, 184 const DominatorTree &DT) { 185 if (!RN->isSubRegion()) 186 return isErrorBlock(*RN->getNodeAs<BasicBlock>(), R, LI, DT); 187 for (BasicBlock *BB : RN->getNodeAs<Region>()->blocks()) 188 if (isErrorBlock(*BB, R, LI, DT)) 189 return true; 190 return false; 191 } 192 193 ///} 194 195 /// Create a map to map from a given iteration to a subsequent iteration. 196 /// 197 /// This map maps from SetSpace -> SetSpace where the dimensions @p Dim 198 /// is incremented by one and all other dimensions are equal, e.g., 199 /// [i0, i1, i2, i3] -> [i0, i1, i2 + 1, i3] 200 /// 201 /// if @p Dim is 2 and @p SetSpace has 4 dimensions. 202 static isl::map createNextIterationMap(isl::space SetSpace, unsigned Dim) { 203 isl::space MapSpace = SetSpace.map_from_set(); 204 isl::map NextIterationMap = isl::map::universe(MapSpace); 205 for (auto u : seq<isl_size>(0, NextIterationMap.dim(isl::dim::in))) 206 if (u != (isl_size)Dim) 207 NextIterationMap = 208 NextIterationMap.equate(isl::dim::in, u, isl::dim::out, u); 209 isl::constraint C = 210 isl::constraint::alloc_equality(isl::local_space(MapSpace)); 211 C = C.set_constant_si(1); 212 C = C.set_coefficient_si(isl::dim::in, Dim, 1); 213 C = C.set_coefficient_si(isl::dim::out, Dim, -1); 214 NextIterationMap = NextIterationMap.add_constraint(C); 215 return NextIterationMap; 216 } 217 218 /// Add @p BSet to set @p BoundedParts if @p BSet is bounded. 219 static isl::set collectBoundedParts(isl::set S) { 220 isl::set BoundedParts = isl::set::empty(S.get_space()); 221 for (isl::basic_set BSet : S.get_basic_set_list()) 222 if (BSet.is_bounded()) 223 BoundedParts = BoundedParts.unite(isl::set(BSet)); 224 return BoundedParts; 225 } 226 227 /// Compute the (un)bounded parts of @p S wrt. to dimension @p Dim. 228 /// 229 /// @returns A separation of @p S into first an unbounded then a bounded subset, 230 /// both with regards to the dimension @p Dim. 231 static std::pair<isl::set, isl::set> partitionSetParts(isl::set S, 232 unsigned Dim) { 233 for (unsigned u = 0, e = S.n_dim(); u < e; u++) 234 S = S.lower_bound_si(isl::dim::set, u, 0); 235 236 unsigned NumDimsS = S.n_dim(); 237 isl::set OnlyDimS = S; 238 239 // Remove dimensions that are greater than Dim as they are not interesting. 240 assert(NumDimsS >= Dim + 1); 241 OnlyDimS = OnlyDimS.project_out(isl::dim::set, Dim + 1, NumDimsS - Dim - 1); 242 243 // Create artificial parametric upper bounds for dimensions smaller than Dim 244 // as we are not interested in them. 245 OnlyDimS = OnlyDimS.insert_dims(isl::dim::param, 0, Dim); 246 247 for (unsigned u = 0; u < Dim; u++) { 248 isl::constraint C = isl::constraint::alloc_inequality( 249 isl::local_space(OnlyDimS.get_space())); 250 C = C.set_coefficient_si(isl::dim::param, u, 1); 251 C = C.set_coefficient_si(isl::dim::set, u, -1); 252 OnlyDimS = OnlyDimS.add_constraint(C); 253 } 254 255 // Collect all bounded parts of OnlyDimS. 256 isl::set BoundedParts = collectBoundedParts(OnlyDimS); 257 258 // Create the dimensions greater than Dim again. 259 BoundedParts = 260 BoundedParts.insert_dims(isl::dim::set, Dim + 1, NumDimsS - Dim - 1); 261 262 // Remove the artificial upper bound parameters again. 263 BoundedParts = BoundedParts.remove_dims(isl::dim::param, 0, Dim); 264 265 isl::set UnboundedParts = S.subtract(BoundedParts); 266 return std::make_pair(UnboundedParts, BoundedParts); 267 } 268 269 /// Create the conditions under which @p L @p Pred @p R is true. 270 static isl::set buildConditionSet(ICmpInst::Predicate Pred, isl::pw_aff L, 271 isl::pw_aff R) { 272 switch (Pred) { 273 case ICmpInst::ICMP_EQ: 274 return L.eq_set(R); 275 case ICmpInst::ICMP_NE: 276 return L.ne_set(R); 277 case ICmpInst::ICMP_SLT: 278 return L.lt_set(R); 279 case ICmpInst::ICMP_SLE: 280 return L.le_set(R); 281 case ICmpInst::ICMP_SGT: 282 return L.gt_set(R); 283 case ICmpInst::ICMP_SGE: 284 return L.ge_set(R); 285 case ICmpInst::ICMP_ULT: 286 return L.lt_set(R); 287 case ICmpInst::ICMP_UGT: 288 return L.gt_set(R); 289 case ICmpInst::ICMP_ULE: 290 return L.le_set(R); 291 case ICmpInst::ICMP_UGE: 292 return L.ge_set(R); 293 default: 294 llvm_unreachable("Non integer predicate not supported"); 295 } 296 } 297 298 isl::set ScopBuilder::adjustDomainDimensions(isl::set Dom, Loop *OldL, 299 Loop *NewL) { 300 // If the loops are the same there is nothing to do. 301 if (NewL == OldL) 302 return Dom; 303 304 int OldDepth = scop->getRelativeLoopDepth(OldL); 305 int NewDepth = scop->getRelativeLoopDepth(NewL); 306 // If both loops are non-affine loops there is nothing to do. 307 if (OldDepth == -1 && NewDepth == -1) 308 return Dom; 309 310 // Distinguish three cases: 311 // 1) The depth is the same but the loops are not. 312 // => One loop was left one was entered. 313 // 2) The depth increased from OldL to NewL. 314 // => One loop was entered, none was left. 315 // 3) The depth decreased from OldL to NewL. 316 // => Loops were left were difference of the depths defines how many. 317 if (OldDepth == NewDepth) { 318 assert(OldL->getParentLoop() == NewL->getParentLoop()); 319 Dom = Dom.project_out(isl::dim::set, NewDepth, 1); 320 Dom = Dom.add_dims(isl::dim::set, 1); 321 } else if (OldDepth < NewDepth) { 322 assert(OldDepth + 1 == NewDepth); 323 auto &R = scop->getRegion(); 324 (void)R; 325 assert(NewL->getParentLoop() == OldL || 326 ((!OldL || !R.contains(OldL)) && R.contains(NewL))); 327 Dom = Dom.add_dims(isl::dim::set, 1); 328 } else { 329 assert(OldDepth > NewDepth); 330 int Diff = OldDepth - NewDepth; 331 int NumDim = Dom.n_dim(); 332 assert(NumDim >= Diff); 333 Dom = Dom.project_out(isl::dim::set, NumDim - Diff, Diff); 334 } 335 336 return Dom; 337 } 338 339 /// Compute the isl representation for the SCEV @p E in this BB. 340 /// 341 /// @param BB The BB for which isl representation is to be 342 /// computed. 343 /// @param InvalidDomainMap A map of BB to their invalid domains. 344 /// @param E The SCEV that should be translated. 345 /// @param NonNegative Flag to indicate the @p E has to be non-negative. 346 /// 347 /// Note that this function will also adjust the invalid context accordingly. 348 349 __isl_give isl_pw_aff * 350 ScopBuilder::getPwAff(BasicBlock *BB, 351 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, 352 const SCEV *E, bool NonNegative) { 353 PWACtx PWAC = scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions); 354 InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second); 355 return PWAC.first.release(); 356 } 357 358 /// Build condition sets for unsigned ICmpInst(s). 359 /// Special handling is required for unsigned operands to ensure that if 360 /// MSB (aka the Sign bit) is set for an operands in an unsigned ICmpInst 361 /// it should wrap around. 362 /// 363 /// @param IsStrictUpperBound holds information on the predicate relation 364 /// between TestVal and UpperBound, i.e, 365 /// TestVal < UpperBound OR TestVal <= UpperBound 366 __isl_give isl_set *ScopBuilder::buildUnsignedConditionSets( 367 BasicBlock *BB, Value *Condition, __isl_keep isl_set *Domain, 368 const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound, 369 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, 370 bool IsStrictUpperBound) { 371 // Do not take NonNeg assumption on TestVal 372 // as it might have MSB (Sign bit) set. 373 isl_pw_aff *TestVal = getPwAff(BB, InvalidDomainMap, SCEV_TestVal, false); 374 // Take NonNeg assumption on UpperBound. 375 isl_pw_aff *UpperBound = 376 getPwAff(BB, InvalidDomainMap, SCEV_UpperBound, true); 377 378 // 0 <= TestVal 379 isl_set *First = 380 isl_pw_aff_le_set(isl_pw_aff_zero_on_domain(isl_local_space_from_space( 381 isl_pw_aff_get_domain_space(TestVal))), 382 isl_pw_aff_copy(TestVal)); 383 384 isl_set *Second; 385 if (IsStrictUpperBound) 386 // TestVal < UpperBound 387 Second = isl_pw_aff_lt_set(TestVal, UpperBound); 388 else 389 // TestVal <= UpperBound 390 Second = isl_pw_aff_le_set(TestVal, UpperBound); 391 392 isl_set *ConsequenceCondSet = isl_set_intersect(First, Second); 393 return ConsequenceCondSet; 394 } 395 396 bool ScopBuilder::buildConditionSets( 397 BasicBlock *BB, SwitchInst *SI, Loop *L, __isl_keep isl_set *Domain, 398 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, 399 SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { 400 Value *Condition = getConditionFromTerminator(SI); 401 assert(Condition && "No condition for switch"); 402 403 isl_pw_aff *LHS, *RHS; 404 LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L)); 405 406 unsigned NumSuccessors = SI->getNumSuccessors(); 407 ConditionSets.resize(NumSuccessors); 408 for (auto &Case : SI->cases()) { 409 unsigned Idx = Case.getSuccessorIndex(); 410 ConstantInt *CaseValue = Case.getCaseValue(); 411 412 RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue)); 413 isl_set *CaseConditionSet = 414 buildConditionSet(ICmpInst::ICMP_EQ, isl::manage_copy(LHS), 415 isl::manage(RHS)) 416 .release(); 417 ConditionSets[Idx] = isl_set_coalesce( 418 isl_set_intersect(CaseConditionSet, isl_set_copy(Domain))); 419 } 420 421 assert(ConditionSets[0] == nullptr && "Default condition set was set"); 422 isl_set *ConditionSetUnion = isl_set_copy(ConditionSets[1]); 423 for (unsigned u = 2; u < NumSuccessors; u++) 424 ConditionSetUnion = 425 isl_set_union(ConditionSetUnion, isl_set_copy(ConditionSets[u])); 426 ConditionSets[0] = isl_set_subtract(isl_set_copy(Domain), ConditionSetUnion); 427 428 isl_pw_aff_free(LHS); 429 430 return true; 431 } 432 433 bool ScopBuilder::buildConditionSets( 434 BasicBlock *BB, Value *Condition, Instruction *TI, Loop *L, 435 __isl_keep isl_set *Domain, 436 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, 437 SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { 438 isl_set *ConsequenceCondSet = nullptr; 439 440 if (auto Load = dyn_cast<LoadInst>(Condition)) { 441 const SCEV *LHSSCEV = SE.getSCEVAtScope(Load, L); 442 const SCEV *RHSSCEV = SE.getZero(LHSSCEV->getType()); 443 bool NonNeg = false; 444 isl_pw_aff *LHS = getPwAff(BB, InvalidDomainMap, LHSSCEV, NonNeg); 445 isl_pw_aff *RHS = getPwAff(BB, InvalidDomainMap, RHSSCEV, NonNeg); 446 ConsequenceCondSet = buildConditionSet(ICmpInst::ICMP_SLE, isl::manage(LHS), 447 isl::manage(RHS)) 448 .release(); 449 } else if (auto *PHI = dyn_cast<PHINode>(Condition)) { 450 auto *Unique = dyn_cast<ConstantInt>( 451 getUniqueNonErrorValue(PHI, &scop->getRegion(), LI, DT)); 452 453 if (Unique->isZero()) 454 ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain)); 455 else 456 ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain)); 457 } else if (auto *CCond = dyn_cast<ConstantInt>(Condition)) { 458 if (CCond->isZero()) 459 ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain)); 460 else 461 ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain)); 462 } else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Condition)) { 463 auto Opcode = BinOp->getOpcode(); 464 assert(Opcode == Instruction::And || Opcode == Instruction::Or); 465 466 bool Valid = buildConditionSets(BB, BinOp->getOperand(0), TI, L, Domain, 467 InvalidDomainMap, ConditionSets) && 468 buildConditionSets(BB, BinOp->getOperand(1), TI, L, Domain, 469 InvalidDomainMap, ConditionSets); 470 if (!Valid) { 471 while (!ConditionSets.empty()) 472 isl_set_free(ConditionSets.pop_back_val()); 473 return false; 474 } 475 476 isl_set_free(ConditionSets.pop_back_val()); 477 isl_set *ConsCondPart0 = ConditionSets.pop_back_val(); 478 isl_set_free(ConditionSets.pop_back_val()); 479 isl_set *ConsCondPart1 = ConditionSets.pop_back_val(); 480 481 if (Opcode == Instruction::And) 482 ConsequenceCondSet = isl_set_intersect(ConsCondPart0, ConsCondPart1); 483 else 484 ConsequenceCondSet = isl_set_union(ConsCondPart0, ConsCondPart1); 485 } else { 486 auto *ICond = dyn_cast<ICmpInst>(Condition); 487 assert(ICond && 488 "Condition of exiting branch was neither constant nor ICmp!"); 489 490 Region &R = scop->getRegion(); 491 492 isl_pw_aff *LHS, *RHS; 493 // For unsigned comparisons we assumed the signed bit of neither operand 494 // to be set. The comparison is equal to a signed comparison under this 495 // assumption. 496 bool NonNeg = ICond->isUnsigned(); 497 const SCEV *LeftOperand = SE.getSCEVAtScope(ICond->getOperand(0), L), 498 *RightOperand = SE.getSCEVAtScope(ICond->getOperand(1), L); 499 500 LeftOperand = tryForwardThroughPHI(LeftOperand, R, SE, LI, DT); 501 RightOperand = tryForwardThroughPHI(RightOperand, R, SE, LI, DT); 502 503 switch (ICond->getPredicate()) { 504 case ICmpInst::ICMP_ULT: 505 ConsequenceCondSet = 506 buildUnsignedConditionSets(BB, Condition, Domain, LeftOperand, 507 RightOperand, InvalidDomainMap, true); 508 break; 509 case ICmpInst::ICMP_ULE: 510 ConsequenceCondSet = 511 buildUnsignedConditionSets(BB, Condition, Domain, LeftOperand, 512 RightOperand, InvalidDomainMap, false); 513 break; 514 case ICmpInst::ICMP_UGT: 515 ConsequenceCondSet = 516 buildUnsignedConditionSets(BB, Condition, Domain, RightOperand, 517 LeftOperand, InvalidDomainMap, true); 518 break; 519 case ICmpInst::ICMP_UGE: 520 ConsequenceCondSet = 521 buildUnsignedConditionSets(BB, Condition, Domain, RightOperand, 522 LeftOperand, InvalidDomainMap, false); 523 break; 524 default: 525 LHS = getPwAff(BB, InvalidDomainMap, LeftOperand, NonNeg); 526 RHS = getPwAff(BB, InvalidDomainMap, RightOperand, NonNeg); 527 ConsequenceCondSet = buildConditionSet(ICond->getPredicate(), 528 isl::manage(LHS), isl::manage(RHS)) 529 .release(); 530 break; 531 } 532 } 533 534 // If no terminator was given we are only looking for parameter constraints 535 // under which @p Condition is true/false. 536 if (!TI) 537 ConsequenceCondSet = isl_set_params(ConsequenceCondSet); 538 assert(ConsequenceCondSet); 539 ConsequenceCondSet = isl_set_coalesce( 540 isl_set_intersect(ConsequenceCondSet, isl_set_copy(Domain))); 541 542 isl_set *AlternativeCondSet = nullptr; 543 bool TooComplex = 544 isl_set_n_basic_set(ConsequenceCondSet) >= MaxDisjunctsInDomain; 545 546 if (!TooComplex) { 547 AlternativeCondSet = isl_set_subtract(isl_set_copy(Domain), 548 isl_set_copy(ConsequenceCondSet)); 549 TooComplex = 550 isl_set_n_basic_set(AlternativeCondSet) >= MaxDisjunctsInDomain; 551 } 552 553 if (TooComplex) { 554 scop->invalidate(COMPLEXITY, TI ? TI->getDebugLoc() : DebugLoc(), 555 TI ? TI->getParent() : nullptr /* BasicBlock */); 556 isl_set_free(AlternativeCondSet); 557 isl_set_free(ConsequenceCondSet); 558 return false; 559 } 560 561 ConditionSets.push_back(ConsequenceCondSet); 562 ConditionSets.push_back(isl_set_coalesce(AlternativeCondSet)); 563 564 return true; 565 } 566 567 bool ScopBuilder::buildConditionSets( 568 BasicBlock *BB, Instruction *TI, Loop *L, __isl_keep isl_set *Domain, 569 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, 570 SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { 571 if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) 572 return buildConditionSets(BB, SI, L, Domain, InvalidDomainMap, 573 ConditionSets); 574 575 assert(isa<BranchInst>(TI) && "Terminator was neither branch nor switch."); 576 577 if (TI->getNumSuccessors() == 1) { 578 ConditionSets.push_back(isl_set_copy(Domain)); 579 return true; 580 } 581 582 Value *Condition = getConditionFromTerminator(TI); 583 assert(Condition && "No condition for Terminator"); 584 585 return buildConditionSets(BB, Condition, TI, L, Domain, InvalidDomainMap, 586 ConditionSets); 587 } 588 589 bool ScopBuilder::propagateDomainConstraints( 590 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 591 // Iterate over the region R and propagate the domain constrains from the 592 // predecessors to the current node. In contrast to the 593 // buildDomainsWithBranchConstraints function, this one will pull the domain 594 // information from the predecessors instead of pushing it to the successors. 595 // Additionally, we assume the domains to be already present in the domain 596 // map here. However, we iterate again in reverse post order so we know all 597 // predecessors have been visited before a block or non-affine subregion is 598 // visited. 599 600 ReversePostOrderTraversal<Region *> RTraversal(R); 601 for (auto *RN : RTraversal) { 602 // Recurse for affine subregions but go on for basic blocks and non-affine 603 // subregions. 604 if (RN->isSubRegion()) { 605 Region *SubRegion = RN->getNodeAs<Region>(); 606 if (!scop->isNonAffineSubRegion(SubRegion)) { 607 if (!propagateDomainConstraints(SubRegion, InvalidDomainMap)) 608 return false; 609 continue; 610 } 611 } 612 613 BasicBlock *BB = getRegionNodeBasicBlock(RN); 614 isl::set &Domain = scop->getOrInitEmptyDomain(BB); 615 assert(Domain); 616 617 // Under the union of all predecessor conditions we can reach this block. 618 isl::set PredDom = getPredecessorDomainConstraints(BB, Domain); 619 Domain = Domain.intersect(PredDom).coalesce(); 620 Domain = Domain.align_params(scop->getParamSpace()); 621 622 Loop *BBLoop = getRegionNodeLoop(RN, LI); 623 if (BBLoop && BBLoop->getHeader() == BB && scop->contains(BBLoop)) 624 if (!addLoopBoundsToHeaderDomain(BBLoop, InvalidDomainMap)) 625 return false; 626 } 627 628 return true; 629 } 630 631 void ScopBuilder::propagateDomainConstraintsToRegionExit( 632 BasicBlock *BB, Loop *BBLoop, 633 SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks, 634 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 635 // Check if the block @p BB is the entry of a region. If so we propagate it's 636 // domain to the exit block of the region. Otherwise we are done. 637 auto *RI = scop->getRegion().getRegionInfo(); 638 auto *BBReg = RI ? RI->getRegionFor(BB) : nullptr; 639 auto *ExitBB = BBReg ? BBReg->getExit() : nullptr; 640 if (!BBReg || BBReg->getEntry() != BB || !scop->contains(ExitBB)) 641 return; 642 643 // Do not propagate the domain if there is a loop backedge inside the region 644 // that would prevent the exit block from being executed. 645 auto *L = BBLoop; 646 while (L && scop->contains(L)) { 647 SmallVector<BasicBlock *, 4> LatchBBs; 648 BBLoop->getLoopLatches(LatchBBs); 649 for (auto *LatchBB : LatchBBs) 650 if (BB != LatchBB && BBReg->contains(LatchBB)) 651 return; 652 L = L->getParentLoop(); 653 } 654 655 isl::set Domain = scop->getOrInitEmptyDomain(BB); 656 assert(Domain && "Cannot propagate a nullptr"); 657 658 Loop *ExitBBLoop = getFirstNonBoxedLoopFor(ExitBB, LI, scop->getBoxedLoops()); 659 660 // Since the dimensions of @p BB and @p ExitBB might be different we have to 661 // adjust the domain before we can propagate it. 662 isl::set AdjustedDomain = adjustDomainDimensions(Domain, BBLoop, ExitBBLoop); 663 isl::set &ExitDomain = scop->getOrInitEmptyDomain(ExitBB); 664 665 // If the exit domain is not yet created we set it otherwise we "add" the 666 // current domain. 667 ExitDomain = ExitDomain ? AdjustedDomain.unite(ExitDomain) : AdjustedDomain; 668 669 // Initialize the invalid domain. 670 InvalidDomainMap[ExitBB] = ExitDomain.empty(ExitDomain.get_space()); 671 672 FinishedExitBlocks.insert(ExitBB); 673 } 674 675 isl::set ScopBuilder::getPredecessorDomainConstraints(BasicBlock *BB, 676 isl::set Domain) { 677 // If @p BB is the ScopEntry we are done 678 if (scop->getRegion().getEntry() == BB) 679 return isl::set::universe(Domain.get_space()); 680 681 // The region info of this function. 682 auto &RI = *scop->getRegion().getRegionInfo(); 683 684 Loop *BBLoop = getFirstNonBoxedLoopFor(BB, LI, scop->getBoxedLoops()); 685 686 // A domain to collect all predecessor domains, thus all conditions under 687 // which the block is executed. To this end we start with the empty domain. 688 isl::set PredDom = isl::set::empty(Domain.get_space()); 689 690 // Set of regions of which the entry block domain has been propagated to BB. 691 // all predecessors inside any of the regions can be skipped. 692 SmallSet<Region *, 8> PropagatedRegions; 693 694 for (auto *PredBB : predecessors(BB)) { 695 // Skip backedges. 696 if (DT.dominates(BB, PredBB)) 697 continue; 698 699 // If the predecessor is in a region we used for propagation we can skip it. 700 auto PredBBInRegion = [PredBB](Region *PR) { return PR->contains(PredBB); }; 701 if (std::any_of(PropagatedRegions.begin(), PropagatedRegions.end(), 702 PredBBInRegion)) { 703 continue; 704 } 705 706 // Check if there is a valid region we can use for propagation, thus look 707 // for a region that contains the predecessor and has @p BB as exit block. 708 auto *PredR = RI.getRegionFor(PredBB); 709 while (PredR->getExit() != BB && !PredR->contains(BB)) 710 PredR->getParent(); 711 712 // If a valid region for propagation was found use the entry of that region 713 // for propagation, otherwise the PredBB directly. 714 if (PredR->getExit() == BB) { 715 PredBB = PredR->getEntry(); 716 PropagatedRegions.insert(PredR); 717 } 718 719 isl::set PredBBDom = scop->getDomainConditions(PredBB); 720 Loop *PredBBLoop = 721 getFirstNonBoxedLoopFor(PredBB, LI, scop->getBoxedLoops()); 722 PredBBDom = adjustDomainDimensions(PredBBDom, PredBBLoop, BBLoop); 723 PredDom = PredDom.unite(PredBBDom); 724 } 725 726 return PredDom; 727 } 728 729 bool ScopBuilder::addLoopBoundsToHeaderDomain( 730 Loop *L, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 731 int LoopDepth = scop->getRelativeLoopDepth(L); 732 assert(LoopDepth >= 0 && "Loop in region should have at least depth one"); 733 734 BasicBlock *HeaderBB = L->getHeader(); 735 assert(scop->isDomainDefined(HeaderBB)); 736 isl::set &HeaderBBDom = scop->getOrInitEmptyDomain(HeaderBB); 737 738 isl::map NextIterationMap = 739 createNextIterationMap(HeaderBBDom.get_space(), LoopDepth); 740 741 isl::set UnionBackedgeCondition = HeaderBBDom.empty(HeaderBBDom.get_space()); 742 743 SmallVector<BasicBlock *, 4> LatchBlocks; 744 L->getLoopLatches(LatchBlocks); 745 746 for (BasicBlock *LatchBB : LatchBlocks) { 747 // If the latch is only reachable via error statements we skip it. 748 if (!scop->isDomainDefined(LatchBB)) 749 continue; 750 751 isl::set LatchBBDom = scop->getDomainConditions(LatchBB); 752 753 isl::set BackedgeCondition = nullptr; 754 755 Instruction *TI = LatchBB->getTerminator(); 756 BranchInst *BI = dyn_cast<BranchInst>(TI); 757 assert(BI && "Only branch instructions allowed in loop latches"); 758 759 if (BI->isUnconditional()) 760 BackedgeCondition = LatchBBDom; 761 else { 762 SmallVector<isl_set *, 8> ConditionSets; 763 int idx = BI->getSuccessor(0) != HeaderBB; 764 if (!buildConditionSets(LatchBB, TI, L, LatchBBDom.get(), 765 InvalidDomainMap, ConditionSets)) 766 return false; 767 768 // Free the non back edge condition set as we do not need it. 769 isl_set_free(ConditionSets[1 - idx]); 770 771 BackedgeCondition = isl::manage(ConditionSets[idx]); 772 } 773 774 int LatchLoopDepth = scop->getRelativeLoopDepth(LI.getLoopFor(LatchBB)); 775 assert(LatchLoopDepth >= LoopDepth); 776 BackedgeCondition = BackedgeCondition.project_out( 777 isl::dim::set, LoopDepth + 1, LatchLoopDepth - LoopDepth); 778 UnionBackedgeCondition = UnionBackedgeCondition.unite(BackedgeCondition); 779 } 780 781 isl::map ForwardMap = ForwardMap.lex_le(HeaderBBDom.get_space()); 782 for (int i = 0; i < LoopDepth; i++) 783 ForwardMap = ForwardMap.equate(isl::dim::in, i, isl::dim::out, i); 784 785 isl::set UnionBackedgeConditionComplement = 786 UnionBackedgeCondition.complement(); 787 UnionBackedgeConditionComplement = 788 UnionBackedgeConditionComplement.lower_bound_si(isl::dim::set, LoopDepth, 789 0); 790 UnionBackedgeConditionComplement = 791 UnionBackedgeConditionComplement.apply(ForwardMap); 792 HeaderBBDom = HeaderBBDom.subtract(UnionBackedgeConditionComplement); 793 HeaderBBDom = HeaderBBDom.apply(NextIterationMap); 794 795 auto Parts = partitionSetParts(HeaderBBDom, LoopDepth); 796 HeaderBBDom = Parts.second; 797 798 // Check if there is a <nsw> tagged AddRec for this loop and if so do not 799 // require a runtime check. The assumption is already implied by the <nsw> 800 // tag. 801 bool RequiresRTC = !scop->hasNSWAddRecForLoop(L); 802 803 isl::set UnboundedCtx = Parts.first.params(); 804 recordAssumption(&RecordedAssumptions, INFINITELOOP, UnboundedCtx, 805 HeaderBB->getTerminator()->getDebugLoc(), AS_RESTRICTION, 806 nullptr, RequiresRTC); 807 return true; 808 } 809 810 void ScopBuilder::buildInvariantEquivalenceClasses() { 811 DenseMap<std::pair<const SCEV *, Type *>, LoadInst *> EquivClasses; 812 813 const InvariantLoadsSetTy &RIL = scop->getRequiredInvariantLoads(); 814 for (LoadInst *LInst : RIL) { 815 const SCEV *PointerSCEV = SE.getSCEV(LInst->getPointerOperand()); 816 817 Type *Ty = LInst->getType(); 818 LoadInst *&ClassRep = EquivClasses[std::make_pair(PointerSCEV, Ty)]; 819 if (ClassRep) { 820 scop->addInvariantLoadMapping(LInst, ClassRep); 821 continue; 822 } 823 824 ClassRep = LInst; 825 scop->addInvariantEquivClass( 826 InvariantEquivClassTy{PointerSCEV, MemoryAccessList(), nullptr, Ty}); 827 } 828 } 829 830 bool ScopBuilder::buildDomains( 831 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 832 bool IsOnlyNonAffineRegion = scop->isNonAffineSubRegion(R); 833 auto *EntryBB = R->getEntry(); 834 auto *L = IsOnlyNonAffineRegion ? nullptr : LI.getLoopFor(EntryBB); 835 int LD = scop->getRelativeLoopDepth(L); 836 auto *S = 837 isl_set_universe(isl_space_set_alloc(scop->getIslCtx().get(), 0, LD + 1)); 838 839 InvalidDomainMap[EntryBB] = isl::manage(isl_set_empty(isl_set_get_space(S))); 840 isl::noexceptions::set Domain = isl::manage(S); 841 scop->setDomain(EntryBB, Domain); 842 843 if (IsOnlyNonAffineRegion) 844 return !containsErrorBlock(R->getNode(), *R, LI, DT); 845 846 if (!buildDomainsWithBranchConstraints(R, InvalidDomainMap)) 847 return false; 848 849 if (!propagateDomainConstraints(R, InvalidDomainMap)) 850 return false; 851 852 // Error blocks and blocks dominated by them have been assumed to never be 853 // executed. Representing them in the Scop does not add any value. In fact, 854 // it is likely to cause issues during construction of the ScopStmts. The 855 // contents of error blocks have not been verified to be expressible and 856 // will cause problems when building up a ScopStmt for them. 857 // Furthermore, basic blocks dominated by error blocks may reference 858 // instructions in the error block which, if the error block is not modeled, 859 // can themselves not be constructed properly. To this end we will replace 860 // the domains of error blocks and those only reachable via error blocks 861 // with an empty set. Additionally, we will record for each block under which 862 // parameter combination it would be reached via an error block in its 863 // InvalidDomain. This information is needed during load hoisting. 864 if (!propagateInvalidStmtDomains(R, InvalidDomainMap)) 865 return false; 866 867 return true; 868 } 869 870 bool ScopBuilder::buildDomainsWithBranchConstraints( 871 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 872 // To create the domain for each block in R we iterate over all blocks and 873 // subregions in R and propagate the conditions under which the current region 874 // element is executed. To this end we iterate in reverse post order over R as 875 // it ensures that we first visit all predecessors of a region node (either a 876 // basic block or a subregion) before we visit the region node itself. 877 // Initially, only the domain for the SCoP region entry block is set and from 878 // there we propagate the current domain to all successors, however we add the 879 // condition that the successor is actually executed next. 880 // As we are only interested in non-loop carried constraints here we can 881 // simply skip loop back edges. 882 883 SmallPtrSet<BasicBlock *, 8> FinishedExitBlocks; 884 ReversePostOrderTraversal<Region *> RTraversal(R); 885 for (auto *RN : RTraversal) { 886 // Recurse for affine subregions but go on for basic blocks and non-affine 887 // subregions. 888 if (RN->isSubRegion()) { 889 Region *SubRegion = RN->getNodeAs<Region>(); 890 if (!scop->isNonAffineSubRegion(SubRegion)) { 891 if (!buildDomainsWithBranchConstraints(SubRegion, InvalidDomainMap)) 892 return false; 893 continue; 894 } 895 } 896 897 if (containsErrorBlock(RN, scop->getRegion(), LI, DT)) 898 scop->notifyErrorBlock(); 899 ; 900 901 BasicBlock *BB = getRegionNodeBasicBlock(RN); 902 Instruction *TI = BB->getTerminator(); 903 904 if (isa<UnreachableInst>(TI)) 905 continue; 906 907 if (!scop->isDomainDefined(BB)) 908 continue; 909 isl::set Domain = scop->getDomainConditions(BB); 910 911 scop->updateMaxLoopDepth(isl_set_n_dim(Domain.get())); 912 913 auto *BBLoop = getRegionNodeLoop(RN, LI); 914 // Propagate the domain from BB directly to blocks that have a superset 915 // domain, at the moment only region exit nodes of regions that start in BB. 916 propagateDomainConstraintsToRegionExit(BB, BBLoop, FinishedExitBlocks, 917 InvalidDomainMap); 918 919 // If all successors of BB have been set a domain through the propagation 920 // above we do not need to build condition sets but can just skip this 921 // block. However, it is important to note that this is a local property 922 // with regards to the region @p R. To this end FinishedExitBlocks is a 923 // local variable. 924 auto IsFinishedRegionExit = [&FinishedExitBlocks](BasicBlock *SuccBB) { 925 return FinishedExitBlocks.count(SuccBB); 926 }; 927 if (std::all_of(succ_begin(BB), succ_end(BB), IsFinishedRegionExit)) 928 continue; 929 930 // Build the condition sets for the successor nodes of the current region 931 // node. If it is a non-affine subregion we will always execute the single 932 // exit node, hence the single entry node domain is the condition set. For 933 // basic blocks we use the helper function buildConditionSets. 934 SmallVector<isl_set *, 8> ConditionSets; 935 if (RN->isSubRegion()) 936 ConditionSets.push_back(Domain.copy()); 937 else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap, 938 ConditionSets)) 939 return false; 940 941 // Now iterate over the successors and set their initial domain based on 942 // their condition set. We skip back edges here and have to be careful when 943 // we leave a loop not to keep constraints over a dimension that doesn't 944 // exist anymore. 945 assert(RN->isSubRegion() || TI->getNumSuccessors() == ConditionSets.size()); 946 for (unsigned u = 0, e = ConditionSets.size(); u < e; u++) { 947 isl::set CondSet = isl::manage(ConditionSets[u]); 948 BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u); 949 950 // Skip blocks outside the region. 951 if (!scop->contains(SuccBB)) 952 continue; 953 954 // If we propagate the domain of some block to "SuccBB" we do not have to 955 // adjust the domain. 956 if (FinishedExitBlocks.count(SuccBB)) 957 continue; 958 959 // Skip back edges. 960 if (DT.dominates(SuccBB, BB)) 961 continue; 962 963 Loop *SuccBBLoop = 964 getFirstNonBoxedLoopFor(SuccBB, LI, scop->getBoxedLoops()); 965 966 CondSet = adjustDomainDimensions(CondSet, BBLoop, SuccBBLoop); 967 968 // Set the domain for the successor or merge it with an existing domain in 969 // case there are multiple paths (without loop back edges) to the 970 // successor block. 971 isl::set &SuccDomain = scop->getOrInitEmptyDomain(SuccBB); 972 973 if (SuccDomain) { 974 SuccDomain = SuccDomain.unite(CondSet).coalesce(); 975 } else { 976 // Initialize the invalid domain. 977 InvalidDomainMap[SuccBB] = CondSet.empty(CondSet.get_space()); 978 SuccDomain = CondSet; 979 } 980 981 SuccDomain = SuccDomain.detect_equalities(); 982 983 // Check if the maximal number of domain disjunctions was reached. 984 // In case this happens we will clean up and bail. 985 if (SuccDomain.n_basic_set() < MaxDisjunctsInDomain) 986 continue; 987 988 scop->invalidate(COMPLEXITY, DebugLoc()); 989 while (++u < ConditionSets.size()) 990 isl_set_free(ConditionSets[u]); 991 return false; 992 } 993 } 994 995 return true; 996 } 997 998 bool ScopBuilder::propagateInvalidStmtDomains( 999 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 1000 ReversePostOrderTraversal<Region *> RTraversal(R); 1001 for (auto *RN : RTraversal) { 1002 1003 // Recurse for affine subregions but go on for basic blocks and non-affine 1004 // subregions. 1005 if (RN->isSubRegion()) { 1006 Region *SubRegion = RN->getNodeAs<Region>(); 1007 if (!scop->isNonAffineSubRegion(SubRegion)) { 1008 propagateInvalidStmtDomains(SubRegion, InvalidDomainMap); 1009 continue; 1010 } 1011 } 1012 1013 bool ContainsErrorBlock = containsErrorBlock(RN, scop->getRegion(), LI, DT); 1014 BasicBlock *BB = getRegionNodeBasicBlock(RN); 1015 isl::set &Domain = scop->getOrInitEmptyDomain(BB); 1016 assert(Domain && "Cannot propagate a nullptr"); 1017 1018 isl::set InvalidDomain = InvalidDomainMap[BB]; 1019 1020 bool IsInvalidBlock = ContainsErrorBlock || Domain.is_subset(InvalidDomain); 1021 1022 if (!IsInvalidBlock) { 1023 InvalidDomain = InvalidDomain.intersect(Domain); 1024 } else { 1025 InvalidDomain = Domain; 1026 isl::set DomPar = Domain.params(); 1027 recordAssumption(&RecordedAssumptions, ERRORBLOCK, DomPar, 1028 BB->getTerminator()->getDebugLoc(), AS_RESTRICTION); 1029 Domain = isl::set::empty(Domain.get_space()); 1030 } 1031 1032 if (InvalidDomain.is_empty()) { 1033 InvalidDomainMap[BB] = InvalidDomain; 1034 continue; 1035 } 1036 1037 auto *BBLoop = getRegionNodeLoop(RN, LI); 1038 auto *TI = BB->getTerminator(); 1039 unsigned NumSuccs = RN->isSubRegion() ? 1 : TI->getNumSuccessors(); 1040 for (unsigned u = 0; u < NumSuccs; u++) { 1041 auto *SuccBB = getRegionNodeSuccessor(RN, TI, u); 1042 1043 // Skip successors outside the SCoP. 1044 if (!scop->contains(SuccBB)) 1045 continue; 1046 1047 // Skip backedges. 1048 if (DT.dominates(SuccBB, BB)) 1049 continue; 1050 1051 Loop *SuccBBLoop = 1052 getFirstNonBoxedLoopFor(SuccBB, LI, scop->getBoxedLoops()); 1053 1054 auto AdjustedInvalidDomain = 1055 adjustDomainDimensions(InvalidDomain, BBLoop, SuccBBLoop); 1056 1057 isl::set SuccInvalidDomain = InvalidDomainMap[SuccBB]; 1058 SuccInvalidDomain = SuccInvalidDomain.unite(AdjustedInvalidDomain); 1059 SuccInvalidDomain = SuccInvalidDomain.coalesce(); 1060 1061 InvalidDomainMap[SuccBB] = SuccInvalidDomain; 1062 1063 // Check if the maximal number of domain disjunctions was reached. 1064 // In case this happens we will bail. 1065 if (SuccInvalidDomain.n_basic_set() < MaxDisjunctsInDomain) 1066 continue; 1067 1068 InvalidDomainMap.erase(BB); 1069 scop->invalidate(COMPLEXITY, TI->getDebugLoc(), TI->getParent()); 1070 return false; 1071 } 1072 1073 InvalidDomainMap[BB] = InvalidDomain; 1074 } 1075 1076 return true; 1077 } 1078 1079 void ScopBuilder::buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI, 1080 Region *NonAffineSubRegion, 1081 bool IsExitBlock) { 1082 // PHI nodes that are in the exit block of the region, hence if IsExitBlock is 1083 // true, are not modeled as ordinary PHI nodes as they are not part of the 1084 // region. However, we model the operands in the predecessor blocks that are 1085 // part of the region as regular scalar accesses. 1086 1087 // If we can synthesize a PHI we can skip it, however only if it is in 1088 // the region. If it is not it can only be in the exit block of the region. 1089 // In this case we model the operands but not the PHI itself. 1090 auto *Scope = LI.getLoopFor(PHI->getParent()); 1091 if (!IsExitBlock && canSynthesize(PHI, *scop, &SE, Scope)) 1092 return; 1093 1094 // PHI nodes are modeled as if they had been demoted prior to the SCoP 1095 // detection. Hence, the PHI is a load of a new memory location in which the 1096 // incoming value was written at the end of the incoming basic block. 1097 bool OnlyNonAffineSubRegionOperands = true; 1098 for (unsigned u = 0; u < PHI->getNumIncomingValues(); u++) { 1099 Value *Op = PHI->getIncomingValue(u); 1100 BasicBlock *OpBB = PHI->getIncomingBlock(u); 1101 ScopStmt *OpStmt = scop->getIncomingStmtFor(PHI->getOperandUse(u)); 1102 1103 // Do not build PHI dependences inside a non-affine subregion, but make 1104 // sure that the necessary scalar values are still made available. 1105 if (NonAffineSubRegion && NonAffineSubRegion->contains(OpBB)) { 1106 auto *OpInst = dyn_cast<Instruction>(Op); 1107 if (!OpInst || !NonAffineSubRegion->contains(OpInst)) 1108 ensureValueRead(Op, OpStmt); 1109 continue; 1110 } 1111 1112 OnlyNonAffineSubRegionOperands = false; 1113 ensurePHIWrite(PHI, OpStmt, OpBB, Op, IsExitBlock); 1114 } 1115 1116 if (!OnlyNonAffineSubRegionOperands && !IsExitBlock) { 1117 addPHIReadAccess(PHIStmt, PHI); 1118 } 1119 } 1120 1121 void ScopBuilder::buildScalarDependences(ScopStmt *UserStmt, 1122 Instruction *Inst) { 1123 assert(!isa<PHINode>(Inst)); 1124 1125 // Pull-in required operands. 1126 for (Use &Op : Inst->operands()) 1127 ensureValueRead(Op.get(), UserStmt); 1128 } 1129 1130 // Create a sequence of two schedules. Either argument may be null and is 1131 // interpreted as the empty schedule. Can also return null if both schedules are 1132 // empty. 1133 static isl::schedule combineInSequence(isl::schedule Prev, isl::schedule Succ) { 1134 if (!Prev) 1135 return Succ; 1136 if (!Succ) 1137 return Prev; 1138 1139 return Prev.sequence(Succ); 1140 } 1141 1142 // Create an isl_multi_union_aff that defines an identity mapping from the 1143 // elements of USet to their N-th dimension. 1144 // 1145 // # Example: 1146 // 1147 // Domain: { A[i,j]; B[i,j,k] } 1148 // N: 1 1149 // 1150 // Resulting Mapping: { {A[i,j] -> [(j)]; B[i,j,k] -> [(j)] } 1151 // 1152 // @param USet A union set describing the elements for which to generate a 1153 // mapping. 1154 // @param N The dimension to map to. 1155 // @returns A mapping from USet to its N-th dimension. 1156 static isl::multi_union_pw_aff mapToDimension(isl::union_set USet, int N) { 1157 assert(N >= 0); 1158 assert(USet); 1159 assert(!USet.is_empty()); 1160 1161 auto Result = isl::union_pw_multi_aff::empty(USet.get_space()); 1162 1163 for (isl::set S : USet.get_set_list()) { 1164 int Dim = S.dim(isl::dim::set); 1165 auto PMA = isl::pw_multi_aff::project_out_map(S.get_space(), isl::dim::set, 1166 N, Dim - N); 1167 if (N > 1) 1168 PMA = PMA.drop_dims(isl::dim::out, 0, N - 1); 1169 1170 Result = Result.add_pw_multi_aff(PMA); 1171 } 1172 1173 return isl::multi_union_pw_aff(isl::union_pw_multi_aff(Result)); 1174 } 1175 1176 void ScopBuilder::buildSchedule() { 1177 Loop *L = getLoopSurroundingScop(*scop, LI); 1178 LoopStackTy LoopStack({LoopStackElementTy(L, nullptr, 0)}); 1179 buildSchedule(scop->getRegion().getNode(), LoopStack); 1180 assert(LoopStack.size() == 1 && LoopStack.back().L == L); 1181 scop->setScheduleTree(LoopStack[0].Schedule); 1182 } 1183 1184 /// To generate a schedule for the elements in a Region we traverse the Region 1185 /// in reverse-post-order and add the contained RegionNodes in traversal order 1186 /// to the schedule of the loop that is currently at the top of the LoopStack. 1187 /// For loop-free codes, this results in a correct sequential ordering. 1188 /// 1189 /// Example: 1190 /// bb1(0) 1191 /// / \. 1192 /// bb2(1) bb3(2) 1193 /// \ / \. 1194 /// bb4(3) bb5(4) 1195 /// \ / 1196 /// bb6(5) 1197 /// 1198 /// Including loops requires additional processing. Whenever a loop header is 1199 /// encountered, the corresponding loop is added to the @p LoopStack. Starting 1200 /// from an empty schedule, we first process all RegionNodes that are within 1201 /// this loop and complete the sequential schedule at this loop-level before 1202 /// processing about any other nodes. To implement this 1203 /// loop-nodes-first-processing, the reverse post-order traversal is 1204 /// insufficient. Hence, we additionally check if the traversal yields 1205 /// sub-regions or blocks that are outside the last loop on the @p LoopStack. 1206 /// These region-nodes are then queue and only traverse after the all nodes 1207 /// within the current loop have been processed. 1208 void ScopBuilder::buildSchedule(Region *R, LoopStackTy &LoopStack) { 1209 Loop *OuterScopLoop = getLoopSurroundingScop(*scop, LI); 1210 1211 ReversePostOrderTraversal<Region *> RTraversal(R); 1212 std::deque<RegionNode *> WorkList(RTraversal.begin(), RTraversal.end()); 1213 std::deque<RegionNode *> DelayList; 1214 bool LastRNWaiting = false; 1215 1216 // Iterate over the region @p R in reverse post-order but queue 1217 // sub-regions/blocks iff they are not part of the last encountered but not 1218 // completely traversed loop. The variable LastRNWaiting is a flag to indicate 1219 // that we queued the last sub-region/block from the reverse post-order 1220 // iterator. If it is set we have to explore the next sub-region/block from 1221 // the iterator (if any) to guarantee progress. If it is not set we first try 1222 // the next queued sub-region/blocks. 1223 while (!WorkList.empty() || !DelayList.empty()) { 1224 RegionNode *RN; 1225 1226 if ((LastRNWaiting && !WorkList.empty()) || DelayList.empty()) { 1227 RN = WorkList.front(); 1228 WorkList.pop_front(); 1229 LastRNWaiting = false; 1230 } else { 1231 RN = DelayList.front(); 1232 DelayList.pop_front(); 1233 } 1234 1235 Loop *L = getRegionNodeLoop(RN, LI); 1236 if (!scop->contains(L)) 1237 L = OuterScopLoop; 1238 1239 Loop *LastLoop = LoopStack.back().L; 1240 if (LastLoop != L) { 1241 if (LastLoop && !LastLoop->contains(L)) { 1242 LastRNWaiting = true; 1243 DelayList.push_back(RN); 1244 continue; 1245 } 1246 LoopStack.push_back({L, nullptr, 0}); 1247 } 1248 buildSchedule(RN, LoopStack); 1249 } 1250 } 1251 1252 void ScopBuilder::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack) { 1253 if (RN->isSubRegion()) { 1254 auto *LocalRegion = RN->getNodeAs<Region>(); 1255 if (!scop->isNonAffineSubRegion(LocalRegion)) { 1256 buildSchedule(LocalRegion, LoopStack); 1257 return; 1258 } 1259 } 1260 1261 assert(LoopStack.rbegin() != LoopStack.rend()); 1262 auto LoopData = LoopStack.rbegin(); 1263 LoopData->NumBlocksProcessed += getNumBlocksInRegionNode(RN); 1264 1265 for (auto *Stmt : scop->getStmtListFor(RN)) { 1266 isl::union_set UDomain{Stmt->getDomain()}; 1267 auto StmtSchedule = isl::schedule::from_domain(UDomain); 1268 LoopData->Schedule = combineInSequence(LoopData->Schedule, StmtSchedule); 1269 } 1270 1271 // Check if we just processed the last node in this loop. If we did, finalize 1272 // the loop by: 1273 // 1274 // - adding new schedule dimensions 1275 // - folding the resulting schedule into the parent loop schedule 1276 // - dropping the loop schedule from the LoopStack. 1277 // 1278 // Then continue to check surrounding loops, which might also have been 1279 // completed by this node. 1280 size_t Dimension = LoopStack.size(); 1281 while (LoopData->L && 1282 LoopData->NumBlocksProcessed == getNumBlocksInLoop(LoopData->L)) { 1283 isl::schedule Schedule = LoopData->Schedule; 1284 auto NumBlocksProcessed = LoopData->NumBlocksProcessed; 1285 1286 assert(std::next(LoopData) != LoopStack.rend()); 1287 ++LoopData; 1288 --Dimension; 1289 1290 if (Schedule) { 1291 isl::union_set Domain = Schedule.get_domain(); 1292 isl::multi_union_pw_aff MUPA = mapToDimension(Domain, Dimension); 1293 Schedule = Schedule.insert_partial_schedule(MUPA); 1294 LoopData->Schedule = combineInSequence(LoopData->Schedule, Schedule); 1295 } 1296 1297 LoopData->NumBlocksProcessed += NumBlocksProcessed; 1298 } 1299 // Now pop all loops processed up there from the LoopStack 1300 LoopStack.erase(LoopStack.begin() + Dimension, LoopStack.end()); 1301 } 1302 1303 void ScopBuilder::buildEscapingDependences(Instruction *Inst) { 1304 // Check for uses of this instruction outside the scop. Because we do not 1305 // iterate over such instructions and therefore did not "ensure" the existence 1306 // of a write, we must determine such use here. 1307 if (scop->isEscaping(Inst)) 1308 ensureValueWrite(Inst); 1309 } 1310 1311 /// Check that a value is a Fortran Array descriptor. 1312 /// 1313 /// We check if V has the following structure: 1314 /// %"struct.array1_real(kind=8)" = type { i8*, i<zz>, i<zz>, 1315 /// [<num> x %struct.descriptor_dimension] } 1316 /// 1317 /// 1318 /// %struct.descriptor_dimension = type { i<zz>, i<zz>, i<zz> } 1319 /// 1320 /// 1. V's type name starts with "struct.array" 1321 /// 2. V's type has layout as shown. 1322 /// 3. Final member of V's type has name "struct.descriptor_dimension", 1323 /// 4. "struct.descriptor_dimension" has layout as shown. 1324 /// 5. Consistent use of i<zz> where <zz> is some fixed integer number. 1325 /// 1326 /// We are interested in such types since this is the code that dragonegg 1327 /// generates for Fortran array descriptors. 1328 /// 1329 /// @param V the Value to be checked. 1330 /// 1331 /// @returns True if V is a Fortran array descriptor, False otherwise. 1332 bool isFortranArrayDescriptor(Value *V) { 1333 PointerType *PTy = dyn_cast<PointerType>(V->getType()); 1334 1335 if (!PTy) 1336 return false; 1337 1338 Type *Ty = PTy->getElementType(); 1339 assert(Ty && "Ty expected to be initialized"); 1340 auto *StructArrTy = dyn_cast<StructType>(Ty); 1341 1342 if (!(StructArrTy && StructArrTy->hasName())) 1343 return false; 1344 1345 if (!StructArrTy->getName().startswith("struct.array")) 1346 return false; 1347 1348 if (StructArrTy->getNumElements() != 4) 1349 return false; 1350 1351 const ArrayRef<Type *> ArrMemberTys = StructArrTy->elements(); 1352 1353 // i8* match 1354 if (ArrMemberTys[0] != Type::getInt8PtrTy(V->getContext())) 1355 return false; 1356 1357 // Get a reference to the int type and check that all the members 1358 // share the same int type 1359 Type *IntTy = ArrMemberTys[1]; 1360 if (ArrMemberTys[2] != IntTy) 1361 return false; 1362 1363 // type: [<num> x %struct.descriptor_dimension] 1364 ArrayType *DescriptorDimArrayTy = dyn_cast<ArrayType>(ArrMemberTys[3]); 1365 if (!DescriptorDimArrayTy) 1366 return false; 1367 1368 // type: %struct.descriptor_dimension := type { ixx, ixx, ixx } 1369 StructType *DescriptorDimTy = 1370 dyn_cast<StructType>(DescriptorDimArrayTy->getElementType()); 1371 1372 if (!(DescriptorDimTy && DescriptorDimTy->hasName())) 1373 return false; 1374 1375 if (DescriptorDimTy->getName() != "struct.descriptor_dimension") 1376 return false; 1377 1378 if (DescriptorDimTy->getNumElements() != 3) 1379 return false; 1380 1381 for (auto MemberTy : DescriptorDimTy->elements()) { 1382 if (MemberTy != IntTy) 1383 return false; 1384 } 1385 1386 return true; 1387 } 1388 1389 Value *ScopBuilder::findFADAllocationVisible(MemAccInst Inst) { 1390 // match: 4.1 & 4.2 store/load 1391 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst)) 1392 return nullptr; 1393 1394 // match: 4 1395 if (Inst.getAlignment() != 8) 1396 return nullptr; 1397 1398 Value *Address = Inst.getPointerOperand(); 1399 1400 const BitCastInst *Bitcast = nullptr; 1401 // [match: 3] 1402 if (auto *Slot = dyn_cast<GetElementPtrInst>(Address)) { 1403 Value *TypedMem = Slot->getPointerOperand(); 1404 // match: 2 1405 Bitcast = dyn_cast<BitCastInst>(TypedMem); 1406 } else { 1407 // match: 2 1408 Bitcast = dyn_cast<BitCastInst>(Address); 1409 } 1410 1411 if (!Bitcast) 1412 return nullptr; 1413 1414 auto *MallocMem = Bitcast->getOperand(0); 1415 1416 // match: 1 1417 auto *MallocCall = dyn_cast<CallInst>(MallocMem); 1418 if (!MallocCall) 1419 return nullptr; 1420 1421 Function *MallocFn = MallocCall->getCalledFunction(); 1422 if (!(MallocFn && MallocFn->hasName() && MallocFn->getName() == "malloc")) 1423 return nullptr; 1424 1425 // Find all uses the malloc'd memory. 1426 // We are looking for a "store" into a struct with the type being the Fortran 1427 // descriptor type 1428 for (auto user : MallocMem->users()) { 1429 /// match: 5 1430 auto *MallocStore = dyn_cast<StoreInst>(user); 1431 if (!MallocStore) 1432 continue; 1433 1434 auto *DescriptorGEP = 1435 dyn_cast<GEPOperator>(MallocStore->getPointerOperand()); 1436 if (!DescriptorGEP) 1437 continue; 1438 1439 // match: 5 1440 auto DescriptorType = 1441 dyn_cast<StructType>(DescriptorGEP->getSourceElementType()); 1442 if (!(DescriptorType && DescriptorType->hasName())) 1443 continue; 1444 1445 Value *Descriptor = dyn_cast<Value>(DescriptorGEP->getPointerOperand()); 1446 1447 if (!Descriptor) 1448 continue; 1449 1450 if (!isFortranArrayDescriptor(Descriptor)) 1451 continue; 1452 1453 return Descriptor; 1454 } 1455 1456 return nullptr; 1457 } 1458 1459 Value *ScopBuilder::findFADAllocationInvisible(MemAccInst Inst) { 1460 // match: 3 1461 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst)) 1462 return nullptr; 1463 1464 Value *Slot = Inst.getPointerOperand(); 1465 1466 LoadInst *MemLoad = nullptr; 1467 // [match: 2] 1468 if (auto *SlotGEP = dyn_cast<GetElementPtrInst>(Slot)) { 1469 // match: 1 1470 MemLoad = dyn_cast<LoadInst>(SlotGEP->getPointerOperand()); 1471 } else { 1472 // match: 1 1473 MemLoad = dyn_cast<LoadInst>(Slot); 1474 } 1475 1476 if (!MemLoad) 1477 return nullptr; 1478 1479 auto *BitcastOperator = 1480 dyn_cast<BitCastOperator>(MemLoad->getPointerOperand()); 1481 if (!BitcastOperator) 1482 return nullptr; 1483 1484 Value *Descriptor = dyn_cast<Value>(BitcastOperator->getOperand(0)); 1485 if (!Descriptor) 1486 return nullptr; 1487 1488 if (!isFortranArrayDescriptor(Descriptor)) 1489 return nullptr; 1490 1491 return Descriptor; 1492 } 1493 1494 void ScopBuilder::addRecordedAssumptions() { 1495 for (auto &AS : llvm::reverse(RecordedAssumptions)) { 1496 1497 if (!AS.BB) { 1498 scop->addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign, 1499 nullptr /* BasicBlock */, AS.RequiresRTC); 1500 continue; 1501 } 1502 1503 // If the domain was deleted the assumptions are void. 1504 isl_set *Dom = scop->getDomainConditions(AS.BB).release(); 1505 if (!Dom) 1506 continue; 1507 1508 // If a basic block was given use its domain to simplify the assumption. 1509 // In case of restrictions we know they only have to hold on the domain, 1510 // thus we can intersect them with the domain of the block. However, for 1511 // assumptions the domain has to imply them, thus: 1512 // _ _____ 1513 // Dom => S <==> A v B <==> A - B 1514 // 1515 // To avoid the complement we will register A - B as a restriction not an 1516 // assumption. 1517 isl_set *S = AS.Set.copy(); 1518 if (AS.Sign == AS_RESTRICTION) 1519 S = isl_set_params(isl_set_intersect(S, Dom)); 1520 else /* (AS.Sign == AS_ASSUMPTION) */ 1521 S = isl_set_params(isl_set_subtract(Dom, S)); 1522 1523 scop->addAssumption(AS.Kind, isl::manage(S), AS.Loc, AS_RESTRICTION, AS.BB, 1524 AS.RequiresRTC); 1525 } 1526 } 1527 1528 void ScopBuilder::addUserAssumptions( 1529 AssumptionCache &AC, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) { 1530 for (auto &Assumption : AC.assumptions()) { 1531 auto *CI = dyn_cast_or_null<CallInst>(Assumption); 1532 if (!CI || CI->getNumArgOperands() != 1) 1533 continue; 1534 1535 bool InScop = scop->contains(CI); 1536 if (!InScop && !scop->isDominatedBy(DT, CI->getParent())) 1537 continue; 1538 1539 auto *L = LI.getLoopFor(CI->getParent()); 1540 auto *Val = CI->getArgOperand(0); 1541 ParameterSetTy DetectedParams; 1542 auto &R = scop->getRegion(); 1543 if (!isAffineConstraint(Val, &R, L, SE, DetectedParams)) { 1544 ORE.emit( 1545 OptimizationRemarkAnalysis(DEBUG_TYPE, "IgnoreUserAssumption", CI) 1546 << "Non-affine user assumption ignored."); 1547 continue; 1548 } 1549 1550 // Collect all newly introduced parameters. 1551 ParameterSetTy NewParams; 1552 for (auto *Param : DetectedParams) { 1553 Param = extractConstantFactor(Param, SE).second; 1554 Param = scop->getRepresentingInvariantLoadSCEV(Param); 1555 if (scop->isParam(Param)) 1556 continue; 1557 NewParams.insert(Param); 1558 } 1559 1560 SmallVector<isl_set *, 2> ConditionSets; 1561 auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr; 1562 BasicBlock *BB = InScop ? CI->getParent() : R.getEntry(); 1563 auto *Dom = InScop ? isl_set_copy(scop->getDomainConditions(BB).get()) 1564 : isl_set_copy(scop->getContext().get()); 1565 assert(Dom && "Cannot propagate a nullptr."); 1566 bool Valid = buildConditionSets(BB, Val, TI, L, Dom, InvalidDomainMap, 1567 ConditionSets); 1568 isl_set_free(Dom); 1569 1570 if (!Valid) 1571 continue; 1572 1573 isl_set *AssumptionCtx = nullptr; 1574 if (InScop) { 1575 AssumptionCtx = isl_set_complement(isl_set_params(ConditionSets[1])); 1576 isl_set_free(ConditionSets[0]); 1577 } else { 1578 AssumptionCtx = isl_set_complement(ConditionSets[1]); 1579 AssumptionCtx = isl_set_intersect(AssumptionCtx, ConditionSets[0]); 1580 } 1581 1582 // Project out newly introduced parameters as they are not otherwise useful. 1583 if (!NewParams.empty()) { 1584 for (isl_size u = 0; u < isl_set_n_param(AssumptionCtx); u++) { 1585 auto *Id = isl_set_get_dim_id(AssumptionCtx, isl_dim_param, u); 1586 auto *Param = static_cast<const SCEV *>(isl_id_get_user(Id)); 1587 isl_id_free(Id); 1588 1589 if (!NewParams.count(Param)) 1590 continue; 1591 1592 AssumptionCtx = 1593 isl_set_project_out(AssumptionCtx, isl_dim_param, u--, 1); 1594 } 1595 } 1596 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "UserAssumption", CI) 1597 << "Use user assumption: " << stringFromIslObj(AssumptionCtx)); 1598 isl::set newContext = 1599 scop->getContext().intersect(isl::manage(AssumptionCtx)); 1600 scop->setContext(newContext); 1601 } 1602 } 1603 1604 bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) { 1605 Value *Val = Inst.getValueOperand(); 1606 Type *ElementType = Val->getType(); 1607 Value *Address = Inst.getPointerOperand(); 1608 const SCEV *AccessFunction = 1609 SE.getSCEVAtScope(Address, LI.getLoopFor(Inst->getParent())); 1610 const SCEVUnknown *BasePointer = 1611 dyn_cast<SCEVUnknown>(SE.getPointerBase(AccessFunction)); 1612 enum MemoryAccess::AccessType AccType = 1613 isa<LoadInst>(Inst) ? MemoryAccess::READ : MemoryAccess::MUST_WRITE; 1614 1615 if (auto *BitCast = dyn_cast<BitCastInst>(Address)) { 1616 auto *Src = BitCast->getOperand(0); 1617 auto *SrcTy = Src->getType(); 1618 auto *DstTy = BitCast->getType(); 1619 // Do not try to delinearize non-sized (opaque) pointers. 1620 if ((SrcTy->isPointerTy() && !SrcTy->getPointerElementType()->isSized()) || 1621 (DstTy->isPointerTy() && !DstTy->getPointerElementType()->isSized())) { 1622 return false; 1623 } 1624 if (SrcTy->isPointerTy() && DstTy->isPointerTy() && 1625 DL.getTypeAllocSize(SrcTy->getPointerElementType()) == 1626 DL.getTypeAllocSize(DstTy->getPointerElementType())) 1627 Address = Src; 1628 } 1629 1630 auto *GEP = dyn_cast<GetElementPtrInst>(Address); 1631 if (!GEP) 1632 return false; 1633 1634 SmallVector<const SCEV *, 4> Subscripts; 1635 SmallVector<int, 4> Sizes; 1636 SE.getIndexExpressionsFromGEP(GEP, Subscripts, Sizes); 1637 auto *BasePtr = GEP->getOperand(0); 1638 1639 if (auto *BasePtrCast = dyn_cast<BitCastInst>(BasePtr)) 1640 BasePtr = BasePtrCast->getOperand(0); 1641 1642 // Check for identical base pointers to ensure that we do not miss index 1643 // offsets that have been added before this GEP is applied. 1644 if (BasePtr != BasePointer->getValue()) 1645 return false; 1646 1647 std::vector<const SCEV *> SizesSCEV; 1648 1649 const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads(); 1650 1651 Loop *SurroundingLoop = Stmt->getSurroundingLoop(); 1652 for (auto *Subscript : Subscripts) { 1653 InvariantLoadsSetTy AccessILS; 1654 if (!isAffineExpr(&scop->getRegion(), SurroundingLoop, Subscript, SE, 1655 &AccessILS)) 1656 return false; 1657 1658 for (LoadInst *LInst : AccessILS) 1659 if (!ScopRIL.count(LInst)) 1660 return false; 1661 } 1662 1663 if (Sizes.empty()) 1664 return false; 1665 1666 SizesSCEV.push_back(nullptr); 1667 1668 for (auto V : Sizes) 1669 SizesSCEV.push_back(SE.getSCEV( 1670 ConstantInt::get(IntegerType::getInt64Ty(BasePtr->getContext()), V))); 1671 1672 addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType, 1673 true, Subscripts, SizesSCEV, Val); 1674 return true; 1675 } 1676 1677 bool ScopBuilder::buildAccessMultiDimParam(MemAccInst Inst, ScopStmt *Stmt) { 1678 if (!PollyDelinearize) 1679 return false; 1680 1681 Value *Address = Inst.getPointerOperand(); 1682 Value *Val = Inst.getValueOperand(); 1683 Type *ElementType = Val->getType(); 1684 unsigned ElementSize = DL.getTypeAllocSize(ElementType); 1685 enum MemoryAccess::AccessType AccType = 1686 isa<LoadInst>(Inst) ? MemoryAccess::READ : MemoryAccess::MUST_WRITE; 1687 1688 const SCEV *AccessFunction = 1689 SE.getSCEVAtScope(Address, LI.getLoopFor(Inst->getParent())); 1690 const SCEVUnknown *BasePointer = 1691 dyn_cast<SCEVUnknown>(SE.getPointerBase(AccessFunction)); 1692 1693 assert(BasePointer && "Could not find base pointer"); 1694 1695 auto &InsnToMemAcc = scop->getInsnToMemAccMap(); 1696 auto AccItr = InsnToMemAcc.find(Inst); 1697 if (AccItr == InsnToMemAcc.end()) 1698 return false; 1699 1700 std::vector<const SCEV *> Sizes = {nullptr}; 1701 1702 Sizes.insert(Sizes.end(), AccItr->second.Shape->DelinearizedSizes.begin(), 1703 AccItr->second.Shape->DelinearizedSizes.end()); 1704 1705 // In case only the element size is contained in the 'Sizes' array, the 1706 // access does not access a real multi-dimensional array. Hence, we allow 1707 // the normal single-dimensional access construction to handle this. 1708 if (Sizes.size() == 1) 1709 return false; 1710 1711 // Remove the element size. This information is already provided by the 1712 // ElementSize parameter. In case the element size of this access and the 1713 // element size used for delinearization differs the delinearization is 1714 // incorrect. Hence, we invalidate the scop. 1715 // 1716 // TODO: Handle delinearization with differing element sizes. 1717 auto DelinearizedSize = 1718 cast<SCEVConstant>(Sizes.back())->getAPInt().getSExtValue(); 1719 Sizes.pop_back(); 1720 if (ElementSize != DelinearizedSize) 1721 scop->invalidate(DELINEARIZATION, Inst->getDebugLoc(), Inst->getParent()); 1722 1723 addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType, 1724 true, AccItr->second.DelinearizedSubscripts, Sizes, Val); 1725 return true; 1726 } 1727 1728 bool ScopBuilder::buildAccessMemIntrinsic(MemAccInst Inst, ScopStmt *Stmt) { 1729 auto *MemIntr = dyn_cast_or_null<MemIntrinsic>(Inst); 1730 1731 if (MemIntr == nullptr) 1732 return false; 1733 1734 auto *L = LI.getLoopFor(Inst->getParent()); 1735 auto *LengthVal = SE.getSCEVAtScope(MemIntr->getLength(), L); 1736 assert(LengthVal); 1737 1738 // Check if the length val is actually affine or if we overapproximate it 1739 InvariantLoadsSetTy AccessILS; 1740 const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads(); 1741 1742 Loop *SurroundingLoop = Stmt->getSurroundingLoop(); 1743 bool LengthIsAffine = isAffineExpr(&scop->getRegion(), SurroundingLoop, 1744 LengthVal, SE, &AccessILS); 1745 for (LoadInst *LInst : AccessILS) 1746 if (!ScopRIL.count(LInst)) 1747 LengthIsAffine = false; 1748 if (!LengthIsAffine) 1749 LengthVal = nullptr; 1750 1751 auto *DestPtrVal = MemIntr->getDest(); 1752 assert(DestPtrVal); 1753 1754 auto *DestAccFunc = SE.getSCEVAtScope(DestPtrVal, L); 1755 assert(DestAccFunc); 1756 // Ignore accesses to "NULL". 1757 // TODO: We could use this to optimize the region further, e.g., intersect 1758 // the context with 1759 // isl_set_complement(isl_set_params(getDomain())) 1760 // as we know it would be undefined to execute this instruction anyway. 1761 if (DestAccFunc->isZero()) 1762 return true; 1763 1764 auto *DestPtrSCEV = dyn_cast<SCEVUnknown>(SE.getPointerBase(DestAccFunc)); 1765 assert(DestPtrSCEV); 1766 DestAccFunc = SE.getMinusSCEV(DestAccFunc, DestPtrSCEV); 1767 addArrayAccess(Stmt, Inst, MemoryAccess::MUST_WRITE, DestPtrSCEV->getValue(), 1768 IntegerType::getInt8Ty(DestPtrVal->getContext()), 1769 LengthIsAffine, {DestAccFunc, LengthVal}, {nullptr}, 1770 Inst.getValueOperand()); 1771 1772 auto *MemTrans = dyn_cast<MemTransferInst>(MemIntr); 1773 if (!MemTrans) 1774 return true; 1775 1776 auto *SrcPtrVal = MemTrans->getSource(); 1777 assert(SrcPtrVal); 1778 1779 auto *SrcAccFunc = SE.getSCEVAtScope(SrcPtrVal, L); 1780 assert(SrcAccFunc); 1781 // Ignore accesses to "NULL". 1782 // TODO: See above TODO 1783 if (SrcAccFunc->isZero()) 1784 return true; 1785 1786 auto *SrcPtrSCEV = dyn_cast<SCEVUnknown>(SE.getPointerBase(SrcAccFunc)); 1787 assert(SrcPtrSCEV); 1788 SrcAccFunc = SE.getMinusSCEV(SrcAccFunc, SrcPtrSCEV); 1789 addArrayAccess(Stmt, Inst, MemoryAccess::READ, SrcPtrSCEV->getValue(), 1790 IntegerType::getInt8Ty(SrcPtrVal->getContext()), 1791 LengthIsAffine, {SrcAccFunc, LengthVal}, {nullptr}, 1792 Inst.getValueOperand()); 1793 1794 return true; 1795 } 1796 1797 bool ScopBuilder::buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt) { 1798 auto *CI = dyn_cast_or_null<CallInst>(Inst); 1799 1800 if (CI == nullptr) 1801 return false; 1802 1803 if (CI->doesNotAccessMemory() || isIgnoredIntrinsic(CI) || isDebugCall(CI)) 1804 return true; 1805 1806 bool ReadOnly = false; 1807 auto *AF = SE.getConstant(IntegerType::getInt64Ty(CI->getContext()), 0); 1808 auto *CalledFunction = CI->getCalledFunction(); 1809 switch (AA.getModRefBehavior(CalledFunction)) { 1810 case FMRB_UnknownModRefBehavior: 1811 llvm_unreachable("Unknown mod ref behaviour cannot be represented."); 1812 case FMRB_DoesNotAccessMemory: 1813 return true; 1814 case FMRB_OnlyWritesMemory: 1815 case FMRB_OnlyWritesInaccessibleMem: 1816 case FMRB_OnlyWritesInaccessibleOrArgMem: 1817 case FMRB_OnlyAccessesInaccessibleMem: 1818 case FMRB_OnlyAccessesInaccessibleOrArgMem: 1819 return false; 1820 case FMRB_OnlyReadsMemory: 1821 case FMRB_OnlyReadsInaccessibleMem: 1822 case FMRB_OnlyReadsInaccessibleOrArgMem: 1823 GlobalReads.emplace_back(Stmt, CI); 1824 return true; 1825 case FMRB_OnlyReadsArgumentPointees: 1826 ReadOnly = true; 1827 LLVM_FALLTHROUGH; 1828 case FMRB_OnlyWritesArgumentPointees: 1829 case FMRB_OnlyAccessesArgumentPointees: { 1830 auto AccType = ReadOnly ? MemoryAccess::READ : MemoryAccess::MAY_WRITE; 1831 Loop *L = LI.getLoopFor(Inst->getParent()); 1832 for (const auto &Arg : CI->arg_operands()) { 1833 if (!Arg->getType()->isPointerTy()) 1834 continue; 1835 1836 auto *ArgSCEV = SE.getSCEVAtScope(Arg, L); 1837 if (ArgSCEV->isZero()) 1838 continue; 1839 1840 auto *ArgBasePtr = cast<SCEVUnknown>(SE.getPointerBase(ArgSCEV)); 1841 addArrayAccess(Stmt, Inst, AccType, ArgBasePtr->getValue(), 1842 ArgBasePtr->getType(), false, {AF}, {nullptr}, CI); 1843 } 1844 return true; 1845 } 1846 } 1847 1848 return true; 1849 } 1850 1851 void ScopBuilder::buildAccessSingleDim(MemAccInst Inst, ScopStmt *Stmt) { 1852 Value *Address = Inst.getPointerOperand(); 1853 Value *Val = Inst.getValueOperand(); 1854 Type *ElementType = Val->getType(); 1855 enum MemoryAccess::AccessType AccType = 1856 isa<LoadInst>(Inst) ? MemoryAccess::READ : MemoryAccess::MUST_WRITE; 1857 1858 const SCEV *AccessFunction = 1859 SE.getSCEVAtScope(Address, LI.getLoopFor(Inst->getParent())); 1860 const SCEVUnknown *BasePointer = 1861 dyn_cast<SCEVUnknown>(SE.getPointerBase(AccessFunction)); 1862 1863 assert(BasePointer && "Could not find base pointer"); 1864 AccessFunction = SE.getMinusSCEV(AccessFunction, BasePointer); 1865 1866 // Check if the access depends on a loop contained in a non-affine subregion. 1867 bool isVariantInNonAffineLoop = false; 1868 SetVector<const Loop *> Loops; 1869 findLoops(AccessFunction, Loops); 1870 for (const Loop *L : Loops) 1871 if (Stmt->contains(L)) { 1872 isVariantInNonAffineLoop = true; 1873 break; 1874 } 1875 1876 InvariantLoadsSetTy AccessILS; 1877 1878 Loop *SurroundingLoop = Stmt->getSurroundingLoop(); 1879 bool IsAffine = !isVariantInNonAffineLoop && 1880 isAffineExpr(&scop->getRegion(), SurroundingLoop, 1881 AccessFunction, SE, &AccessILS); 1882 1883 const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads(); 1884 for (LoadInst *LInst : AccessILS) 1885 if (!ScopRIL.count(LInst)) 1886 IsAffine = false; 1887 1888 if (!IsAffine && AccType == MemoryAccess::MUST_WRITE) 1889 AccType = MemoryAccess::MAY_WRITE; 1890 1891 addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType, 1892 IsAffine, {AccessFunction}, {nullptr}, Val); 1893 } 1894 1895 void ScopBuilder::buildMemoryAccess(MemAccInst Inst, ScopStmt *Stmt) { 1896 if (buildAccessMemIntrinsic(Inst, Stmt)) 1897 return; 1898 1899 if (buildAccessCallInst(Inst, Stmt)) 1900 return; 1901 1902 if (buildAccessMultiDimFixed(Inst, Stmt)) 1903 return; 1904 1905 if (buildAccessMultiDimParam(Inst, Stmt)) 1906 return; 1907 1908 buildAccessSingleDim(Inst, Stmt); 1909 } 1910 1911 void ScopBuilder::buildAccessFunctions() { 1912 for (auto &Stmt : *scop) { 1913 if (Stmt.isBlockStmt()) { 1914 buildAccessFunctions(&Stmt, *Stmt.getBasicBlock()); 1915 continue; 1916 } 1917 1918 Region *R = Stmt.getRegion(); 1919 for (BasicBlock *BB : R->blocks()) 1920 buildAccessFunctions(&Stmt, *BB, R); 1921 } 1922 1923 // Build write accesses for values that are used after the SCoP. 1924 // The instructions defining them might be synthesizable and therefore not 1925 // contained in any statement, hence we iterate over the original instructions 1926 // to identify all escaping values. 1927 for (BasicBlock *BB : scop->getRegion().blocks()) { 1928 for (Instruction &Inst : *BB) 1929 buildEscapingDependences(&Inst); 1930 } 1931 } 1932 1933 bool ScopBuilder::shouldModelInst(Instruction *Inst, Loop *L) { 1934 return !Inst->isTerminator() && !isIgnoredIntrinsic(Inst) && 1935 !canSynthesize(Inst, *scop, &SE, L); 1936 } 1937 1938 /// Generate a name for a statement. 1939 /// 1940 /// @param BB The basic block the statement will represent. 1941 /// @param BBIdx The index of the @p BB relative to other BBs/regions. 1942 /// @param Count The index of the created statement in @p BB. 1943 /// @param IsMain Whether this is the main of all statement for @p BB. If true, 1944 /// no suffix will be added. 1945 /// @param IsLast Uses a special indicator for the last statement of a BB. 1946 static std::string makeStmtName(BasicBlock *BB, long BBIdx, int Count, 1947 bool IsMain, bool IsLast = false) { 1948 std::string Suffix; 1949 if (!IsMain) { 1950 if (UseInstructionNames) 1951 Suffix = '_'; 1952 if (IsLast) 1953 Suffix += "last"; 1954 else if (Count < 26) 1955 Suffix += 'a' + Count; 1956 else 1957 Suffix += std::to_string(Count); 1958 } 1959 return getIslCompatibleName("Stmt", BB, BBIdx, Suffix, UseInstructionNames); 1960 } 1961 1962 /// Generate a name for a statement that represents a non-affine subregion. 1963 /// 1964 /// @param R The region the statement will represent. 1965 /// @param RIdx The index of the @p R relative to other BBs/regions. 1966 static std::string makeStmtName(Region *R, long RIdx) { 1967 return getIslCompatibleName("Stmt", R->getNameStr(), RIdx, "", 1968 UseInstructionNames); 1969 } 1970 1971 void ScopBuilder::buildSequentialBlockStmts(BasicBlock *BB, bool SplitOnStore) { 1972 Loop *SurroundingLoop = LI.getLoopFor(BB); 1973 1974 int Count = 0; 1975 long BBIdx = scop->getNextStmtIdx(); 1976 std::vector<Instruction *> Instructions; 1977 for (Instruction &Inst : *BB) { 1978 if (shouldModelInst(&Inst, SurroundingLoop)) 1979 Instructions.push_back(&Inst); 1980 if (Inst.getMetadata("polly_split_after") || 1981 (SplitOnStore && isa<StoreInst>(Inst))) { 1982 std::string Name = makeStmtName(BB, BBIdx, Count, Count == 0); 1983 scop->addScopStmt(BB, Name, SurroundingLoop, Instructions); 1984 Count++; 1985 Instructions.clear(); 1986 } 1987 } 1988 1989 std::string Name = makeStmtName(BB, BBIdx, Count, Count == 0); 1990 scop->addScopStmt(BB, Name, SurroundingLoop, Instructions); 1991 } 1992 1993 /// Is @p Inst an ordered instruction? 1994 /// 1995 /// An unordered instruction is an instruction, such that a sequence of 1996 /// unordered instructions can be permuted without changing semantics. Any 1997 /// instruction for which this is not always the case is ordered. 1998 static bool isOrderedInstruction(Instruction *Inst) { 1999 return Inst->mayHaveSideEffects() || Inst->mayReadOrWriteMemory(); 2000 } 2001 2002 /// Join instructions to the same statement if one uses the scalar result of the 2003 /// other. 2004 static void joinOperandTree(EquivalenceClasses<Instruction *> &UnionFind, 2005 ArrayRef<Instruction *> ModeledInsts) { 2006 for (Instruction *Inst : ModeledInsts) { 2007 if (isa<PHINode>(Inst)) 2008 continue; 2009 2010 for (Use &Op : Inst->operands()) { 2011 Instruction *OpInst = dyn_cast<Instruction>(Op.get()); 2012 if (!OpInst) 2013 continue; 2014 2015 // Check if OpInst is in the BB and is a modeled instruction. 2016 auto OpVal = UnionFind.findValue(OpInst); 2017 if (OpVal == UnionFind.end()) 2018 continue; 2019 2020 UnionFind.unionSets(Inst, OpInst); 2021 } 2022 } 2023 } 2024 2025 /// Ensure that the order of ordered instructions does not change. 2026 /// 2027 /// If we encounter an ordered instruction enclosed in instructions belonging to 2028 /// a different statement (which might as well contain ordered instructions, but 2029 /// this is not tested here), join them. 2030 static void 2031 joinOrderedInstructions(EquivalenceClasses<Instruction *> &UnionFind, 2032 ArrayRef<Instruction *> ModeledInsts) { 2033 SetVector<Instruction *> SeenLeaders; 2034 for (Instruction *Inst : ModeledInsts) { 2035 if (!isOrderedInstruction(Inst)) 2036 continue; 2037 2038 Instruction *Leader = UnionFind.getLeaderValue(Inst); 2039 // Since previous iterations might have merged sets, some items in 2040 // SeenLeaders are not leaders anymore. However, The new leader of 2041 // previously merged instructions must be one of the former leaders of 2042 // these merged instructions. 2043 bool Inserted = SeenLeaders.insert(Leader); 2044 if (Inserted) 2045 continue; 2046 2047 // Merge statements to close holes. Say, we have already seen statements A 2048 // and B, in this order. Then we see an instruction of A again and we would 2049 // see the pattern "A B A". This function joins all statements until the 2050 // only seen occurrence of A. 2051 for (Instruction *Prev : reverse(SeenLeaders)) { 2052 // We are backtracking from the last element until we see Inst's leader 2053 // in SeenLeaders and merge all into one set. Although leaders of 2054 // instructions change during the execution of this loop, it's irrelevant 2055 // as we are just searching for the element that we already confirmed is 2056 // in the list. 2057 if (Prev == Leader) 2058 break; 2059 UnionFind.unionSets(Prev, Leader); 2060 } 2061 } 2062 } 2063 2064 /// If the BasicBlock has an edge from itself, ensure that the PHI WRITEs for 2065 /// the incoming values from this block are executed after the PHI READ. 2066 /// 2067 /// Otherwise it could overwrite the incoming value from before the BB with the 2068 /// value for the next execution. This can happen if the PHI WRITE is added to 2069 /// the statement with the instruction that defines the incoming value (instead 2070 /// of the last statement of the same BB). To ensure that the PHI READ and WRITE 2071 /// are in order, we put both into the statement. PHI WRITEs are always executed 2072 /// after PHI READs when they are in the same statement. 2073 /// 2074 /// TODO: This is an overpessimization. We only have to ensure that the PHI 2075 /// WRITE is not put into a statement containing the PHI itself. That could also 2076 /// be done by 2077 /// - having all (strongly connected) PHIs in a single statement, 2078 /// - unite only the PHIs in the operand tree of the PHI WRITE (because it only 2079 /// has a chance of being lifted before a PHI by being in a statement with a 2080 /// PHI that comes before in the basic block), or 2081 /// - when uniting statements, ensure that no (relevant) PHIs are overtaken. 2082 static void joinOrderedPHIs(EquivalenceClasses<Instruction *> &UnionFind, 2083 ArrayRef<Instruction *> ModeledInsts) { 2084 for (Instruction *Inst : ModeledInsts) { 2085 PHINode *PHI = dyn_cast<PHINode>(Inst); 2086 if (!PHI) 2087 continue; 2088 2089 int Idx = PHI->getBasicBlockIndex(PHI->getParent()); 2090 if (Idx < 0) 2091 continue; 2092 2093 Instruction *IncomingVal = 2094 dyn_cast<Instruction>(PHI->getIncomingValue(Idx)); 2095 if (!IncomingVal) 2096 continue; 2097 2098 UnionFind.unionSets(PHI, IncomingVal); 2099 } 2100 } 2101 2102 void ScopBuilder::buildEqivClassBlockStmts(BasicBlock *BB) { 2103 Loop *L = LI.getLoopFor(BB); 2104 2105 // Extracting out modeled instructions saves us from checking 2106 // shouldModelInst() repeatedly. 2107 SmallVector<Instruction *, 32> ModeledInsts; 2108 EquivalenceClasses<Instruction *> UnionFind; 2109 Instruction *MainInst = nullptr, *MainLeader = nullptr; 2110 for (Instruction &Inst : *BB) { 2111 if (!shouldModelInst(&Inst, L)) 2112 continue; 2113 ModeledInsts.push_back(&Inst); 2114 UnionFind.insert(&Inst); 2115 2116 // When a BB is split into multiple statements, the main statement is the 2117 // one containing the 'main' instruction. We select the first instruction 2118 // that is unlikely to be removed (because it has side-effects) as the main 2119 // one. It is used to ensure that at least one statement from the bb has the 2120 // same name as with -polly-stmt-granularity=bb. 2121 if (!MainInst && (isa<StoreInst>(Inst) || 2122 (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst)))) 2123 MainInst = &Inst; 2124 } 2125 2126 joinOperandTree(UnionFind, ModeledInsts); 2127 joinOrderedInstructions(UnionFind, ModeledInsts); 2128 joinOrderedPHIs(UnionFind, ModeledInsts); 2129 2130 // The list of instructions for statement (statement represented by the leader 2131 // instruction). 2132 MapVector<Instruction *, std::vector<Instruction *>> LeaderToInstList; 2133 2134 // The order of statements must be preserved w.r.t. their ordered 2135 // instructions. Without this explicit scan, we would also use non-ordered 2136 // instructions (whose order is arbitrary) to determine statement order. 2137 for (Instruction *Inst : ModeledInsts) { 2138 if (!isOrderedInstruction(Inst)) 2139 continue; 2140 2141 auto LeaderIt = UnionFind.findLeader(Inst); 2142 if (LeaderIt == UnionFind.member_end()) 2143 continue; 2144 2145 // Insert element for the leader instruction. 2146 (void)LeaderToInstList[*LeaderIt]; 2147 } 2148 2149 // Collect the instructions of all leaders. UnionFind's member iterator 2150 // unfortunately are not in any specific order. 2151 for (Instruction *Inst : ModeledInsts) { 2152 auto LeaderIt = UnionFind.findLeader(Inst); 2153 if (LeaderIt == UnionFind.member_end()) 2154 continue; 2155 2156 if (Inst == MainInst) 2157 MainLeader = *LeaderIt; 2158 std::vector<Instruction *> &InstList = LeaderToInstList[*LeaderIt]; 2159 InstList.push_back(Inst); 2160 } 2161 2162 // Finally build the statements. 2163 int Count = 0; 2164 long BBIdx = scop->getNextStmtIdx(); 2165 for (auto &Instructions : LeaderToInstList) { 2166 std::vector<Instruction *> &InstList = Instructions.second; 2167 2168 // If there is no main instruction, make the first statement the main. 2169 bool IsMain = (MainInst ? MainLeader == Instructions.first : Count == 0); 2170 2171 std::string Name = makeStmtName(BB, BBIdx, Count, IsMain); 2172 scop->addScopStmt(BB, Name, L, std::move(InstList)); 2173 Count += 1; 2174 } 2175 2176 // Unconditionally add an epilogue (last statement). It contains no 2177 // instructions, but holds the PHI write accesses for successor basic blocks, 2178 // if the incoming value is not defined in another statement if the same BB. 2179 // The epilogue becomes the main statement only if there is no other 2180 // statement that could become main. 2181 // The epilogue will be removed if no PHIWrite is added to it. 2182 std::string EpilogueName = makeStmtName(BB, BBIdx, Count, Count == 0, true); 2183 scop->addScopStmt(BB, EpilogueName, L, {}); 2184 } 2185 2186 void ScopBuilder::buildStmts(Region &SR) { 2187 if (scop->isNonAffineSubRegion(&SR)) { 2188 std::vector<Instruction *> Instructions; 2189 Loop *SurroundingLoop = 2190 getFirstNonBoxedLoopFor(SR.getEntry(), LI, scop->getBoxedLoops()); 2191 for (Instruction &Inst : *SR.getEntry()) 2192 if (shouldModelInst(&Inst, SurroundingLoop)) 2193 Instructions.push_back(&Inst); 2194 long RIdx = scop->getNextStmtIdx(); 2195 std::string Name = makeStmtName(&SR, RIdx); 2196 scop->addScopStmt(&SR, Name, SurroundingLoop, Instructions); 2197 return; 2198 } 2199 2200 for (auto I = SR.element_begin(), E = SR.element_end(); I != E; ++I) 2201 if (I->isSubRegion()) 2202 buildStmts(*I->getNodeAs<Region>()); 2203 else { 2204 BasicBlock *BB = I->getNodeAs<BasicBlock>(); 2205 switch (StmtGranularity) { 2206 case GranularityChoice::BasicBlocks: 2207 buildSequentialBlockStmts(BB); 2208 break; 2209 case GranularityChoice::ScalarIndependence: 2210 buildEqivClassBlockStmts(BB); 2211 break; 2212 case GranularityChoice::Stores: 2213 buildSequentialBlockStmts(BB, true); 2214 break; 2215 } 2216 } 2217 } 2218 2219 void ScopBuilder::buildAccessFunctions(ScopStmt *Stmt, BasicBlock &BB, 2220 Region *NonAffineSubRegion) { 2221 assert( 2222 Stmt && 2223 "The exit BB is the only one that cannot be represented by a statement"); 2224 assert(Stmt->represents(&BB)); 2225 2226 // We do not build access functions for error blocks, as they may contain 2227 // instructions we can not model. 2228 if (isErrorBlock(BB, scop->getRegion(), LI, DT)) 2229 return; 2230 2231 auto BuildAccessesForInst = [this, Stmt, 2232 NonAffineSubRegion](Instruction *Inst) { 2233 PHINode *PHI = dyn_cast<PHINode>(Inst); 2234 if (PHI) 2235 buildPHIAccesses(Stmt, PHI, NonAffineSubRegion, false); 2236 2237 if (auto MemInst = MemAccInst::dyn_cast(*Inst)) { 2238 assert(Stmt && "Cannot build access function in non-existing statement"); 2239 buildMemoryAccess(MemInst, Stmt); 2240 } 2241 2242 // PHI nodes have already been modeled above and terminators that are 2243 // not part of a non-affine subregion are fully modeled and regenerated 2244 // from the polyhedral domains. Hence, they do not need to be modeled as 2245 // explicit data dependences. 2246 if (!PHI) 2247 buildScalarDependences(Stmt, Inst); 2248 }; 2249 2250 const InvariantLoadsSetTy &RIL = scop->getRequiredInvariantLoads(); 2251 bool IsEntryBlock = (Stmt->getEntryBlock() == &BB); 2252 if (IsEntryBlock) { 2253 for (Instruction *Inst : Stmt->getInstructions()) 2254 BuildAccessesForInst(Inst); 2255 if (Stmt->isRegionStmt()) 2256 BuildAccessesForInst(BB.getTerminator()); 2257 } else { 2258 for (Instruction &Inst : BB) { 2259 if (isIgnoredIntrinsic(&Inst)) 2260 continue; 2261 2262 // Invariant loads already have been processed. 2263 if (isa<LoadInst>(Inst) && RIL.count(cast<LoadInst>(&Inst))) 2264 continue; 2265 2266 BuildAccessesForInst(&Inst); 2267 } 2268 } 2269 } 2270 2271 MemoryAccess *ScopBuilder::addMemoryAccess( 2272 ScopStmt *Stmt, Instruction *Inst, MemoryAccess::AccessType AccType, 2273 Value *BaseAddress, Type *ElementType, bool Affine, Value *AccessValue, 2274 ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes, 2275 MemoryKind Kind) { 2276 bool isKnownMustAccess = false; 2277 2278 // Accesses in single-basic block statements are always executed. 2279 if (Stmt->isBlockStmt()) 2280 isKnownMustAccess = true; 2281 2282 if (Stmt->isRegionStmt()) { 2283 // Accesses that dominate the exit block of a non-affine region are always 2284 // executed. In non-affine regions there may exist MemoryKind::Values that 2285 // do not dominate the exit. MemoryKind::Values will always dominate the 2286 // exit and MemoryKind::PHIs only if there is at most one PHI_WRITE in the 2287 // non-affine region. 2288 if (Inst && DT.dominates(Inst->getParent(), Stmt->getRegion()->getExit())) 2289 isKnownMustAccess = true; 2290 } 2291 2292 // Non-affine PHI writes do not "happen" at a particular instruction, but 2293 // after exiting the statement. Therefore they are guaranteed to execute and 2294 // overwrite the old value. 2295 if (Kind == MemoryKind::PHI || Kind == MemoryKind::ExitPHI) 2296 isKnownMustAccess = true; 2297 2298 if (!isKnownMustAccess && AccType == MemoryAccess::MUST_WRITE) 2299 AccType = MemoryAccess::MAY_WRITE; 2300 2301 auto *Access = new MemoryAccess(Stmt, Inst, AccType, BaseAddress, ElementType, 2302 Affine, Subscripts, Sizes, AccessValue, Kind); 2303 2304 scop->addAccessFunction(Access); 2305 Stmt->addAccess(Access); 2306 return Access; 2307 } 2308 2309 void ScopBuilder::addArrayAccess(ScopStmt *Stmt, MemAccInst MemAccInst, 2310 MemoryAccess::AccessType AccType, 2311 Value *BaseAddress, Type *ElementType, 2312 bool IsAffine, 2313 ArrayRef<const SCEV *> Subscripts, 2314 ArrayRef<const SCEV *> Sizes, 2315 Value *AccessValue) { 2316 ArrayBasePointers.insert(BaseAddress); 2317 auto *MemAccess = addMemoryAccess(Stmt, MemAccInst, AccType, BaseAddress, 2318 ElementType, IsAffine, AccessValue, 2319 Subscripts, Sizes, MemoryKind::Array); 2320 2321 if (!DetectFortranArrays) 2322 return; 2323 2324 if (Value *FAD = findFADAllocationInvisible(MemAccInst)) 2325 MemAccess->setFortranArrayDescriptor(FAD); 2326 else if (Value *FAD = findFADAllocationVisible(MemAccInst)) 2327 MemAccess->setFortranArrayDescriptor(FAD); 2328 } 2329 2330 /// Check if @p Expr is divisible by @p Size. 2331 static bool isDivisible(const SCEV *Expr, unsigned Size, ScalarEvolution &SE) { 2332 assert(Size != 0); 2333 if (Size == 1) 2334 return true; 2335 2336 // Only one factor needs to be divisible. 2337 if (auto *MulExpr = dyn_cast<SCEVMulExpr>(Expr)) { 2338 for (auto *FactorExpr : MulExpr->operands()) 2339 if (isDivisible(FactorExpr, Size, SE)) 2340 return true; 2341 return false; 2342 } 2343 2344 // For other n-ary expressions (Add, AddRec, Max,...) all operands need 2345 // to be divisible. 2346 if (auto *NAryExpr = dyn_cast<SCEVNAryExpr>(Expr)) { 2347 for (auto *OpExpr : NAryExpr->operands()) 2348 if (!isDivisible(OpExpr, Size, SE)) 2349 return false; 2350 return true; 2351 } 2352 2353 auto *SizeSCEV = SE.getConstant(Expr->getType(), Size); 2354 auto *UDivSCEV = SE.getUDivExpr(Expr, SizeSCEV); 2355 auto *MulSCEV = SE.getMulExpr(UDivSCEV, SizeSCEV); 2356 return MulSCEV == Expr; 2357 } 2358 2359 void ScopBuilder::foldSizeConstantsToRight() { 2360 isl::union_set Accessed = scop->getAccesses().range(); 2361 2362 for (auto Array : scop->arrays()) { 2363 if (Array->getNumberOfDimensions() <= 1) 2364 continue; 2365 2366 isl::space Space = Array->getSpace(); 2367 Space = Space.align_params(Accessed.get_space()); 2368 2369 if (!Accessed.contains(Space)) 2370 continue; 2371 2372 isl::set Elements = Accessed.extract_set(Space); 2373 isl::map Transform = isl::map::universe(Array->getSpace().map_from_set()); 2374 2375 std::vector<int> Int; 2376 int Dims = Elements.dim(isl::dim::set); 2377 for (int i = 0; i < Dims; i++) { 2378 isl::set DimOnly = isl::set(Elements).project_out(isl::dim::set, 0, i); 2379 DimOnly = DimOnly.project_out(isl::dim::set, 1, Dims - i - 1); 2380 DimOnly = DimOnly.lower_bound_si(isl::dim::set, 0, 0); 2381 2382 isl::basic_set DimHull = DimOnly.affine_hull(); 2383 2384 if (i == Dims - 1) { 2385 Int.push_back(1); 2386 Transform = Transform.equate(isl::dim::in, i, isl::dim::out, i); 2387 continue; 2388 } 2389 2390 if (DimHull.dim(isl::dim::div) == 1) { 2391 isl::aff Diff = DimHull.get_div(0); 2392 isl::val Val = Diff.get_denominator_val(); 2393 2394 int ValInt = 1; 2395 if (Val.is_int()) { 2396 auto ValAPInt = APIntFromVal(Val); 2397 if (ValAPInt.isSignedIntN(32)) 2398 ValInt = ValAPInt.getSExtValue(); 2399 } else { 2400 } 2401 2402 Int.push_back(ValInt); 2403 isl::constraint C = isl::constraint::alloc_equality( 2404 isl::local_space(Transform.get_space())); 2405 C = C.set_coefficient_si(isl::dim::out, i, ValInt); 2406 C = C.set_coefficient_si(isl::dim::in, i, -1); 2407 Transform = Transform.add_constraint(C); 2408 continue; 2409 } 2410 2411 isl::basic_set ZeroSet = isl::basic_set(DimHull); 2412 ZeroSet = ZeroSet.fix_si(isl::dim::set, 0, 0); 2413 2414 int ValInt = 1; 2415 if (ZeroSet.is_equal(DimHull)) { 2416 ValInt = 0; 2417 } 2418 2419 Int.push_back(ValInt); 2420 Transform = Transform.equate(isl::dim::in, i, isl::dim::out, i); 2421 } 2422 2423 isl::set MappedElements = isl::map(Transform).domain(); 2424 if (!Elements.is_subset(MappedElements)) 2425 continue; 2426 2427 bool CanFold = true; 2428 if (Int[0] <= 1) 2429 CanFold = false; 2430 2431 unsigned NumDims = Array->getNumberOfDimensions(); 2432 for (unsigned i = 1; i < NumDims - 1; i++) 2433 if (Int[0] != Int[i] && Int[i]) 2434 CanFold = false; 2435 2436 if (!CanFold) 2437 continue; 2438 2439 for (auto &Access : scop->access_functions()) 2440 if (Access->getScopArrayInfo() == Array) 2441 Access->setAccessRelation( 2442 Access->getAccessRelation().apply_range(Transform)); 2443 2444 std::vector<const SCEV *> Sizes; 2445 for (unsigned i = 0; i < NumDims; i++) { 2446 auto Size = Array->getDimensionSize(i); 2447 2448 if (i == NumDims - 1) 2449 Size = SE.getMulExpr(Size, SE.getConstant(Size->getType(), Int[0])); 2450 Sizes.push_back(Size); 2451 } 2452 2453 Array->updateSizes(Sizes, false /* CheckConsistency */); 2454 } 2455 } 2456 2457 void ScopBuilder::markFortranArrays() { 2458 for (ScopStmt &Stmt : *scop) { 2459 for (MemoryAccess *MemAcc : Stmt) { 2460 Value *FAD = MemAcc->getFortranArrayDescriptor(); 2461 if (!FAD) 2462 continue; 2463 2464 // TODO: const_cast-ing to edit 2465 ScopArrayInfo *SAI = 2466 const_cast<ScopArrayInfo *>(MemAcc->getLatestScopArrayInfo()); 2467 assert(SAI && "memory access into a Fortran array does not " 2468 "have an associated ScopArrayInfo"); 2469 SAI->applyAndSetFAD(FAD); 2470 } 2471 } 2472 } 2473 2474 void ScopBuilder::finalizeAccesses() { 2475 updateAccessDimensionality(); 2476 foldSizeConstantsToRight(); 2477 foldAccessRelations(); 2478 assumeNoOutOfBounds(); 2479 markFortranArrays(); 2480 } 2481 2482 void ScopBuilder::updateAccessDimensionality() { 2483 // Check all array accesses for each base pointer and find a (virtual) element 2484 // size for the base pointer that divides all access functions. 2485 for (ScopStmt &Stmt : *scop) 2486 for (MemoryAccess *Access : Stmt) { 2487 if (!Access->isArrayKind()) 2488 continue; 2489 ScopArrayInfo *Array = 2490 const_cast<ScopArrayInfo *>(Access->getScopArrayInfo()); 2491 2492 if (Array->getNumberOfDimensions() != 1) 2493 continue; 2494 unsigned DivisibleSize = Array->getElemSizeInBytes(); 2495 const SCEV *Subscript = Access->getSubscript(0); 2496 while (!isDivisible(Subscript, DivisibleSize, SE)) 2497 DivisibleSize /= 2; 2498 auto *Ty = IntegerType::get(SE.getContext(), DivisibleSize * 8); 2499 Array->updateElementType(Ty); 2500 } 2501 2502 for (auto &Stmt : *scop) 2503 for (auto &Access : Stmt) 2504 Access->updateDimensionality(); 2505 } 2506 2507 void ScopBuilder::foldAccessRelations() { 2508 for (auto &Stmt : *scop) 2509 for (auto &Access : Stmt) 2510 Access->foldAccessRelation(); 2511 } 2512 2513 void ScopBuilder::assumeNoOutOfBounds() { 2514 if (PollyIgnoreInbounds) 2515 return; 2516 for (auto &Stmt : *scop) 2517 for (auto &Access : Stmt) { 2518 isl::set Outside = Access->assumeNoOutOfBound(); 2519 const auto &Loc = Access->getAccessInstruction() 2520 ? Access->getAccessInstruction()->getDebugLoc() 2521 : DebugLoc(); 2522 recordAssumption(&RecordedAssumptions, INBOUNDS, Outside, Loc, 2523 AS_ASSUMPTION); 2524 } 2525 } 2526 2527 void ScopBuilder::ensureValueWrite(Instruction *Inst) { 2528 // Find the statement that defines the value of Inst. That statement has to 2529 // write the value to make it available to those statements that read it. 2530 ScopStmt *Stmt = scop->getStmtFor(Inst); 2531 2532 // It is possible that the value is synthesizable within a loop (such that it 2533 // is not part of any statement), but not after the loop (where you need the 2534 // number of loop round-trips to synthesize it). In LCSSA-form a PHI node will 2535 // avoid this. In case the IR has no such PHI, use the last statement (where 2536 // the value is synthesizable) to write the value. 2537 if (!Stmt) 2538 Stmt = scop->getLastStmtFor(Inst->getParent()); 2539 2540 // Inst not defined within this SCoP. 2541 if (!Stmt) 2542 return; 2543 2544 // Do not process further if the instruction is already written. 2545 if (Stmt->lookupValueWriteOf(Inst)) 2546 return; 2547 2548 addMemoryAccess(Stmt, Inst, MemoryAccess::MUST_WRITE, Inst, Inst->getType(), 2549 true, Inst, ArrayRef<const SCEV *>(), 2550 ArrayRef<const SCEV *>(), MemoryKind::Value); 2551 } 2552 2553 void ScopBuilder::ensureValueRead(Value *V, ScopStmt *UserStmt) { 2554 // TODO: Make ScopStmt::ensureValueRead(Value*) offer the same functionality 2555 // to be able to replace this one. Currently, there is a split responsibility. 2556 // In a first step, the MemoryAccess is created, but without the 2557 // AccessRelation. In the second step by ScopStmt::buildAccessRelations(), the 2558 // AccessRelation is created. At least for scalar accesses, there is no new 2559 // information available at ScopStmt::buildAccessRelations(), so we could 2560 // create the AccessRelation right away. This is what 2561 // ScopStmt::ensureValueRead(Value*) does. 2562 2563 auto *Scope = UserStmt->getSurroundingLoop(); 2564 auto VUse = VirtualUse::create(scop.get(), UserStmt, Scope, V, false); 2565 switch (VUse.getKind()) { 2566 case VirtualUse::Constant: 2567 case VirtualUse::Block: 2568 case VirtualUse::Synthesizable: 2569 case VirtualUse::Hoisted: 2570 case VirtualUse::Intra: 2571 // Uses of these kinds do not need a MemoryAccess. 2572 break; 2573 2574 case VirtualUse::ReadOnly: 2575 // Add MemoryAccess for invariant values only if requested. 2576 if (!ModelReadOnlyScalars) 2577 break; 2578 2579 LLVM_FALLTHROUGH; 2580 case VirtualUse::Inter: 2581 2582 // Do not create another MemoryAccess for reloading the value if one already 2583 // exists. 2584 if (UserStmt->lookupValueReadOf(V)) 2585 break; 2586 2587 addMemoryAccess(UserStmt, nullptr, MemoryAccess::READ, V, V->getType(), 2588 true, V, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), 2589 MemoryKind::Value); 2590 2591 // Inter-statement uses need to write the value in their defining statement. 2592 if (VUse.isInter()) 2593 ensureValueWrite(cast<Instruction>(V)); 2594 break; 2595 } 2596 } 2597 2598 void ScopBuilder::ensurePHIWrite(PHINode *PHI, ScopStmt *IncomingStmt, 2599 BasicBlock *IncomingBlock, 2600 Value *IncomingValue, bool IsExitBlock) { 2601 // As the incoming block might turn out to be an error statement ensure we 2602 // will create an exit PHI SAI object. It is needed during code generation 2603 // and would be created later anyway. 2604 if (IsExitBlock) 2605 scop->getOrCreateScopArrayInfo(PHI, PHI->getType(), {}, 2606 MemoryKind::ExitPHI); 2607 2608 // This is possible if PHI is in the SCoP's entry block. The incoming blocks 2609 // from outside the SCoP's region have no statement representation. 2610 if (!IncomingStmt) 2611 return; 2612 2613 // Take care for the incoming value being available in the incoming block. 2614 // This must be done before the check for multiple PHI writes because multiple 2615 // exiting edges from subregion each can be the effective written value of the 2616 // subregion. As such, all of them must be made available in the subregion 2617 // statement. 2618 ensureValueRead(IncomingValue, IncomingStmt); 2619 2620 // Do not add more than one MemoryAccess per PHINode and ScopStmt. 2621 if (MemoryAccess *Acc = IncomingStmt->lookupPHIWriteOf(PHI)) { 2622 assert(Acc->getAccessInstruction() == PHI); 2623 Acc->addIncoming(IncomingBlock, IncomingValue); 2624 return; 2625 } 2626 2627 MemoryAccess *Acc = addMemoryAccess( 2628 IncomingStmt, PHI, MemoryAccess::MUST_WRITE, PHI, PHI->getType(), true, 2629 PHI, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), 2630 IsExitBlock ? MemoryKind::ExitPHI : MemoryKind::PHI); 2631 assert(Acc); 2632 Acc->addIncoming(IncomingBlock, IncomingValue); 2633 } 2634 2635 void ScopBuilder::addPHIReadAccess(ScopStmt *PHIStmt, PHINode *PHI) { 2636 addMemoryAccess(PHIStmt, PHI, MemoryAccess::READ, PHI, PHI->getType(), true, 2637 PHI, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), 2638 MemoryKind::PHI); 2639 } 2640 2641 void ScopBuilder::buildDomain(ScopStmt &Stmt) { 2642 isl::id Id = isl::id::alloc(scop->getIslCtx(), Stmt.getBaseName(), &Stmt); 2643 2644 Stmt.Domain = scop->getDomainConditions(&Stmt); 2645 Stmt.Domain = Stmt.Domain.set_tuple_id(Id); 2646 } 2647 2648 void ScopBuilder::collectSurroundingLoops(ScopStmt &Stmt) { 2649 isl::set Domain = Stmt.getDomain(); 2650 BasicBlock *BB = Stmt.getEntryBlock(); 2651 2652 Loop *L = LI.getLoopFor(BB); 2653 2654 while (L && Stmt.isRegionStmt() && Stmt.getRegion()->contains(L)) 2655 L = L->getParentLoop(); 2656 2657 SmallVector<llvm::Loop *, 8> Loops; 2658 2659 while (L && Stmt.getParent()->getRegion().contains(L)) { 2660 Loops.push_back(L); 2661 L = L->getParentLoop(); 2662 } 2663 2664 Stmt.NestLoops.insert(Stmt.NestLoops.begin(), Loops.rbegin(), Loops.rend()); 2665 } 2666 2667 /// Return the reduction type for a given binary operator. 2668 static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp, 2669 const Instruction *Load) { 2670 if (!BinOp) 2671 return MemoryAccess::RT_NONE; 2672 switch (BinOp->getOpcode()) { 2673 case Instruction::FAdd: 2674 if (!BinOp->isFast()) 2675 return MemoryAccess::RT_NONE; 2676 LLVM_FALLTHROUGH; 2677 case Instruction::Add: 2678 return MemoryAccess::RT_ADD; 2679 case Instruction::Or: 2680 return MemoryAccess::RT_BOR; 2681 case Instruction::Xor: 2682 return MemoryAccess::RT_BXOR; 2683 case Instruction::And: 2684 return MemoryAccess::RT_BAND; 2685 case Instruction::FMul: 2686 if (!BinOp->isFast()) 2687 return MemoryAccess::RT_NONE; 2688 LLVM_FALLTHROUGH; 2689 case Instruction::Mul: 2690 if (DisableMultiplicativeReductions) 2691 return MemoryAccess::RT_NONE; 2692 return MemoryAccess::RT_MUL; 2693 default: 2694 return MemoryAccess::RT_NONE; 2695 } 2696 } 2697 2698 void ScopBuilder::checkForReductions(ScopStmt &Stmt) { 2699 SmallVector<MemoryAccess *, 2> Loads; 2700 SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates; 2701 2702 // First collect candidate load-store reduction chains by iterating over all 2703 // stores and collecting possible reduction loads. 2704 for (MemoryAccess *StoreMA : Stmt) { 2705 if (StoreMA->isRead()) 2706 continue; 2707 2708 Loads.clear(); 2709 collectCandidateReductionLoads(StoreMA, Loads); 2710 for (MemoryAccess *LoadMA : Loads) 2711 Candidates.push_back(std::make_pair(LoadMA, StoreMA)); 2712 } 2713 2714 // Then check each possible candidate pair. 2715 for (const auto &CandidatePair : Candidates) { 2716 bool Valid = true; 2717 isl::map LoadAccs = CandidatePair.first->getAccessRelation(); 2718 isl::map StoreAccs = CandidatePair.second->getAccessRelation(); 2719 2720 // Skip those with obviously unequal base addresses. 2721 if (!LoadAccs.has_equal_space(StoreAccs)) { 2722 continue; 2723 } 2724 2725 // And check if the remaining for overlap with other memory accesses. 2726 isl::map AllAccsRel = LoadAccs.unite(StoreAccs); 2727 AllAccsRel = AllAccsRel.intersect_domain(Stmt.getDomain()); 2728 isl::set AllAccs = AllAccsRel.range(); 2729 2730 for (MemoryAccess *MA : Stmt) { 2731 if (MA == CandidatePair.first || MA == CandidatePair.second) 2732 continue; 2733 2734 isl::map AccRel = 2735 MA->getAccessRelation().intersect_domain(Stmt.getDomain()); 2736 isl::set Accs = AccRel.range(); 2737 2738 if (AllAccs.has_equal_space(Accs)) { 2739 isl::set OverlapAccs = Accs.intersect(AllAccs); 2740 Valid = Valid && OverlapAccs.is_empty(); 2741 } 2742 } 2743 2744 if (!Valid) 2745 continue; 2746 2747 const LoadInst *Load = 2748 dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction()); 2749 MemoryAccess::ReductionType RT = 2750 getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load); 2751 2752 // If no overlapping access was found we mark the load and store as 2753 // reduction like. 2754 CandidatePair.first->markAsReductionLike(RT); 2755 CandidatePair.second->markAsReductionLike(RT); 2756 } 2757 } 2758 2759 void ScopBuilder::verifyInvariantLoads() { 2760 auto &RIL = scop->getRequiredInvariantLoads(); 2761 for (LoadInst *LI : RIL) { 2762 assert(LI && scop->contains(LI)); 2763 // If there exists a statement in the scop which has a memory access for 2764 // @p LI, then mark this scop as infeasible for optimization. 2765 for (ScopStmt &Stmt : *scop) 2766 if (Stmt.getArrayAccessOrNULLFor(LI)) { 2767 scop->invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent()); 2768 return; 2769 } 2770 } 2771 } 2772 2773 void ScopBuilder::hoistInvariantLoads() { 2774 if (!PollyInvariantLoadHoisting) 2775 return; 2776 2777 isl::union_map Writes = scop->getWrites(); 2778 for (ScopStmt &Stmt : *scop) { 2779 InvariantAccessesTy InvariantAccesses; 2780 2781 for (MemoryAccess *Access : Stmt) 2782 if (isl::set NHCtx = getNonHoistableCtx(Access, Writes)) 2783 InvariantAccesses.push_back({Access, NHCtx}); 2784 2785 // Transfer the memory access from the statement to the SCoP. 2786 for (auto InvMA : InvariantAccesses) 2787 Stmt.removeMemoryAccess(InvMA.MA); 2788 addInvariantLoads(Stmt, InvariantAccesses); 2789 } 2790 } 2791 2792 /// Check if an access range is too complex. 2793 /// 2794 /// An access range is too complex, if it contains either many disjuncts or 2795 /// very complex expressions. As a simple heuristic, we assume if a set to 2796 /// be too complex if the sum of existentially quantified dimensions and 2797 /// set dimensions is larger than a threshold. This reliably detects both 2798 /// sets with many disjuncts as well as sets with many divisions as they 2799 /// arise in h264. 2800 /// 2801 /// @param AccessRange The range to check for complexity. 2802 /// 2803 /// @returns True if the access range is too complex. 2804 static bool isAccessRangeTooComplex(isl::set AccessRange) { 2805 int NumTotalDims = 0; 2806 2807 for (isl::basic_set BSet : AccessRange.get_basic_set_list()) { 2808 NumTotalDims += BSet.dim(isl::dim::div); 2809 NumTotalDims += BSet.dim(isl::dim::set); 2810 } 2811 2812 if (NumTotalDims > MaxDimensionsInAccessRange) 2813 return true; 2814 2815 return false; 2816 } 2817 2818 bool ScopBuilder::hasNonHoistableBasePtrInScop(MemoryAccess *MA, 2819 isl::union_map Writes) { 2820 if (auto *BasePtrMA = scop->lookupBasePtrAccess(MA)) { 2821 return getNonHoistableCtx(BasePtrMA, Writes).is_null(); 2822 } 2823 2824 Value *BaseAddr = MA->getOriginalBaseAddr(); 2825 if (auto *BasePtrInst = dyn_cast<Instruction>(BaseAddr)) 2826 if (!isa<LoadInst>(BasePtrInst)) 2827 return scop->contains(BasePtrInst); 2828 2829 return false; 2830 } 2831 2832 void ScopBuilder::addUserContext() { 2833 if (UserContextStr.empty()) 2834 return; 2835 2836 isl::set UserContext = isl::set(scop->getIslCtx(), UserContextStr.c_str()); 2837 isl::space Space = scop->getParamSpace(); 2838 if (Space.dim(isl::dim::param) != UserContext.dim(isl::dim::param)) { 2839 std::string SpaceStr = Space.to_str(); 2840 errs() << "Error: the context provided in -polly-context has not the same " 2841 << "number of dimensions than the computed context. Due to this " 2842 << "mismatch, the -polly-context option is ignored. Please provide " 2843 << "the context in the parameter space: " << SpaceStr << ".\n"; 2844 return; 2845 } 2846 2847 for (auto i : seq<isl_size>(0, Space.dim(isl::dim::param))) { 2848 std::string NameContext = 2849 scop->getContext().get_dim_name(isl::dim::param, i); 2850 std::string NameUserContext = UserContext.get_dim_name(isl::dim::param, i); 2851 2852 if (NameContext != NameUserContext) { 2853 std::string SpaceStr = Space.to_str(); 2854 errs() << "Error: the name of dimension " << i 2855 << " provided in -polly-context " 2856 << "is '" << NameUserContext << "', but the name in the computed " 2857 << "context is '" << NameContext 2858 << "'. Due to this name mismatch, " 2859 << "the -polly-context option is ignored. Please provide " 2860 << "the context in the parameter space: " << SpaceStr << ".\n"; 2861 return; 2862 } 2863 2864 UserContext = UserContext.set_dim_id(isl::dim::param, i, 2865 Space.get_dim_id(isl::dim::param, i)); 2866 } 2867 isl::set newContext = scop->getContext().intersect(UserContext); 2868 scop->setContext(newContext); 2869 } 2870 2871 isl::set ScopBuilder::getNonHoistableCtx(MemoryAccess *Access, 2872 isl::union_map Writes) { 2873 // TODO: Loads that are not loop carried, hence are in a statement with 2874 // zero iterators, are by construction invariant, though we 2875 // currently "hoist" them anyway. This is necessary because we allow 2876 // them to be treated as parameters (e.g., in conditions) and our code 2877 // generation would otherwise use the old value. 2878 2879 auto &Stmt = *Access->getStatement(); 2880 BasicBlock *BB = Stmt.getEntryBlock(); 2881 2882 if (Access->isScalarKind() || Access->isWrite() || !Access->isAffine() || 2883 Access->isMemoryIntrinsic()) 2884 return nullptr; 2885 2886 // Skip accesses that have an invariant base pointer which is defined but 2887 // not loaded inside the SCoP. This can happened e.g., if a readnone call 2888 // returns a pointer that is used as a base address. However, as we want 2889 // to hoist indirect pointers, we allow the base pointer to be defined in 2890 // the region if it is also a memory access. Each ScopArrayInfo object 2891 // that has a base pointer origin has a base pointer that is loaded and 2892 // that it is invariant, thus it will be hoisted too. However, if there is 2893 // no base pointer origin we check that the base pointer is defined 2894 // outside the region. 2895 auto *LI = cast<LoadInst>(Access->getAccessInstruction()); 2896 if (hasNonHoistableBasePtrInScop(Access, Writes)) 2897 return nullptr; 2898 2899 isl::map AccessRelation = Access->getAccessRelation(); 2900 assert(!AccessRelation.is_empty()); 2901 2902 if (AccessRelation.involves_dims(isl::dim::in, 0, Stmt.getNumIterators())) 2903 return nullptr; 2904 2905 AccessRelation = AccessRelation.intersect_domain(Stmt.getDomain()); 2906 isl::set SafeToLoad; 2907 2908 auto &DL = scop->getFunction().getParent()->getDataLayout(); 2909 if (isSafeToLoadUnconditionally(LI->getPointerOperand(), LI->getType(), 2910 LI->getAlign(), DL)) { 2911 SafeToLoad = isl::set::universe(AccessRelation.get_space().range()); 2912 } else if (BB != LI->getParent()) { 2913 // Skip accesses in non-affine subregions as they might not be executed 2914 // under the same condition as the entry of the non-affine subregion. 2915 return nullptr; 2916 } else { 2917 SafeToLoad = AccessRelation.range(); 2918 } 2919 2920 if (isAccessRangeTooComplex(AccessRelation.range())) 2921 return nullptr; 2922 2923 isl::union_map Written = Writes.intersect_range(SafeToLoad); 2924 isl::set WrittenCtx = Written.params(); 2925 bool IsWritten = !WrittenCtx.is_empty(); 2926 2927 if (!IsWritten) 2928 return WrittenCtx; 2929 2930 WrittenCtx = WrittenCtx.remove_divs(); 2931 bool TooComplex = WrittenCtx.n_basic_set() >= MaxDisjunctsInDomain; 2932 if (TooComplex || !isRequiredInvariantLoad(LI)) 2933 return nullptr; 2934 2935 scop->addAssumption(INVARIANTLOAD, WrittenCtx, LI->getDebugLoc(), 2936 AS_RESTRICTION, LI->getParent()); 2937 return WrittenCtx; 2938 } 2939 2940 static bool isAParameter(llvm::Value *maybeParam, const Function &F) { 2941 for (const llvm::Argument &Arg : F.args()) 2942 if (&Arg == maybeParam) 2943 return true; 2944 2945 return false; 2946 } 2947 2948 bool ScopBuilder::canAlwaysBeHoisted(MemoryAccess *MA, 2949 bool StmtInvalidCtxIsEmpty, 2950 bool MAInvalidCtxIsEmpty, 2951 bool NonHoistableCtxIsEmpty) { 2952 LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction()); 2953 const DataLayout &DL = LInst->getParent()->getModule()->getDataLayout(); 2954 if (PollyAllowDereferenceOfAllFunctionParams && 2955 isAParameter(LInst->getPointerOperand(), scop->getFunction())) 2956 return true; 2957 2958 // TODO: We can provide more information for better but more expensive 2959 // results. 2960 if (!isDereferenceableAndAlignedPointer( 2961 LInst->getPointerOperand(), LInst->getType(), LInst->getAlign(), DL)) 2962 return false; 2963 2964 // If the location might be overwritten we do not hoist it unconditionally. 2965 // 2966 // TODO: This is probably too conservative. 2967 if (!NonHoistableCtxIsEmpty) 2968 return false; 2969 2970 // If a dereferenceable load is in a statement that is modeled precisely we 2971 // can hoist it. 2972 if (StmtInvalidCtxIsEmpty && MAInvalidCtxIsEmpty) 2973 return true; 2974 2975 // Even if the statement is not modeled precisely we can hoist the load if it 2976 // does not involve any parameters that might have been specialized by the 2977 // statement domain. 2978 for (const SCEV *Subscript : MA->subscripts()) 2979 if (!isa<SCEVConstant>(Subscript)) 2980 return false; 2981 return true; 2982 } 2983 2984 void ScopBuilder::addInvariantLoads(ScopStmt &Stmt, 2985 InvariantAccessesTy &InvMAs) { 2986 if (InvMAs.empty()) 2987 return; 2988 2989 isl::set StmtInvalidCtx = Stmt.getInvalidContext(); 2990 bool StmtInvalidCtxIsEmpty = StmtInvalidCtx.is_empty(); 2991 2992 // Get the context under which the statement is executed but remove the error 2993 // context under which this statement is reached. 2994 isl::set DomainCtx = Stmt.getDomain().params(); 2995 DomainCtx = DomainCtx.subtract(StmtInvalidCtx); 2996 2997 if (DomainCtx.n_basic_set() >= MaxDisjunctsInDomain) { 2998 auto *AccInst = InvMAs.front().MA->getAccessInstruction(); 2999 scop->invalidate(COMPLEXITY, AccInst->getDebugLoc(), AccInst->getParent()); 3000 return; 3001 } 3002 3003 // Project out all parameters that relate to loads in the statement. Otherwise 3004 // we could have cyclic dependences on the constraints under which the 3005 // hoisted loads are executed and we could not determine an order in which to 3006 // pre-load them. This happens because not only lower bounds are part of the 3007 // domain but also upper bounds. 3008 for (auto &InvMA : InvMAs) { 3009 auto *MA = InvMA.MA; 3010 Instruction *AccInst = MA->getAccessInstruction(); 3011 if (SE.isSCEVable(AccInst->getType())) { 3012 SetVector<Value *> Values; 3013 for (const SCEV *Parameter : scop->parameters()) { 3014 Values.clear(); 3015 findValues(Parameter, SE, Values); 3016 if (!Values.count(AccInst)) 3017 continue; 3018 3019 if (isl::id ParamId = scop->getIdForParam(Parameter)) { 3020 int Dim = DomainCtx.find_dim_by_id(isl::dim::param, ParamId); 3021 if (Dim >= 0) 3022 DomainCtx = DomainCtx.eliminate(isl::dim::param, Dim, 1); 3023 } 3024 } 3025 } 3026 } 3027 3028 for (auto &InvMA : InvMAs) { 3029 auto *MA = InvMA.MA; 3030 isl::set NHCtx = InvMA.NonHoistableCtx; 3031 3032 // Check for another invariant access that accesses the same location as 3033 // MA and if found consolidate them. Otherwise create a new equivalence 3034 // class at the end of InvariantEquivClasses. 3035 LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction()); 3036 Type *Ty = LInst->getType(); 3037 const SCEV *PointerSCEV = SE.getSCEV(LInst->getPointerOperand()); 3038 3039 isl::set MAInvalidCtx = MA->getInvalidContext(); 3040 bool NonHoistableCtxIsEmpty = NHCtx.is_empty(); 3041 bool MAInvalidCtxIsEmpty = MAInvalidCtx.is_empty(); 3042 3043 isl::set MACtx; 3044 // Check if we know that this pointer can be speculatively accessed. 3045 if (canAlwaysBeHoisted(MA, StmtInvalidCtxIsEmpty, MAInvalidCtxIsEmpty, 3046 NonHoistableCtxIsEmpty)) { 3047 MACtx = isl::set::universe(DomainCtx.get_space()); 3048 } else { 3049 MACtx = DomainCtx; 3050 MACtx = MACtx.subtract(MAInvalidCtx.unite(NHCtx)); 3051 MACtx = MACtx.gist_params(scop->getContext()); 3052 } 3053 3054 bool Consolidated = false; 3055 for (auto &IAClass : scop->invariantEquivClasses()) { 3056 if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType) 3057 continue; 3058 3059 // If the pointer and the type is equal check if the access function wrt. 3060 // to the domain is equal too. It can happen that the domain fixes 3061 // parameter values and these can be different for distinct part of the 3062 // SCoP. If this happens we cannot consolidate the loads but need to 3063 // create a new invariant load equivalence class. 3064 auto &MAs = IAClass.InvariantAccesses; 3065 if (!MAs.empty()) { 3066 auto *LastMA = MAs.front(); 3067 3068 isl::set AR = MA->getAccessRelation().range(); 3069 isl::set LastAR = LastMA->getAccessRelation().range(); 3070 bool SameAR = AR.is_equal(LastAR); 3071 3072 if (!SameAR) 3073 continue; 3074 } 3075 3076 // Add MA to the list of accesses that are in this class. 3077 MAs.push_front(MA); 3078 3079 Consolidated = true; 3080 3081 // Unify the execution context of the class and this statement. 3082 isl::set IAClassDomainCtx = IAClass.ExecutionContext; 3083 if (IAClassDomainCtx) 3084 IAClassDomainCtx = IAClassDomainCtx.unite(MACtx).coalesce(); 3085 else 3086 IAClassDomainCtx = MACtx; 3087 IAClass.ExecutionContext = IAClassDomainCtx; 3088 break; 3089 } 3090 3091 if (Consolidated) 3092 continue; 3093 3094 MACtx = MACtx.coalesce(); 3095 3096 // If we did not consolidate MA, thus did not find an equivalence class 3097 // for it, we create a new one. 3098 scop->addInvariantEquivClass( 3099 InvariantEquivClassTy{PointerSCEV, MemoryAccessList{MA}, MACtx, Ty}); 3100 } 3101 } 3102 3103 void ScopBuilder::collectCandidateReductionLoads( 3104 MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) { 3105 ScopStmt *Stmt = StoreMA->getStatement(); 3106 3107 auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction()); 3108 if (!Store) 3109 return; 3110 3111 // Skip if there is not one binary operator between the load and the store 3112 auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand()); 3113 if (!BinOp) 3114 return; 3115 3116 // Skip if the binary operators has multiple uses 3117 if (BinOp->getNumUses() != 1) 3118 return; 3119 3120 // Skip if the opcode of the binary operator is not commutative/associative 3121 if (!BinOp->isCommutative() || !BinOp->isAssociative()) 3122 return; 3123 3124 // Skip if the binary operator is outside the current SCoP 3125 if (BinOp->getParent() != Store->getParent()) 3126 return; 3127 3128 // Skip if it is a multiplicative reduction and we disabled them 3129 if (DisableMultiplicativeReductions && 3130 (BinOp->getOpcode() == Instruction::Mul || 3131 BinOp->getOpcode() == Instruction::FMul)) 3132 return; 3133 3134 // Check the binary operator operands for a candidate load 3135 auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0)); 3136 auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1)); 3137 if (!PossibleLoad0 && !PossibleLoad1) 3138 return; 3139 3140 // A load is only a candidate if it cannot escape (thus has only this use) 3141 if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1) 3142 if (PossibleLoad0->getParent() == Store->getParent()) 3143 Loads.push_back(&Stmt->getArrayAccessFor(PossibleLoad0)); 3144 if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1) 3145 if (PossibleLoad1->getParent() == Store->getParent()) 3146 Loads.push_back(&Stmt->getArrayAccessFor(PossibleLoad1)); 3147 } 3148 3149 /// Find the canonical scop array info object for a set of invariant load 3150 /// hoisted loads. The canonical array is the one that corresponds to the 3151 /// first load in the list of accesses which is used as base pointer of a 3152 /// scop array. 3153 static const ScopArrayInfo *findCanonicalArray(Scop &S, 3154 MemoryAccessList &Accesses) { 3155 for (MemoryAccess *Access : Accesses) { 3156 const ScopArrayInfo *CanonicalArray = S.getScopArrayInfoOrNull( 3157 Access->getAccessInstruction(), MemoryKind::Array); 3158 if (CanonicalArray) 3159 return CanonicalArray; 3160 } 3161 return nullptr; 3162 } 3163 3164 /// Check if @p Array severs as base array in an invariant load. 3165 static bool isUsedForIndirectHoistedLoad(Scop &S, const ScopArrayInfo *Array) { 3166 for (InvariantEquivClassTy &EqClass2 : S.getInvariantAccesses()) 3167 for (MemoryAccess *Access2 : EqClass2.InvariantAccesses) 3168 if (Access2->getScopArrayInfo() == Array) 3169 return true; 3170 return false; 3171 } 3172 3173 /// Replace the base pointer arrays in all memory accesses referencing @p Old, 3174 /// with a reference to @p New. 3175 static void replaceBasePtrArrays(Scop &S, const ScopArrayInfo *Old, 3176 const ScopArrayInfo *New) { 3177 for (ScopStmt &Stmt : S) 3178 for (MemoryAccess *Access : Stmt) { 3179 if (Access->getLatestScopArrayInfo() != Old) 3180 continue; 3181 3182 isl::id Id = New->getBasePtrId(); 3183 isl::map Map = Access->getAccessRelation(); 3184 Map = Map.set_tuple_id(isl::dim::out, Id); 3185 Access->setAccessRelation(Map); 3186 } 3187 } 3188 3189 void ScopBuilder::canonicalizeDynamicBasePtrs() { 3190 for (InvariantEquivClassTy &EqClass : scop->InvariantEquivClasses) { 3191 MemoryAccessList &BasePtrAccesses = EqClass.InvariantAccesses; 3192 3193 const ScopArrayInfo *CanonicalBasePtrSAI = 3194 findCanonicalArray(*scop, BasePtrAccesses); 3195 3196 if (!CanonicalBasePtrSAI) 3197 continue; 3198 3199 for (MemoryAccess *BasePtrAccess : BasePtrAccesses) { 3200 const ScopArrayInfo *BasePtrSAI = scop->getScopArrayInfoOrNull( 3201 BasePtrAccess->getAccessInstruction(), MemoryKind::Array); 3202 if (!BasePtrSAI || BasePtrSAI == CanonicalBasePtrSAI || 3203 !BasePtrSAI->isCompatibleWith(CanonicalBasePtrSAI)) 3204 continue; 3205 3206 // we currently do not canonicalize arrays where some accesses are 3207 // hoisted as invariant loads. If we would, we need to update the access 3208 // function of the invariant loads as well. However, as this is not a 3209 // very common situation, we leave this for now to avoid further 3210 // complexity increases. 3211 if (isUsedForIndirectHoistedLoad(*scop, BasePtrSAI)) 3212 continue; 3213 3214 replaceBasePtrArrays(*scop, BasePtrSAI, CanonicalBasePtrSAI); 3215 } 3216 } 3217 } 3218 3219 void ScopBuilder::buildAccessRelations(ScopStmt &Stmt) { 3220 for (MemoryAccess *Access : Stmt.MemAccs) { 3221 Type *ElementType = Access->getElementType(); 3222 3223 MemoryKind Ty; 3224 if (Access->isPHIKind()) 3225 Ty = MemoryKind::PHI; 3226 else if (Access->isExitPHIKind()) 3227 Ty = MemoryKind::ExitPHI; 3228 else if (Access->isValueKind()) 3229 Ty = MemoryKind::Value; 3230 else 3231 Ty = MemoryKind::Array; 3232 3233 // Create isl::pw_aff for SCEVs which describe sizes. Collect all 3234 // assumptions which are taken. isl::pw_aff objects are cached internally 3235 // and they are used later by scop. 3236 for (const SCEV *Size : Access->Sizes) { 3237 if (!Size) 3238 continue; 3239 scop->getPwAff(Size, nullptr, false, &RecordedAssumptions); 3240 } 3241 auto *SAI = scop->getOrCreateScopArrayInfo(Access->getOriginalBaseAddr(), 3242 ElementType, Access->Sizes, Ty); 3243 3244 // Create isl::pw_aff for SCEVs which describe subscripts. Collect all 3245 // assumptions which are taken. isl::pw_aff objects are cached internally 3246 // and they are used later by scop. 3247 for (const SCEV *Subscript : Access->subscripts()) { 3248 if (!Access->isAffine() || !Subscript) 3249 continue; 3250 scop->getPwAff(Subscript, Stmt.getEntryBlock(), false, 3251 &RecordedAssumptions); 3252 } 3253 Access->buildAccessRelation(SAI); 3254 scop->addAccessData(Access); 3255 } 3256 } 3257 3258 /// Add the minimal/maximal access in @p Set to @p User. 3259 /// 3260 /// @return True if more accesses should be added, false if we reached the 3261 /// maximal number of run-time checks to be generated. 3262 static bool buildMinMaxAccess(isl::set Set, 3263 Scop::MinMaxVectorTy &MinMaxAccesses, Scop &S) { 3264 isl::pw_multi_aff MinPMA, MaxPMA; 3265 isl::pw_aff LastDimAff; 3266 isl::aff OneAff; 3267 unsigned Pos; 3268 3269 Set = Set.remove_divs(); 3270 polly::simplify(Set); 3271 3272 if (Set.n_basic_set() > RunTimeChecksMaxAccessDisjuncts) 3273 Set = Set.simple_hull(); 3274 3275 // Restrict the number of parameters involved in the access as the lexmin/ 3276 // lexmax computation will take too long if this number is high. 3277 // 3278 // Experiments with a simple test case using an i7 4800MQ: 3279 // 3280 // #Parameters involved | Time (in sec) 3281 // 6 | 0.01 3282 // 7 | 0.04 3283 // 8 | 0.12 3284 // 9 | 0.40 3285 // 10 | 1.54 3286 // 11 | 6.78 3287 // 12 | 30.38 3288 // 3289 if (isl_set_n_param(Set.get()) > 3290 static_cast<isl_size>(RunTimeChecksMaxParameters)) { 3291 unsigned InvolvedParams = 0; 3292 for (unsigned u = 0, e = isl_set_n_param(Set.get()); u < e; u++) 3293 if (Set.involves_dims(isl::dim::param, u, 1)) 3294 InvolvedParams++; 3295 3296 if (InvolvedParams > RunTimeChecksMaxParameters) 3297 return false; 3298 } 3299 3300 MinPMA = Set.lexmin_pw_multi_aff(); 3301 MaxPMA = Set.lexmax_pw_multi_aff(); 3302 3303 MinPMA = MinPMA.coalesce(); 3304 MaxPMA = MaxPMA.coalesce(); 3305 3306 // Adjust the last dimension of the maximal access by one as we want to 3307 // enclose the accessed memory region by MinPMA and MaxPMA. The pointer 3308 // we test during code generation might now point after the end of the 3309 // allocated array but we will never dereference it anyway. 3310 assert((!MaxPMA || MaxPMA.dim(isl::dim::out)) && 3311 "Assumed at least one output dimension"); 3312 3313 Pos = MaxPMA.dim(isl::dim::out) - 1; 3314 LastDimAff = MaxPMA.get_pw_aff(Pos); 3315 OneAff = isl::aff(isl::local_space(LastDimAff.get_domain_space())); 3316 OneAff = OneAff.add_constant_si(1); 3317 LastDimAff = LastDimAff.add(OneAff); 3318 MaxPMA = MaxPMA.set_pw_aff(Pos, LastDimAff); 3319 3320 if (!MinPMA || !MaxPMA) 3321 return false; 3322 3323 MinMaxAccesses.push_back(std::make_pair(MinPMA, MaxPMA)); 3324 3325 return true; 3326 } 3327 3328 /// Wrapper function to calculate minimal/maximal accesses to each array. 3329 bool ScopBuilder::calculateMinMaxAccess(AliasGroupTy AliasGroup, 3330 Scop::MinMaxVectorTy &MinMaxAccesses) { 3331 MinMaxAccesses.reserve(AliasGroup.size()); 3332 3333 isl::union_set Domains = scop->getDomains(); 3334 isl::union_map Accesses = isl::union_map::empty(scop->getParamSpace()); 3335 3336 for (MemoryAccess *MA : AliasGroup) 3337 Accesses = Accesses.add_map(MA->getAccessRelation()); 3338 3339 Accesses = Accesses.intersect_domain(Domains); 3340 isl::union_set Locations = Accesses.range(); 3341 3342 bool LimitReached = false; 3343 for (isl::set Set : Locations.get_set_list()) { 3344 LimitReached |= !buildMinMaxAccess(Set, MinMaxAccesses, *scop); 3345 if (LimitReached) 3346 break; 3347 } 3348 3349 return !LimitReached; 3350 } 3351 3352 static isl::set getAccessDomain(MemoryAccess *MA) { 3353 isl::set Domain = MA->getStatement()->getDomain(); 3354 Domain = Domain.project_out(isl::dim::set, 0, Domain.n_dim()); 3355 return Domain.reset_tuple_id(); 3356 } 3357 3358 bool ScopBuilder::buildAliasChecks() { 3359 if (!PollyUseRuntimeAliasChecks) 3360 return true; 3361 3362 if (buildAliasGroups()) { 3363 // Aliasing assumptions do not go through addAssumption but we still want to 3364 // collect statistics so we do it here explicitly. 3365 if (scop->getAliasGroups().size()) 3366 Scop::incrementNumberOfAliasingAssumptions(1); 3367 return true; 3368 } 3369 3370 // If a problem occurs while building the alias groups we need to delete 3371 // this SCoP and pretend it wasn't valid in the first place. To this end 3372 // we make the assumed context infeasible. 3373 scop->invalidate(ALIASING, DebugLoc()); 3374 3375 LLVM_DEBUG( 3376 dbgs() << "\n\nNOTE: Run time checks for " << scop->getNameStr() 3377 << " could not be created as the number of parameters involved " 3378 "is too high. The SCoP will be " 3379 "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust " 3380 "the maximal number of parameters but be advised that the " 3381 "compile time might increase exponentially.\n\n"); 3382 return false; 3383 } 3384 3385 std::tuple<ScopBuilder::AliasGroupVectorTy, DenseSet<const ScopArrayInfo *>> 3386 ScopBuilder::buildAliasGroupsForAccesses() { 3387 AliasSetTracker AST(AA); 3388 3389 DenseMap<Value *, MemoryAccess *> PtrToAcc; 3390 DenseSet<const ScopArrayInfo *> HasWriteAccess; 3391 for (ScopStmt &Stmt : *scop) { 3392 3393 isl::set StmtDomain = Stmt.getDomain(); 3394 bool StmtDomainEmpty = StmtDomain.is_empty(); 3395 3396 // Statements with an empty domain will never be executed. 3397 if (StmtDomainEmpty) 3398 continue; 3399 3400 for (MemoryAccess *MA : Stmt) { 3401 if (MA->isScalarKind()) 3402 continue; 3403 if (!MA->isRead()) 3404 HasWriteAccess.insert(MA->getScopArrayInfo()); 3405 MemAccInst Acc(MA->getAccessInstruction()); 3406 if (MA->isRead() && isa<MemTransferInst>(Acc)) 3407 PtrToAcc[cast<MemTransferInst>(Acc)->getRawSource()] = MA; 3408 else 3409 PtrToAcc[Acc.getPointerOperand()] = MA; 3410 AST.add(Acc); 3411 } 3412 } 3413 3414 AliasGroupVectorTy AliasGroups; 3415 for (AliasSet &AS : AST) { 3416 if (AS.isMustAlias() || AS.isForwardingAliasSet()) 3417 continue; 3418 AliasGroupTy AG; 3419 for (auto &PR : AS) 3420 AG.push_back(PtrToAcc[PR.getValue()]); 3421 if (AG.size() < 2) 3422 continue; 3423 AliasGroups.push_back(std::move(AG)); 3424 } 3425 3426 return std::make_tuple(AliasGroups, HasWriteAccess); 3427 } 3428 3429 bool ScopBuilder::buildAliasGroups() { 3430 // To create sound alias checks we perform the following steps: 3431 // o) We partition each group into read only and non read only accesses. 3432 // o) For each group with more than one base pointer we then compute minimal 3433 // and maximal accesses to each array of a group in read only and non 3434 // read only partitions separately. 3435 AliasGroupVectorTy AliasGroups; 3436 DenseSet<const ScopArrayInfo *> HasWriteAccess; 3437 3438 std::tie(AliasGroups, HasWriteAccess) = buildAliasGroupsForAccesses(); 3439 3440 splitAliasGroupsByDomain(AliasGroups); 3441 3442 for (AliasGroupTy &AG : AliasGroups) { 3443 if (!scop->hasFeasibleRuntimeContext()) 3444 return false; 3445 3446 { 3447 IslMaxOperationsGuard MaxOpGuard(scop->getIslCtx().get(), OptComputeOut); 3448 bool Valid = buildAliasGroup(AG, HasWriteAccess); 3449 if (!Valid) 3450 return false; 3451 } 3452 if (isl_ctx_last_error(scop->getIslCtx().get()) == isl_error_quota) { 3453 scop->invalidate(COMPLEXITY, DebugLoc()); 3454 return false; 3455 } 3456 } 3457 3458 return true; 3459 } 3460 3461 bool ScopBuilder::buildAliasGroup( 3462 AliasGroupTy &AliasGroup, DenseSet<const ScopArrayInfo *> HasWriteAccess) { 3463 AliasGroupTy ReadOnlyAccesses; 3464 AliasGroupTy ReadWriteAccesses; 3465 SmallPtrSet<const ScopArrayInfo *, 4> ReadWriteArrays; 3466 SmallPtrSet<const ScopArrayInfo *, 4> ReadOnlyArrays; 3467 3468 if (AliasGroup.size() < 2) 3469 return true; 3470 3471 for (MemoryAccess *Access : AliasGroup) { 3472 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "PossibleAlias", 3473 Access->getAccessInstruction()) 3474 << "Possibly aliasing pointer, use restrict keyword."); 3475 const ScopArrayInfo *Array = Access->getScopArrayInfo(); 3476 if (HasWriteAccess.count(Array)) { 3477 ReadWriteArrays.insert(Array); 3478 ReadWriteAccesses.push_back(Access); 3479 } else { 3480 ReadOnlyArrays.insert(Array); 3481 ReadOnlyAccesses.push_back(Access); 3482 } 3483 } 3484 3485 // If there are no read-only pointers, and less than two read-write pointers, 3486 // no alias check is needed. 3487 if (ReadOnlyAccesses.empty() && ReadWriteArrays.size() <= 1) 3488 return true; 3489 3490 // If there is no read-write pointer, no alias check is needed. 3491 if (ReadWriteArrays.empty()) 3492 return true; 3493 3494 // For non-affine accesses, no alias check can be generated as we cannot 3495 // compute a sufficiently tight lower and upper bound: bail out. 3496 for (MemoryAccess *MA : AliasGroup) { 3497 if (!MA->isAffine()) { 3498 scop->invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc(), 3499 MA->getAccessInstruction()->getParent()); 3500 return false; 3501 } 3502 } 3503 3504 // Ensure that for all memory accesses for which we generate alias checks, 3505 // their base pointers are available. 3506 for (MemoryAccess *MA : AliasGroup) { 3507 if (MemoryAccess *BasePtrMA = scop->lookupBasePtrAccess(MA)) 3508 scop->addRequiredInvariantLoad( 3509 cast<LoadInst>(BasePtrMA->getAccessInstruction())); 3510 } 3511 3512 // scop->getAliasGroups().emplace_back(); 3513 // Scop::MinMaxVectorPairTy &pair = scop->getAliasGroups().back(); 3514 Scop::MinMaxVectorTy MinMaxAccessesReadWrite; 3515 Scop::MinMaxVectorTy MinMaxAccessesReadOnly; 3516 3517 bool Valid; 3518 3519 Valid = calculateMinMaxAccess(ReadWriteAccesses, MinMaxAccessesReadWrite); 3520 3521 if (!Valid) 3522 return false; 3523 3524 // Bail out if the number of values we need to compare is too large. 3525 // This is important as the number of comparisons grows quadratically with 3526 // the number of values we need to compare. 3527 if (MinMaxAccessesReadWrite.size() + ReadOnlyArrays.size() > 3528 RunTimeChecksMaxArraysPerGroup) 3529 return false; 3530 3531 Valid = calculateMinMaxAccess(ReadOnlyAccesses, MinMaxAccessesReadOnly); 3532 3533 scop->addAliasGroup(MinMaxAccessesReadWrite, MinMaxAccessesReadOnly); 3534 if (!Valid) 3535 return false; 3536 3537 return true; 3538 } 3539 3540 void ScopBuilder::splitAliasGroupsByDomain(AliasGroupVectorTy &AliasGroups) { 3541 for (unsigned u = 0; u < AliasGroups.size(); u++) { 3542 AliasGroupTy NewAG; 3543 AliasGroupTy &AG = AliasGroups[u]; 3544 AliasGroupTy::iterator AGI = AG.begin(); 3545 isl::set AGDomain = getAccessDomain(*AGI); 3546 while (AGI != AG.end()) { 3547 MemoryAccess *MA = *AGI; 3548 isl::set MADomain = getAccessDomain(MA); 3549 if (AGDomain.is_disjoint(MADomain)) { 3550 NewAG.push_back(MA); 3551 AGI = AG.erase(AGI); 3552 } else { 3553 AGDomain = AGDomain.unite(MADomain); 3554 AGI++; 3555 } 3556 } 3557 if (NewAG.size() > 1) 3558 AliasGroups.push_back(std::move(NewAG)); 3559 } 3560 } 3561 3562 #ifndef NDEBUG 3563 static void verifyUse(Scop *S, Use &Op, LoopInfo &LI) { 3564 auto PhysUse = VirtualUse::create(S, Op, &LI, false); 3565 auto VirtUse = VirtualUse::create(S, Op, &LI, true); 3566 assert(PhysUse.getKind() == VirtUse.getKind()); 3567 } 3568 3569 /// Check the consistency of every statement's MemoryAccesses. 3570 /// 3571 /// The check is carried out by expecting the "physical" kind of use (derived 3572 /// from the BasicBlocks instructions resides in) to be same as the "virtual" 3573 /// kind of use (derived from a statement's MemoryAccess). 3574 /// 3575 /// The "physical" uses are taken by ensureValueRead to determine whether to 3576 /// create MemoryAccesses. When done, the kind of scalar access should be the 3577 /// same no matter which way it was derived. 3578 /// 3579 /// The MemoryAccesses might be changed by later SCoP-modifying passes and hence 3580 /// can intentionally influence on the kind of uses (not corresponding to the 3581 /// "physical" anymore, hence called "virtual"). The CodeGenerator therefore has 3582 /// to pick up the virtual uses. But here in the code generator, this has not 3583 /// happened yet, such that virtual and physical uses are equivalent. 3584 static void verifyUses(Scop *S, LoopInfo &LI, DominatorTree &DT) { 3585 for (auto *BB : S->getRegion().blocks()) { 3586 for (auto &Inst : *BB) { 3587 auto *Stmt = S->getStmtFor(&Inst); 3588 if (!Stmt) 3589 continue; 3590 3591 if (isIgnoredIntrinsic(&Inst)) 3592 continue; 3593 3594 // Branch conditions are encoded in the statement domains. 3595 if (Inst.isTerminator() && Stmt->isBlockStmt()) 3596 continue; 3597 3598 // Verify all uses. 3599 for (auto &Op : Inst.operands()) 3600 verifyUse(S, Op, LI); 3601 3602 // Stores do not produce values used by other statements. 3603 if (isa<StoreInst>(Inst)) 3604 continue; 3605 3606 // For every value defined in the block, also check that a use of that 3607 // value in the same statement would not be an inter-statement use. It can 3608 // still be synthesizable or load-hoisted, but these kind of instructions 3609 // are not directly copied in code-generation. 3610 auto VirtDef = 3611 VirtualUse::create(S, Stmt, Stmt->getSurroundingLoop(), &Inst, true); 3612 assert(VirtDef.getKind() == VirtualUse::Synthesizable || 3613 VirtDef.getKind() == VirtualUse::Intra || 3614 VirtDef.getKind() == VirtualUse::Hoisted); 3615 } 3616 } 3617 3618 if (S->hasSingleExitEdge()) 3619 return; 3620 3621 // PHINodes in the SCoP region's exit block are also uses to be checked. 3622 if (!S->getRegion().isTopLevelRegion()) { 3623 for (auto &Inst : *S->getRegion().getExit()) { 3624 if (!isa<PHINode>(Inst)) 3625 break; 3626 3627 for (auto &Op : Inst.operands()) 3628 verifyUse(S, Op, LI); 3629 } 3630 } 3631 } 3632 #endif 3633 3634 void ScopBuilder::buildScop(Region &R, AssumptionCache &AC) { 3635 scop.reset(new Scop(R, SE, LI, DT, *SD.getDetectionContext(&R), ORE, 3636 SD.getNextID())); 3637 3638 buildStmts(R); 3639 3640 // Create all invariant load instructions first. These are categorized as 3641 // 'synthesizable', therefore are not part of any ScopStmt but need to be 3642 // created somewhere. 3643 const InvariantLoadsSetTy &RIL = scop->getRequiredInvariantLoads(); 3644 for (BasicBlock *BB : scop->getRegion().blocks()) { 3645 if (isErrorBlock(*BB, scop->getRegion(), LI, DT)) 3646 continue; 3647 3648 for (Instruction &Inst : *BB) { 3649 LoadInst *Load = dyn_cast<LoadInst>(&Inst); 3650 if (!Load) 3651 continue; 3652 3653 if (!RIL.count(Load)) 3654 continue; 3655 3656 // Invariant loads require a MemoryAccess to be created in some statement. 3657 // It is not important to which statement the MemoryAccess is added 3658 // because it will later be removed from the ScopStmt again. We chose the 3659 // first statement of the basic block the LoadInst is in. 3660 ArrayRef<ScopStmt *> List = scop->getStmtListFor(BB); 3661 assert(!List.empty()); 3662 ScopStmt *RILStmt = List.front(); 3663 buildMemoryAccess(Load, RILStmt); 3664 } 3665 } 3666 buildAccessFunctions(); 3667 3668 // In case the region does not have an exiting block we will later (during 3669 // code generation) split the exit block. This will move potential PHI nodes 3670 // from the current exit block into the new region exiting block. Hence, PHI 3671 // nodes that are at this point not part of the region will be. 3672 // To handle these PHI nodes later we will now model their operands as scalar 3673 // accesses. Note that we do not model anything in the exit block if we have 3674 // an exiting block in the region, as there will not be any splitting later. 3675 if (!R.isTopLevelRegion() && !scop->hasSingleExitEdge()) { 3676 for (Instruction &Inst : *R.getExit()) { 3677 PHINode *PHI = dyn_cast<PHINode>(&Inst); 3678 if (!PHI) 3679 break; 3680 3681 buildPHIAccesses(nullptr, PHI, nullptr, true); 3682 } 3683 } 3684 3685 // Create memory accesses for global reads since all arrays are now known. 3686 auto *AF = SE.getConstant(IntegerType::getInt64Ty(SE.getContext()), 0); 3687 for (auto GlobalReadPair : GlobalReads) { 3688 ScopStmt *GlobalReadStmt = GlobalReadPair.first; 3689 Instruction *GlobalRead = GlobalReadPair.second; 3690 for (auto *BP : ArrayBasePointers) 3691 addArrayAccess(GlobalReadStmt, MemAccInst(GlobalRead), MemoryAccess::READ, 3692 BP, BP->getType(), false, {AF}, {nullptr}, GlobalRead); 3693 } 3694 3695 buildInvariantEquivalenceClasses(); 3696 3697 /// A map from basic blocks to their invalid domains. 3698 DenseMap<BasicBlock *, isl::set> InvalidDomainMap; 3699 3700 if (!buildDomains(&R, InvalidDomainMap)) { 3701 LLVM_DEBUG( 3702 dbgs() << "Bailing-out because buildDomains encountered problems\n"); 3703 return; 3704 } 3705 3706 addUserAssumptions(AC, InvalidDomainMap); 3707 3708 // Initialize the invalid domain. 3709 for (ScopStmt &Stmt : scop->Stmts) 3710 if (Stmt.isBlockStmt()) 3711 Stmt.setInvalidDomain(InvalidDomainMap[Stmt.getEntryBlock()]); 3712 else 3713 Stmt.setInvalidDomain(InvalidDomainMap[getRegionNodeBasicBlock( 3714 Stmt.getRegion()->getNode())]); 3715 3716 // Remove empty statements. 3717 // Exit early in case there are no executable statements left in this scop. 3718 scop->removeStmtNotInDomainMap(); 3719 scop->simplifySCoP(false); 3720 if (scop->isEmpty()) { 3721 LLVM_DEBUG(dbgs() << "Bailing-out because SCoP is empty\n"); 3722 return; 3723 } 3724 3725 // The ScopStmts now have enough information to initialize themselves. 3726 for (ScopStmt &Stmt : *scop) { 3727 collectSurroundingLoops(Stmt); 3728 3729 buildDomain(Stmt); 3730 buildAccessRelations(Stmt); 3731 3732 if (DetectReductions) 3733 checkForReductions(Stmt); 3734 } 3735 3736 // Check early for a feasible runtime context. 3737 if (!scop->hasFeasibleRuntimeContext()) { 3738 LLVM_DEBUG(dbgs() << "Bailing-out because of unfeasible context (early)\n"); 3739 return; 3740 } 3741 3742 // Check early for profitability. Afterwards it cannot change anymore, 3743 // only the runtime context could become infeasible. 3744 if (!scop->isProfitable(UnprofitableScalarAccs)) { 3745 scop->invalidate(PROFITABLE, DebugLoc()); 3746 LLVM_DEBUG( 3747 dbgs() << "Bailing-out because SCoP is not considered profitable\n"); 3748 return; 3749 } 3750 3751 buildSchedule(); 3752 3753 finalizeAccesses(); 3754 3755 scop->realignParams(); 3756 addUserContext(); 3757 3758 // After the context was fully constructed, thus all our knowledge about 3759 // the parameters is in there, we add all recorded assumptions to the 3760 // assumed/invalid context. 3761 addRecordedAssumptions(); 3762 3763 scop->simplifyContexts(); 3764 if (!buildAliasChecks()) { 3765 LLVM_DEBUG(dbgs() << "Bailing-out because could not build alias checks\n"); 3766 return; 3767 } 3768 3769 hoistInvariantLoads(); 3770 canonicalizeDynamicBasePtrs(); 3771 verifyInvariantLoads(); 3772 scop->simplifySCoP(true); 3773 3774 // Check late for a feasible runtime context because profitability did not 3775 // change. 3776 if (!scop->hasFeasibleRuntimeContext()) { 3777 LLVM_DEBUG(dbgs() << "Bailing-out because of unfeasible context (late)\n"); 3778 return; 3779 } 3780 3781 #ifndef NDEBUG 3782 verifyUses(scop.get(), LI, DT); 3783 #endif 3784 } 3785 3786 ScopBuilder::ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA, 3787 const DataLayout &DL, DominatorTree &DT, LoopInfo &LI, 3788 ScopDetection &SD, ScalarEvolution &SE, 3789 OptimizationRemarkEmitter &ORE) 3790 : AA(AA), DL(DL), DT(DT), LI(LI), SD(SD), SE(SE), ORE(ORE) { 3791 DebugLoc Beg, End; 3792 auto P = getBBPairForRegion(R); 3793 getDebugLocations(P, Beg, End); 3794 3795 std::string Msg = "SCoP begins here."; 3796 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEntry", Beg, P.first) 3797 << Msg); 3798 3799 buildScop(*R, AC); 3800 3801 LLVM_DEBUG(dbgs() << *scop); 3802 3803 if (!scop->hasFeasibleRuntimeContext()) { 3804 InfeasibleScops++; 3805 Msg = "SCoP ends here but was dismissed."; 3806 LLVM_DEBUG(dbgs() << "SCoP detected but dismissed\n"); 3807 RecordedAssumptions.clear(); 3808 scop.reset(); 3809 } else { 3810 Msg = "SCoP ends here."; 3811 ++ScopFound; 3812 if (scop->getMaxLoopDepth() > 0) 3813 ++RichScopFound; 3814 } 3815 3816 if (R->isTopLevelRegion()) 3817 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.first) 3818 << Msg); 3819 else 3820 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.second) 3821 << Msg); 3822 } 3823