1 //===- EarlyCSE.cpp - Simple and fast CSE pass ----------------------------===// 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 performs a simple dominator tree walk that eliminates trivially 11 // redundant instructions. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Transforms/Scalar.h" 16 #include "llvm/ADT/Hashing.h" 17 #include "llvm/ADT/ScopedHashTable.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/Analysis/InstructionSimplify.h" 20 #include "llvm/IR/DataLayout.h" 21 #include "llvm/IR/Dominators.h" 22 #include "llvm/IR/Instructions.h" 23 #include "llvm/Pass.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/RecyclingAllocator.h" 26 #include "llvm/Target/TargetLibraryInfo.h" 27 #include "llvm/Transforms/Utils/Local.h" 28 #include <vector> 29 using namespace llvm; 30 31 #define DEBUG_TYPE "early-cse" 32 33 STATISTIC(NumSimplify, "Number of instructions simplified or DCE'd"); 34 STATISTIC(NumCSE, "Number of instructions CSE'd"); 35 STATISTIC(NumCSELoad, "Number of load instructions CSE'd"); 36 STATISTIC(NumCSECall, "Number of call instructions CSE'd"); 37 STATISTIC(NumDSE, "Number of trivial dead stores removed"); 38 39 static unsigned getHash(const void *V) { 40 return DenseMapInfo<const void*>::getHashValue(V); 41 } 42 43 //===----------------------------------------------------------------------===// 44 // SimpleValue 45 //===----------------------------------------------------------------------===// 46 47 namespace { 48 /// SimpleValue - Instances of this struct represent available values in the 49 /// scoped hash table. 50 struct SimpleValue { 51 Instruction *Inst; 52 53 SimpleValue(Instruction *I) : Inst(I) { 54 assert((isSentinel() || canHandle(I)) && "Inst can't be handled!"); 55 } 56 57 bool isSentinel() const { 58 return Inst == DenseMapInfo<Instruction*>::getEmptyKey() || 59 Inst == DenseMapInfo<Instruction*>::getTombstoneKey(); 60 } 61 62 static bool canHandle(Instruction *Inst) { 63 // This can only handle non-void readnone functions. 64 if (CallInst *CI = dyn_cast<CallInst>(Inst)) 65 return CI->doesNotAccessMemory() && !CI->getType()->isVoidTy(); 66 return isa<CastInst>(Inst) || isa<BinaryOperator>(Inst) || 67 isa<GetElementPtrInst>(Inst) || isa<CmpInst>(Inst) || 68 isa<SelectInst>(Inst) || isa<ExtractElementInst>(Inst) || 69 isa<InsertElementInst>(Inst) || isa<ShuffleVectorInst>(Inst) || 70 isa<ExtractValueInst>(Inst) || isa<InsertValueInst>(Inst); 71 } 72 }; 73 } 74 75 namespace llvm { 76 template<> struct DenseMapInfo<SimpleValue> { 77 static inline SimpleValue getEmptyKey() { 78 return DenseMapInfo<Instruction*>::getEmptyKey(); 79 } 80 static inline SimpleValue getTombstoneKey() { 81 return DenseMapInfo<Instruction*>::getTombstoneKey(); 82 } 83 static unsigned getHashValue(SimpleValue Val); 84 static bool isEqual(SimpleValue LHS, SimpleValue RHS); 85 }; 86 } 87 88 unsigned DenseMapInfo<SimpleValue>::getHashValue(SimpleValue Val) { 89 Instruction *Inst = Val.Inst; 90 // Hash in all of the operands as pointers. 91 if (BinaryOperator* BinOp = dyn_cast<BinaryOperator>(Inst)) { 92 Value *LHS = BinOp->getOperand(0); 93 Value *RHS = BinOp->getOperand(1); 94 if (BinOp->isCommutative() && BinOp->getOperand(0) > BinOp->getOperand(1)) 95 std::swap(LHS, RHS); 96 97 if (isa<OverflowingBinaryOperator>(BinOp)) { 98 // Hash the overflow behavior 99 unsigned Overflow = 100 BinOp->hasNoSignedWrap() * OverflowingBinaryOperator::NoSignedWrap | 101 BinOp->hasNoUnsignedWrap() * OverflowingBinaryOperator::NoUnsignedWrap; 102 return hash_combine(BinOp->getOpcode(), Overflow, LHS, RHS); 103 } 104 105 return hash_combine(BinOp->getOpcode(), LHS, RHS); 106 } 107 108 if (CmpInst *CI = dyn_cast<CmpInst>(Inst)) { 109 Value *LHS = CI->getOperand(0); 110 Value *RHS = CI->getOperand(1); 111 CmpInst::Predicate Pred = CI->getPredicate(); 112 if (Inst->getOperand(0) > Inst->getOperand(1)) { 113 std::swap(LHS, RHS); 114 Pred = CI->getSwappedPredicate(); 115 } 116 return hash_combine(Inst->getOpcode(), Pred, LHS, RHS); 117 } 118 119 if (CastInst *CI = dyn_cast<CastInst>(Inst)) 120 return hash_combine(CI->getOpcode(), CI->getType(), CI->getOperand(0)); 121 122 if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Inst)) 123 return hash_combine(EVI->getOpcode(), EVI->getOperand(0), 124 hash_combine_range(EVI->idx_begin(), EVI->idx_end())); 125 126 if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(Inst)) 127 return hash_combine(IVI->getOpcode(), IVI->getOperand(0), 128 IVI->getOperand(1), 129 hash_combine_range(IVI->idx_begin(), IVI->idx_end())); 130 131 assert((isa<CallInst>(Inst) || isa<BinaryOperator>(Inst) || 132 isa<GetElementPtrInst>(Inst) || isa<SelectInst>(Inst) || 133 isa<ExtractElementInst>(Inst) || isa<InsertElementInst>(Inst) || 134 isa<ShuffleVectorInst>(Inst)) && "Invalid/unknown instruction"); 135 136 // Mix in the opcode. 137 return hash_combine(Inst->getOpcode(), 138 hash_combine_range(Inst->value_op_begin(), 139 Inst->value_op_end())); 140 } 141 142 bool DenseMapInfo<SimpleValue>::isEqual(SimpleValue LHS, SimpleValue RHS) { 143 Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; 144 145 if (LHS.isSentinel() || RHS.isSentinel()) 146 return LHSI == RHSI; 147 148 if (LHSI->getOpcode() != RHSI->getOpcode()) return false; 149 if (LHSI->isIdenticalTo(RHSI)) return true; 150 151 // If we're not strictly identical, we still might be a commutable instruction 152 if (BinaryOperator *LHSBinOp = dyn_cast<BinaryOperator>(LHSI)) { 153 if (!LHSBinOp->isCommutative()) 154 return false; 155 156 assert(isa<BinaryOperator>(RHSI) 157 && "same opcode, but different instruction type?"); 158 BinaryOperator *RHSBinOp = cast<BinaryOperator>(RHSI); 159 160 // Check overflow attributes 161 if (isa<OverflowingBinaryOperator>(LHSBinOp)) { 162 assert(isa<OverflowingBinaryOperator>(RHSBinOp) 163 && "same opcode, but different operator type?"); 164 if (LHSBinOp->hasNoUnsignedWrap() != RHSBinOp->hasNoUnsignedWrap() || 165 LHSBinOp->hasNoSignedWrap() != RHSBinOp->hasNoSignedWrap()) 166 return false; 167 } 168 169 // Commuted equality 170 return LHSBinOp->getOperand(0) == RHSBinOp->getOperand(1) && 171 LHSBinOp->getOperand(1) == RHSBinOp->getOperand(0); 172 } 173 if (CmpInst *LHSCmp = dyn_cast<CmpInst>(LHSI)) { 174 assert(isa<CmpInst>(RHSI) 175 && "same opcode, but different instruction type?"); 176 CmpInst *RHSCmp = cast<CmpInst>(RHSI); 177 // Commuted equality 178 return LHSCmp->getOperand(0) == RHSCmp->getOperand(1) && 179 LHSCmp->getOperand(1) == RHSCmp->getOperand(0) && 180 LHSCmp->getSwappedPredicate() == RHSCmp->getPredicate(); 181 } 182 183 return false; 184 } 185 186 //===----------------------------------------------------------------------===// 187 // CallValue 188 //===----------------------------------------------------------------------===// 189 190 namespace { 191 /// CallValue - Instances of this struct represent available call values in 192 /// the scoped hash table. 193 struct CallValue { 194 Instruction *Inst; 195 196 CallValue(Instruction *I) : Inst(I) { 197 assert((isSentinel() || canHandle(I)) && "Inst can't be handled!"); 198 } 199 200 bool isSentinel() const { 201 return Inst == DenseMapInfo<Instruction*>::getEmptyKey() || 202 Inst == DenseMapInfo<Instruction*>::getTombstoneKey(); 203 } 204 205 static bool canHandle(Instruction *Inst) { 206 // Don't value number anything that returns void. 207 if (Inst->getType()->isVoidTy()) 208 return false; 209 210 CallInst *CI = dyn_cast<CallInst>(Inst); 211 if (!CI || !CI->onlyReadsMemory()) 212 return false; 213 return true; 214 } 215 }; 216 } 217 218 namespace llvm { 219 template<> struct DenseMapInfo<CallValue> { 220 static inline CallValue getEmptyKey() { 221 return DenseMapInfo<Instruction*>::getEmptyKey(); 222 } 223 static inline CallValue getTombstoneKey() { 224 return DenseMapInfo<Instruction*>::getTombstoneKey(); 225 } 226 static unsigned getHashValue(CallValue Val); 227 static bool isEqual(CallValue LHS, CallValue RHS); 228 }; 229 } 230 unsigned DenseMapInfo<CallValue>::getHashValue(CallValue Val) { 231 Instruction *Inst = Val.Inst; 232 // Hash in all of the operands as pointers. 233 unsigned Res = 0; 234 for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) { 235 assert(!Inst->getOperand(i)->getType()->isMetadataTy() && 236 "Cannot value number calls with metadata operands"); 237 Res ^= getHash(Inst->getOperand(i)) << (i & 0xF); 238 } 239 240 // Mix in the opcode. 241 return (Res << 1) ^ Inst->getOpcode(); 242 } 243 244 bool DenseMapInfo<CallValue>::isEqual(CallValue LHS, CallValue RHS) { 245 Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; 246 if (LHS.isSentinel() || RHS.isSentinel()) 247 return LHSI == RHSI; 248 return LHSI->isIdenticalTo(RHSI); 249 } 250 251 252 //===----------------------------------------------------------------------===// 253 // EarlyCSE pass. 254 //===----------------------------------------------------------------------===// 255 256 namespace { 257 258 /// EarlyCSE - This pass does a simple depth-first walk over the dominator 259 /// tree, eliminating trivially redundant instructions and using instsimplify 260 /// to canonicalize things as it goes. It is intended to be fast and catch 261 /// obvious cases so that instcombine and other passes are more effective. It 262 /// is expected that a later pass of GVN will catch the interesting/hard 263 /// cases. 264 class EarlyCSE : public FunctionPass { 265 public: 266 const DataLayout *DL; 267 const TargetLibraryInfo *TLI; 268 DominatorTree *DT; 269 typedef RecyclingAllocator<BumpPtrAllocator, 270 ScopedHashTableVal<SimpleValue, Value*> > AllocatorTy; 271 typedef ScopedHashTable<SimpleValue, Value*, DenseMapInfo<SimpleValue>, 272 AllocatorTy> ScopedHTType; 273 274 /// AvailableValues - This scoped hash table contains the current values of 275 /// all of our simple scalar expressions. As we walk down the domtree, we 276 /// look to see if instructions are in this: if so, we replace them with what 277 /// we find, otherwise we insert them so that dominated values can succeed in 278 /// their lookup. 279 ScopedHTType *AvailableValues; 280 281 /// AvailableLoads - This scoped hash table contains the current values 282 /// of loads. This allows us to get efficient access to dominating loads when 283 /// we have a fully redundant load. In addition to the most recent load, we 284 /// keep track of a generation count of the read, which is compared against 285 /// the current generation count. The current generation count is 286 /// incremented after every possibly writing memory operation, which ensures 287 /// that we only CSE loads with other loads that have no intervening store. 288 typedef RecyclingAllocator<BumpPtrAllocator, 289 ScopedHashTableVal<Value*, std::pair<Value*, unsigned> > > LoadMapAllocator; 290 typedef ScopedHashTable<Value*, std::pair<Value*, unsigned>, 291 DenseMapInfo<Value*>, LoadMapAllocator> LoadHTType; 292 LoadHTType *AvailableLoads; 293 294 /// AvailableCalls - This scoped hash table contains the current values 295 /// of read-only call values. It uses the same generation count as loads. 296 typedef ScopedHashTable<CallValue, std::pair<Value*, unsigned> > CallHTType; 297 CallHTType *AvailableCalls; 298 299 /// CurrentGeneration - This is the current generation of the memory value. 300 unsigned CurrentGeneration; 301 302 static char ID; 303 explicit EarlyCSE() : FunctionPass(ID) { 304 initializeEarlyCSEPass(*PassRegistry::getPassRegistry()); 305 } 306 307 bool runOnFunction(Function &F) override; 308 309 private: 310 311 // NodeScope - almost a POD, but needs to call the constructors for the 312 // scoped hash tables so that a new scope gets pushed on. These are RAII so 313 // that the scope gets popped when the NodeScope is destroyed. 314 class NodeScope { 315 public: 316 NodeScope(ScopedHTType *availableValues, 317 LoadHTType *availableLoads, 318 CallHTType *availableCalls) : 319 Scope(*availableValues), 320 LoadScope(*availableLoads), 321 CallScope(*availableCalls) {} 322 323 private: 324 NodeScope(const NodeScope&) LLVM_DELETED_FUNCTION; 325 void operator=(const NodeScope&) LLVM_DELETED_FUNCTION; 326 327 ScopedHTType::ScopeTy Scope; 328 LoadHTType::ScopeTy LoadScope; 329 CallHTType::ScopeTy CallScope; 330 }; 331 332 // StackNode - contains all the needed information to create a stack for 333 // doing a depth first tranversal of the tree. This includes scopes for 334 // values, loads, and calls as well as the generation. There is a child 335 // iterator so that the children do not need to be store spearately. 336 class StackNode { 337 public: 338 StackNode(ScopedHTType *availableValues, 339 LoadHTType *availableLoads, 340 CallHTType *availableCalls, 341 unsigned cg, DomTreeNode *n, 342 DomTreeNode::iterator child, DomTreeNode::iterator end) : 343 CurrentGeneration(cg), ChildGeneration(cg), Node(n), 344 ChildIter(child), EndIter(end), 345 Scopes(availableValues, availableLoads, availableCalls), 346 Processed(false) {} 347 348 // Accessors. 349 unsigned currentGeneration() { return CurrentGeneration; } 350 unsigned childGeneration() { return ChildGeneration; } 351 void childGeneration(unsigned generation) { ChildGeneration = generation; } 352 DomTreeNode *node() { return Node; } 353 DomTreeNode::iterator childIter() { return ChildIter; } 354 DomTreeNode *nextChild() { 355 DomTreeNode *child = *ChildIter; 356 ++ChildIter; 357 return child; 358 } 359 DomTreeNode::iterator end() { return EndIter; } 360 bool isProcessed() { return Processed; } 361 void process() { Processed = true; } 362 363 private: 364 StackNode(const StackNode&) LLVM_DELETED_FUNCTION; 365 void operator=(const StackNode&) LLVM_DELETED_FUNCTION; 366 367 // Members. 368 unsigned CurrentGeneration; 369 unsigned ChildGeneration; 370 DomTreeNode *Node; 371 DomTreeNode::iterator ChildIter; 372 DomTreeNode::iterator EndIter; 373 NodeScope Scopes; 374 bool Processed; 375 }; 376 377 bool processNode(DomTreeNode *Node); 378 379 // This transformation requires dominator postdominator info 380 void getAnalysisUsage(AnalysisUsage &AU) const override { 381 AU.addRequired<DominatorTreeWrapperPass>(); 382 AU.addRequired<TargetLibraryInfo>(); 383 AU.setPreservesCFG(); 384 } 385 }; 386 } 387 388 char EarlyCSE::ID = 0; 389 390 // createEarlyCSEPass - The public interface to this file. 391 FunctionPass *llvm::createEarlyCSEPass() { 392 return new EarlyCSE(); 393 } 394 395 INITIALIZE_PASS_BEGIN(EarlyCSE, "early-cse", "Early CSE", false, false) 396 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 397 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) 398 INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) 399 400 bool EarlyCSE::processNode(DomTreeNode *Node) { 401 BasicBlock *BB = Node->getBlock(); 402 403 // If this block has a single predecessor, then the predecessor is the parent 404 // of the domtree node and all of the live out memory values are still current 405 // in this block. If this block has multiple predecessors, then they could 406 // have invalidated the live-out memory values of our parent value. For now, 407 // just be conservative and invalidate memory if this block has multiple 408 // predecessors. 409 if (!BB->getSinglePredecessor()) 410 ++CurrentGeneration; 411 412 /// LastStore - Keep track of the last non-volatile store that we saw... for 413 /// as long as there in no instruction that reads memory. If we see a store 414 /// to the same location, we delete the dead store. This zaps trivial dead 415 /// stores which can occur in bitfield code among other things. 416 StoreInst *LastStore = nullptr; 417 418 bool Changed = false; 419 420 // See if any instructions in the block can be eliminated. If so, do it. If 421 // not, add them to AvailableValues. 422 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { 423 Instruction *Inst = I++; 424 425 // Dead instructions should just be removed. 426 if (isInstructionTriviallyDead(Inst, TLI)) { 427 DEBUG(dbgs() << "EarlyCSE DCE: " << *Inst << '\n'); 428 Inst->eraseFromParent(); 429 Changed = true; 430 ++NumSimplify; 431 continue; 432 } 433 434 // If the instruction can be simplified (e.g. X+0 = X) then replace it with 435 // its simpler value. 436 if (Value *V = SimplifyInstruction(Inst, DL, TLI, DT)) { 437 DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n'); 438 Inst->replaceAllUsesWith(V); 439 Inst->eraseFromParent(); 440 Changed = true; 441 ++NumSimplify; 442 continue; 443 } 444 445 // If this is a simple instruction that we can value number, process it. 446 if (SimpleValue::canHandle(Inst)) { 447 // See if the instruction has an available value. If so, use it. 448 if (Value *V = AvailableValues->lookup(Inst)) { 449 DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n'); 450 Inst->replaceAllUsesWith(V); 451 Inst->eraseFromParent(); 452 Changed = true; 453 ++NumCSE; 454 continue; 455 } 456 457 // Otherwise, just remember that this value is available. 458 AvailableValues->insert(Inst, Inst); 459 continue; 460 } 461 462 // If this is a non-volatile load, process it. 463 if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) { 464 // Ignore volatile loads. 465 if (!LI->isSimple()) { 466 LastStore = nullptr; 467 continue; 468 } 469 470 // If we have an available version of this load, and if it is the right 471 // generation, replace this instruction. 472 std::pair<Value*, unsigned> InVal = 473 AvailableLoads->lookup(Inst->getOperand(0)); 474 if (InVal.first != nullptr && InVal.second == CurrentGeneration) { 475 DEBUG(dbgs() << "EarlyCSE CSE LOAD: " << *Inst << " to: " 476 << *InVal.first << '\n'); 477 if (!Inst->use_empty()) Inst->replaceAllUsesWith(InVal.first); 478 Inst->eraseFromParent(); 479 Changed = true; 480 ++NumCSELoad; 481 continue; 482 } 483 484 // Otherwise, remember that we have this instruction. 485 AvailableLoads->insert(Inst->getOperand(0), 486 std::pair<Value*, unsigned>(Inst, CurrentGeneration)); 487 LastStore = nullptr; 488 continue; 489 } 490 491 // If this instruction may read from memory, forget LastStore. 492 if (Inst->mayReadFromMemory()) 493 LastStore = nullptr; 494 495 // If this is a read-only call, process it. 496 if (CallValue::canHandle(Inst)) { 497 // If we have an available version of this call, and if it is the right 498 // generation, replace this instruction. 499 std::pair<Value*, unsigned> InVal = AvailableCalls->lookup(Inst); 500 if (InVal.first != nullptr && InVal.second == CurrentGeneration) { 501 DEBUG(dbgs() << "EarlyCSE CSE CALL: " << *Inst << " to: " 502 << *InVal.first << '\n'); 503 if (!Inst->use_empty()) Inst->replaceAllUsesWith(InVal.first); 504 Inst->eraseFromParent(); 505 Changed = true; 506 ++NumCSECall; 507 continue; 508 } 509 510 // Otherwise, remember that we have this instruction. 511 AvailableCalls->insert(Inst, 512 std::pair<Value*, unsigned>(Inst, CurrentGeneration)); 513 continue; 514 } 515 516 // Okay, this isn't something we can CSE at all. Check to see if it is 517 // something that could modify memory. If so, our available memory values 518 // cannot be used so bump the generation count. 519 if (Inst->mayWriteToMemory()) { 520 ++CurrentGeneration; 521 522 if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { 523 // We do a trivial form of DSE if there are two stores to the same 524 // location with no intervening loads. Delete the earlier store. 525 if (LastStore && 526 LastStore->getPointerOperand() == SI->getPointerOperand()) { 527 DEBUG(dbgs() << "EarlyCSE DEAD STORE: " << *LastStore << " due to: " 528 << *Inst << '\n'); 529 LastStore->eraseFromParent(); 530 Changed = true; 531 ++NumDSE; 532 LastStore = nullptr; 533 continue; 534 } 535 536 // Okay, we just invalidated anything we knew about loaded values. Try 537 // to salvage *something* by remembering that the stored value is a live 538 // version of the pointer. It is safe to forward from volatile stores 539 // to non-volatile loads, so we don't have to check for volatility of 540 // the store. 541 AvailableLoads->insert(SI->getPointerOperand(), 542 std::pair<Value*, unsigned>(SI->getValueOperand(), CurrentGeneration)); 543 544 // Remember that this was the last store we saw for DSE. 545 if (SI->isSimple()) 546 LastStore = SI; 547 } 548 } 549 } 550 551 return Changed; 552 } 553 554 555 bool EarlyCSE::runOnFunction(Function &F) { 556 if (skipOptnoneFunction(F)) 557 return false; 558 559 std::vector<StackNode *> nodesToProcess; 560 561 DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); 562 DL = DLP ? &DLP->getDataLayout() : nullptr; 563 TLI = &getAnalysis<TargetLibraryInfo>(); 564 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 565 566 // Tables that the pass uses when walking the domtree. 567 ScopedHTType AVTable; 568 AvailableValues = &AVTable; 569 LoadHTType LoadTable; 570 AvailableLoads = &LoadTable; 571 CallHTType CallTable; 572 AvailableCalls = &CallTable; 573 574 CurrentGeneration = 0; 575 bool Changed = false; 576 577 // Process the root node. 578 nodesToProcess.push_back( 579 new StackNode(AvailableValues, AvailableLoads, AvailableCalls, 580 CurrentGeneration, DT->getRootNode(), 581 DT->getRootNode()->begin(), 582 DT->getRootNode()->end())); 583 584 // Save the current generation. 585 unsigned LiveOutGeneration = CurrentGeneration; 586 587 // Process the stack. 588 while (!nodesToProcess.empty()) { 589 // Grab the first item off the stack. Set the current generation, remove 590 // the node from the stack, and process it. 591 StackNode *NodeToProcess = nodesToProcess.back(); 592 593 // Initialize class members. 594 CurrentGeneration = NodeToProcess->currentGeneration(); 595 596 // Check if the node needs to be processed. 597 if (!NodeToProcess->isProcessed()) { 598 // Process the node. 599 Changed |= processNode(NodeToProcess->node()); 600 NodeToProcess->childGeneration(CurrentGeneration); 601 NodeToProcess->process(); 602 } else if (NodeToProcess->childIter() != NodeToProcess->end()) { 603 // Push the next child onto the stack. 604 DomTreeNode *child = NodeToProcess->nextChild(); 605 nodesToProcess.push_back( 606 new StackNode(AvailableValues, 607 AvailableLoads, 608 AvailableCalls, 609 NodeToProcess->childGeneration(), child, 610 child->begin(), child->end())); 611 } else { 612 // It has been processed, and there are no more children to process, 613 // so delete it and pop it off the stack. 614 delete NodeToProcess; 615 nodesToProcess.pop_back(); 616 } 617 } // while (!nodes...) 618 619 // Reset the current generation. 620 CurrentGeneration = LiveOutGeneration; 621 622 return Changed; 623 } 624