1 //===------ Simplify.cpp ----------------------------------------*- C++ -*-===// 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 // Simplify a SCoP by removing unnecessary statements and accesses. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "polly/Simplify.h" 14 #include "polly/ScopInfo.h" 15 #include "polly/ScopPass.h" 16 #include "polly/Support/GICHelper.h" 17 #include "polly/Support/ISLOStream.h" 18 #include "polly/Support/ISLTools.h" 19 #include "polly/Support/VirtualInstruction.h" 20 #include "llvm/ADT/Statistic.h" 21 #include "llvm/InitializePasses.h" 22 #include "llvm/Support/Debug.h" 23 24 #define DEBUG_TYPE "polly-simplify" 25 26 using namespace llvm; 27 using namespace polly; 28 29 namespace { 30 31 #define TWO_STATISTICS(VARNAME, DESC) \ 32 static llvm::Statistic VARNAME[2] = { \ 33 {DEBUG_TYPE, #VARNAME "0", DESC " (first)"}, \ 34 {DEBUG_TYPE, #VARNAME "1", DESC " (second)"}} 35 36 /// Number of max disjuncts we allow in removeOverwrites(). This is to avoid 37 /// that the analysis of accesses in a statement is becoming too complex. Chosen 38 /// to be relatively small because all the common cases should access only few 39 /// array elements per statement. 40 static unsigned const SimplifyMaxDisjuncts = 4; 41 42 TWO_STATISTICS(ScopsProcessed, "Number of SCoPs processed"); 43 TWO_STATISTICS(ScopsModified, "Number of SCoPs simplified"); 44 45 TWO_STATISTICS(TotalEmptyDomainsRemoved, 46 "Number of statement with empty domains removed in any SCoP"); 47 TWO_STATISTICS(TotalOverwritesRemoved, "Number of removed overwritten writes"); 48 TWO_STATISTICS(TotalWritesCoalesced, "Number of writes coalesced with another"); 49 TWO_STATISTICS(TotalRedundantWritesRemoved, 50 "Number of writes of same value removed in any SCoP"); 51 TWO_STATISTICS(TotalEmptyPartialAccessesRemoved, 52 "Number of empty partial accesses removed"); 53 TWO_STATISTICS(TotalDeadAccessesRemoved, "Number of dead accesses removed"); 54 TWO_STATISTICS(TotalDeadInstructionsRemoved, 55 "Number of unused instructions removed"); 56 TWO_STATISTICS(TotalStmtsRemoved, "Number of statements removed in any SCoP"); 57 58 TWO_STATISTICS(NumValueWrites, "Number of scalar value writes after Simplify"); 59 TWO_STATISTICS( 60 NumValueWritesInLoops, 61 "Number of scalar value writes nested in affine loops after Simplify"); 62 TWO_STATISTICS(NumPHIWrites, 63 "Number of scalar phi writes after the first simplification"); 64 TWO_STATISTICS( 65 NumPHIWritesInLoops, 66 "Number of scalar phi writes nested in affine loops after Simplify"); 67 TWO_STATISTICS(NumSingletonWrites, "Number of singleton writes after Simplify"); 68 TWO_STATISTICS( 69 NumSingletonWritesInLoops, 70 "Number of singleton writes nested in affine loops after Simplify"); 71 72 static bool isImplicitRead(MemoryAccess *MA) { 73 return MA->isRead() && MA->isOriginalScalarKind(); 74 } 75 76 static bool isExplicitAccess(MemoryAccess *MA) { 77 return MA->isOriginalArrayKind(); 78 } 79 80 static bool isImplicitWrite(MemoryAccess *MA) { 81 return MA->isWrite() && MA->isOriginalScalarKind(); 82 } 83 84 /// Like isl::union_map::unite, but may also return an underapproximated 85 /// result if getting too complex. 86 /// 87 /// This is implemented by adding disjuncts to the results until the limit is 88 /// reached. 89 static isl::union_map underapproximatedAddMap(isl::union_map UMap, 90 isl::map Map) { 91 if (UMap.is_null() || Map.is_null()) 92 return {}; 93 94 isl::map PrevMap = UMap.extract_map(Map.get_space()); 95 96 // Fast path: If known that we cannot exceed the disjunct limit, just add 97 // them. 98 if (unsignedFromIslSize(PrevMap.n_basic_map()) + 99 unsignedFromIslSize(Map.n_basic_map()) <= 100 SimplifyMaxDisjuncts) 101 return UMap.unite(Map); 102 103 isl::map Result = isl::map::empty(PrevMap.get_space()); 104 for (isl::basic_map BMap : PrevMap.get_basic_map_list()) { 105 if (unsignedFromIslSize(Result.n_basic_map()) > SimplifyMaxDisjuncts) 106 break; 107 Result = Result.unite(BMap); 108 } 109 for (isl::basic_map BMap : Map.get_basic_map_list()) { 110 if (unsignedFromIslSize(Result.n_basic_map()) > SimplifyMaxDisjuncts) 111 break; 112 Result = Result.unite(BMap); 113 } 114 115 isl::union_map UResult = 116 UMap.subtract(isl::map::universe(PrevMap.get_space())); 117 UResult.unite(Result); 118 119 return UResult; 120 } 121 122 class SimplifyImpl { 123 private: 124 /// The invocation id (if there are multiple instances in the pass manager's 125 /// pipeline) to determine which statistics to update. 126 int CallNo; 127 128 /// The last/current SCoP that is/has been processed. 129 Scop *S = nullptr; 130 131 /// Number of statements with empty domains removed from the SCoP. 132 int EmptyDomainsRemoved = 0; 133 134 /// Number of writes that are overwritten anyway. 135 int OverwritesRemoved = 0; 136 137 /// Number of combined writes. 138 int WritesCoalesced = 0; 139 140 /// Number of redundant writes removed from this SCoP. 141 int RedundantWritesRemoved = 0; 142 143 /// Number of writes with empty access domain removed. 144 int EmptyPartialAccessesRemoved = 0; 145 146 /// Number of unused accesses removed from this SCoP. 147 int DeadAccessesRemoved = 0; 148 149 /// Number of unused instructions removed from this SCoP. 150 int DeadInstructionsRemoved = 0; 151 152 /// Number of unnecessary statements removed from the SCoP. 153 int StmtsRemoved = 0; 154 155 /// Remove statements that are never executed due to their domains being 156 /// empty. 157 /// 158 /// In contrast to Scop::simplifySCoP, this removes based on the SCoP's 159 /// effective domain, i.e. including the SCoP's context as used by some other 160 /// simplification methods in this pass. This is necessary because the 161 /// analysis on empty domains is unreliable, e.g. remove a scalar value 162 /// definition MemoryAccesses, but not its use. 163 void removeEmptyDomainStmts(); 164 165 /// Remove writes that are overwritten unconditionally later in the same 166 /// statement. 167 /// 168 /// There must be no read of the same value between the write (that is to be 169 /// removed) and the overwrite. 170 void removeOverwrites(); 171 172 /// Combine writes that write the same value if possible. 173 /// 174 /// This function is able to combine: 175 /// - Partial writes with disjoint domain. 176 /// - Writes that write to the same array element. 177 /// 178 /// In all cases, both writes must write the same values. 179 void coalesceWrites(); 180 181 /// Remove writes that just write the same value already stored in the 182 /// element. 183 void removeRedundantWrites(); 184 185 /// Remove statements without side effects. 186 void removeUnnecessaryStmts(); 187 188 /// Remove accesses that have an empty domain. 189 void removeEmptyPartialAccesses(); 190 191 /// Mark all reachable instructions and access, and sweep those that are not 192 /// reachable. 193 void markAndSweep(LoopInfo *LI); 194 195 /// Print simplification statistics to @p OS. 196 void printStatistics(llvm::raw_ostream &OS, int Indent = 0) const; 197 198 /// Print the current state of all MemoryAccesses to @p OS. 199 void printAccesses(llvm::raw_ostream &OS, int Indent = 0) const; 200 201 public: 202 explicit SimplifyImpl(int CallNo = 0) : CallNo(CallNo) {} 203 204 void run(Scop &S, LoopInfo *LI); 205 206 void printScop(raw_ostream &OS, Scop &S) const; 207 208 /// Return whether at least one simplification has been applied. 209 bool isModified() const; 210 }; 211 212 /// Return whether at least one simplification has been applied. 213 bool SimplifyImpl::isModified() const { 214 return EmptyDomainsRemoved > 0 || OverwritesRemoved > 0 || 215 WritesCoalesced > 0 || RedundantWritesRemoved > 0 || 216 EmptyPartialAccessesRemoved > 0 || DeadAccessesRemoved > 0 || 217 DeadInstructionsRemoved > 0 || StmtsRemoved > 0; 218 } 219 220 /// Remove statements that are never executed due to their domains being 221 /// empty. 222 /// 223 /// In contrast to Scop::simplifySCoP, this removes based on the SCoP's 224 /// effective domain, i.e. including the SCoP's context as used by some other 225 /// simplification methods in this pass. This is necessary because the 226 /// analysis on empty domains is unreliable, e.g. remove a scalar value 227 /// definition MemoryAccesses, but not its use. 228 void SimplifyImpl::removeEmptyDomainStmts() { 229 size_t NumStmtsBefore = S->getSize(); 230 231 S->removeStmts([](ScopStmt &Stmt) -> bool { 232 auto EffectiveDomain = 233 Stmt.getDomain().intersect_params(Stmt.getParent()->getContext()); 234 return EffectiveDomain.is_empty(); 235 }); 236 237 assert(NumStmtsBefore >= S->getSize()); 238 EmptyDomainsRemoved = NumStmtsBefore - S->getSize(); 239 LLVM_DEBUG(dbgs() << "Removed " << EmptyDomainsRemoved << " (of " 240 << NumStmtsBefore << ") statements with empty domains \n"); 241 TotalEmptyDomainsRemoved[CallNo] += EmptyDomainsRemoved; 242 } 243 244 /// Remove writes that are overwritten unconditionally later in the same 245 /// statement. 246 /// 247 /// There must be no read of the same value between the write (that is to be 248 /// removed) and the overwrite. 249 void SimplifyImpl::removeOverwrites() { 250 for (auto &Stmt : *S) { 251 isl::set Domain = Stmt.getDomain(); 252 isl::union_map WillBeOverwritten = isl::union_map::empty(S->getIslCtx()); 253 254 SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt)); 255 256 // Iterate in reverse order, so the overwrite comes before the write that 257 // is to be removed. 258 for (auto *MA : reverse(Accesses)) { 259 260 // In region statements, the explicit accesses can be in blocks that are 261 // can be executed in any order. We therefore process only the implicit 262 // writes and stop after that. 263 if (Stmt.isRegionStmt() && isExplicitAccess(MA)) 264 break; 265 266 auto AccRel = MA->getAccessRelation(); 267 AccRel = AccRel.intersect_domain(Domain); 268 AccRel = AccRel.intersect_params(S->getContext()); 269 270 // If a value is read in-between, do not consider it as overwritten. 271 if (MA->isRead()) { 272 // Invalidate all overwrites for the array it accesses to avoid too 273 // complex isl sets. 274 isl::map AccRelUniv = isl::map::universe(AccRel.get_space()); 275 WillBeOverwritten = WillBeOverwritten.subtract(AccRelUniv); 276 continue; 277 } 278 279 // If all of a write's elements are overwritten, remove it. 280 isl::union_map AccRelUnion = AccRel; 281 if (AccRelUnion.is_subset(WillBeOverwritten)) { 282 LLVM_DEBUG(dbgs() << "Removing " << MA 283 << " which will be overwritten anyway\n"); 284 285 Stmt.removeSingleMemoryAccess(MA); 286 OverwritesRemoved++; 287 TotalOverwritesRemoved[CallNo]++; 288 } 289 290 // Unconditional writes overwrite other values. 291 if (MA->isMustWrite()) { 292 // Avoid too complex isl sets. If necessary, throw away some of the 293 // knowledge. 294 WillBeOverwritten = underapproximatedAddMap(WillBeOverwritten, AccRel); 295 } 296 } 297 } 298 } 299 300 /// Combine writes that write the same value if possible. 301 /// 302 /// This function is able to combine: 303 /// - Partial writes with disjoint domain. 304 /// - Writes that write to the same array element. 305 /// 306 /// In all cases, both writes must write the same values. 307 void SimplifyImpl::coalesceWrites() { 308 for (auto &Stmt : *S) { 309 isl::set Domain = Stmt.getDomain().intersect_params(S->getContext()); 310 311 // We let isl do the lookup for the same-value condition. For this, we 312 // wrap llvm::Value into an isl::set such that isl can do the lookup in 313 // its hashtable implementation. llvm::Values are only compared within a 314 // ScopStmt, so the map can be local to this scope. TODO: Refactor with 315 // ZoneAlgorithm::makeValueSet() 316 SmallDenseMap<Value *, isl::set> ValueSets; 317 auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set { 318 assert(V); 319 isl::set &Result = ValueSets[V]; 320 if (Result.is_null()) { 321 isl::ctx Ctx = S->getIslCtx(); 322 std::string Name = getIslCompatibleName( 323 "Val", V, ValueSets.size() - 1, std::string(), UseInstructionNames); 324 isl::id Id = isl::id::alloc(Ctx, Name, V); 325 Result = isl::set::universe( 326 isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id)); 327 } 328 return Result; 329 }; 330 331 // List of all eligible (for coalescing) writes of the future. 332 // { [Domain[] -> Element[]] -> [Value[] -> MemoryAccess[]] } 333 isl::union_map FutureWrites = isl::union_map::empty(S->getIslCtx()); 334 335 // Iterate over accesses from the last to the first. 336 SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt)); 337 for (MemoryAccess *MA : reverse(Accesses)) { 338 // In region statements, the explicit accesses can be in blocks that can 339 // be executed in any order. We therefore process only the implicit 340 // writes and stop after that. 341 if (Stmt.isRegionStmt() && isExplicitAccess(MA)) 342 break; 343 344 // { Domain[] -> Element[] } 345 isl::map AccRel = MA->getLatestAccessRelation().intersect_domain(Domain); 346 347 // { [Domain[] -> Element[]] } 348 isl::set AccRelWrapped = AccRel.wrap(); 349 350 // { Value[] } 351 isl::set ValSet; 352 353 if (MA->isMustWrite() && (MA->isOriginalScalarKind() || 354 isa<StoreInst>(MA->getAccessInstruction()))) { 355 // Normally, tryGetValueStored() should be used to determine which 356 // element is written, but it can return nullptr; For PHI accesses, 357 // getAccessValue() returns the PHI instead of the PHI's incoming 358 // value. In this case, where we only compare values of a single 359 // statement, this is fine, because within a statement, a PHI in a 360 // successor block has always the same value as the incoming write. We 361 // still preferably use the incoming value directly so we also catch 362 // direct uses of that. 363 Value *StoredVal = MA->tryGetValueStored(); 364 if (!StoredVal) 365 StoredVal = MA->getAccessValue(); 366 ValSet = makeValueSet(StoredVal); 367 368 // { Domain[] } 369 isl::set AccDomain = AccRel.domain(); 370 371 // Parts of the statement's domain that is not written by this access. 372 isl::set UndefDomain = Domain.subtract(AccDomain); 373 374 // { Element[] } 375 isl::set ElementUniverse = 376 isl::set::universe(AccRel.get_space().range()); 377 378 // { Domain[] -> Element[] } 379 isl::map UndefAnything = 380 isl::map::from_domain_and_range(UndefDomain, ElementUniverse); 381 382 // We are looking a compatible write access. The other write can 383 // access these elements... 384 isl::map AllowedAccesses = AccRel.unite(UndefAnything); 385 386 // ... and must write the same value. 387 // { [Domain[] -> Element[]] -> Value[] } 388 isl::map Filter = 389 isl::map::from_domain_and_range(AllowedAccesses.wrap(), ValSet); 390 391 // Lookup future write that fulfills these conditions. 392 // { [[Domain[] -> Element[]] -> Value[]] -> MemoryAccess[] } 393 isl::union_map Filtered = 394 FutureWrites.uncurry().intersect_domain(Filter.wrap()); 395 396 // Iterate through the candidates. 397 for (isl::map Map : Filtered.get_map_list()) { 398 MemoryAccess *OtherMA = (MemoryAccess *)Map.get_space() 399 .get_tuple_id(isl::dim::out) 400 .get_user(); 401 402 isl::map OtherAccRel = 403 OtherMA->getLatestAccessRelation().intersect_domain(Domain); 404 405 // The filter only guaranteed that some of OtherMA's accessed 406 // elements are allowed. Verify that it only accesses allowed 407 // elements. Otherwise, continue with the next candidate. 408 if (!OtherAccRel.is_subset(AllowedAccesses).is_true()) 409 continue; 410 411 // The combined access relation. 412 // { Domain[] -> Element[] } 413 isl::map NewAccRel = AccRel.unite(OtherAccRel); 414 simplify(NewAccRel); 415 416 // Carry out the coalescing. 417 Stmt.removeSingleMemoryAccess(MA); 418 OtherMA->setNewAccessRelation(NewAccRel); 419 420 // We removed MA, OtherMA takes its role. 421 MA = OtherMA; 422 423 TotalWritesCoalesced[CallNo]++; 424 WritesCoalesced++; 425 426 // Don't look for more candidates. 427 break; 428 } 429 } 430 431 // Two writes cannot be coalesced if there is another access (to some of 432 // the written elements) between them. Remove all visited write accesses 433 // from the list of eligible writes. Don't just remove the accessed 434 // elements, but any MemoryAccess that touches any of the invalidated 435 // elements. 436 SmallPtrSet<MemoryAccess *, 2> TouchedAccesses; 437 for (isl::map Map : 438 FutureWrites.intersect_domain(AccRelWrapped).get_map_list()) { 439 MemoryAccess *MA = (MemoryAccess *)Map.get_space() 440 .range() 441 .unwrap() 442 .get_tuple_id(isl::dim::out) 443 .get_user(); 444 TouchedAccesses.insert(MA); 445 } 446 isl::union_map NewFutureWrites = 447 isl::union_map::empty(FutureWrites.ctx()); 448 for (isl::map FutureWrite : FutureWrites.get_map_list()) { 449 MemoryAccess *MA = (MemoryAccess *)FutureWrite.get_space() 450 .range() 451 .unwrap() 452 .get_tuple_id(isl::dim::out) 453 .get_user(); 454 if (!TouchedAccesses.count(MA)) 455 NewFutureWrites = NewFutureWrites.unite(FutureWrite); 456 } 457 FutureWrites = NewFutureWrites; 458 459 if (MA->isMustWrite() && !ValSet.is_null()) { 460 // { MemoryAccess[] } 461 auto AccSet = 462 isl::set::universe(isl::space(S->getIslCtx(), 0, 0) 463 .set_tuple_id(isl::dim::set, MA->getId())); 464 465 // { Val[] -> MemoryAccess[] } 466 isl::map ValAccSet = isl::map::from_domain_and_range(ValSet, AccSet); 467 468 // { [Domain[] -> Element[]] -> [Value[] -> MemoryAccess[]] } 469 isl::map AccRelValAcc = 470 isl::map::from_domain_and_range(AccRelWrapped, ValAccSet.wrap()); 471 FutureWrites = FutureWrites.unite(AccRelValAcc); 472 } 473 } 474 } 475 } 476 477 /// Remove writes that just write the same value already stored in the 478 /// element. 479 void SimplifyImpl::removeRedundantWrites() { 480 for (auto &Stmt : *S) { 481 SmallDenseMap<Value *, isl::set> ValueSets; 482 auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set { 483 assert(V); 484 isl::set &Result = ValueSets[V]; 485 if (Result.is_null()) { 486 isl_ctx *Ctx = S->getIslCtx().get(); 487 std::string Name = getIslCompatibleName( 488 "Val", V, ValueSets.size() - 1, std::string(), UseInstructionNames); 489 isl::id Id = isl::manage(isl_id_alloc(Ctx, Name.c_str(), V)); 490 Result = isl::set::universe( 491 isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id)); 492 } 493 return Result; 494 }; 495 496 isl::set Domain = Stmt.getDomain(); 497 Domain = Domain.intersect_params(S->getContext()); 498 499 // List of element reads that still have the same value while iterating 500 // through the MemoryAccesses. 501 // { [Domain[] -> Element[]] -> Val[] } 502 isl::union_map Known = isl::union_map::empty(S->getIslCtx()); 503 504 SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt)); 505 for (MemoryAccess *MA : Accesses) { 506 // Is the memory access in a defined order relative to the other 507 // accesses? In region statements, only the first and the last accesses 508 // have defined order. Execution of those in the middle may depend on 509 // runtime conditions an therefore cannot be modified. 510 bool IsOrdered = 511 Stmt.isBlockStmt() || MA->isOriginalScalarKind() || 512 (!S->getBoxedLoops().size() && MA->getAccessInstruction() && 513 Stmt.getEntryBlock() == MA->getAccessInstruction()->getParent()); 514 515 isl::map AccRel = MA->getAccessRelation(); 516 AccRel = AccRel.intersect_domain(Domain); 517 isl::set AccRelWrapped = AccRel.wrap(); 518 519 // Determine whether a write is redundant (stores only values that are 520 // already present in the written array elements) and remove it if this 521 // is the case. 522 if (IsOrdered && MA->isMustWrite() && 523 (isa<StoreInst>(MA->getAccessInstruction()) || 524 MA->isOriginalScalarKind())) { 525 Value *StoredVal = MA->tryGetValueStored(); 526 if (!StoredVal) 527 StoredVal = MA->getAccessValue(); 528 529 if (StoredVal) { 530 // Lookup in the set of known values. 531 isl::map AccRelStoredVal = isl::map::from_domain_and_range( 532 AccRelWrapped, makeValueSet(StoredVal)); 533 if (isl::union_map(AccRelStoredVal).is_subset(Known)) { 534 LLVM_DEBUG(dbgs() << "Cleanup of " << MA << ":\n"); 535 LLVM_DEBUG(dbgs() << " Scalar: " << *StoredVal << "\n"); 536 LLVM_DEBUG(dbgs() << " AccRel: " << AccRel << "\n"); 537 538 Stmt.removeSingleMemoryAccess(MA); 539 540 RedundantWritesRemoved++; 541 TotalRedundantWritesRemoved[CallNo]++; 542 } 543 } 544 } 545 546 // Update the know values set. 547 if (MA->isRead()) { 548 // Loaded values are the currently known values of the array element 549 // it was loaded from. 550 Value *LoadedVal = MA->getAccessValue(); 551 if (LoadedVal && IsOrdered) { 552 isl::map AccRelVal = isl::map::from_domain_and_range( 553 AccRelWrapped, makeValueSet(LoadedVal)); 554 555 Known = Known.unite(AccRelVal); 556 } 557 } else if (MA->isWrite()) { 558 // Remove (possibly) overwritten values from the known elements set. 559 // We remove all elements of the accessed array to avoid too complex 560 // isl sets. 561 isl::set AccRelUniv = isl::set::universe(AccRelWrapped.get_space()); 562 Known = Known.subtract_domain(AccRelUniv); 563 564 // At this point, we could add the written value of must-writes. 565 // However, writing same values is already handled by 566 // coalesceWrites(). 567 } 568 } 569 } 570 } 571 572 /// Remove statements without side effects. 573 void SimplifyImpl::removeUnnecessaryStmts() { 574 auto NumStmtsBefore = S->getSize(); 575 S->simplifySCoP(true); 576 assert(NumStmtsBefore >= S->getSize()); 577 StmtsRemoved = NumStmtsBefore - S->getSize(); 578 LLVM_DEBUG(dbgs() << "Removed " << StmtsRemoved << " (of " << NumStmtsBefore 579 << ") statements\n"); 580 TotalStmtsRemoved[CallNo] += StmtsRemoved; 581 } 582 583 /// Remove accesses that have an empty domain. 584 void SimplifyImpl::removeEmptyPartialAccesses() { 585 for (ScopStmt &Stmt : *S) { 586 // Defer the actual removal to not invalidate iterators. 587 SmallVector<MemoryAccess *, 8> DeferredRemove; 588 589 for (MemoryAccess *MA : Stmt) { 590 if (!MA->isWrite()) 591 continue; 592 593 isl::map AccRel = MA->getAccessRelation(); 594 if (!AccRel.is_empty().is_true()) 595 continue; 596 597 LLVM_DEBUG( 598 dbgs() << "Removing " << MA 599 << " because it's a partial access that never occurs\n"); 600 DeferredRemove.push_back(MA); 601 } 602 603 for (MemoryAccess *MA : DeferredRemove) { 604 Stmt.removeSingleMemoryAccess(MA); 605 EmptyPartialAccessesRemoved++; 606 TotalEmptyPartialAccessesRemoved[CallNo]++; 607 } 608 } 609 } 610 611 /// Mark all reachable instructions and access, and sweep those that are not 612 /// reachable. 613 void SimplifyImpl::markAndSweep(LoopInfo *LI) { 614 DenseSet<MemoryAccess *> UsedMA; 615 DenseSet<VirtualInstruction> UsedInsts; 616 617 // Get all reachable instructions and accesses. 618 markReachable(S, LI, UsedInsts, UsedMA); 619 620 // Remove all non-reachable accesses. 621 // We need get all MemoryAccesses first, in order to not invalidate the 622 // iterators when removing them. 623 SmallVector<MemoryAccess *, 64> AllMAs; 624 for (ScopStmt &Stmt : *S) 625 AllMAs.append(Stmt.begin(), Stmt.end()); 626 627 for (MemoryAccess *MA : AllMAs) { 628 if (UsedMA.count(MA)) 629 continue; 630 LLVM_DEBUG(dbgs() << "Removing " << MA 631 << " because its value is not used\n"); 632 ScopStmt *Stmt = MA->getStatement(); 633 Stmt->removeSingleMemoryAccess(MA); 634 635 DeadAccessesRemoved++; 636 TotalDeadAccessesRemoved[CallNo]++; 637 } 638 639 // Remove all non-reachable instructions. 640 for (ScopStmt &Stmt : *S) { 641 // Note that for region statements, we can only remove the non-terminator 642 // instructions of the entry block. All other instructions are not in the 643 // instructions list, but implicitly always part of the statement. 644 645 SmallVector<Instruction *, 32> AllInsts(Stmt.insts_begin(), 646 Stmt.insts_end()); 647 SmallVector<Instruction *, 32> RemainInsts; 648 649 for (Instruction *Inst : AllInsts) { 650 auto It = UsedInsts.find({&Stmt, Inst}); 651 if (It == UsedInsts.end()) { 652 LLVM_DEBUG(dbgs() << "Removing "; Inst->print(dbgs()); 653 dbgs() << " because it is not used\n"); 654 DeadInstructionsRemoved++; 655 TotalDeadInstructionsRemoved[CallNo]++; 656 continue; 657 } 658 659 RemainInsts.push_back(Inst); 660 661 // If instructions appear multiple times, keep only the first. 662 UsedInsts.erase(It); 663 } 664 665 // Set the new instruction list to be only those we did not remove. 666 Stmt.setInstructions(RemainInsts); 667 } 668 } 669 670 /// Print simplification statistics to @p OS. 671 void SimplifyImpl::printStatistics(llvm::raw_ostream &OS, int Indent) const { 672 OS.indent(Indent) << "Statistics {\n"; 673 OS.indent(Indent + 4) << "Empty domains removed: " << EmptyDomainsRemoved 674 << '\n'; 675 OS.indent(Indent + 4) << "Overwrites removed: " << OverwritesRemoved << '\n'; 676 OS.indent(Indent + 4) << "Partial writes coalesced: " << WritesCoalesced 677 << "\n"; 678 OS.indent(Indent + 4) << "Redundant writes removed: " 679 << RedundantWritesRemoved << "\n"; 680 OS.indent(Indent + 4) << "Accesses with empty domains removed: " 681 << EmptyPartialAccessesRemoved << "\n"; 682 OS.indent(Indent + 4) << "Dead accesses removed: " << DeadAccessesRemoved 683 << '\n'; 684 OS.indent(Indent + 4) << "Dead instructions removed: " 685 << DeadInstructionsRemoved << '\n'; 686 OS.indent(Indent + 4) << "Stmts removed: " << StmtsRemoved << "\n"; 687 OS.indent(Indent) << "}\n"; 688 } 689 690 /// Print the current state of all MemoryAccesses to @p OS. 691 void SimplifyImpl::printAccesses(llvm::raw_ostream &OS, int Indent) const { 692 OS.indent(Indent) << "After accesses {\n"; 693 for (auto &Stmt : *S) { 694 OS.indent(Indent + 4) << Stmt.getBaseName() << "\n"; 695 for (auto *MA : Stmt) 696 MA->print(OS); 697 } 698 OS.indent(Indent) << "}\n"; 699 } 700 701 void SimplifyImpl::run(Scop &S, LoopInfo *LI) { 702 // Must not have run before. 703 assert(!this->S); 704 assert(!isModified()); 705 706 // Prepare processing of this SCoP. 707 this->S = &S; 708 ScopsProcessed[CallNo]++; 709 710 LLVM_DEBUG(dbgs() << "Removing statements that are never executed...\n"); 711 removeEmptyDomainStmts(); 712 713 LLVM_DEBUG(dbgs() << "Removing partial writes that never happen...\n"); 714 removeEmptyPartialAccesses(); 715 716 LLVM_DEBUG(dbgs() << "Removing overwrites...\n"); 717 removeOverwrites(); 718 719 LLVM_DEBUG(dbgs() << "Coalesce partial writes...\n"); 720 coalesceWrites(); 721 722 LLVM_DEBUG(dbgs() << "Removing redundant writes...\n"); 723 removeRedundantWrites(); 724 725 LLVM_DEBUG(dbgs() << "Cleanup unused accesses...\n"); 726 markAndSweep(LI); 727 728 LLVM_DEBUG(dbgs() << "Removing statements without side effects...\n"); 729 removeUnnecessaryStmts(); 730 731 if (isModified()) 732 ScopsModified[CallNo]++; 733 LLVM_DEBUG(dbgs() << "\nFinal Scop:\n"); 734 LLVM_DEBUG(dbgs() << S); 735 736 auto ScopStats = S.getStatistics(); 737 NumValueWrites[CallNo] += ScopStats.NumValueWrites; 738 NumValueWritesInLoops[CallNo] += ScopStats.NumValueWritesInLoops; 739 NumPHIWrites[CallNo] += ScopStats.NumPHIWrites; 740 NumPHIWritesInLoops[CallNo] += ScopStats.NumPHIWritesInLoops; 741 NumSingletonWrites[CallNo] += ScopStats.NumSingletonWrites; 742 NumSingletonWritesInLoops[CallNo] += ScopStats.NumSingletonWritesInLoops; 743 } 744 745 void SimplifyImpl::printScop(raw_ostream &OS, Scop &S) const { 746 assert(&S == this->S && 747 "Can only print analysis for the last processed SCoP"); 748 printStatistics(OS); 749 750 if (!isModified()) { 751 OS << "SCoP could not be simplified\n"; 752 return; 753 } 754 printAccesses(OS); 755 } 756 757 class SimplifyWrapperPass : public ScopPass { 758 public: 759 static char ID; 760 int CallNo; 761 Optional<SimplifyImpl> Impl; 762 763 explicit SimplifyWrapperPass(int CallNo = 0) : ScopPass(ID), CallNo(CallNo) {} 764 765 virtual void getAnalysisUsage(AnalysisUsage &AU) const override { 766 AU.addRequiredTransitive<ScopInfoRegionPass>(); 767 AU.addRequired<LoopInfoWrapperPass>(); 768 AU.setPreservesAll(); 769 } 770 771 virtual bool runOnScop(Scop &S) override { 772 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 773 774 Impl.emplace(CallNo); 775 Impl->run(S, LI); 776 777 return false; 778 } 779 780 virtual void printScop(raw_ostream &OS, Scop &S) const override { 781 if (Impl) 782 Impl->printScop(OS, S); 783 } 784 785 virtual void releaseMemory() override { Impl.reset(); } 786 }; 787 788 char SimplifyWrapperPass::ID; 789 790 static llvm::PreservedAnalyses 791 runSimplifyUsingNPM(Scop &S, ScopAnalysisManager &SAM, 792 ScopStandardAnalysisResults &SAR, SPMUpdater &U, int CallNo, 793 raw_ostream *OS) { 794 SimplifyImpl Impl(CallNo); 795 Impl.run(S, &SAR.LI); 796 if (OS) { 797 *OS << "Printing analysis 'Polly - Simplify' for region: '" << S.getName() 798 << "' in function '" << S.getFunction().getName() << "':\n"; 799 Impl.printScop(*OS, S); 800 } 801 802 if (!Impl.isModified()) 803 return llvm::PreservedAnalyses::all(); 804 805 PreservedAnalyses PA; 806 PA.preserveSet<AllAnalysesOn<Module>>(); 807 PA.preserveSet<AllAnalysesOn<Function>>(); 808 PA.preserveSet<AllAnalysesOn<Loop>>(); 809 return PA; 810 } 811 812 } // anonymous namespace 813 814 llvm::PreservedAnalyses SimplifyPass::run(Scop &S, ScopAnalysisManager &SAM, 815 ScopStandardAnalysisResults &SAR, 816 SPMUpdater &U) { 817 return runSimplifyUsingNPM(S, SAM, SAR, U, CallNo, nullptr); 818 } 819 820 llvm::PreservedAnalyses 821 SimplifyPrinterPass::run(Scop &S, ScopAnalysisManager &SAM, 822 ScopStandardAnalysisResults &SAR, SPMUpdater &U) { 823 return runSimplifyUsingNPM(S, SAM, SAR, U, CallNo, &OS); 824 } 825 826 SmallVector<MemoryAccess *, 32> polly::getAccessesInOrder(ScopStmt &Stmt) { 827 SmallVector<MemoryAccess *, 32> Accesses; 828 829 for (MemoryAccess *MemAcc : Stmt) 830 if (isImplicitRead(MemAcc)) 831 Accesses.push_back(MemAcc); 832 833 for (MemoryAccess *MemAcc : Stmt) 834 if (isExplicitAccess(MemAcc)) 835 Accesses.push_back(MemAcc); 836 837 for (MemoryAccess *MemAcc : Stmt) 838 if (isImplicitWrite(MemAcc)) 839 Accesses.push_back(MemAcc); 840 841 return Accesses; 842 } 843 844 Pass *polly::createSimplifyWrapperPass(int CallNo) { 845 return new SimplifyWrapperPass(CallNo); 846 } 847 848 INITIALIZE_PASS_BEGIN(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify", 849 false, false) 850 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 851 INITIALIZE_PASS_END(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify", 852 false, false) 853