1 //===- GVNHoist.cpp - Hoist scalar and load expressions -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass hoists expressions from branches to a common dominator. It uses 11 // GVN (global value numbering) to discover expressions computing the same 12 // values. The primary goal is to reduce the code size, and in some 13 // cases reduce critical path (by exposing more ILP). 14 // Hoisting may affect the performance in some cases. To mitigate that, hoisting 15 // is disabled in the following cases. 16 // 1. Scalars across calls. 17 // 2. geps when corresponding load/store cannot be hoisted. 18 //===----------------------------------------------------------------------===// 19 20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/ADT/SmallPtrSet.h" 22 #include "llvm/ADT/Statistic.h" 23 #include "llvm/Analysis/ValueTracking.h" 24 #include "llvm/Transforms/Scalar.h" 25 #include "llvm/Transforms/Scalar/GVN.h" 26 #include "llvm/Transforms/Utils/MemorySSA.h" 27 28 using namespace llvm; 29 30 #define DEBUG_TYPE "gvn-hoist" 31 32 STATISTIC(NumHoisted, "Number of instructions hoisted"); 33 STATISTIC(NumRemoved, "Number of instructions removed"); 34 STATISTIC(NumLoadsHoisted, "Number of loads hoisted"); 35 STATISTIC(NumLoadsRemoved, "Number of loads removed"); 36 STATISTIC(NumStoresHoisted, "Number of stores hoisted"); 37 STATISTIC(NumStoresRemoved, "Number of stores removed"); 38 STATISTIC(NumCallsHoisted, "Number of calls hoisted"); 39 STATISTIC(NumCallsRemoved, "Number of calls removed"); 40 41 static cl::opt<int> 42 MaxHoistedThreshold("gvn-max-hoisted", cl::Hidden, cl::init(-1), 43 cl::desc("Max number of instructions to hoist " 44 "(default unlimited = -1)")); 45 static cl::opt<int> MaxNumberOfBBSInPath( 46 "gvn-hoist-max-bbs", cl::Hidden, cl::init(4), 47 cl::desc("Max number of basic blocks on the path between " 48 "hoisting locations (default = 4, unlimited = -1)")); 49 50 namespace { 51 52 // Provides a sorting function based on the execution order of two instructions. 53 struct SortByDFSIn { 54 private: 55 DenseMap<const BasicBlock *, unsigned> &DFSNumber; 56 57 public: 58 SortByDFSIn(DenseMap<const BasicBlock *, unsigned> &D) : DFSNumber(D) {} 59 60 // Returns true when A executes before B. 61 bool operator()(const Instruction *A, const Instruction *B) const { 62 // FIXME: libc++ has a std::sort() algorithm that will call the compare 63 // function on the same element. Once PR20837 is fixed and some more years 64 // pass by and all the buildbots have moved to a corrected std::sort(), 65 // enable the following assert: 66 // 67 // assert(A != B); 68 69 const BasicBlock *BA = A->getParent(); 70 const BasicBlock *BB = B->getParent(); 71 unsigned NA = DFSNumber[BA]; 72 unsigned NB = DFSNumber[BB]; 73 if (NA < NB) 74 return true; 75 if (NA == NB) { 76 // Sort them in the order they occur in the same basic block. 77 BasicBlock::const_iterator AI(A), BI(B); 78 return std::distance(AI, BI) < 0; 79 } 80 return false; 81 } 82 }; 83 84 // A map from a VN (value number) to all the instructions with that VN. 85 typedef DenseMap<unsigned, SmallVector<Instruction *, 4>> VNtoInsns; 86 87 // Records all scalar instructions candidate for code hoisting. 88 class InsnInfo { 89 VNtoInsns VNtoScalars; 90 91 public: 92 // Inserts I and its value number in VNtoScalars. 93 void insert(Instruction *I, GVN::ValueTable &VN) { 94 // Scalar instruction. 95 unsigned V = VN.lookupOrAdd(I); 96 VNtoScalars[V].push_back(I); 97 } 98 99 const VNtoInsns &getVNTable() const { return VNtoScalars; } 100 }; 101 102 // Records all load instructions candidate for code hoisting. 103 class LoadInfo { 104 VNtoInsns VNtoLoads; 105 106 public: 107 // Insert Load and the value number of its memory address in VNtoLoads. 108 void insert(LoadInst *Load, GVN::ValueTable &VN) { 109 if (Load->isSimple()) { 110 unsigned V = VN.lookupOrAdd(Load->getPointerOperand()); 111 VNtoLoads[V].push_back(Load); 112 } 113 } 114 115 const VNtoInsns &getVNTable() const { return VNtoLoads; } 116 }; 117 118 // Records all store instructions candidate for code hoisting. 119 class StoreInfo { 120 VNtoInsns VNtoStores; 121 122 public: 123 // Insert the Store and a hash number of the store address and the stored 124 // value in VNtoStores. 125 void insert(StoreInst *Store, GVN::ValueTable &VN) { 126 if (!Store->isSimple()) 127 return; 128 // Hash the store address and the stored value. 129 Value *Ptr = Store->getPointerOperand(); 130 Value *Val = Store->getValueOperand(); 131 VNtoStores[hash_combine(VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val))] 132 .push_back(Store); 133 } 134 135 const VNtoInsns &getVNTable() const { return VNtoStores; } 136 }; 137 138 // Records all call instructions candidate for code hoisting. 139 class CallInfo { 140 VNtoInsns VNtoCallsScalars; 141 VNtoInsns VNtoCallsLoads; 142 VNtoInsns VNtoCallsStores; 143 144 public: 145 // Insert Call and its value numbering in one of the VNtoCalls* containers. 146 void insert(CallInst *Call, GVN::ValueTable &VN) { 147 // A call that doesNotAccessMemory is handled as a Scalar, 148 // onlyReadsMemory will be handled as a Load instruction, 149 // all other calls will be handled as stores. 150 unsigned V = VN.lookupOrAdd(Call); 151 152 if (Call->doesNotAccessMemory()) 153 VNtoCallsScalars[V].push_back(Call); 154 else if (Call->onlyReadsMemory()) 155 VNtoCallsLoads[V].push_back(Call); 156 else 157 VNtoCallsStores[V].push_back(Call); 158 } 159 160 const VNtoInsns &getScalarVNTable() const { return VNtoCallsScalars; } 161 162 const VNtoInsns &getLoadVNTable() const { return VNtoCallsLoads; } 163 164 const VNtoInsns &getStoreVNTable() const { return VNtoCallsStores; } 165 }; 166 167 typedef DenseMap<const BasicBlock *, bool> BBSideEffectsSet; 168 typedef SmallVector<Instruction *, 4> SmallVecInsn; 169 typedef SmallVectorImpl<Instruction *> SmallVecImplInsn; 170 171 // This pass hoists common computations across branches sharing common 172 // dominator. The primary goal is to reduce the code size, and in some 173 // cases reduce critical path (by exposing more ILP). 174 class GVNHoist { 175 public: 176 GVN::ValueTable VN; 177 DominatorTree *DT; 178 AliasAnalysis *AA; 179 MemoryDependenceResults *MD; 180 const bool OptForMinSize; 181 DenseMap<const BasicBlock *, unsigned> DFSNumber; 182 BBSideEffectsSet BBSideEffects; 183 MemorySSA *MSSA; 184 int HoistedCtr; 185 186 enum InsKind { Unknown, Scalar, Load, Store }; 187 188 GVNHoist(DominatorTree *Dt, AliasAnalysis *Aa, MemoryDependenceResults *Md, 189 bool OptForMinSize) 190 : DT(Dt), AA(Aa), MD(Md), OptForMinSize(OptForMinSize), HoistedCtr(0) {} 191 192 // Return true when there are exception handling in BB. 193 bool hasEH(const BasicBlock *BB) { 194 auto It = BBSideEffects.find(BB); 195 if (It != BBSideEffects.end()) 196 return It->second; 197 198 if (BB->isEHPad() || BB->hasAddressTaken()) { 199 BBSideEffects[BB] = true; 200 return true; 201 } 202 203 if (BB->getTerminator()->mayThrow()) { 204 BBSideEffects[BB] = true; 205 return true; 206 } 207 208 BBSideEffects[BB] = false; 209 return false; 210 } 211 212 // Return true when all paths from A to the end of the function pass through 213 // either B or C. 214 bool hoistingFromAllPaths(const BasicBlock *A, const BasicBlock *B, 215 const BasicBlock *C) { 216 // We fully copy the WL in order to be able to remove items from it. 217 SmallPtrSet<const BasicBlock *, 2> WL; 218 WL.insert(B); 219 WL.insert(C); 220 221 for (auto It = df_begin(A), E = df_end(A); It != E;) { 222 // There exists a path from A to the exit of the function if we are still 223 // iterating in DF traversal and we removed all instructions from the work 224 // list. 225 if (WL.empty()) 226 return false; 227 228 const BasicBlock *BB = *It; 229 if (WL.erase(BB)) { 230 // Stop DFS traversal when BB is in the work list. 231 It.skipChildren(); 232 continue; 233 } 234 235 // Check for end of function, calls that do not return, etc. 236 if (!isGuaranteedToTransferExecutionToSuccessor(BB->getTerminator())) 237 return false; 238 239 // Increment DFS traversal when not skipping children. 240 ++It; 241 } 242 243 return true; 244 } 245 246 /* Return true when I1 appears before I2 in the instructions of BB. */ 247 bool firstInBB(BasicBlock *BB, const Instruction *I1, const Instruction *I2) { 248 for (Instruction &I : *BB) { 249 if (&I == I1) 250 return true; 251 if (&I == I2) 252 return false; 253 } 254 255 llvm_unreachable("I1 and I2 not found in BB"); 256 } 257 // Return true when there are users of Def in BB. 258 bool hasMemoryUseOnPath(MemoryAccess *Def, const BasicBlock *BB, 259 const Instruction *OldPt) { 260 const BasicBlock *DefBB = Def->getBlock(); 261 const BasicBlock *OldBB = OldPt->getParent(); 262 263 for (User *U : Def->users()) 264 if (auto *MU = dyn_cast<MemoryUse>(U)) { 265 BasicBlock *UBB = MU->getBlock(); 266 // Only analyze uses in BB. 267 if (BB != UBB) 268 continue; 269 270 // A use in the same block as the Def is on the path. 271 if (UBB == DefBB) { 272 assert(MSSA->locallyDominates(Def, MU) && "def not dominating use"); 273 return true; 274 } 275 276 if (UBB != OldBB) 277 return true; 278 279 // It is only harmful to hoist when the use is before OldPt. 280 if (firstInBB(UBB, MU->getMemoryInst(), OldPt)) 281 return true; 282 } 283 284 return false; 285 } 286 287 // Return true when there are exception handling or loads of memory Def 288 // between OldPt and NewPt. 289 290 // Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and 291 // return true when the counter NBBsOnAllPaths reaces 0, except when it is 292 // initialized to -1 which is unlimited. 293 bool hasEHOrLoadsOnPath(const Instruction *NewPt, const Instruction *OldPt, 294 MemoryAccess *Def, int &NBBsOnAllPaths) { 295 const BasicBlock *NewBB = NewPt->getParent(); 296 const BasicBlock *OldBB = OldPt->getParent(); 297 assert(DT->dominates(NewBB, OldBB) && "invalid path"); 298 assert(DT->dominates(Def->getBlock(), NewBB) && 299 "def does not dominate new hoisting point"); 300 301 // Walk all basic blocks reachable in depth-first iteration on the inverse 302 // CFG from OldBB to NewBB. These blocks are all the blocks that may be 303 // executed between the execution of NewBB and OldBB. Hoisting an expression 304 // from OldBB into NewBB has to be safe on all execution paths. 305 for (auto I = idf_begin(OldBB), E = idf_end(OldBB); I != E;) { 306 if (*I == NewBB) { 307 // Stop traversal when reaching HoistPt. 308 I.skipChildren(); 309 continue; 310 } 311 312 // Impossible to hoist with exceptions on the path. 313 if (hasEH(*I)) 314 return true; 315 316 // Check that we do not move a store past loads. 317 if (hasMemoryUseOnPath(Def, *I, OldPt)) 318 return true; 319 320 // Stop walk once the limit is reached. 321 if (NBBsOnAllPaths == 0) 322 return true; 323 324 // -1 is unlimited number of blocks on all paths. 325 if (NBBsOnAllPaths != -1) 326 --NBBsOnAllPaths; 327 328 ++I; 329 } 330 331 return false; 332 } 333 334 // Return true when there are exception handling between HoistPt and BB. 335 // Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and 336 // return true when the counter NBBsOnAllPaths reaches 0, except when it is 337 // initialized to -1 which is unlimited. 338 bool hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *BB, 339 int &NBBsOnAllPaths) { 340 assert(DT->dominates(HoistPt, BB) && "Invalid path"); 341 342 // Walk all basic blocks reachable in depth-first iteration on 343 // the inverse CFG from BBInsn to NewHoistPt. These blocks are all the 344 // blocks that may be executed between the execution of NewHoistPt and 345 // BBInsn. Hoisting an expression from BBInsn into NewHoistPt has to be safe 346 // on all execution paths. 347 for (auto I = idf_begin(BB), E = idf_end(BB); I != E;) { 348 if (*I == HoistPt) { 349 // Stop traversal when reaching NewHoistPt. 350 I.skipChildren(); 351 continue; 352 } 353 354 // Impossible to hoist with exceptions on the path. 355 if (hasEH(*I)) 356 return true; 357 358 // Stop walk once the limit is reached. 359 if (NBBsOnAllPaths == 0) 360 return true; 361 362 // -1 is unlimited number of blocks on all paths. 363 if (NBBsOnAllPaths != -1) 364 --NBBsOnAllPaths; 365 366 ++I; 367 } 368 369 return false; 370 } 371 372 // Return true when it is safe to hoist a memory load or store U from OldPt 373 // to NewPt. 374 bool safeToHoistLdSt(const Instruction *NewPt, const Instruction *OldPt, 375 MemoryUseOrDef *U, InsKind K, int &NBBsOnAllPaths) { 376 377 // In place hoisting is safe. 378 if (NewPt == OldPt) 379 return true; 380 381 const BasicBlock *NewBB = NewPt->getParent(); 382 const BasicBlock *OldBB = OldPt->getParent(); 383 const BasicBlock *UBB = U->getBlock(); 384 385 // Check for dependences on the Memory SSA. 386 MemoryAccess *D = U->getDefiningAccess(); 387 BasicBlock *DBB = D->getBlock(); 388 if (DT->properlyDominates(NewBB, DBB)) 389 // Cannot move the load or store to NewBB above its definition in DBB. 390 return false; 391 392 if (NewBB == DBB && !MSSA->isLiveOnEntryDef(D)) 393 if (auto *UD = dyn_cast<MemoryUseOrDef>(D)) 394 if (firstInBB(DBB, NewPt, UD->getMemoryInst())) 395 // Cannot move the load or store to NewPt above its definition in D. 396 return false; 397 398 // Check for unsafe hoistings due to side effects. 399 if (K == InsKind::Store) { 400 if (hasEHOrLoadsOnPath(NewPt, OldPt, D, NBBsOnAllPaths)) 401 return false; 402 } else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths)) 403 return false; 404 405 if (UBB == NewBB) { 406 if (DT->properlyDominates(DBB, NewBB)) 407 return true; 408 assert(UBB == DBB); 409 assert(MSSA->locallyDominates(D, U)); 410 } 411 412 // No side effects: it is safe to hoist. 413 return true; 414 } 415 416 // Return true when it is safe to hoist scalar instructions from BB1 and BB2 417 // to HoistBB. 418 bool safeToHoistScalar(const BasicBlock *HoistBB, const BasicBlock *BB1, 419 const BasicBlock *BB2, int &NBBsOnAllPaths) { 420 // Check that the hoisted expression is needed on all paths. When HoistBB 421 // already contains an instruction to be hoisted, the expression is needed 422 // on all paths. Enable scalar hoisting at -Oz as it is safe to hoist 423 // scalars to a place where they are partially needed. 424 if (!OptForMinSize && BB1 != HoistBB && 425 !hoistingFromAllPaths(HoistBB, BB1, BB2)) 426 return false; 427 428 if (hasEHOnPath(HoistBB, BB1, NBBsOnAllPaths) || 429 hasEHOnPath(HoistBB, BB2, NBBsOnAllPaths)) 430 return false; 431 432 // Safe to hoist scalars from BB1 and BB2 to HoistBB. 433 return true; 434 } 435 436 // Each element of a hoisting list contains the basic block where to hoist and 437 // a list of instructions to be hoisted. 438 typedef std::pair<BasicBlock *, SmallVecInsn> HoistingPointInfo; 439 typedef SmallVector<HoistingPointInfo, 4> HoistingPointList; 440 441 // Partition InstructionsToHoist into a set of candidates which can share a 442 // common hoisting point. The partitions are collected in HPL. IsScalar is 443 // true when the instructions in InstructionsToHoist are scalars. IsLoad is 444 // true when the InstructionsToHoist are loads, false when they are stores. 445 void partitionCandidates(SmallVecImplInsn &InstructionsToHoist, 446 HoistingPointList &HPL, InsKind K) { 447 // No need to sort for two instructions. 448 if (InstructionsToHoist.size() > 2) { 449 SortByDFSIn Pred(DFSNumber); 450 std::sort(InstructionsToHoist.begin(), InstructionsToHoist.end(), Pred); 451 } 452 453 int NBBsOnAllPaths = MaxNumberOfBBSInPath; 454 455 SmallVecImplInsn::iterator II = InstructionsToHoist.begin(); 456 SmallVecImplInsn::iterator Start = II; 457 Instruction *HoistPt = *II; 458 BasicBlock *HoistBB = HoistPt->getParent(); 459 MemoryUseOrDef *UD; 460 if (K != InsKind::Scalar) 461 UD = cast<MemoryUseOrDef>(MSSA->getMemoryAccess(HoistPt)); 462 463 for (++II; II != InstructionsToHoist.end(); ++II) { 464 Instruction *Insn = *II; 465 BasicBlock *BB = Insn->getParent(); 466 BasicBlock *NewHoistBB; 467 Instruction *NewHoistPt; 468 469 if (BB == HoistBB) { 470 NewHoistBB = HoistBB; 471 NewHoistPt = firstInBB(BB, Insn, HoistPt) ? Insn : HoistPt; 472 } else { 473 NewHoistBB = DT->findNearestCommonDominator(HoistBB, BB); 474 if (NewHoistBB == BB) 475 NewHoistPt = Insn; 476 else if (NewHoistBB == HoistBB) 477 NewHoistPt = HoistPt; 478 else 479 NewHoistPt = NewHoistBB->getTerminator(); 480 } 481 482 if (K == InsKind::Scalar) { 483 if (safeToHoistScalar(NewHoistBB, HoistBB, BB, NBBsOnAllPaths)) { 484 // Extend HoistPt to NewHoistPt. 485 HoistPt = NewHoistPt; 486 HoistBB = NewHoistBB; 487 continue; 488 } 489 } else { 490 // When NewBB already contains an instruction to be hoisted, the 491 // expression is needed on all paths. 492 // Check that the hoisted expression is needed on all paths: it is 493 // unsafe to hoist loads to a place where there may be a path not 494 // loading from the same address: for instance there may be a branch on 495 // which the address of the load may not be initialized. 496 if ((HoistBB == NewHoistBB || BB == NewHoistBB || 497 hoistingFromAllPaths(NewHoistBB, HoistBB, BB)) && 498 // Also check that it is safe to move the load or store from HoistPt 499 // to NewHoistPt, and from Insn to NewHoistPt. 500 safeToHoistLdSt(NewHoistPt, HoistPt, UD, K, NBBsOnAllPaths) && 501 safeToHoistLdSt(NewHoistPt, Insn, 502 cast<MemoryUseOrDef>(MSSA->getMemoryAccess(Insn)), 503 K, NBBsOnAllPaths)) { 504 // Extend HoistPt to NewHoistPt. 505 HoistPt = NewHoistPt; 506 HoistBB = NewHoistBB; 507 continue; 508 } 509 } 510 511 // At this point it is not safe to extend the current hoisting to 512 // NewHoistPt: save the hoisting list so far. 513 if (std::distance(Start, II) > 1) 514 HPL.push_back({HoistBB, SmallVecInsn(Start, II)}); 515 516 // Start over from BB. 517 Start = II; 518 if (K != InsKind::Scalar) 519 UD = cast<MemoryUseOrDef>(MSSA->getMemoryAccess(*Start)); 520 HoistPt = Insn; 521 HoistBB = BB; 522 NBBsOnAllPaths = MaxNumberOfBBSInPath; 523 } 524 525 // Save the last partition. 526 if (std::distance(Start, II) > 1) 527 HPL.push_back({HoistBB, SmallVecInsn(Start, II)}); 528 } 529 530 // Initialize HPL from Map. 531 void computeInsertionPoints(const VNtoInsns &Map, HoistingPointList &HPL, 532 InsKind K) { 533 for (const auto &Entry : Map) { 534 if (MaxHoistedThreshold != -1 && ++HoistedCtr > MaxHoistedThreshold) 535 return; 536 537 const SmallVecInsn &V = Entry.second; 538 if (V.size() < 2) 539 continue; 540 541 // Compute the insertion point and the list of expressions to be hoisted. 542 SmallVecInsn InstructionsToHoist; 543 for (auto I : V) 544 if (!hasEH(I->getParent())) 545 InstructionsToHoist.push_back(I); 546 547 if (!InstructionsToHoist.empty()) 548 partitionCandidates(InstructionsToHoist, HPL, K); 549 } 550 } 551 552 // Return true when all operands of Instr are available at insertion point 553 // HoistPt. When limiting the number of hoisted expressions, one could hoist 554 // a load without hoisting its access function. So before hoisting any 555 // expression, make sure that all its operands are available at insert point. 556 bool allOperandsAvailable(const Instruction *I, 557 const BasicBlock *HoistPt) const { 558 for (const Use &Op : I->operands()) 559 if (const auto *Inst = dyn_cast<Instruction>(&Op)) 560 if (!DT->dominates(Inst->getParent(), HoistPt)) 561 return false; 562 563 return true; 564 } 565 566 Instruction *firstOfTwo(Instruction *I, Instruction *J) const { 567 for (Instruction &I1 : *I->getParent()) 568 if (&I1 == I || &I1 == J) 569 return &I1; 570 llvm_unreachable("Both I and J must be from same BB"); 571 } 572 573 // Replace the use of From with To in Insn. 574 void replaceUseWith(Instruction *Insn, Value *From, Value *To) const { 575 for (Value::use_iterator UI = From->use_begin(), UE = From->use_end(); 576 UI != UE;) { 577 Use &U = *UI++; 578 if (U.getUser() == Insn) { 579 U.set(To); 580 return; 581 } 582 } 583 llvm_unreachable("should replace exactly once"); 584 } 585 586 bool makeOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt) const { 587 // Check whether the GEP of a ld/st can be synthesized at HoistPt. 588 Instruction *Gep = nullptr; 589 Instruction *Val = nullptr; 590 if (auto *Ld = dyn_cast<LoadInst>(Repl)) 591 Gep = dyn_cast<Instruction>(Ld->getPointerOperand()); 592 if (auto *St = dyn_cast<StoreInst>(Repl)) { 593 Gep = dyn_cast<Instruction>(St->getPointerOperand()); 594 Val = dyn_cast<Instruction>(St->getValueOperand()); 595 } 596 597 if (!Gep || !isa<GetElementPtrInst>(Gep)) 598 return false; 599 600 // Check whether we can compute the Gep at HoistPt. 601 if (!allOperandsAvailable(Gep, HoistPt)) 602 return false; 603 604 // Also check that the stored value is available. 605 if (Val && !allOperandsAvailable(Val, HoistPt)) 606 return false; 607 608 // Copy the gep before moving the ld/st. 609 Instruction *ClonedGep = Gep->clone(); 610 ClonedGep->insertBefore(HoistPt->getTerminator()); 611 replaceUseWith(Repl, Gep, ClonedGep); 612 613 // Also copy Val. 614 if (Val) { 615 Instruction *ClonedVal = Val->clone(); 616 ClonedVal->insertBefore(HoistPt->getTerminator()); 617 replaceUseWith(Repl, Val, ClonedVal); 618 } 619 620 return true; 621 } 622 623 std::pair<unsigned, unsigned> hoist(HoistingPointList &HPL) { 624 unsigned NI = 0, NL = 0, NS = 0, NC = 0, NR = 0; 625 for (const HoistingPointInfo &HP : HPL) { 626 // Find out whether we already have one of the instructions in HoistPt, 627 // in which case we do not have to move it. 628 BasicBlock *HoistPt = HP.first; 629 const SmallVecInsn &InstructionsToHoist = HP.second; 630 Instruction *Repl = nullptr; 631 for (Instruction *I : InstructionsToHoist) 632 if (I->getParent() == HoistPt) { 633 // If there are two instructions in HoistPt to be hoisted in place: 634 // update Repl to be the first one, such that we can rename the uses 635 // of the second based on the first. 636 Repl = !Repl ? I : firstOfTwo(Repl, I); 637 } 638 639 if (Repl) { 640 // Repl is already in HoistPt: it remains in place. 641 assert(allOperandsAvailable(Repl, HoistPt) && 642 "instruction depends on operands that are not available"); 643 } else { 644 // When we do not find Repl in HoistPt, select the first in the list 645 // and move it to HoistPt. 646 Repl = InstructionsToHoist.front(); 647 648 // We can move Repl in HoistPt only when all operands are available. 649 // The order in which hoistings are done may influence the availability 650 // of operands. 651 if (!allOperandsAvailable(Repl, HoistPt) && 652 !makeOperandsAvailable(Repl, HoistPt)) 653 continue; 654 Repl->moveBefore(HoistPt->getTerminator()); 655 } 656 657 if (isa<LoadInst>(Repl)) 658 ++NL; 659 else if (isa<StoreInst>(Repl)) 660 ++NS; 661 else if (isa<CallInst>(Repl)) 662 ++NC; 663 else // Scalar 664 ++NI; 665 666 // Remove and rename all other instructions. 667 for (Instruction *I : InstructionsToHoist) 668 if (I != Repl) { 669 ++NR; 670 if (isa<LoadInst>(Repl)) 671 ++NumLoadsRemoved; 672 else if (isa<StoreInst>(Repl)) 673 ++NumStoresRemoved; 674 else if (isa<CallInst>(Repl)) 675 ++NumCallsRemoved; 676 I->replaceAllUsesWith(Repl); 677 I->eraseFromParent(); 678 } 679 } 680 681 NumHoisted += NL + NS + NC + NI; 682 NumRemoved += NR; 683 NumLoadsHoisted += NL; 684 NumStoresHoisted += NS; 685 NumCallsHoisted += NC; 686 return {NI, NL + NC + NS}; 687 } 688 689 // Hoist all expressions. Returns Number of scalars hoisted 690 // and number of non-scalars hoisted. 691 std::pair<unsigned, unsigned> hoistExpressions(Function &F) { 692 InsnInfo II; 693 LoadInfo LI; 694 StoreInfo SI; 695 CallInfo CI; 696 for (BasicBlock *BB : depth_first(&F.getEntryBlock())) { 697 for (Instruction &I1 : *BB) { 698 if (auto *Load = dyn_cast<LoadInst>(&I1)) 699 LI.insert(Load, VN); 700 else if (auto *Store = dyn_cast<StoreInst>(&I1)) 701 SI.insert(Store, VN); 702 else if (auto *Call = dyn_cast<CallInst>(&I1)) { 703 if (auto *Intr = dyn_cast<IntrinsicInst>(Call)) { 704 if (isa<DbgInfoIntrinsic>(Intr) || 705 Intr->getIntrinsicID() == Intrinsic::assume) 706 continue; 707 } 708 if (Call->mayHaveSideEffects()) { 709 if (!OptForMinSize) 710 break; 711 // We may continue hoisting across calls which write to memory. 712 if (Call->mayThrow()) 713 break; 714 } 715 CI.insert(Call, VN); 716 } else if (OptForMinSize || !isa<GetElementPtrInst>(&I1)) 717 // Do not hoist scalars past calls that may write to memory because 718 // that could result in spills later. geps are handled separately. 719 // TODO: We can relax this for targets like AArch64 as they have more 720 // registers than X86. 721 II.insert(&I1, VN); 722 } 723 } 724 725 HoistingPointList HPL; 726 computeInsertionPoints(II.getVNTable(), HPL, InsKind::Scalar); 727 computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load); 728 computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store); 729 computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar); 730 computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load); 731 computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store); 732 return hoist(HPL); 733 } 734 735 bool run(Function &F) { 736 VN.setDomTree(DT); 737 VN.setAliasAnalysis(AA); 738 VN.setMemDep(MD); 739 bool Res = false; 740 741 unsigned I = 0; 742 for (const BasicBlock *BB : depth_first(&F.getEntryBlock())) 743 DFSNumber.insert({BB, ++I}); 744 745 // FIXME: use lazy evaluation of VN to avoid the fix-point computation. 746 while (1) { 747 // FIXME: only compute MemorySSA once. We need to update the analysis in 748 // the same time as transforming the code. 749 MemorySSA M(F, AA, DT); 750 MSSA = &M; 751 752 auto HoistStat = hoistExpressions(F); 753 if (HoistStat.first + HoistStat.second == 0) { 754 return Res; 755 } 756 if (HoistStat.second > 0) { 757 // To address a limitation of the current GVN, we need to rerun the 758 // hoisting after we hoisted loads in order to be able to hoist all 759 // scalars dependent on the hoisted loads. Same for stores. 760 VN.clear(); 761 } 762 Res = true; 763 } 764 765 return Res; 766 } 767 }; 768 769 class GVNHoistLegacyPass : public FunctionPass { 770 public: 771 static char ID; 772 773 GVNHoistLegacyPass() : FunctionPass(ID) { 774 initializeGVNHoistLegacyPassPass(*PassRegistry::getPassRegistry()); 775 } 776 777 bool runOnFunction(Function &F) override { 778 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 779 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults(); 780 auto &MD = getAnalysis<MemoryDependenceWrapperPass>().getMemDep(); 781 782 GVNHoist G(&DT, &AA, &MD, F.optForMinSize()); 783 return G.run(F); 784 } 785 786 void getAnalysisUsage(AnalysisUsage &AU) const override { 787 AU.addRequired<DominatorTreeWrapperPass>(); 788 AU.addRequired<AAResultsWrapperPass>(); 789 AU.addRequired<MemoryDependenceWrapperPass>(); 790 AU.addPreserved<DominatorTreeWrapperPass>(); 791 } 792 }; 793 } // namespace 794 795 PreservedAnalyses GVNHoistPass::run(Function &F, 796 AnalysisManager<Function> &AM) { 797 DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); 798 AliasAnalysis &AA = AM.getResult<AAManager>(F); 799 MemoryDependenceResults &MD = AM.getResult<MemoryDependenceAnalysis>(F); 800 801 GVNHoist G(&DT, &AA, &MD, F.optForMinSize()); 802 if (!G.run(F)) 803 return PreservedAnalyses::all(); 804 805 PreservedAnalyses PA; 806 PA.preserve<DominatorTreeAnalysis>(); 807 return PA; 808 } 809 810 char GVNHoistLegacyPass::ID = 0; 811 INITIALIZE_PASS_BEGIN(GVNHoistLegacyPass, "gvn-hoist", 812 "Early GVN Hoisting of Expressions", false, false) 813 INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) 814 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 815 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 816 INITIALIZE_PASS_END(GVNHoistLegacyPass, "gvn-hoist", 817 "Early GVN Hoisting of Expressions", false, false) 818 819 FunctionPass *llvm::createGVNHoistPass() { return new GVNHoistLegacyPass(); } 820