diff options
author | Owen Anderson <resistor@mac.com> | 2008-08-15 21:31:02 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2008-08-15 21:31:02 +0000 |
commit | 3688f268cb31dbfb5b36131d96af668fa2fc6a8d (patch) | |
tree | 5cbacc759b0f9cbea95786085820e7aceaaffa04 /lib/Transforms | |
parent | 35115f92e4a1e19921af4ae43db6e31f9a633738 (diff) | |
download | external_llvm-3688f268cb31dbfb5b36131d96af668fa2fc6a8d.zip external_llvm-3688f268cb31dbfb5b36131d96af668fa2fc6a8d.tar.gz external_llvm-3688f268cb31dbfb5b36131d96af668fa2fc6a8d.tar.bz2 |
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/GCSE.cpp | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/lib/Transforms/Scalar/GCSE.cpp b/lib/Transforms/Scalar/GCSE.cpp deleted file mode 100644 index 9d3f1a8..0000000 --- a/lib/Transforms/Scalar/GCSE.cpp +++ /dev/null @@ -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(); -} |