LLVM API Documentation
00001 //===- MergedLoadStoreMotion.cpp - merge and hoist/sink load/stores -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 //! \file 00011 //! \brief This pass performs merges of loads and stores on both sides of a 00012 // diamond (hammock). It hoists the loads and sinks the stores. 00013 // 00014 // The algorithm iteratively hoists two loads to the same address out of a 00015 // diamond (hammock) and merges them into a single load in the header. Similar 00016 // it sinks and merges two stores to the tail block (footer). The algorithm 00017 // iterates over the instructions of one side of the diamond and attempts to 00018 // find a matching load/store on the other side. It hoists / sinks when it 00019 // thinks it safe to do so. This optimization helps with eg. hiding load 00020 // latencies, triggering if-conversion, and reducing static code size. 00021 // 00022 //===----------------------------------------------------------------------===// 00023 // 00024 // 00025 // Example: 00026 // Diamond shaped code before merge: 00027 // 00028 // header: 00029 // br %cond, label %if.then, label %if.else 00030 // + + 00031 // + + 00032 // + + 00033 // if.then: if.else: 00034 // %lt = load %addr_l %le = load %addr_l 00035 // <use %lt> <use %le> 00036 // <...> <...> 00037 // store %st, %addr_s store %se, %addr_s 00038 // br label %if.end br label %if.end 00039 // + + 00040 // + + 00041 // + + 00042 // if.end ("footer"): 00043 // <...> 00044 // 00045 // Diamond shaped code after merge: 00046 // 00047 // header: 00048 // %l = load %addr_l 00049 // br %cond, label %if.then, label %if.else 00050 // + + 00051 // + + 00052 // + + 00053 // if.then: if.else: 00054 // <use %l> <use %l> 00055 // <...> <...> 00056 // br label %if.end br label %if.end 00057 // + + 00058 // + + 00059 // + + 00060 // if.end ("footer"): 00061 // %s.sink = phi [%st, if.then], [%se, if.else] 00062 // <...> 00063 // store %s.sink, %addr_s 00064 // <...> 00065 // 00066 // 00067 //===----------------------- TODO -----------------------------------------===// 00068 // 00069 // 1) Generalize to regions other than diamonds 00070 // 2) Be more aggressive merging memory operations 00071 // Note that both changes require register pressure control 00072 // 00073 //===----------------------------------------------------------------------===// 00074 00075 #include "llvm/Transforms/Scalar.h" 00076 #include "llvm/ADT/SetVector.h" 00077 #include "llvm/ADT/SmallPtrSet.h" 00078 #include "llvm/ADT/Statistic.h" 00079 #include "llvm/Analysis/AliasAnalysis.h" 00080 #include "llvm/Analysis/CFG.h" 00081 #include "llvm/Analysis/Loads.h" 00082 #include "llvm/Analysis/MemoryBuiltins.h" 00083 #include "llvm/Analysis/MemoryDependenceAnalysis.h" 00084 #include "llvm/IR/Metadata.h" 00085 #include "llvm/IR/PatternMatch.h" 00086 #include "llvm/Support/Allocator.h" 00087 #include "llvm/Support/CommandLine.h" 00088 #include "llvm/Support/Debug.h" 00089 #include "llvm/Target/TargetLibraryInfo.h" 00090 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 00091 #include "llvm/Transforms/Utils/SSAUpdater.h" 00092 #include <vector> 00093 using namespace llvm; 00094 00095 #define DEBUG_TYPE "mldst-motion" 00096 00097 //===----------------------------------------------------------------------===// 00098 // MergedLoadStoreMotion Pass 00099 //===----------------------------------------------------------------------===// 00100 00101 namespace { 00102 class MergedLoadStoreMotion : public FunctionPass { 00103 AliasAnalysis *AA; 00104 MemoryDependenceAnalysis *MD; 00105 00106 public: 00107 static char ID; // Pass identification, replacement for typeid 00108 explicit MergedLoadStoreMotion(void) 00109 : FunctionPass(ID), MD(nullptr), MagicCompileTimeControl(250) { 00110 initializeMergedLoadStoreMotionPass(*PassRegistry::getPassRegistry()); 00111 } 00112 00113 bool runOnFunction(Function &F) override; 00114 00115 private: 00116 // This transformation requires dominator postdominator info 00117 void getAnalysisUsage(AnalysisUsage &AU) const override { 00118 AU.addRequired<TargetLibraryInfo>(); 00119 AU.addRequired<MemoryDependenceAnalysis>(); 00120 AU.addRequired<AliasAnalysis>(); 00121 AU.addPreserved<AliasAnalysis>(); 00122 } 00123 00124 // Helper routines 00125 00126 /// 00127 /// \brief Remove instruction from parent and update memory dependence 00128 /// analysis. 00129 /// 00130 void removeInstruction(Instruction *Inst); 00131 BasicBlock *getDiamondTail(BasicBlock *BB); 00132 bool isDiamondHead(BasicBlock *BB); 00133 // Routines for hoisting loads 00134 bool isLoadHoistBarrier(Instruction *Inst); 00135 LoadInst *canHoistFromBlock(BasicBlock *BB, LoadInst *LI); 00136 void hoistInstruction(BasicBlock *BB, Instruction *HoistCand, 00137 Instruction *ElseInst); 00138 bool isSafeToHoist(Instruction *I) const; 00139 bool hoistLoad(BasicBlock *BB, LoadInst *HoistCand, LoadInst *ElseInst); 00140 bool mergeLoads(BasicBlock *BB); 00141 // Routines for sinking stores 00142 StoreInst *canSinkFromBlock(BasicBlock *BB, StoreInst *SI); 00143 PHINode *getPHIOperand(BasicBlock *BB, StoreInst *S0, StoreInst *S1); 00144 bool isStoreSinkBarrier(Instruction *Inst); 00145 bool sinkStore(BasicBlock *BB, StoreInst *SinkCand, StoreInst *ElseInst); 00146 bool mergeStores(BasicBlock *BB); 00147 // The mergeLoad/Store algorithms could have Size0 * Size1 complexity, 00148 // where Size0 and Size1 are the #instructions on the two sides of 00149 // the diamond. The constant chosen here is arbitrary. Compiler Time 00150 // Control is enforced by the check Size0 * Size1 < MagicCompileTimeControl. 00151 const int MagicCompileTimeControl; 00152 }; 00153 00154 char MergedLoadStoreMotion::ID = 0; 00155 } 00156 00157 /// 00158 /// \brief createMergedLoadStoreMotionPass - The public interface to this file. 00159 /// 00160 FunctionPass *llvm::createMergedLoadStoreMotionPass() { 00161 return new MergedLoadStoreMotion(); 00162 } 00163 00164 INITIALIZE_PASS_BEGIN(MergedLoadStoreMotion, "mldst-motion", 00165 "MergedLoadStoreMotion", false, false) 00166 INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) 00167 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) 00168 INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 00169 INITIALIZE_PASS_END(MergedLoadStoreMotion, "mldst-motion", 00170 "MergedLoadStoreMotion", false, false) 00171 00172 /// 00173 /// \brief Remove instruction from parent and update memory dependence analysis. 00174 /// 00175 void MergedLoadStoreMotion::removeInstruction(Instruction *Inst) { 00176 // Notify the memory dependence analysis. 00177 if (MD) { 00178 MD->removeInstruction(Inst); 00179 if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) 00180 MD->invalidateCachedPointerInfo(LI->getPointerOperand()); 00181 if (Inst->getType()->getScalarType()->isPointerTy()) { 00182 MD->invalidateCachedPointerInfo(Inst); 00183 } 00184 } 00185 Inst->eraseFromParent(); 00186 } 00187 00188 /// 00189 /// \brief Return tail block of a diamond. 00190 /// 00191 BasicBlock *MergedLoadStoreMotion::getDiamondTail(BasicBlock *BB) { 00192 assert(isDiamondHead(BB) && "Basic block is not head of a diamond"); 00193 BranchInst *BI = (BranchInst *)(BB->getTerminator()); 00194 BasicBlock *Succ0 = BI->getSuccessor(0); 00195 BasicBlock *Tail = Succ0->getTerminator()->getSuccessor(0); 00196 return Tail; 00197 } 00198 00199 /// 00200 /// \brief True when BB is the head of a diamond (hammock) 00201 /// 00202 bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) { 00203 if (!BB) 00204 return false; 00205 if (!isa<BranchInst>(BB->getTerminator())) 00206 return false; 00207 if (BB->getTerminator()->getNumSuccessors() != 2) 00208 return false; 00209 00210 BranchInst *BI = (BranchInst *)(BB->getTerminator()); 00211 BasicBlock *Succ0 = BI->getSuccessor(0); 00212 BasicBlock *Succ1 = BI->getSuccessor(1); 00213 00214 if (!Succ0->getSinglePredecessor() || 00215 Succ0->getTerminator()->getNumSuccessors() != 1) 00216 return false; 00217 if (!Succ1->getSinglePredecessor() || 00218 Succ1->getTerminator()->getNumSuccessors() != 1) 00219 return false; 00220 00221 BasicBlock *Tail = Succ0->getTerminator()->getSuccessor(0); 00222 // Ignore triangles. 00223 if (Succ1->getTerminator()->getSuccessor(0) != Tail) 00224 return false; 00225 return true; 00226 } 00227 00228 /// 00229 /// \brief True when instruction is a hoist barrier for a load 00230 /// 00231 /// Whenever an instruction could possibly modify the value 00232 /// being loaded or protect against the load from happening 00233 /// it is considered a hoist barrier. 00234 /// 00235 bool MergedLoadStoreMotion::isLoadHoistBarrier(Instruction *Inst) { 00236 // FIXME: A call with no side effects should not be a barrier. 00237 // Aren't all such calls covered by mayHaveSideEffects() below? 00238 // Then this check can be removed. 00239 if (isa<CallInst>(Inst)) 00240 return true; 00241 if (isa<TerminatorInst>(Inst)) 00242 return true; 00243 // FIXME: Conservatively let a store instruction block the load. 00244 // Use alias analysis instead. 00245 if (isa<StoreInst>(Inst)) 00246 return true; 00247 // Note: mayHaveSideEffects covers all instructions that could 00248 // trigger a change to state. Eg. in-flight stores have to be executed 00249 // before ordered loads or fences, calls could invoke functions that store 00250 // data to memory etc. 00251 if (Inst->mayHaveSideEffects()) { 00252 return true; 00253 } 00254 DEBUG(dbgs() << "No Hoist Barrier\n"); 00255 return false; 00256 } 00257 00258 /// 00259 /// \brief Decide if a load can be hoisted 00260 /// 00261 /// When there is a load in \p BB to the same address as \p LI 00262 /// and it can be hoisted from \p BB, return that load. 00263 /// Otherwise return Null. 00264 /// 00265 LoadInst *MergedLoadStoreMotion::canHoistFromBlock(BasicBlock *BB, 00266 LoadInst *LI) { 00267 LoadInst *I = nullptr; 00268 assert(isa<LoadInst>(LI)); 00269 if (LI->isUsedOutsideOfBlock(LI->getParent())) 00270 return nullptr; 00271 00272 for (BasicBlock::iterator BBI = BB->begin(), BBE = BB->end(); BBI != BBE; 00273 ++BBI) { 00274 Instruction *Inst = BBI; 00275 00276 // Only merge and hoist loads when their result in used only in BB 00277 if (isLoadHoistBarrier(Inst)) 00278 break; 00279 if (!isa<LoadInst>(Inst)) 00280 continue; 00281 if (Inst->isUsedOutsideOfBlock(Inst->getParent())) 00282 continue; 00283 00284 AliasAnalysis::Location LocLI = AA->getLocation(LI); 00285 AliasAnalysis::Location LocInst = AA->getLocation((LoadInst *)Inst); 00286 if (AA->isMustAlias(LocLI, LocInst) && LI->getType() == Inst->getType()) { 00287 I = (LoadInst *)Inst; 00288 break; 00289 } 00290 } 00291 return I; 00292 } 00293 00294 /// 00295 /// \brief Merge two equivalent instructions \p HoistCand and \p ElseInst into 00296 /// \p BB 00297 /// 00298 /// BB is the head of a diamond 00299 /// 00300 void MergedLoadStoreMotion::hoistInstruction(BasicBlock *BB, 00301 Instruction *HoistCand, 00302 Instruction *ElseInst) { 00303 DEBUG(dbgs() << " Hoist Instruction into BB \n"; BB->dump(); 00304 dbgs() << "Instruction Left\n"; HoistCand->dump(); dbgs() << "\n"; 00305 dbgs() << "Instruction Right\n"; ElseInst->dump(); dbgs() << "\n"); 00306 // Hoist the instruction. 00307 assert(HoistCand->getParent() != BB); 00308 00309 // Intersect optional metadata. 00310 HoistCand->intersectOptionalDataWith(ElseInst); 00311 HoistCand->dropUnknownMetadata(); 00312 00313 // Prepend point for instruction insert 00314 Instruction *HoistPt = BB->getTerminator(); 00315 00316 // Merged instruction 00317 Instruction *HoistedInst = HoistCand->clone(); 00318 00319 // Notify AA of the new value. 00320 if (isa<LoadInst>(HoistCand)) 00321 AA->copyValue(HoistCand, HoistedInst); 00322 00323 // Hoist instruction. 00324 HoistedInst->insertBefore(HoistPt); 00325 00326 HoistCand->replaceAllUsesWith(HoistedInst); 00327 removeInstruction(HoistCand); 00328 // Replace the else block instruction. 00329 ElseInst->replaceAllUsesWith(HoistedInst); 00330 removeInstruction(ElseInst); 00331 } 00332 00333 /// 00334 /// \brief Return true if no operand of \p I is defined in I's parent block 00335 /// 00336 bool MergedLoadStoreMotion::isSafeToHoist(Instruction *I) const { 00337 BasicBlock *Parent = I->getParent(); 00338 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { 00339 Instruction *Instr = dyn_cast<Instruction>(I->getOperand(i)); 00340 if (Instr && Instr->getParent() == Parent) 00341 return false; 00342 } 00343 return true; 00344 } 00345 00346 /// 00347 /// \brief Merge two equivalent loads and GEPs and hoist into diamond head 00348 /// 00349 bool MergedLoadStoreMotion::hoistLoad(BasicBlock *BB, LoadInst *L0, 00350 LoadInst *L1) { 00351 // Only one definition? 00352 Instruction *A0 = dyn_cast<Instruction>(L0->getPointerOperand()); 00353 Instruction *A1 = dyn_cast<Instruction>(L1->getPointerOperand()); 00354 if (A0 && A1 && A0->isIdenticalTo(A1) && isSafeToHoist(A0) && 00355 A0->hasOneUse() && (A0->getParent() == L0->getParent()) && 00356 A1->hasOneUse() && (A1->getParent() == L1->getParent()) && 00357 isa<GetElementPtrInst>(A0)) { 00358 DEBUG(dbgs() << "Hoist Instruction into BB \n"; BB->dump(); 00359 dbgs() << "Instruction Left\n"; L0->dump(); dbgs() << "\n"; 00360 dbgs() << "Instruction Right\n"; L1->dump(); dbgs() << "\n"); 00361 hoistInstruction(BB, A0, A1); 00362 hoistInstruction(BB, L0, L1); 00363 return true; 00364 } else 00365 return false; 00366 } 00367 00368 /// 00369 /// \brief Try to hoist two loads to same address into diamond header 00370 /// 00371 /// Starting from a diamond head block, iterate over the instructions in one 00372 /// successor block and try to match a load in the second successor. 00373 /// 00374 bool MergedLoadStoreMotion::mergeLoads(BasicBlock *BB) { 00375 bool MergedLoads = false; 00376 assert(isDiamondHead(BB)); 00377 BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()); 00378 BasicBlock *Succ0 = BI->getSuccessor(0); 00379 BasicBlock *Succ1 = BI->getSuccessor(1); 00380 // #Instructions in Succ1 for Compile Time Control 00381 int Size1 = Succ1->size(); 00382 int NLoads = 0; 00383 for (BasicBlock::iterator BBI = Succ0->begin(), BBE = Succ0->end(); 00384 BBI != BBE;) { 00385 00386 Instruction *I = BBI; 00387 ++BBI; 00388 if (isLoadHoistBarrier(I)) 00389 break; 00390 00391 // Only move non-simple (atomic, volatile) loads. 00392 if (!isa<LoadInst>(I)) 00393 continue; 00394 00395 LoadInst *L0 = (LoadInst *)I; 00396 if (!L0->isSimple()) 00397 continue; 00398 00399 ++NLoads; 00400 if (NLoads * Size1 >= MagicCompileTimeControl) 00401 break; 00402 if (LoadInst *L1 = canHoistFromBlock(Succ1, L0)) { 00403 bool Res = hoistLoad(BB, L0, L1); 00404 MergedLoads |= Res; 00405 // Don't attempt to hoist above loads that had not been hoisted. 00406 if (!Res) 00407 break; 00408 } 00409 } 00410 return MergedLoads; 00411 } 00412 00413 /// 00414 /// \brief True when instruction is sink barrier for a store 00415 /// 00416 bool MergedLoadStoreMotion::isStoreSinkBarrier(Instruction *Inst) { 00417 // FIXME: Conservatively let a load instruction block the store. 00418 // Use alias analysis instead. 00419 if (isa<LoadInst>(Inst)) 00420 return true; 00421 if (isa<CallInst>(Inst)) 00422 return true; 00423 if (isa<TerminatorInst>(Inst) && !isa<BranchInst>(Inst)) 00424 return true; 00425 // Note: mayHaveSideEffects covers all instructions that could 00426 // trigger a change to state. Eg. in-flight stores have to be executed 00427 // before ordered loads or fences, calls could invoke functions that store 00428 // data to memory etc. 00429 if (!isa<StoreInst>(Inst) && Inst->mayHaveSideEffects()) { 00430 return true; 00431 } 00432 DEBUG(dbgs() << "No Sink Barrier\n"); 00433 return false; 00434 } 00435 00436 /// 00437 /// \brief Check if \p BB contains a store to the same address as \p SI 00438 /// 00439 /// \return The store in \p when it is safe to sink. Otherwise return Null. 00440 /// 00441 StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB, 00442 StoreInst *SI) { 00443 StoreInst *I = 0; 00444 DEBUG(dbgs() << "can Sink? : "; SI->dump(); dbgs() << "\n"); 00445 for (BasicBlock::reverse_iterator RBI = BB->rbegin(), RBE = BB->rend(); 00446 RBI != RBE; ++RBI) { 00447 Instruction *Inst = &*RBI; 00448 00449 // Only move loads if they are used in the block. 00450 if (isStoreSinkBarrier(Inst)) 00451 break; 00452 if (isa<StoreInst>(Inst)) { 00453 AliasAnalysis::Location LocSI = AA->getLocation(SI); 00454 AliasAnalysis::Location LocInst = AA->getLocation((StoreInst *)Inst); 00455 if (AA->isMustAlias(LocSI, LocInst)) { 00456 I = (StoreInst *)Inst; 00457 break; 00458 } 00459 } 00460 } 00461 return I; 00462 } 00463 00464 /// 00465 /// \brief Create a PHI node in BB for the operands of S0 and S1 00466 /// 00467 PHINode *MergedLoadStoreMotion::getPHIOperand(BasicBlock *BB, StoreInst *S0, 00468 StoreInst *S1) { 00469 // Create a phi if the values mismatch. 00470 PHINode *NewPN = 0; 00471 Value *Opd1 = S0->getValueOperand(); 00472 Value *Opd2 = S1->getValueOperand(); 00473 if (Opd1 != Opd2) { 00474 NewPN = PHINode::Create(Opd1->getType(), 2, Opd2->getName() + ".sink", 00475 BB->begin()); 00476 NewPN->addIncoming(Opd1, S0->getParent()); 00477 NewPN->addIncoming(Opd2, S1->getParent()); 00478 if (NewPN->getType()->getScalarType()->isPointerTy()) { 00479 // Notify AA of the new value. 00480 AA->copyValue(Opd1, NewPN); 00481 AA->copyValue(Opd2, NewPN); 00482 // AA needs to be informed when a PHI-use of the pointer value is added 00483 for (unsigned I = 0, E = NewPN->getNumIncomingValues(); I != E; ++I) { 00484 unsigned J = PHINode::getOperandNumForIncomingValue(I); 00485 AA->addEscapingUse(NewPN->getOperandUse(J)); 00486 } 00487 if (MD) 00488 MD->invalidateCachedPointerInfo(NewPN); 00489 } 00490 } 00491 return NewPN; 00492 } 00493 00494 /// 00495 /// \brief Merge two stores to same address and sink into \p BB 00496 /// 00497 /// Also sinks GEP instruction computing the store address 00498 /// 00499 bool MergedLoadStoreMotion::sinkStore(BasicBlock *BB, StoreInst *S0, 00500 StoreInst *S1) { 00501 // Only one definition? 00502 Instruction *A0 = dyn_cast<Instruction>(S0->getPointerOperand()); 00503 Instruction *A1 = dyn_cast<Instruction>(S1->getPointerOperand()); 00504 if (A0 && A1 && A0->isIdenticalTo(A1) && A0->hasOneUse() && 00505 (A0->getParent() == S0->getParent()) && A1->hasOneUse() && 00506 (A1->getParent() == S1->getParent()) && isa<GetElementPtrInst>(A0)) { 00507 DEBUG(dbgs() << "Sink Instruction into BB \n"; BB->dump(); 00508 dbgs() << "Instruction Left\n"; S0->dump(); dbgs() << "\n"; 00509 dbgs() << "Instruction Right\n"; S1->dump(); dbgs() << "\n"); 00510 // Hoist the instruction. 00511 BasicBlock::iterator InsertPt = BB->getFirstInsertionPt(); 00512 // Intersect optional metadata. 00513 S0->intersectOptionalDataWith(S1); 00514 S0->dropUnknownMetadata(); 00515 00516 // Create the new store to be inserted at the join point. 00517 StoreInst *SNew = (StoreInst *)(S0->clone()); 00518 Instruction *ANew = A0->clone(); 00519 AA->copyValue(S0, SNew); 00520 SNew->insertBefore(InsertPt); 00521 ANew->insertBefore(SNew); 00522 00523 assert(S0->getParent() == A0->getParent()); 00524 assert(S1->getParent() == A1->getParent()); 00525 00526 PHINode *NewPN = getPHIOperand(BB, S0, S1); 00527 // New PHI operand? Use it. 00528 if (NewPN) 00529 SNew->setOperand(0, NewPN); 00530 removeInstruction(S0); 00531 removeInstruction(S1); 00532 A0->replaceAllUsesWith(ANew); 00533 removeInstruction(A0); 00534 A1->replaceAllUsesWith(ANew); 00535 removeInstruction(A1); 00536 return true; 00537 } 00538 return false; 00539 } 00540 00541 /// 00542 /// \brief True when two stores are equivalent and can sink into the footer 00543 /// 00544 /// Starting from a diamond tail block, iterate over the instructions in one 00545 /// predecessor block and try to match a store in the second predecessor. 00546 /// 00547 bool MergedLoadStoreMotion::mergeStores(BasicBlock *T) { 00548 00549 bool MergedStores = false; 00550 assert(T && "Footer of a diamond cannot be empty"); 00551 00552 pred_iterator PI = pred_begin(T), E = pred_end(T); 00553 assert(PI != E); 00554 BasicBlock *Pred0 = *PI; 00555 ++PI; 00556 BasicBlock *Pred1 = *PI; 00557 ++PI; 00558 // tail block of a diamond/hammock? 00559 if (Pred0 == Pred1) 00560 return false; // No. 00561 if (PI != E) 00562 return false; // No. More than 2 predecessors. 00563 00564 // #Instructions in Succ1 for Compile Time Control 00565 int Size1 = Pred1->size(); 00566 int NStores = 0; 00567 00568 for (BasicBlock::reverse_iterator RBI = Pred0->rbegin(), RBE = Pred0->rend(); 00569 RBI != RBE;) { 00570 00571 Instruction *I = &*RBI; 00572 ++RBI; 00573 if (isStoreSinkBarrier(I)) 00574 break; 00575 // Sink move non-simple (atomic, volatile) stores 00576 if (!isa<StoreInst>(I)) 00577 continue; 00578 StoreInst *S0 = (StoreInst *)I; 00579 if (!S0->isSimple()) 00580 continue; 00581 00582 ++NStores; 00583 if (NStores * Size1 >= MagicCompileTimeControl) 00584 break; 00585 if (StoreInst *S1 = canSinkFromBlock(Pred1, S0)) { 00586 bool Res = sinkStore(T, S0, S1); 00587 MergedStores |= Res; 00588 // Don't attempt to sink below stores that had to stick around 00589 // But after removal of a store and some of its feeding 00590 // instruction search again from the beginning since the iterator 00591 // is likely stale at this point. 00592 if (!Res) 00593 break; 00594 else { 00595 RBI = Pred0->rbegin(); 00596 RBE = Pred0->rend(); 00597 DEBUG(dbgs() << "Search again\n"; Instruction *I = &*RBI; I->dump()); 00598 } 00599 } 00600 } 00601 return MergedStores; 00602 } 00603 /// 00604 /// \brief Run the transformation for each function 00605 /// 00606 bool MergedLoadStoreMotion::runOnFunction(Function &F) { 00607 MD = &getAnalysis<MemoryDependenceAnalysis>(); 00608 AA = &getAnalysis<AliasAnalysis>(); 00609 00610 bool Changed = false; 00611 DEBUG(dbgs() << "Instruction Merger\n"); 00612 00613 // Merge unconditional branches, allowing PRE to catch more 00614 // optimization opportunities. 00615 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) { 00616 BasicBlock *BB = FI++; 00617 00618 // Hoist equivalent loads and sink stores 00619 // outside diamonds when possible 00620 if (isDiamondHead(BB)) { 00621 Changed |= mergeLoads(BB); 00622 Changed |= mergeStores(getDiamondTail(BB)); 00623 } 00624 } 00625 return Changed; 00626 }