llvm-6502/lib/Transforms/Scalar/GCSE.cpp
Dan Gohman 844731a7f1 Clean up the use of static and anonymous namespaces. This turned up
several things that were neither in an anonymous namespace nor static
but not intended to be global.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51017 91177308-0d34-0410-b5e6-96231b3b80d8
2008-05-13 00:00:25 +00:00

203 lines
7.3 KiB
C++

//===-- 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 implementation to identify the common
// subexpressions, eliminating them when possible.
//
//===----------------------------------------------------------------------===//
#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->getParent()->getInstList().erase(I);
}