X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FLoadValueNumbering.cpp;h=f99ebb4a83d3b50bdbef4a6c9d0105502d44e54e;hb=a3ec5d6eccb0fa3746050a3d3c739bd9718b6bd0;hp=5188dae5291611a40b3a083cf5fdcd517aa2c1a1;hpb=46b58f78697fafa1500228337c84dc969a8bfcc3;p=oota-llvm.git diff --git a/lib/Analysis/LoadValueNumbering.cpp b/lib/Analysis/LoadValueNumbering.cpp index 5188dae5291..f99ebb4a83d 100644 --- a/lib/Analysis/LoadValueNumbering.cpp +++ b/lib/Analysis/LoadValueNumbering.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -40,6 +40,8 @@ using namespace llvm; namespace { // FIXME: This should not be a FunctionPass. struct VISIBILITY_HIDDEN LoadVN : public FunctionPass, public ValueNumbering { + static char ID; // Class identification, replacement for typeinfo + LoadVN() : FunctionPass((intptr_t)&ID) {} /// Pass Implementation stuff. This doesn't do any analysis. /// @@ -80,13 +82,15 @@ namespace { void getCallEqualNumberNodes(CallInst *CI, std::vector &RetVals) const; }; +} - // Register this pass... - RegisterPass X("load-vn", "Load Value Numbering"); +char LoadVN::ID = 0; +// Register this pass... +static RegisterPass +X("load-vn", "Load Value Numbering", false, true); - // Declare that we implement the ValueNumbering interface - RegisterAnalysisGroup Y(X); -} +// Declare that we implement the ValueNumbering interface +static RegisterAnalysisGroup Y(X); FunctionPass *llvm::createLoadValueNumberingPass() { return new LoadVN(); } @@ -98,7 +102,7 @@ void LoadVN::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredTransitive(); AU.addRequired(); - AU.addRequiredTransitive(); + AU.addRequiredTransitive(); AU.addRequiredTransitive(); } @@ -113,9 +117,9 @@ static bool isPathTransparentTo(BasicBlock *CurBlock, BasicBlock *Dom, // Check whether this block is known transparent or not. std::map::iterator TBI = - TransparentBlocks.lower_bound(CurBlock); + TransparentBlocks.find(CurBlock); - if (TBI == TransparentBlocks.end() || TBI->first != CurBlock) { + if (TBI == TransparentBlocks.end()) { // If this basic block can modify the memory location, then the path is not // transparent! if (AA.canBasicBlockModify(*CurBlock, Ptr, Size)) { @@ -145,7 +149,7 @@ void LoadVN::getCallEqualNumberNodes(CallInst *CI, Function *CF = CI->getCalledFunction(); if (CF == 0) return; // Indirect call. AliasAnalysis &AA = getAnalysis(); - AliasAnalysis::ModRefBehavior MRB = AA.getModRefBehavior(CF, CI); + AliasAnalysis::ModRefBehavior MRB = AA.getModRefBehavior(CI); if (MRB != AliasAnalysis::DoesNotAccessMemory && MRB != AliasAnalysis::OnlyReadsMemory) return; // Nothing we can do for now. @@ -154,10 +158,10 @@ void LoadVN::getCallEqualNumberNodes(CallInst *CI, // global. In particular, we would prefer to have an argument or instruction // operand to chase the def-use chains of. Value *Op = CF; - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) - if (isa(CI->getOperand(i)) || - isa(CI->getOperand(i))) { - Op = CI->getOperand(i); + for (User::op_iterator i = CI->op_begin() + 1, e = CI->op_end(); i != e; ++i) + if (isa(*i) || + isa(*i)) { + Op = *i; break; } @@ -172,8 +176,9 @@ void LoadVN::getCallEqualNumberNodes(CallInst *CI, C->getOperand(0) == CI->getOperand(0) && C->getParent()->getParent() == CIFunc && C != CI) { bool AllOperandsEqual = true; - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) - if (C->getOperand(i) != CI->getOperand(i)) { + for (User::op_iterator i = CI->op_begin() + 1, j = C->op_begin() + 1, + e = CI->op_end(); i != e; ++i, ++j) + if (*j != *i) { AllOperandsEqual = false; break; } @@ -198,20 +203,20 @@ void LoadVN::getCallEqualNumberNodes(CallInst *CI, // ANY memory. // if (MRB == AliasAnalysis::OnlyReadsMemory) { - ETForest &EF = getAnalysis(); + DominatorTree &DT = getAnalysis(); BasicBlock *CIBB = CI->getParent(); for (unsigned i = 0; i != IdenticalCalls.size(); ++i) { CallInst *C = IdenticalCalls[i]; bool CantEqual = false; - if (EF.dominates(CIBB, C->getParent())) { + if (DT.dominates(CIBB, C->getParent())) { // FIXME: we currently only handle the case where both calls are in the // same basic block. if (CIBB != C->getParent()) { CantEqual = true; } else { Instruction *First = CI, *Second = C; - if (!EF.dominates(CI, C)) + if (!DT.dominates(CI, C)) std::swap(First, Second); // Scan the instructions between the calls, checking for stores or @@ -224,8 +229,7 @@ void LoadVN::getCallEqualNumberNodes(CallInst *CI, CantEqual = true; break; } else if (CallInst *CI = dyn_cast(I)) { - if (CI->getCalledFunction() == 0 || - !AA.onlyReadsMemory(CI->getCalledFunction())) { + if (!AA.onlyReadsMemory(CI)) { CantEqual = true; break; } @@ -236,7 +240,7 @@ void LoadVN::getCallEqualNumberNodes(CallInst *CI, } } - } else if (EF.dominates(C->getParent(), CIBB)) { + } else if (DT.dominates(C->getParent(), CIBB)) { // FIXME: We could implement this, but we don't for now. CantEqual = true; } else { @@ -290,7 +294,7 @@ void LoadVN::getEqualNumberNodes(Value *V, Function *F = LoadBB->getParent(); // Find out how many bytes of memory are loaded by the load instruction... - unsigned LoadSize = getAnalysis().getTypeSize(LI->getType()); + unsigned LoadSize = getAnalysis().getTypeStoreSize(LI->getType()); AliasAnalysis &AA = getAnalysis(); // Figure out if the load is invalidated from the entry of the block it is in @@ -336,15 +340,18 @@ void LoadVN::getEqualNumberNodes(Value *V, // we see any candidate loads, then we know they have the same value # as LI. // bool LoadInvalidatedInBBAfter = false; - for (BasicBlock::iterator I = LI->getNext(); I != LoadBB->end(); ++I) { - // If this instruction is a load, then this instruction returns the same - // value as LI. - if (isa(I) && cast(I)->getOperand(0) == LoadPtr) - RetVals.push_back(I); + { + BasicBlock::iterator I = LI; + for (++I; I != LoadBB->end(); ++I) { + // If this instruction is a load, then this instruction returns the same + // value as LI. + if (isa(I) && cast(I)->getOperand(0) == LoadPtr) + RetVals.push_back(I); - if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) { - LoadInvalidatedInBBAfter = true; - break; + if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) { + LoadInvalidatedInBBAfter = true; + break; + } } } @@ -374,7 +381,7 @@ void LoadVN::getEqualNumberNodes(Value *V, } // Get dominators. - ETForest &EF = getAnalysis(); + DominatorTree &DT = getAnalysis(); // TransparentBlocks - For each basic block the load/store is alive across, // figure out if the pointer is invalidated or not. If it is invalidated, the @@ -393,12 +400,12 @@ void LoadVN::getEqualNumberNodes(Value *V, // Right now we only can handle cases where one load dominates the other. // FIXME: generalize this! BasicBlock *BB1 = I->first, *BB2 = LoadBB; - if (EF.dominates(BB1, BB2)) { + if (DT.dominates(BB1, BB2)) { // The other load dominates LI. If the loaded value is killed entering // the LoadBB block, we know the load is not live. if (LoadInvalidatedInBBBefore) CantEqual = true; - } else if (EF.dominates(BB2, BB1)) { + } else if (DT.dominates(BB2, BB1)) { std::swap(BB1, BB2); // Canonicalize // LI dominates the other load. If the loaded value is killed exiting // the LoadBB block, we know the load is not live. @@ -480,7 +487,7 @@ void LoadVN::getEqualNumberNodes(Value *V, for (std::set::iterator I = CandidateStores.begin(), E = CandidateStores.end(); I != E; ++I) - if (EF.dominates(*I, LoadBB)) { + if (DT.dominates(*I, LoadBB)) { BasicBlock *StoreBB = *I; // Check to see if the path from the store to the load is transparent