Skip to content
GVN.cpp 35.3 KiB
Newer Older
            MD.getDependency(CI) != MD.getDependency(cast<CallInst>(repl))) {
          // There must be an intervening may-alias store, so nothing from
          // this point on will be able to be replaced with the preceding call
          currAvail.erase(repl);
          currAvail.insert(I);
          
          return false;
        }
      }
    }
    
    // Remove it!
    MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
    MD.removeInstruction(I);
    
    I->replaceAllUsesWith(repl);
    toErase.push_back(I);
    return true;
  } else if (!I->isTerminator()) {
    currAvail.set(num);
    currAvail.insert(I);
  }
  
  return false;
}

// GVN::runOnFunction - This is the main transformation entry point for a
// function.
//
Owen Anderson's avatar
Owen Anderson committed
bool GVN::runOnFunction(Function& F) {
  VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>());
  
Owen Anderson's avatar
Owen Anderson committed
  bool changed = false;
  bool shouldContinue = true;
  
  while (shouldContinue) {
    shouldContinue = iterateOnFunction(F);
    changed |= shouldContinue;
  }
  
  return changed;
}


// GVN::iterateOnFunction - Executes one iteration of GVN
bool GVN::iterateOnFunction(Function &F) {
  // Clean out global sets from any previous functions
  VN.clear();
  availableOut.clear();
 
  bool changed_function = false;
  
  DominatorTree &DT = getAnalysis<DominatorTree>();   
  
  SmallVector<Instruction*, 8> toErase;
  DenseMap<Value*, LoadInst*> lastSeenLoad;
  DenseMap<DomTreeNode*, size_t> numChildrenVisited;
  // Top-down walk of the dominator tree
  for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()),
         E = df_end(DT.getRootNode()); DI != E; ++DI) {
    
    // Get the set to update for this block
    ValueNumberedSet& currAvail = availableOut[DI->getBlock()];     
    BasicBlock* BB = DI->getBlock();
  
    // A block inherits AVAIL_OUT from its dominator
      currAvail = availableOut[DI->getIDom()->getBlock()];
      
      numChildrenVisited[DI->getIDom()]++;
      
      if (numChildrenVisited[DI->getIDom()] == DI->getIDom()->getNumChildren()) {
        availableOut.erase(DI->getIDom()->getBlock());
        numChildrenVisited.erase(DI->getIDom());
      }
    }

    for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
Owen Anderson's avatar
Owen Anderson committed
      changed_function |= processInstruction(BI, currAvail,
                                             lastSeenLoad, toErase);
      // If we need some instructions deleted, do it now.
      NumGVNInstr += toErase.size();
      
      // Avoid iterator invalidation.
      bool AtStart = BI == BB->begin();
      if (!AtStart)
        --BI;
      for (SmallVector<Instruction*, 4>::iterator I = toErase.begin(),
           E = toErase.end(); I != E; ++I)
        (*I)->eraseFromParent();