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