mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Remove GCSE, ValueNumbering, and LoadValueNumbering. These have been deprecated for almost a year; it's finally time for them to go away.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54822 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -1,35 +0,0 @@ | |||||||
| //===- llvm/Analysis/LoadValueNumbering.h - Value # Load Insts --*- C++ -*-===// |  | ||||||
| // |  | ||||||
| //                     The LLVM Compiler Infrastructure |  | ||||||
| // |  | ||||||
| // This file is distributed under the University of Illinois Open Source |  | ||||||
| // License. See LICENSE.TXT for details. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // This file defines a value numbering pass that value #'s load instructions. |  | ||||||
| // To do this, it finds lexically identical load instructions, and uses alias |  | ||||||
| // analysis to determine which loads are guaranteed to produce the same value. |  | ||||||
| // |  | ||||||
| // This pass builds off of another value numbering pass to implement value |  | ||||||
| // numbering for non-load instructions.  It uses Alias Analysis so that it can |  | ||||||
| // disambiguate the load instructions.  The more powerful these base analyses |  | ||||||
| // are, the more powerful the resultant analysis will be. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
|  |  | ||||||
| #ifndef LLVM_ANALYSIS_LOAD_VALUE_NUMBERING_H |  | ||||||
| #define LLVM_ANALYSIS_LOAD_VALUE_NUMBERING_H |  | ||||||
|  |  | ||||||
| namespace llvm { |  | ||||||
|  |  | ||||||
| class FunctionPass; |  | ||||||
|  |  | ||||||
| /// createLoadValueNumberingPass - Create and return a new pass that implements |  | ||||||
| /// the ValueNumbering interface. |  | ||||||
| /// |  | ||||||
| FunctionPass *createLoadValueNumberingPass(); |  | ||||||
|  |  | ||||||
| } // End llvm namespace |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @@ -77,13 +77,6 @@ namespace llvm { | |||||||
|   // |   // | ||||||
|   ModulePass *createAndersensPass(); |   ModulePass *createAndersensPass(); | ||||||
|  |  | ||||||
|   //===--------------------------------------------------------------------===// |  | ||||||
|   // |  | ||||||
|   // createBasicVNPass - This pass walks SSA def-use chains to trivially |  | ||||||
|   // identify lexically identical expressions. |  | ||||||
|   // |  | ||||||
|   ImmutablePass *createBasicVNPass(); |  | ||||||
|  |  | ||||||
|   //===--------------------------------------------------------------------===// |   //===--------------------------------------------------------------------===// | ||||||
|   // |   // | ||||||
|   // createProfileLoaderPass - This pass loads information from a profile dump |   // createProfileLoaderPass - This pass loads information from a profile dump | ||||||
|   | |||||||
| @@ -1,75 +0,0 @@ | |||||||
| //===- llvm/Analysis/ValueNumbering.h - Value #'ing Interface ---*- C++ -*-===// |  | ||||||
| // |  | ||||||
| //                     The LLVM Compiler Infrastructure |  | ||||||
| // |  | ||||||
| // This file is distributed under the University of Illinois Open Source |  | ||||||
| // License. See LICENSE.TXT for details. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // This file defines the abstract ValueNumbering interface, which is used as the |  | ||||||
| // common interface used by all clients of value numbering information, and |  | ||||||
| // implemented by all value numbering implementations. |  | ||||||
| // |  | ||||||
| // Implementations of this interface must implement the various virtual methods, |  | ||||||
| // which automatically provides functionality for the entire suite of client |  | ||||||
| // APIs. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
|  |  | ||||||
| #ifndef LLVM_ANALYSIS_VALUE_NUMBERING_H |  | ||||||
| #define LLVM_ANALYSIS_VALUE_NUMBERING_H |  | ||||||
|  |  | ||||||
| #include <vector> |  | ||||||
| #include "llvm/Pass.h" |  | ||||||
| #include "llvm/System/IncludeFile.h" |  | ||||||
|  |  | ||||||
| namespace llvm { |  | ||||||
|  |  | ||||||
| class Value; |  | ||||||
| class Instruction; |  | ||||||
|  |  | ||||||
| struct ValueNumbering { |  | ||||||
|   static char ID; // Class identification, replacement for typeinfo |  | ||||||
|   virtual ~ValueNumbering();    // We want to be subclassed |  | ||||||
|  |  | ||||||
|   /// getEqualNumberNodes - Return nodes with the same value number as the |  | ||||||
|   /// specified Value.  This fills in the argument vector with any equal values. |  | ||||||
|   /// |  | ||||||
|   virtual void getEqualNumberNodes(Value *V1, |  | ||||||
|                                    std::vector<Value*> &RetVals) const = 0; |  | ||||||
|  |  | ||||||
|   ///===-------------------------------------------------------------------===// |  | ||||||
|   /// Interfaces to update value numbering analysis information as the client |  | ||||||
|   /// changes the program. |  | ||||||
|   /// |  | ||||||
|  |  | ||||||
|   /// deleteValue - This method should be called whenever an LLVM Value is |  | ||||||
|   /// deleted from the program, for example when an instruction is found to be |  | ||||||
|   /// redundant and is eliminated. |  | ||||||
|   /// |  | ||||||
|   virtual void deleteValue(Value *V) {} |  | ||||||
|  |  | ||||||
|   /// copyValue - This method should be used whenever a preexisting value in the |  | ||||||
|   /// program is copied or cloned, introducing a new value.  Note that analysis |  | ||||||
|   /// implementations should tolerate clients that use this method to introduce |  | ||||||
|   /// the same value multiple times: if the analysis already knows about a |  | ||||||
|   /// value, it should ignore the request. |  | ||||||
|   /// |  | ||||||
|   virtual void copyValue(Value *From, Value *To) {} |  | ||||||
|  |  | ||||||
|   /// replaceWithNewValue - This method is the obvious combination of the two |  | ||||||
|   /// above, and it provided as a helper to simplify client code. |  | ||||||
|   /// |  | ||||||
|   void replaceWithNewValue(Value *Old, Value *New) { |  | ||||||
|     copyValue(Old, New); |  | ||||||
|     deleteValue(Old); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| } // End llvm namespace |  | ||||||
|  |  | ||||||
| // Force any file including this header to get the implementation as well |  | ||||||
| FORCE_DEFINING_FILE_TO_BE_LINKED(BasicValueNumbering) |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @@ -18,7 +18,6 @@ | |||||||
| #include "llvm/Analysis/AliasSetTracker.h" | #include "llvm/Analysis/AliasSetTracker.h" | ||||||
| #include "llvm/Analysis/FindUsedTypes.h" | #include "llvm/Analysis/FindUsedTypes.h" | ||||||
| #include "llvm/Analysis/IntervalPartition.h" | #include "llvm/Analysis/IntervalPartition.h" | ||||||
| #include "llvm/Analysis/LoadValueNumbering.h" |  | ||||||
| #include "llvm/Analysis/LoopVR.h" | #include "llvm/Analysis/LoopVR.h" | ||||||
| #include "llvm/Analysis/Passes.h" | #include "llvm/Analysis/Passes.h" | ||||||
| #include "llvm/Analysis/PostDominators.h" | #include "llvm/Analysis/PostDominators.h" | ||||||
| @@ -50,7 +49,6 @@ namespace { | |||||||
|       (void) llvm::createStructRetPromotionPass(); |       (void) llvm::createStructRetPromotionPass(); | ||||||
|       (void) llvm::createBasicAliasAnalysisPass(); |       (void) llvm::createBasicAliasAnalysisPass(); | ||||||
|       (void) llvm::createLibCallAliasAnalysisPass(0); |       (void) llvm::createLibCallAliasAnalysisPass(0); | ||||||
|       (void) llvm::createBasicVNPass(); |  | ||||||
|       (void) llvm::createBlockPlacementPass(); |       (void) llvm::createBlockPlacementPass(); | ||||||
|       (void) llvm::createBlockProfilerPass(); |       (void) llvm::createBlockProfilerPass(); | ||||||
|       (void) llvm::createBreakCriticalEdgesPass(); |       (void) llvm::createBreakCriticalEdgesPass(); | ||||||
| @@ -65,7 +63,6 @@ namespace { | |||||||
|       (void) llvm::createEdgeProfilerPass(); |       (void) llvm::createEdgeProfilerPass(); | ||||||
|       (void) llvm::createFunctionInliningPass(); |       (void) llvm::createFunctionInliningPass(); | ||||||
|       (void) llvm::createFunctionProfilerPass(); |       (void) llvm::createFunctionProfilerPass(); | ||||||
|       (void) llvm::createGCSEPass(); |  | ||||||
|       (void) llvm::createGlobalDCEPass(); |       (void) llvm::createGlobalDCEPass(); | ||||||
|       (void) llvm::createGlobalOptimizerPass(); |       (void) llvm::createGlobalOptimizerPass(); | ||||||
|       (void) llvm::createGlobalsModRefPass(); |       (void) llvm::createGlobalsModRefPass(); | ||||||
| @@ -77,7 +74,6 @@ namespace { | |||||||
|       (void) llvm::createInternalizePass(false); |       (void) llvm::createInternalizePass(false); | ||||||
|       (void) llvm::createLCSSAPass(); |       (void) llvm::createLCSSAPass(); | ||||||
|       (void) llvm::createLICMPass(); |       (void) llvm::createLICMPass(); | ||||||
|       (void) llvm::createLoadValueNumberingPass(); |  | ||||||
|       (void) llvm::createLoopExtractorPass(); |       (void) llvm::createLoopExtractorPass(); | ||||||
|       (void) llvm::createLoopSimplifyPass(); |       (void) llvm::createLoopSimplifyPass(); | ||||||
|       (void) llvm::createLoopStrengthReducePass(); |       (void) llvm::createLoopStrengthReducePass(); | ||||||
|   | |||||||
| @@ -76,15 +76,6 @@ FunctionPass *createAggressiveDCEPass(); | |||||||
| // | // | ||||||
| FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1); | FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1); | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // GCSE - This pass is designed to be a very quick global transformation that |  | ||||||
| // eliminates global common subexpressions from a function.  It does this by |  | ||||||
| // examining the SSA value graph of the function, instead of doing slow |  | ||||||
| // bit-vector computations. |  | ||||||
| // |  | ||||||
| FunctionPass *createGCSEPass(); |  | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| // | // | ||||||
| // InductionVariableSimplify - Transform induction variables in a program to all | // InductionVariableSimplify - Transform induction variables in a program to all | ||||||
|   | |||||||
| @@ -1,530 +0,0 @@ | |||||||
| //===- LoadValueNumbering.cpp - Load Value #'ing Implementation -*- C++ -*-===// |  | ||||||
| // |  | ||||||
| //                     The LLVM Compiler Infrastructure |  | ||||||
| // |  | ||||||
| // This file is distributed under the University of Illinois Open Source |  | ||||||
| // License. See LICENSE.TXT for details. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // This file implements a value numbering pass that value numbers load and call |  | ||||||
| // instructions.  To do this, it finds lexically identical load instructions, |  | ||||||
| // and uses alias analysis to determine which loads are guaranteed to produce |  | ||||||
| // the same value.  To value number call instructions, it looks for calls to |  | ||||||
| // functions that do not write to memory which do not have intervening |  | ||||||
| // instructions that clobber the memory that is read from. |  | ||||||
| // |  | ||||||
| // This pass builds off of another value numbering pass to implement value |  | ||||||
| // numbering for non-load and non-call instructions.  It uses Alias Analysis so |  | ||||||
| // that it can disambiguate the load instructions.  The more powerful these base |  | ||||||
| // analyses are, the more powerful the resultant value numbering will be. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
|  |  | ||||||
| #include "llvm/Analysis/LoadValueNumbering.h" |  | ||||||
| #include "llvm/Constants.h" |  | ||||||
| #include "llvm/Function.h" |  | ||||||
| #include "llvm/Instructions.h" |  | ||||||
| #include "llvm/Pass.h" |  | ||||||
| #include "llvm/Type.h" |  | ||||||
| #include "llvm/Analysis/ValueNumbering.h" |  | ||||||
| #include "llvm/Analysis/AliasAnalysis.h" |  | ||||||
| #include "llvm/Analysis/Dominators.h" |  | ||||||
| #include "llvm/Support/CFG.h" |  | ||||||
| #include "llvm/Support/Compiler.h" |  | ||||||
| #include "llvm/Target/TargetData.h" |  | ||||||
| #include <set> |  | ||||||
| #include <algorithm> |  | ||||||
| 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. |  | ||||||
|     /// |  | ||||||
|     bool runOnFunction(Function &) { return false; } |  | ||||||
|  |  | ||||||
|     /// getAnalysisUsage - Does not modify anything.  It uses Value Numbering |  | ||||||
|     /// and Alias Analysis. |  | ||||||
|     /// |  | ||||||
|     virtual void getAnalysisUsage(AnalysisUsage &AU) const; |  | ||||||
|  |  | ||||||
|     /// getEqualNumberNodes - Return nodes with the same value number as the |  | ||||||
|     /// specified Value.  This fills in the argument vector with any equal |  | ||||||
|     /// values. |  | ||||||
|     /// |  | ||||||
|     virtual void getEqualNumberNodes(Value *V1, |  | ||||||
|                                      std::vector<Value*> &RetVals) const; |  | ||||||
|  |  | ||||||
|     /// deleteValue - This method should be called whenever an LLVM Value is |  | ||||||
|     /// deleted from the program, for example when an instruction is found to be |  | ||||||
|     /// redundant and is eliminated. |  | ||||||
|     /// |  | ||||||
|     virtual void deleteValue(Value *V) { |  | ||||||
|       getAnalysis<AliasAnalysis>().deleteValue(V); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// copyValue - This method should be used whenever a preexisting value in |  | ||||||
|     /// the program is copied or cloned, introducing a new value.  Note that |  | ||||||
|     /// analysis implementations should tolerate clients that use this method to |  | ||||||
|     /// introduce the same value multiple times: if the analysis already knows |  | ||||||
|     /// about a value, it should ignore the request. |  | ||||||
|     /// |  | ||||||
|     virtual void copyValue(Value *From, Value *To) { |  | ||||||
|       getAnalysis<AliasAnalysis>().copyValue(From, To); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// getCallEqualNumberNodes - Given a call instruction, find other calls |  | ||||||
|     /// that have the same value number. |  | ||||||
|     void getCallEqualNumberNodes(CallInst *CI, |  | ||||||
|                                  std::vector<Value*> &RetVals) const; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| char LoadVN::ID = 0; |  | ||||||
| // Register this pass... |  | ||||||
| static RegisterPass<LoadVN> |  | ||||||
| X("load-vn", "Load Value Numbering", false, true); |  | ||||||
|  |  | ||||||
| // Declare that we implement the ValueNumbering interface |  | ||||||
| static RegisterAnalysisGroup<ValueNumbering> Y(X); |  | ||||||
|  |  | ||||||
| FunctionPass *llvm::createLoadValueNumberingPass() { return new LoadVN(); } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /// getAnalysisUsage - Does not modify anything.  It uses Value Numbering and |  | ||||||
| /// Alias Analysis. |  | ||||||
| /// |  | ||||||
| void LoadVN::getAnalysisUsage(AnalysisUsage &AU) const { |  | ||||||
|   AU.setPreservesAll(); |  | ||||||
|   AU.addRequiredTransitive<AliasAnalysis>(); |  | ||||||
|   AU.addRequired<ValueNumbering>(); |  | ||||||
|   AU.addRequiredTransitive<DominatorTree>(); |  | ||||||
|   AU.addRequiredTransitive<TargetData>(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static bool isPathTransparentTo(BasicBlock *CurBlock, BasicBlock *Dom, |  | ||||||
|                                 Value *Ptr, unsigned Size, AliasAnalysis &AA, |  | ||||||
|                                 std::set<BasicBlock*> &Visited, |  | ||||||
|                                 std::map<BasicBlock*, bool> &TransparentBlocks){ |  | ||||||
|   // If we have already checked out this path, or if we reached our destination, |  | ||||||
|   // stop searching, returning success. |  | ||||||
|   if (CurBlock == Dom || !Visited.insert(CurBlock).second) |  | ||||||
|     return true; |  | ||||||
|  |  | ||||||
|   // Check whether this block is known transparent or not. |  | ||||||
|   std::map<BasicBlock*, bool>::iterator TBI = |  | ||||||
|     TransparentBlocks.find(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)) { |  | ||||||
|       TransparentBlocks.insert(TBI, std::make_pair(CurBlock, false)); |  | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|     TransparentBlocks.insert(TBI, std::make_pair(CurBlock, true)); |  | ||||||
|   } else if (!TBI->second) |  | ||||||
|     // This block is known non-transparent, so that path can't be either. |  | ||||||
|     return false; |  | ||||||
|  |  | ||||||
|   // The current block is known to be transparent.  The entire path is |  | ||||||
|   // transparent if all of the predecessors paths to the parent is also |  | ||||||
|   // transparent to the memory location. |  | ||||||
|   for (pred_iterator PI = pred_begin(CurBlock), E = pred_end(CurBlock); |  | ||||||
|        PI != E; ++PI) |  | ||||||
|     if (!isPathTransparentTo(*PI, Dom, Ptr, Size, AA, Visited, |  | ||||||
|                              TransparentBlocks)) |  | ||||||
|       return false; |  | ||||||
|   return true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// getCallEqualNumberNodes - Given a call instruction, find other calls that |  | ||||||
| /// have the same value number. |  | ||||||
| void LoadVN::getCallEqualNumberNodes(CallInst *CI, |  | ||||||
|                                      std::vector<Value*> &RetVals) const { |  | ||||||
|   Function *CF = CI->getCalledFunction(); |  | ||||||
|   if (CF == 0) return;  // Indirect call. |  | ||||||
|   AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); |  | ||||||
|   AliasAnalysis::ModRefBehavior MRB = AA.getModRefBehavior(CI); |  | ||||||
|   if (MRB != AliasAnalysis::DoesNotAccessMemory && |  | ||||||
|       MRB != AliasAnalysis::OnlyReadsMemory) |  | ||||||
|     return;  // Nothing we can do for now. |  | ||||||
|  |  | ||||||
|   // Scan all of the arguments of the function, looking for one that is not |  | ||||||
|   // global.  In particular, we would prefer to have an argument or instruction |  | ||||||
|   // operand to chase the def-use chains of. |  | ||||||
|   Value *Op = CF; |  | ||||||
|   for (User::op_iterator i = CI->op_begin() + 1, e = CI->op_end(); i != e; ++i) |  | ||||||
|     if (isa<Argument>(*i) || |  | ||||||
|         isa<Instruction>(*i)) { |  | ||||||
|       Op = *i; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   // Identify all lexically identical calls in this function. |  | ||||||
|   std::vector<CallInst*> IdenticalCalls; |  | ||||||
|  |  | ||||||
|   Function *CIFunc = CI->getParent()->getParent(); |  | ||||||
|   for (Value::use_iterator UI = Op->use_begin(), E = Op->use_end(); UI != E; |  | ||||||
|        ++UI) |  | ||||||
|     if (CallInst *C = dyn_cast<CallInst>(*UI)) |  | ||||||
|       if (C->getNumOperands() == CI->getNumOperands() && |  | ||||||
|           C->getOperand(0) == CI->getOperand(0) && |  | ||||||
|           C->getParent()->getParent() == CIFunc && C != CI) { |  | ||||||
|         bool AllOperandsEqual = true; |  | ||||||
|         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; |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|         if (AllOperandsEqual) |  | ||||||
|           IdenticalCalls.push_back(C); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|   if (IdenticalCalls.empty()) return; |  | ||||||
|  |  | ||||||
|   // Eliminate duplicates, which could occur if we chose a value that is passed |  | ||||||
|   // into a call site multiple times. |  | ||||||
|   std::sort(IdenticalCalls.begin(), IdenticalCalls.end()); |  | ||||||
|   IdenticalCalls.erase(std::unique(IdenticalCalls.begin(),IdenticalCalls.end()), |  | ||||||
|                        IdenticalCalls.end()); |  | ||||||
|  |  | ||||||
|   // If the call reads memory, we must make sure that there are no stores |  | ||||||
|   // between the calls in question. |  | ||||||
|   // |  | ||||||
|   // FIXME: This should use mod/ref information.  What we really care about it |  | ||||||
|   // whether an intervening instruction could modify memory that is read, not |  | ||||||
|   // ANY memory. |  | ||||||
|   // |  | ||||||
|   if (MRB == AliasAnalysis::OnlyReadsMemory) { |  | ||||||
|     DominatorTree &DT = getAnalysis<DominatorTree>(); |  | ||||||
|     BasicBlock *CIBB = CI->getParent(); |  | ||||||
|     for (unsigned i = 0; i != IdenticalCalls.size(); ++i) { |  | ||||||
|       CallInst *C = IdenticalCalls[i]; |  | ||||||
|       bool CantEqual = false; |  | ||||||
|  |  | ||||||
|       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 (!DT.dominates(CI, C)) |  | ||||||
|             std::swap(First, Second); |  | ||||||
|  |  | ||||||
|           // Scan the instructions between the calls, checking for stores or |  | ||||||
|           // calls to dangerous functions. |  | ||||||
|           BasicBlock::iterator I = First; |  | ||||||
|           for (++First; I != BasicBlock::iterator(Second); ++I) { |  | ||||||
|             if (isa<StoreInst>(I)) { |  | ||||||
|               // FIXME: We could use mod/ref information to make this much |  | ||||||
|               // better! |  | ||||||
|               CantEqual = true; |  | ||||||
|               break; |  | ||||||
|             } else if (CallInst *CI = dyn_cast<CallInst>(I)) { |  | ||||||
|               if (!AA.onlyReadsMemory(CI)) { |  | ||||||
|                 CantEqual = true; |  | ||||||
|                 break; |  | ||||||
|               } |  | ||||||
|             } else if (I->mayWriteToMemory()) { |  | ||||||
|               CantEqual = true; |  | ||||||
|               break; |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       } else if (DT.dominates(C->getParent(), CIBB)) { |  | ||||||
|         // FIXME: We could implement this, but we don't for now. |  | ||||||
|         CantEqual = true; |  | ||||||
|       } else { |  | ||||||
|         // FIXME: if one doesn't dominate the other, we can't tell yet. |  | ||||||
|         CantEqual = true; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|       if (CantEqual) { |  | ||||||
|         // This call does not produce the same value as the one in the query. |  | ||||||
|         std::swap(IdenticalCalls[i--], IdenticalCalls.back()); |  | ||||||
|         IdenticalCalls.pop_back(); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Any calls that are identical and not destroyed will produce equal values! |  | ||||||
|   for (unsigned i = 0, e = IdenticalCalls.size(); i != e; ++i) |  | ||||||
|     RetVals.push_back(IdenticalCalls[i]); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // getEqualNumberNodes - Return nodes with the same value number as the |  | ||||||
| // specified Value.  This fills in the argument vector with any equal values. |  | ||||||
| // |  | ||||||
| void LoadVN::getEqualNumberNodes(Value *V, |  | ||||||
|                                  std::vector<Value*> &RetVals) const { |  | ||||||
|   // If the alias analysis has any must alias information to share with us, we |  | ||||||
|   // can definitely use it. |  | ||||||
|   if (isa<PointerType>(V->getType())) |  | ||||||
|     getAnalysis<AliasAnalysis>().getMustAliases(V, RetVals); |  | ||||||
|  |  | ||||||
|   if (!isa<LoadInst>(V)) { |  | ||||||
|     if (CallInst *CI = dyn_cast<CallInst>(V)) |  | ||||||
|       getCallEqualNumberNodes(CI, RetVals); |  | ||||||
|  |  | ||||||
|     // Not a load instruction?  Just chain to the base value numbering |  | ||||||
|     // implementation to satisfy the request... |  | ||||||
|     assert(&getAnalysis<ValueNumbering>() != (ValueNumbering*)this && |  | ||||||
|            "getAnalysis() returned this!"); |  | ||||||
|  |  | ||||||
|     return getAnalysis<ValueNumbering>().getEqualNumberNodes(V, RetVals); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Volatile loads cannot be replaced with the value of other loads. |  | ||||||
|   LoadInst *LI = cast<LoadInst>(V); |  | ||||||
|   if (LI->isVolatile()) |  | ||||||
|     return getAnalysis<ValueNumbering>().getEqualNumberNodes(V, RetVals); |  | ||||||
|  |  | ||||||
|   Value *LoadPtr = LI->getOperand(0); |  | ||||||
|   BasicBlock *LoadBB = LI->getParent(); |  | ||||||
|   Function *F = LoadBB->getParent(); |  | ||||||
|  |  | ||||||
|   // Find out how many bytes of memory are loaded by the load instruction... |  | ||||||
|   unsigned LoadSize = getAnalysis<TargetData>().getTypeStoreSize(LI->getType()); |  | ||||||
|   AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); |  | ||||||
|  |  | ||||||
|   // Figure out if the load is invalidated from the entry of the block it is in |  | ||||||
|   // until the actual instruction.  This scans the block backwards from LI.  If |  | ||||||
|   // we see any candidate load or store instructions, then we know that the |  | ||||||
|   // candidates have the same value # as LI. |  | ||||||
|   bool LoadInvalidatedInBBBefore = false; |  | ||||||
|   for (BasicBlock::iterator I = LI; I != LoadBB->begin(); ) { |  | ||||||
|     --I; |  | ||||||
|     if (I == LoadPtr) { |  | ||||||
|       // If we run into an allocation of the value being loaded, then the |  | ||||||
|       // contents are not initialized. |  | ||||||
|       if (isa<AllocationInst>(I)) |  | ||||||
|         RetVals.push_back(UndefValue::get(LI->getType())); |  | ||||||
|  |  | ||||||
|       // Otherwise, since this is the definition of what we are loading, this |  | ||||||
|       // loaded value cannot occur before this block. |  | ||||||
|       LoadInvalidatedInBBBefore = true; |  | ||||||
|       break; |  | ||||||
|     } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) { |  | ||||||
|       // If this instruction is a candidate load before LI, we know there are no |  | ||||||
|       // invalidating instructions between it and LI, so they have the same |  | ||||||
|       // value number. |  | ||||||
|       if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) |  | ||||||
|         RetVals.push_back(I); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) { |  | ||||||
|       // If the invalidating instruction is a store, and its in our candidate |  | ||||||
|       // set, then we can do store-load forwarding: the load has the same value |  | ||||||
|       // # as the stored value. |  | ||||||
|       if (StoreInst *SI = dyn_cast<StoreInst>(I)) |  | ||||||
|         if (SI->getOperand(1) == LoadPtr) |  | ||||||
|           RetVals.push_back(I->getOperand(0)); |  | ||||||
|  |  | ||||||
|       LoadInvalidatedInBBBefore = true; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Figure out if the load is invalidated between the load and the exit of the |  | ||||||
|   // block it is defined in.  While we are scanning the current basic block, if |  | ||||||
|   // we see any candidate loads, then we know they have the same value # as LI. |  | ||||||
|   // |  | ||||||
|   bool LoadInvalidatedInBBAfter = false; |  | ||||||
|   { |  | ||||||
|     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<LoadInst>(I) && cast<LoadInst>(I)->getOperand(0) == LoadPtr) |  | ||||||
|         RetVals.push_back(I); |  | ||||||
|  |  | ||||||
|       if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) { |  | ||||||
|         LoadInvalidatedInBBAfter = true; |  | ||||||
|         break; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // If the pointer is clobbered on entry and on exit to the function, there is |  | ||||||
|   // no need to do any global analysis at all. |  | ||||||
|   if (LoadInvalidatedInBBBefore && LoadInvalidatedInBBAfter) |  | ||||||
|     return; |  | ||||||
|  |  | ||||||
|   // Now that we know the value is not neccesarily killed on entry or exit to |  | ||||||
|   // the BB, find out how many load and store instructions (to this location) |  | ||||||
|   // live in each BB in the function. |  | ||||||
|   // |  | ||||||
|   std::map<BasicBlock*, unsigned>  CandidateLoads; |  | ||||||
|   std::set<BasicBlock*> CandidateStores; |  | ||||||
|  |  | ||||||
|   for (Value::use_iterator UI = LoadPtr->use_begin(), UE = LoadPtr->use_end(); |  | ||||||
|        UI != UE; ++UI) |  | ||||||
|     if (LoadInst *Cand = dyn_cast<LoadInst>(*UI)) {// Is a load of source? |  | ||||||
|       if (Cand->getParent()->getParent() == F &&   // In the same function? |  | ||||||
|           // Not in LI's block? |  | ||||||
|           Cand->getParent() != LoadBB && !Cand->isVolatile()) |  | ||||||
|         ++CandidateLoads[Cand->getParent()];       // Got one. |  | ||||||
|     } else if (StoreInst *Cand = dyn_cast<StoreInst>(*UI)) { |  | ||||||
|       if (Cand->getParent()->getParent() == F && !Cand->isVolatile() && |  | ||||||
|           Cand->getOperand(1) == LoadPtr) // It's a store THROUGH the ptr. |  | ||||||
|         CandidateStores.insert(Cand->getParent()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   // Get dominators. |  | ||||||
|   DominatorTree &DT = getAnalysis<DominatorTree>(); |  | ||||||
|  |  | ||||||
|   // 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 |  | ||||||
|   // boolean is set to false, if it's not it is set to true.  If we don't know |  | ||||||
|   // yet, the entry is not in the map. |  | ||||||
|   std::map<BasicBlock*, bool> TransparentBlocks; |  | ||||||
|  |  | ||||||
|   // Loop over all of the basic blocks that also load the value.  If the value |  | ||||||
|   // is live across the CFG from the source to destination blocks, and if the |  | ||||||
|   // value is not invalidated in either the source or destination blocks, add it |  | ||||||
|   // to the equivalence sets. |  | ||||||
|   for (std::map<BasicBlock*, unsigned>::iterator |  | ||||||
|          I = CandidateLoads.begin(), E = CandidateLoads.end(); I != E; ++I) { |  | ||||||
|     bool CantEqual = false; |  | ||||||
|  |  | ||||||
|     // Right now we only can handle cases where one load dominates the other. |  | ||||||
|     // FIXME: generalize this! |  | ||||||
|     BasicBlock *BB1 = I->first, *BB2 = LoadBB; |  | ||||||
|     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 (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. |  | ||||||
|       if (LoadInvalidatedInBBAfter) |  | ||||||
|         CantEqual = true; |  | ||||||
|     } else { |  | ||||||
|       // None of these loads can VN the same. |  | ||||||
|       CantEqual = true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (!CantEqual) { |  | ||||||
|       // Ok, at this point, we know that BB1 dominates BB2, and that there is |  | ||||||
|       // nothing in the LI block that kills the loaded value.  Check to see if |  | ||||||
|       // the value is live across the CFG. |  | ||||||
|       std::set<BasicBlock*> Visited; |  | ||||||
|       for (pred_iterator PI = pred_begin(BB2), E = pred_end(BB2); PI!=E; ++PI) |  | ||||||
|         if (!isPathTransparentTo(*PI, BB1, LoadPtr, LoadSize, AA, |  | ||||||
|                                  Visited, TransparentBlocks)) { |  | ||||||
|           // None of these loads can VN the same. |  | ||||||
|           CantEqual = true; |  | ||||||
|           break; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // If the loads can equal so far, scan the basic block that contains the |  | ||||||
|     // loads under consideration to see if they are invalidated in the block. |  | ||||||
|     // For any loads that are not invalidated, add them to the equivalence |  | ||||||
|     // set! |  | ||||||
|     if (!CantEqual) { |  | ||||||
|       unsigned NumLoads = I->second; |  | ||||||
|       if (BB1 == LoadBB) { |  | ||||||
|         // If LI dominates the block in question, check to see if any of the |  | ||||||
|         // loads in this block are invalidated before they are reached. |  | ||||||
|         for (BasicBlock::iterator BBI = I->first->begin(); ; ++BBI) { |  | ||||||
|           if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) { |  | ||||||
|             if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) { |  | ||||||
|               // The load is in the set! |  | ||||||
|               RetVals.push_back(BBI); |  | ||||||
|               if (--NumLoads == 0) break;  // Found last load to check. |  | ||||||
|             } |  | ||||||
|           } else if (AA.getModRefInfo(BBI, LoadPtr, LoadSize) |  | ||||||
|                                 & AliasAnalysis::Mod) { |  | ||||||
|             // If there is a modifying instruction, nothing below it will value |  | ||||||
|             // # the same. |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         // If the block dominates LI, make sure that the loads in the block are |  | ||||||
|         // not invalidated before the block ends. |  | ||||||
|         BasicBlock::iterator BBI = I->first->end(); |  | ||||||
|         while (1) { |  | ||||||
|           --BBI; |  | ||||||
|           if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) { |  | ||||||
|             if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) { |  | ||||||
|               // The load is the same as this load! |  | ||||||
|               RetVals.push_back(BBI); |  | ||||||
|               if (--NumLoads == 0) break;  // Found all of the laods. |  | ||||||
|             } |  | ||||||
|           } else if (AA.getModRefInfo(BBI, LoadPtr, LoadSize) |  | ||||||
|                              & AliasAnalysis::Mod) { |  | ||||||
|             // If there is a modifying instruction, nothing above it will value |  | ||||||
|             // # the same. |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Handle candidate stores.  If the loaded location is clobbered on entrance |  | ||||||
|   // to the LoadBB, no store outside of the LoadBB can value number equal, so |  | ||||||
|   // quick exit. |  | ||||||
|   if (LoadInvalidatedInBBBefore) |  | ||||||
|     return; |  | ||||||
|  |  | ||||||
|   // Stores in the load-bb are handled above. |  | ||||||
|   CandidateStores.erase(LoadBB); |  | ||||||
|  |  | ||||||
|   for (std::set<BasicBlock*>::iterator I = CandidateStores.begin(), |  | ||||||
|          E = CandidateStores.end(); I != E; ++I) |  | ||||||
|     if (DT.dominates(*I, LoadBB)) { |  | ||||||
|       BasicBlock *StoreBB = *I; |  | ||||||
|  |  | ||||||
|       // Check to see if the path from the store to the load is transparent |  | ||||||
|       // w.r.t. the memory location. |  | ||||||
|       bool CantEqual = false; |  | ||||||
|       std::set<BasicBlock*> Visited; |  | ||||||
|       for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); |  | ||||||
|            PI != E; ++PI) |  | ||||||
|         if (!isPathTransparentTo(*PI, StoreBB, LoadPtr, LoadSize, AA, |  | ||||||
|                                  Visited, TransparentBlocks)) { |  | ||||||
|           // None of these stores can VN the same. |  | ||||||
|           CantEqual = true; |  | ||||||
|           break; |  | ||||||
|         } |  | ||||||
|       Visited.clear(); |  | ||||||
|       if (!CantEqual) { |  | ||||||
|         // Okay, the path from the store block to the load block is clear, and |  | ||||||
|         // we know that there are no invalidating instructions from the start |  | ||||||
|         // of the load block to the load itself.  Now we just scan the store |  | ||||||
|         // block. |  | ||||||
|  |  | ||||||
|         BasicBlock::iterator BBI = StoreBB->end(); |  | ||||||
|         while (1) { |  | ||||||
|           assert(BBI != StoreBB->begin() && |  | ||||||
|                  "There is a store in this block of the pointer, but the store" |  | ||||||
|                  " doesn't mod the address being stored to??  Must be a bug in" |  | ||||||
|                  " the alias analysis implementation!"); |  | ||||||
|           --BBI; |  | ||||||
|           if (AA.getModRefInfo(BBI, LoadPtr, LoadSize) & AliasAnalysis::Mod) { |  | ||||||
|             // If the invalidating instruction is one of the candidates, |  | ||||||
|             // then it provides the value the load loads. |  | ||||||
|             if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) |  | ||||||
|               if (SI->getOperand(1) == LoadPtr) |  | ||||||
|                 RetVals.push_back(SI->getOperand(0)); |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,286 +0,0 @@ | |||||||
| //===- ValueNumbering.cpp - Value #'ing Implementation ----------*- C++ -*-===// |  | ||||||
| // |  | ||||||
| //                     The LLVM Compiler Infrastructure |  | ||||||
| // |  | ||||||
| // This file is distributed under the University of Illinois Open Source |  | ||||||
| // License. See LICENSE.TXT for details. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // This file implements the non-abstract Value Numbering methods as well as a |  | ||||||
| // default implementation for the analysis group. |  | ||||||
| // |  | ||||||
| // The ValueNumbering analysis pass is mostly deprecated. It is only used by the |  | ||||||
| // Global Common Subexpression Elimination pass, which is deprecated by the |  | ||||||
| // Global Value Numbering pass (which does its value numbering on its own). |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
|  |  | ||||||
| #include "llvm/Analysis/Passes.h" |  | ||||||
| #include "llvm/Analysis/ValueNumbering.h" |  | ||||||
| #include "llvm/Support/InstVisitor.h" |  | ||||||
| #include "llvm/BasicBlock.h" |  | ||||||
| #include "llvm/Instructions.h" |  | ||||||
| #include "llvm/Pass.h" |  | ||||||
| #include "llvm/Type.h" |  | ||||||
| #include "llvm/Support/Compiler.h" |  | ||||||
| using namespace llvm; |  | ||||||
|  |  | ||||||
| char ValueNumbering::ID = 0; |  | ||||||
| // Register the ValueNumbering interface, providing a nice name to refer to. |  | ||||||
| static RegisterAnalysisGroup<ValueNumbering> V("Value Numbering"); |  | ||||||
|  |  | ||||||
| /// ValueNumbering destructor: DO NOT move this to the header file for |  | ||||||
| /// ValueNumbering or else clients of the ValueNumbering class may not depend on |  | ||||||
| /// the ValueNumbering.o file in the current .a file, causing alias analysis |  | ||||||
| /// support to not be included in the tool correctly! |  | ||||||
| /// |  | ||||||
| ValueNumbering::~ValueNumbering() {} |  | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // Basic ValueNumbering Pass Implementation |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // Because of the way .a files work, the implementation of the BasicVN class |  | ||||||
| // MUST be in the ValueNumbering file itself, or else we run the risk of |  | ||||||
| // ValueNumbering being used, but the default implementation not being linked |  | ||||||
| // into the tool that uses it.  As such, we register and implement the class |  | ||||||
| // here. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| namespace { |  | ||||||
|   /// BasicVN - This class is the default implementation of the ValueNumbering |  | ||||||
|   /// interface.  It walks the SSA def-use chains to trivially identify |  | ||||||
|   /// lexically identical expressions.  This does not require any ahead of time |  | ||||||
|   /// analysis, so it is a very fast default implementation. |  | ||||||
|   /// |  | ||||||
|   struct VISIBILITY_HIDDEN BasicVN  |  | ||||||
|       : public ImmutablePass, public ValueNumbering { |  | ||||||
|     static char ID; // Class identification, replacement for typeinfo |  | ||||||
|     BasicVN() : ImmutablePass((intptr_t)&ID) {} |  | ||||||
|  |  | ||||||
|     /// getEqualNumberNodes - Return nodes with the same value number as the |  | ||||||
|     /// specified Value.  This fills in the argument vector with any equal |  | ||||||
|     /// values. |  | ||||||
|     /// |  | ||||||
|     /// This is where our implementation is. |  | ||||||
|     /// |  | ||||||
|     virtual void getEqualNumberNodes(Value *V1, |  | ||||||
|                                      std::vector<Value*> &RetVals) const; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| char BasicVN::ID = 0; |  | ||||||
| // Register this pass... |  | ||||||
| static RegisterPass<BasicVN> |  | ||||||
| X("basicvn", "Basic Value Numbering (default GVN impl)", false, true); |  | ||||||
|  |  | ||||||
| // Declare that we implement the ValueNumbering interface |  | ||||||
| static RegisterAnalysisGroup<ValueNumbering, true> Y(X); |  | ||||||
|  |  | ||||||
| namespace { |  | ||||||
|   /// BVNImpl - Implement BasicVN in terms of a visitor class that |  | ||||||
|   /// handles the different types of instructions as appropriate. |  | ||||||
|   /// |  | ||||||
|   struct VISIBILITY_HIDDEN BVNImpl : public InstVisitor<BVNImpl> { |  | ||||||
|     std::vector<Value*> &RetVals; |  | ||||||
|     explicit BVNImpl(std::vector<Value*> &RV) : RetVals(RV) {} |  | ||||||
|  |  | ||||||
|     void visitCastInst(CastInst &I); |  | ||||||
|     void visitGetElementPtrInst(GetElementPtrInst &I); |  | ||||||
|     void visitCmpInst(CmpInst &I); |  | ||||||
|  |  | ||||||
|     void handleBinaryInst(Instruction &I); |  | ||||||
|     void visitBinaryOperator(Instruction &I)     { handleBinaryInst(I); } |  | ||||||
|     void visitShiftInst(Instruction &I)          { handleBinaryInst(I); } |  | ||||||
|     void visitExtractElementInst(Instruction &I) { handleBinaryInst(I); } |  | ||||||
|  |  | ||||||
|     void handleTernaryInst(Instruction &I); |  | ||||||
|     void visitSelectInst(Instruction &I)         { handleTernaryInst(I); } |  | ||||||
|     void visitInsertElementInst(Instruction &I)  { handleTernaryInst(I); } |  | ||||||
|     void visitShuffleVectorInst(Instruction &I)  { handleTernaryInst(I); } |  | ||||||
|     void visitInstruction(Instruction &) { |  | ||||||
|       // Cannot value number calls or terminator instructions. |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ImmutablePass *llvm::createBasicVNPass() { return new BasicVN(); } |  | ||||||
|  |  | ||||||
| // getEqualNumberNodes - Return nodes with the same value number as the |  | ||||||
| // specified Value.  This fills in the argument vector with any equal values. |  | ||||||
| // |  | ||||||
| void BasicVN::getEqualNumberNodes(Value *V, std::vector<Value*> &RetVals) const{ |  | ||||||
|   assert(V->getType() != Type::VoidTy && |  | ||||||
|          "Can only value number non-void values!"); |  | ||||||
|   // We can only handle the case where I is an instruction! |  | ||||||
|   if (Instruction *I = dyn_cast<Instruction>(V)) |  | ||||||
|     BVNImpl(RetVals).visit(I); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void BVNImpl::visitCastInst(CastInst &CI) { |  | ||||||
|   Instruction &I = (Instruction&)CI; |  | ||||||
|   Value *Op = I.getOperand(0); |  | ||||||
|   Function *F = I.getParent()->getParent(); |  | ||||||
|  |  | ||||||
|   for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end(); |  | ||||||
|        UI != UE; ++UI) |  | ||||||
|     if (CastInst *Other = dyn_cast<CastInst>(*UI)) |  | ||||||
|       // Check that the opcode is the same |  | ||||||
|       if (Other->getOpcode() == Instruction::CastOps(I.getOpcode()) && |  | ||||||
|           // Check that the destination types are the same |  | ||||||
|           Other->getType() == I.getType() && |  | ||||||
|           // Is it embedded in the same function?  (This could be false if LHS |  | ||||||
|           // is a constant or global!) |  | ||||||
|           Other->getParent()->getParent() == F && |  | ||||||
|           // Check to see if this new cast is not I. |  | ||||||
|           Other != &I) { |  | ||||||
|         // These instructions are identical.  Add to list... |  | ||||||
|         RetVals.push_back(Other); |  | ||||||
|       } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void  BVNImpl::visitCmpInst(CmpInst &CI1) { |  | ||||||
|   Value *LHS = CI1.getOperand(0); |  | ||||||
|   for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end(); |  | ||||||
|        UI != UE; ++UI) |  | ||||||
|     if (CmpInst *CI2 = dyn_cast<CmpInst>(*UI)) |  | ||||||
|       // Check to see if this compare instruction is not CI, but same opcode, |  | ||||||
|       // same predicate, and in the same function. |  | ||||||
|       if (CI2 != &CI1 && CI2->getOpcode() == CI1.getOpcode() && |  | ||||||
|           CI2->getPredicate() == CI1.getPredicate() && |  | ||||||
|           CI2->getParent()->getParent() == CI1.getParent()->getParent()) |  | ||||||
|         // If the operands are the same |  | ||||||
|         if ((CI2->getOperand(0) == CI1.getOperand(0) && |  | ||||||
|             CI2->getOperand(1) == CI1.getOperand(1)) || |  | ||||||
|             // Or the compare is commutative and the operands are reversed  |  | ||||||
|             (CI1.isCommutative() &&  |  | ||||||
|              CI2->getOperand(0) == CI1.getOperand(1) && |  | ||||||
|              CI2->getOperand(1) == CI1.getOperand(0))) |  | ||||||
|           // Then the instructiosn are identical, add to list. |  | ||||||
|           RetVals.push_back(CI2); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // isIdenticalBinaryInst - Return true if the two binary instructions are |  | ||||||
| // identical. |  | ||||||
| // |  | ||||||
| static inline bool isIdenticalBinaryInst(const Instruction &I1, |  | ||||||
|                                          const Instruction *I2) { |  | ||||||
|   // Is it embedded in the same function?  (This could be false if LHS |  | ||||||
|   // is a constant or global!) |  | ||||||
|   if (I1.getOpcode() != I2->getOpcode() || |  | ||||||
|       I1.getParent()->getParent() != I2->getParent()->getParent()) |  | ||||||
|     return false; |  | ||||||
|  |  | ||||||
|   // If they are CmpInst instructions, check their predicates |  | ||||||
|   if (CmpInst *CI1 = dyn_cast<CmpInst>(&const_cast<Instruction&>(I1))) |  | ||||||
|     if (CI1->getPredicate() != cast<CmpInst>(I2)->getPredicate()) |  | ||||||
|       return false; |  | ||||||
|  |  | ||||||
|   // They are identical if both operands are the same! |  | ||||||
|   if (I1.getOperand(0) == I2->getOperand(0) && |  | ||||||
|       I1.getOperand(1) == I2->getOperand(1)) |  | ||||||
|     return true; |  | ||||||
|  |  | ||||||
|   // If the instruction is commutative, the instruction can match if the |  | ||||||
|   // operands are swapped! |  | ||||||
|   // |  | ||||||
|   if ((I1.getOperand(0) == I2->getOperand(1) && |  | ||||||
|        I1.getOperand(1) == I2->getOperand(0)) && |  | ||||||
|       I1.isCommutative()) |  | ||||||
|     return true; |  | ||||||
|  |  | ||||||
|   return false; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // isIdenticalTernaryInst - Return true if the two ternary instructions are |  | ||||||
| // identical. |  | ||||||
| // |  | ||||||
| static inline bool isIdenticalTernaryInst(const Instruction &I1, |  | ||||||
|                                           const Instruction *I2) { |  | ||||||
|   // Is it embedded in the same function?  (This could be false if LHS |  | ||||||
|   // is a constant or global!) |  | ||||||
|   if (I1.getParent()->getParent() != I2->getParent()->getParent()) |  | ||||||
|     return false; |  | ||||||
|    |  | ||||||
|   // They are identical if all operands are the same! |  | ||||||
|   return I1.getOperand(0) == I2->getOperand(0) && |  | ||||||
|          I1.getOperand(1) == I2->getOperand(1) && |  | ||||||
|          I1.getOperand(2) == I2->getOperand(2); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void BVNImpl::handleBinaryInst(Instruction &I) { |  | ||||||
|   Value *LHS = I.getOperand(0); |  | ||||||
|  |  | ||||||
|   for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end(); |  | ||||||
|        UI != UE; ++UI) |  | ||||||
|     if (Instruction *Other = dyn_cast<Instruction>(*UI)) |  | ||||||
|       // Check to see if this new binary operator is not I, but same operand... |  | ||||||
|       if (Other != &I && isIdenticalBinaryInst(I, Other)) { |  | ||||||
|         // These instructions are identical.  Handle the situation. |  | ||||||
|         RetVals.push_back(Other); |  | ||||||
|       } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IdenticalComplexInst - Return true if the two instructions are the same, by |  | ||||||
| // using a brute force comparison.  This is useful for instructions with an |  | ||||||
| // arbitrary number of arguments. |  | ||||||
| // |  | ||||||
| static inline bool IdenticalComplexInst(const Instruction *I1, |  | ||||||
|                                         const Instruction *I2) { |  | ||||||
|   assert(I1->getOpcode() == I2->getOpcode()); |  | ||||||
|   // Equal if they are in the same function... |  | ||||||
|   return I1->getParent()->getParent() == I2->getParent()->getParent() && |  | ||||||
|     // And return the same type... |  | ||||||
|     I1->getType() == I2->getType() && |  | ||||||
|     // And have the same number of operands... |  | ||||||
|     I1->getNumOperands() == I2->getNumOperands() && |  | ||||||
|     // And all of the operands are equal. |  | ||||||
|     std::equal(I1->op_begin(), I1->op_end(), I2->op_begin()); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void BVNImpl::visitGetElementPtrInst(GetElementPtrInst &I) { |  | ||||||
|   Value *Op = I.getOperand(0); |  | ||||||
|  |  | ||||||
|   // Try to pick a local operand if possible instead of a constant or a global |  | ||||||
|   // that might have a lot of uses. |  | ||||||
|   for (User::op_iterator i = I.op_begin() + 1, e = I.op_end(); i != e; ++i) |  | ||||||
|     if (isa<Instruction>(*i) || isa<Argument>(*i)) { |  | ||||||
|       Op = *i; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end(); |  | ||||||
|        UI != UE; ++UI) |  | ||||||
|     if (GetElementPtrInst *Other = dyn_cast<GetElementPtrInst>(*UI)) |  | ||||||
|       // Check to see if this new getelementptr is not I, but same operand... |  | ||||||
|       if (Other != &I && IdenticalComplexInst(&I, Other)) { |  | ||||||
|         // These instructions are identical.  Handle the situation. |  | ||||||
|         RetVals.push_back(Other); |  | ||||||
|       } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void BVNImpl::handleTernaryInst(Instruction &I) { |  | ||||||
|   Value *Op0 = I.getOperand(0); |  | ||||||
|   Instruction *OtherInst; |  | ||||||
|    |  | ||||||
|   for (Value::use_iterator UI = Op0->use_begin(), UE = Op0->use_end(); |  | ||||||
|        UI != UE; ++UI) |  | ||||||
|     if ((OtherInst = dyn_cast<Instruction>(*UI)) &&  |  | ||||||
|         OtherInst->getOpcode() == I.getOpcode()) { |  | ||||||
|       // Check to see if this new select is not I, but has the same operands. |  | ||||||
|       if (OtherInst != &I && isIdenticalTernaryInst(I, OtherInst)) { |  | ||||||
|         // These instructions are identical.  Handle the situation. |  | ||||||
|         RetVals.push_back(OtherInst); |  | ||||||
|       } |  | ||||||
|          |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // Ensure that users of ValueNumbering.h will link with this file |  | ||||||
| DEFINING_FILE_FOR(BasicValueNumbering) |  | ||||||
| @@ -1,205 +0,0 @@ | |||||||
| //===-- GCSE.cpp - SSA-based Global Common Subexpression Elimination ------===// |  | ||||||
| // |  | ||||||
| //                     The LLVM Compiler Infrastructure |  | ||||||
| // |  | ||||||
| // This file is distributed under the University of Illinois Open Source |  | ||||||
| // License. See LICENSE.TXT for details. |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| // |  | ||||||
| // This pass is designed to be a very quick global transformation that |  | ||||||
| // eliminates global common subexpressions from a function.  It does this by |  | ||||||
| // using an existing value numbering analysis pass to identify the common |  | ||||||
| // subexpressions, eliminating them when possible. |  | ||||||
| // |  | ||||||
| // This pass is deprecated by the Global Value Numbering pass (which does a |  | ||||||
| // better job with its own value numbering). |  | ||||||
| // |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
|  |  | ||||||
| #define DEBUG_TYPE "gcse" |  | ||||||
| #include "llvm/Transforms/Scalar.h" |  | ||||||
| #include "llvm/Instructions.h" |  | ||||||
| #include "llvm/Function.h" |  | ||||||
| #include "llvm/Type.h" |  | ||||||
| #include "llvm/Analysis/ConstantFolding.h" |  | ||||||
| #include "llvm/Analysis/Dominators.h" |  | ||||||
| #include "llvm/Analysis/ValueNumbering.h" |  | ||||||
| #include "llvm/ADT/DepthFirstIterator.h" |  | ||||||
| #include "llvm/ADT/Statistic.h" |  | ||||||
| #include "llvm/Support/Compiler.h" |  | ||||||
| #include <algorithm> |  | ||||||
| using namespace llvm; |  | ||||||
|  |  | ||||||
| STATISTIC(NumInstRemoved, "Number of instructions removed"); |  | ||||||
| STATISTIC(NumLoadRemoved, "Number of loads removed"); |  | ||||||
| STATISTIC(NumCallRemoved, "Number of calls removed"); |  | ||||||
| STATISTIC(NumNonInsts   , "Number of instructions removed due " |  | ||||||
|                           "to non-instruction values"); |  | ||||||
| STATISTIC(NumArgsRepl   , "Number of function arguments replaced " |  | ||||||
|                           "with constant values"); |  | ||||||
| namespace { |  | ||||||
|   struct VISIBILITY_HIDDEN GCSE : public FunctionPass { |  | ||||||
|     static char ID; // Pass identification, replacement for typeid |  | ||||||
|     GCSE() : FunctionPass((intptr_t)&ID) {} |  | ||||||
|  |  | ||||||
|     virtual bool runOnFunction(Function &F); |  | ||||||
|  |  | ||||||
|   private: |  | ||||||
|     void ReplaceInstructionWith(Instruction *I, Value *V); |  | ||||||
|  |  | ||||||
|     // This transformation requires dominator and immediate dominator info |  | ||||||
|     virtual void getAnalysisUsage(AnalysisUsage &AU) const { |  | ||||||
|       AU.setPreservesCFG(); |  | ||||||
|       AU.addRequired<DominatorTree>(); |  | ||||||
|       AU.addRequired<ValueNumbering>(); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| char GCSE::ID = 0; |  | ||||||
| static RegisterPass<GCSE> |  | ||||||
| X("gcse", "Global Common Subexpression Elimination"); |  | ||||||
|  |  | ||||||
| // createGCSEPass - The public interface to this file... |  | ||||||
| FunctionPass *llvm::createGCSEPass() { return new GCSE(); } |  | ||||||
|  |  | ||||||
| // GCSE::runOnFunction - This is the main transformation entry point for a |  | ||||||
| // function. |  | ||||||
| // |  | ||||||
| bool GCSE::runOnFunction(Function &F) { |  | ||||||
|   bool Changed = false; |  | ||||||
|  |  | ||||||
|   // Get pointers to the analysis results that we will be using... |  | ||||||
|   DominatorTree &DT = getAnalysis<DominatorTree>(); |  | ||||||
|   ValueNumbering &VN = getAnalysis<ValueNumbering>(); |  | ||||||
|  |  | ||||||
|   std::vector<Value*> EqualValues; |  | ||||||
|  |  | ||||||
|   // Check for value numbers of arguments.  If the value numbering |  | ||||||
|   // implementation can prove that an incoming argument is a constant or global |  | ||||||
|   // value address, substitute it, making the argument dead. |  | ||||||
|   for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); AI != E;++AI) |  | ||||||
|     if (!AI->use_empty()) { |  | ||||||
|       VN.getEqualNumberNodes(AI, EqualValues); |  | ||||||
|       if (!EqualValues.empty()) { |  | ||||||
|         for (unsigned i = 0, e = EqualValues.size(); i != e; ++i) |  | ||||||
|           if (isa<Constant>(EqualValues[i])) { |  | ||||||
|             AI->replaceAllUsesWith(EqualValues[i]); |  | ||||||
|             ++NumArgsRepl; |  | ||||||
|             Changed = true; |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         EqualValues.clear(); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   // Traverse the CFG of the function in dominator order, so that we see each |  | ||||||
|   // instruction after we see its operands. |  | ||||||
|   for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()), |  | ||||||
|          E = df_end(DT.getRootNode()); DI != E; ++DI) { |  | ||||||
|     BasicBlock *BB = DI->getBlock(); |  | ||||||
|  |  | ||||||
|     // Remember which instructions we've seen in this basic block as we scan. |  | ||||||
|     std::set<Instruction*> BlockInsts; |  | ||||||
|  |  | ||||||
|     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { |  | ||||||
|       Instruction *Inst = I++; |  | ||||||
|  |  | ||||||
|       if (Constant *C = ConstantFoldInstruction(Inst)) { |  | ||||||
|         ReplaceInstructionWith(Inst, C); |  | ||||||
|       } else if (Inst->getType() != Type::VoidTy) { |  | ||||||
|         // If this instruction computes a value, try to fold together common |  | ||||||
|         // instructions that compute it. |  | ||||||
|         // |  | ||||||
|         VN.getEqualNumberNodes(Inst, EqualValues); |  | ||||||
|  |  | ||||||
|         // If this instruction computes a value that is already computed |  | ||||||
|         // elsewhere, try to recycle the old value. |  | ||||||
|         if (!EqualValues.empty()) { |  | ||||||
|           if (Inst == &*BB->begin()) |  | ||||||
|             I = BB->end(); |  | ||||||
|           else { |  | ||||||
|             I = Inst; --I; |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|           // First check to see if we were able to value number this instruction |  | ||||||
|           // to a non-instruction value.  If so, prefer that value over other |  | ||||||
|           // instructions which may compute the same thing. |  | ||||||
|           for (unsigned i = 0, e = EqualValues.size(); i != e; ++i) |  | ||||||
|             if (!isa<Instruction>(EqualValues[i])) { |  | ||||||
|               ++NumNonInsts;      // Keep track of # of insts repl with values |  | ||||||
|  |  | ||||||
|               // Change all users of Inst to use the replacement and remove it |  | ||||||
|               // from the program. |  | ||||||
|               ReplaceInstructionWith(Inst, EqualValues[i]); |  | ||||||
|               Inst = 0; |  | ||||||
|               EqualValues.clear();  // don't enter the next loop |  | ||||||
|               break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|           // If there were no non-instruction values that this instruction |  | ||||||
|           // produces, find a dominating instruction that produces the same |  | ||||||
|           // value.  If we find one, use it's value instead of ours. |  | ||||||
|           for (unsigned i = 0, e = EqualValues.size(); i != e; ++i) { |  | ||||||
|             Instruction *OtherI = cast<Instruction>(EqualValues[i]); |  | ||||||
|             bool Dominates = false; |  | ||||||
|             if (OtherI->getParent() == BB) |  | ||||||
|               Dominates = BlockInsts.count(OtherI); |  | ||||||
|             else |  | ||||||
|               Dominates = DT.dominates(OtherI->getParent(), BB); |  | ||||||
|  |  | ||||||
|             if (Dominates) { |  | ||||||
|               // Okay, we found an instruction with the same value as this one |  | ||||||
|               // and that dominates this one.  Replace this instruction with the |  | ||||||
|               // specified one. |  | ||||||
|               ReplaceInstructionWith(Inst, OtherI); |  | ||||||
|               Inst = 0; |  | ||||||
|               break; |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|           EqualValues.clear(); |  | ||||||
|  |  | ||||||
|           if (Inst) { |  | ||||||
|             I = Inst; ++I;             // Deleted no instructions |  | ||||||
|           } else if (I == BB->end()) { // Deleted first instruction |  | ||||||
|             I = BB->begin(); |  | ||||||
|           } else {                     // Deleted inst in middle of block. |  | ||||||
|             ++I; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (Inst) |  | ||||||
|           BlockInsts.insert(Inst); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // When the worklist is empty, return whether or not we changed anything... |  | ||||||
|   return Changed; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GCSE::ReplaceInstructionWith(Instruction *I, Value *V) { |  | ||||||
|   if (isa<LoadInst>(I)) |  | ||||||
|     ++NumLoadRemoved; // Keep track of loads eliminated |  | ||||||
|   if (isa<CallInst>(I)) |  | ||||||
|     ++NumCallRemoved; // Keep track of calls eliminated |  | ||||||
|   ++NumInstRemoved;   // Keep track of number of insts eliminated |  | ||||||
|  |  | ||||||
|   // Update value numbering |  | ||||||
|   getAnalysis<ValueNumbering>().deleteValue(I); |  | ||||||
|  |  | ||||||
|   I->replaceAllUsesWith(V); |  | ||||||
|  |  | ||||||
|   if (InvokeInst *II = dyn_cast<InvokeInst>(I)) { |  | ||||||
|     // Removing an invoke instruction requires adding a branch to the normal |  | ||||||
|     // destination and removing PHI node entries in the exception destination. |  | ||||||
|     BranchInst::Create(II->getNormalDest(), II); |  | ||||||
|     II->getUnwindDest()->removePredecessor(II->getParent()); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Erase the instruction from the program. |  | ||||||
|   I->eraseFromParent(); |  | ||||||
| } |  | ||||||
| @@ -13,7 +13,6 @@ | |||||||
|  |  | ||||||
| #include "llvm/Module.h" | #include "llvm/Module.h" | ||||||
| #include "llvm/PassManager.h" | #include "llvm/PassManager.h" | ||||||
| #include "llvm/Analysis/LoadValueNumbering.h" |  | ||||||
| #include "llvm/Analysis/Passes.h" | #include "llvm/Analysis/Passes.h" | ||||||
| #include "llvm/Analysis/LoopPass.h" | #include "llvm/Analysis/LoopPass.h" | ||||||
| #include "llvm/Analysis/Verifier.h" | #include "llvm/Analysis/Verifier.h" | ||||||
|   | |||||||
| @@ -31,7 +31,6 @@ | |||||||
| #include "llvm/Analysis/Passes.h" | #include "llvm/Analysis/Passes.h" | ||||||
| #include "llvm/Analysis/LoopPass.h" | #include "llvm/Analysis/LoopPass.h" | ||||||
| #include "llvm/Analysis/Verifier.h" | #include "llvm/Analysis/Verifier.h" | ||||||
| #include "llvm/Analysis/LoadValueNumbering.h" |  | ||||||
| #include "llvm/CodeGen/FileWriters.h" | #include "llvm/CodeGen/FileWriters.h" | ||||||
| #include "llvm/Target/SubtargetFeature.h" | #include "llvm/Target/SubtargetFeature.h" | ||||||
| #include "llvm/Target/TargetOptions.h" | #include "llvm/Target/TargetOptions.h" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user