Newer
Older
//===- GVN.cpp - Eliminate redundant values and loads ---------------------===//
Owen Anderson
committed
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
Owen Anderson
committed
//
//===----------------------------------------------------------------------===//
//
// This pass performs global value numbering to eliminate fully redundant
// instructions. It also performs simple dead load elimination.
//
// Note that this pass does the value numbering itself; it does not use the
Matthijs Kooijman
committed
// ValueNumbering analysis passes.
//
Owen Anderson
committed
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "gvn"
#include "llvm/Transforms/Scalar.h"
#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
Owen Anderson
committed
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/LLVMContext.h"
#include "llvm/Operator.h"
#include "llvm/Value.h"
Owen Anderson
committed
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
Owen Anderson
committed
#include "llvm/ADT/PostOrderIterator.h"
Owen Anderson
committed
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/AliasAnalysis.h"
Victor Hernandez
committed
#include "llvm/Analysis/MallocHelper.h"
Owen Anderson
committed
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
Daniel Dunbar
committed
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
Owen Anderson
committed
using namespace llvm;
STATISTIC(NumGVNInstr, "Number of instructions deleted");
STATISTIC(NumGVNLoad, "Number of loads deleted");
STATISTIC(NumGVNPRE, "Number of instructions PRE'd");
Owen Anderson
committed
STATISTIC(NumGVNBlocks, "Number of blocks merged");
STATISTIC(NumPRELoad, "Number of loads PRE'd");
static cl::opt<bool> EnablePRE("enable-pre",
cl::init(true), cl::Hidden);
static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
Owen Anderson
committed
//===----------------------------------------------------------------------===//
// ValueTable Class
//===----------------------------------------------------------------------===//
/// This class holds the mapping between values and value numbers. It is used
/// as an efficient mechanism to determine the expression-wise equivalence of
/// two values.
namespace {
struct Expression {
enum ExpressionOpcode { ADD, FADD, SUB, FSUB, MUL, FMUL,
UDIV, SDIV, FDIV, UREM, SREM,
FREM, SHL, LSHR, ASHR, AND, OR, XOR, ICMPEQ,
ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE,
ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ,
FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE,
FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE,
Owen Anderson
committed
FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT,
SHUFFLE, SELECT, TRUNC, ZEXT, SEXT, FPTOUI,
FPTOSI, UITOFP, SITOFP, FPTRUNC, FPEXT,
PTRTOINT, INTTOPTR, BITCAST, GEP, CALL, CONSTANT,
Owen Anderson
committed
EMPTY, TOMBSTONE };
Owen Anderson
committed
ExpressionOpcode opcode;
const Type* type;
uint32_t firstVN;
uint32_t secondVN;
uint32_t thirdVN;
SmallVector<uint32_t, 4> varargs;
Owen Anderson
committed
Expression() { }
Expression(ExpressionOpcode o) : opcode(o) { }
Owen Anderson
committed
bool operator==(const Expression &other) const {
if (opcode != other.opcode)
return false;
else if (opcode == EMPTY || opcode == TOMBSTONE)
return true;
else if (type != other.type)
return false;
else if (function != other.function)
return false;
Owen Anderson
committed
else if (firstVN != other.firstVN)
return false;
else if (secondVN != other.secondVN)
return false;
else if (thirdVN != other.thirdVN)
return false;
else {
if (varargs.size() != other.varargs.size())
return false;
Owen Anderson
committed
for (size_t i = 0; i < varargs.size(); ++i)
if (varargs[i] != other.varargs[i])
return false;
Owen Anderson
committed
return true;
}
}
Owen Anderson
committed
bool operator!=(const Expression &other) const {
Bill Wendling
committed
return !(*this == other);
Owen Anderson
committed
}
};
class ValueTable {
Owen Anderson
committed
private:
DenseMap<Value*, uint32_t> valueNumbering;
DenseMap<Expression, uint32_t> expressionNumbering;
AliasAnalysis* AA;
MemoryDependenceAnalysis* MD;
DominatorTree* DT;
Owen Anderson
committed
uint32_t nextValueNumber;
Owen Anderson
committed
Expression::ExpressionOpcode getOpcode(BinaryOperator* BO);
Expression::ExpressionOpcode getOpcode(CmpInst* C);
Expression::ExpressionOpcode getOpcode(CastInst* C);
Expression create_expression(BinaryOperator* BO);
Expression create_expression(CmpInst* C);
Expression create_expression(ShuffleVectorInst* V);
Expression create_expression(ExtractElementInst* C);
Expression create_expression(InsertElementInst* V);
Expression create_expression(SelectInst* V);
Expression create_expression(CastInst* C);
Expression create_expression(GetElementPtrInst* G);
Expression create_expression(CallInst* C);
Expression create_expression(Constant* C);
Owen Anderson
committed
public:
ValueTable() : nextValueNumber(1) { }
uint32_t lookup_or_add(Value *V);
uint32_t lookup(Value *V) const;
void add(Value *V, uint32_t num);
Owen Anderson
committed
void clear();
Owen Anderson
committed
unsigned size();
void setAliasAnalysis(AliasAnalysis* A) { AA = A; }
AliasAnalysis *getAliasAnalysis() const { return AA; }
void setMemDep(MemoryDependenceAnalysis* M) { MD = M; }
void setDomTree(DominatorTree* D) { DT = D; }
Owen Anderson
committed
uint32_t getNextUnusedValueNumber() { return nextValueNumber; }
Bill Wendling
committed
void verifyRemoved(const Value *) const;
Owen Anderson
committed
};
}
namespace llvm {
template <> struct DenseMapInfo<Expression> {
static inline Expression getEmptyKey() {
return Expression(Expression::EMPTY);
}
static inline Expression getTombstoneKey() {
return Expression(Expression::TOMBSTONE);
}
Owen Anderson
committed
static unsigned getHashValue(const Expression e) {
unsigned hash = e.opcode;
Owen Anderson
committed
hash = e.firstVN + hash * 37;
hash = e.secondVN + hash * 37;
hash = e.thirdVN + hash * 37;
hash = ((unsigned)((uintptr_t)e.type >> 4) ^
(unsigned)((uintptr_t)e.type >> 9)) +
hash * 37;
for (SmallVector<uint32_t, 4>::const_iterator I = e.varargs.begin(),
E = e.varargs.end(); I != E; ++I)
Owen Anderson
committed
hash = *I + hash * 37;
hash = ((unsigned)((uintptr_t)e.function >> 4) ^
(unsigned)((uintptr_t)e.function >> 9)) +
hash * 37;
Owen Anderson
committed
return hash;
}
static bool isEqual(const Expression &LHS, const Expression &RHS) {
return LHS == RHS;
}
Owen Anderson
committed
static bool isPod() { return true; }
};
}
//===----------------------------------------------------------------------===//
// ValueTable Internal Functions
//===----------------------------------------------------------------------===//
Expression::ExpressionOpcode ValueTable::getOpcode(BinaryOperator* BO) {
Owen Anderson
committed
switch(BO->getOpcode()) {
default: // THIS SHOULD NEVER HAPPEN
llvm_unreachable("Binary operator with unknown opcode?");
case Instruction::Add: return Expression::ADD;
case Instruction::FAdd: return Expression::FADD;
case Instruction::Sub: return Expression::SUB;
case Instruction::FSub: return Expression::FSUB;
case Instruction::Mul: return Expression::MUL;
case Instruction::FMul: return Expression::FMUL;
case Instruction::UDiv: return Expression::UDIV;
case Instruction::SDiv: return Expression::SDIV;
case Instruction::FDiv: return Expression::FDIV;
case Instruction::URem: return Expression::UREM;
case Instruction::SRem: return Expression::SREM;
case Instruction::FRem: return Expression::FREM;
case Instruction::Shl: return Expression::SHL;
case Instruction::LShr: return Expression::LSHR;
case Instruction::AShr: return Expression::ASHR;
case Instruction::And: return Expression::AND;
case Instruction::Or: return Expression::OR;
case Instruction::Xor: return Expression::XOR;
Owen Anderson
committed
}
}
Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
if (isa<ICmpInst>(C)) {
Owen Anderson
committed
switch (C->getPredicate()) {
default: // THIS SHOULD NEVER HAPPEN
llvm_unreachable("Comparison with unknown predicate?");
case ICmpInst::ICMP_EQ: return Expression::ICMPEQ;
case ICmpInst::ICMP_NE: return Expression::ICMPNE;
case ICmpInst::ICMP_UGT: return Expression::ICMPUGT;
case ICmpInst::ICMP_UGE: return Expression::ICMPUGE;
case ICmpInst::ICMP_ULT: return Expression::ICMPULT;
case ICmpInst::ICMP_ULE: return Expression::ICMPULE;
case ICmpInst::ICMP_SGT: return Expression::ICMPSGT;
case ICmpInst::ICMP_SGE: return Expression::ICMPSGE;
case ICmpInst::ICMP_SLT: return Expression::ICMPSLT;
case ICmpInst::ICMP_SLE: return Expression::ICMPSLE;
Owen Anderson
committed
}
} else {
switch (C->getPredicate()) {
default: // THIS SHOULD NEVER HAPPEN
llvm_unreachable("Comparison with unknown predicate?");
case FCmpInst::FCMP_OEQ: return Expression::FCMPOEQ;
case FCmpInst::FCMP_OGT: return Expression::FCMPOGT;
case FCmpInst::FCMP_OGE: return Expression::FCMPOGE;
case FCmpInst::FCMP_OLT: return Expression::FCMPOLT;
case FCmpInst::FCMP_OLE: return Expression::FCMPOLE;
case FCmpInst::FCMP_ONE: return Expression::FCMPONE;
case FCmpInst::FCMP_ORD: return Expression::FCMPORD;
case FCmpInst::FCMP_UNO: return Expression::FCMPUNO;
case FCmpInst::FCMP_UEQ: return Expression::FCMPUEQ;
case FCmpInst::FCMP_UGT: return Expression::FCMPUGT;
case FCmpInst::FCMP_UGE: return Expression::FCMPUGE;
case FCmpInst::FCMP_ULT: return Expression::FCMPULT;
case FCmpInst::FCMP_ULE: return Expression::FCMPULE;
case FCmpInst::FCMP_UNE: return Expression::FCMPUNE;
}
Owen Anderson
committed
}
Expression::ExpressionOpcode ValueTable::getOpcode(CastInst* C) {
Owen Anderson
committed
switch(C->getOpcode()) {
default: // THIS SHOULD NEVER HAPPEN
llvm_unreachable("Cast operator with unknown opcode?");
case Instruction::Trunc: return Expression::TRUNC;
case Instruction::ZExt: return Expression::ZEXT;
case Instruction::SExt: return Expression::SEXT;
case Instruction::FPToUI: return Expression::FPTOUI;
case Instruction::FPToSI: return Expression::FPTOSI;
case Instruction::UIToFP: return Expression::UITOFP;
case Instruction::SIToFP: return Expression::SITOFP;
case Instruction::FPTrunc: return Expression::FPTRUNC;
case Instruction::FPExt: return Expression::FPEXT;
case Instruction::PtrToInt: return Expression::PTRTOINT;
case Instruction::IntToPtr: return Expression::INTTOPTR;
case Instruction::BitCast: return Expression::BITCAST;
Owen Anderson
committed
}
}
Expression ValueTable::create_expression(CallInst* C) {
Expression e;
e.type = C->getType();
e.firstVN = 0;
e.secondVN = 0;
e.thirdVN = 0;
e.function = C->getCalledFunction();
e.opcode = Expression::CALL;
for (CallInst::op_iterator I = C->op_begin()+1, E = C->op_end();
I != E; ++I)
Owen Anderson
committed
e.varargs.push_back(lookup_or_add(*I));
return e;
}
Owen Anderson
committed
Expression ValueTable::create_expression(BinaryOperator* BO) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(BO->getOperand(0));
e.secondVN = lookup_or_add(BO->getOperand(1));
Owen Anderson
committed
e.thirdVN = 0;
e.function = 0;
Owen Anderson
committed
e.type = BO->getType();
e.opcode = getOpcode(BO);
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(CmpInst* C) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(C->getOperand(0));
e.secondVN = lookup_or_add(C->getOperand(1));
Owen Anderson
committed
e.thirdVN = 0;
e.function = 0;
Owen Anderson
committed
e.type = C->getType();
e.opcode = getOpcode(C);
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(CastInst* C) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(C->getOperand(0));
Owen Anderson
committed
e.secondVN = 0;
e.thirdVN = 0;
e.function = 0;
Owen Anderson
committed
e.type = C->getType();
e.opcode = getOpcode(C);
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(ShuffleVectorInst* S) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(S->getOperand(0));
e.secondVN = lookup_or_add(S->getOperand(1));
e.thirdVN = lookup_or_add(S->getOperand(2));
e.function = 0;
Owen Anderson
committed
e.type = S->getType();
e.opcode = Expression::SHUFFLE;
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(ExtractElementInst* E) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(E->getOperand(0));
e.secondVN = lookup_or_add(E->getOperand(1));
Owen Anderson
committed
e.thirdVN = 0;
e.function = 0;
Owen Anderson
committed
e.type = E->getType();
e.opcode = Expression::EXTRACT;
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(InsertElementInst* I) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(I->getOperand(0));
e.secondVN = lookup_or_add(I->getOperand(1));
e.thirdVN = lookup_or_add(I->getOperand(2));
e.function = 0;
Owen Anderson
committed
e.type = I->getType();
e.opcode = Expression::INSERT;
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(SelectInst* I) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(I->getCondition());
e.secondVN = lookup_or_add(I->getTrueValue());
e.thirdVN = lookup_or_add(I->getFalseValue());
e.function = 0;
Owen Anderson
committed
e.type = I->getType();
e.opcode = Expression::SELECT;
Owen Anderson
committed
return e;
}
Expression ValueTable::create_expression(GetElementPtrInst* G) {
Expression e;
Owen Anderson
committed
e.firstVN = lookup_or_add(G->getPointerOperand());
Owen Anderson
committed
e.secondVN = 0;
e.thirdVN = 0;
e.function = 0;
Owen Anderson
committed
e.type = G->getType();
e.opcode = Expression::GEP;
Owen Anderson
committed
for (GetElementPtrInst::op_iterator I = G->idx_begin(), E = G->idx_end();
I != E; ++I)
Owen Anderson
committed
e.varargs.push_back(lookup_or_add(*I));
Owen Anderson
committed
return e;
}
//===----------------------------------------------------------------------===//
// ValueTable External Functions
//===----------------------------------------------------------------------===//
Owen Anderson
committed
/// add - Insert a value into the table with a specified value number.
void ValueTable::add(Value *V, uint32_t num) {
Owen Anderson
committed
valueNumbering.insert(std::make_pair(V, num));
}
Owen Anderson
committed
/// lookup_or_add - Returns the value number for the specified value, assigning
/// it a new number if it did not have one before.
uint32_t ValueTable::lookup_or_add(Value *V) {
Owen Anderson
committed
DenseMap<Value*, uint32_t>::iterator VI = valueNumbering.find(V);
if (VI != valueNumbering.end())
return VI->second;
if (CallInst* C = dyn_cast<CallInst>(V)) {
Owen Anderson
committed
if (AA->doesNotAccessMemory(C)) {
Expression exp = create_expression(C);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
} else if (AA->onlyReadsMemory(C)) {
Expression exp = create_expression(C);
uint32_t& e = expressionNumbering[exp];
if (!e) {
e = nextValueNumber++;
valueNumbering[V] = e;
return e;
MemDepResult local_dep = MD->getDependency(C);
if (!local_dep.isDef() && !local_dep.isNonLocal()) {
return nextValueNumber++;
if (local_dep.isDef()) {
CallInst* local_cdep = cast<CallInst>(local_dep.getInst());
if (local_cdep->getNumOperands() != C->getNumOperands()) {
return nextValueNumber++;
for (unsigned i = 1; i < C->getNumOperands(); ++i) {
uint32_t c_vn = lookup_or_add(C->getOperand(i));
uint32_t cd_vn = lookup_or_add(local_cdep->getOperand(i));
if (c_vn != cd_vn) {
return nextValueNumber++;
}
}
uint32_t v = lookup_or_add(local_cdep);
}
const MemoryDependenceAnalysis::NonLocalDepInfo &deps =
MD->getNonLocalCallDependency(CallSite(C));
// FIXME: call/call dependencies for readonly calls should return def, not
// clobber! Move the checking logic to MemDep!
CallInst* cdep = 0;
// Check to see if we have a single dominating call instruction that is
// identical to C.
for (unsigned i = 0, e = deps.size(); i != e; ++i) {
const MemoryDependenceAnalysis::NonLocalDepEntry *I = &deps[i];
// Ignore non-local dependencies.
if (I->second.isNonLocal())
continue;
// We don't handle non-depedencies. If we already have a call, reject
// instruction dependencies.
if (I->second.isClobber() || cdep != 0) {
cdep = 0;
break;
}
CallInst *NonLocalDepCall = dyn_cast<CallInst>(I->second.getInst());
// FIXME: All duplicated with non-local case.
if (NonLocalDepCall && DT->properlyDominates(I->first, C->getParent())){
cdep = NonLocalDepCall;
continue;
cdep = 0;
break;
if (!cdep) {
return nextValueNumber++;
}
if (cdep->getNumOperands() != C->getNumOperands()) {
return nextValueNumber++;
}
for (unsigned i = 1; i < C->getNumOperands(); ++i) {
uint32_t c_vn = lookup_or_add(C->getOperand(i));
uint32_t cd_vn = lookup_or_add(cdep->getOperand(i));
if (c_vn != cd_vn) {
return nextValueNumber++;
}
uint32_t v = lookup_or_add(cdep);
} else {
return nextValueNumber++;
}
} else if (BinaryOperator* BO = dyn_cast<BinaryOperator>(V)) {
Expression exp = create_expression(BO);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (CmpInst* C = dyn_cast<CmpInst>(V)) {
Expression exp = create_expression(C);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (ShuffleVectorInst* U = dyn_cast<ShuffleVectorInst>(V)) {
Expression exp = create_expression(U);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (ExtractElementInst* U = dyn_cast<ExtractElementInst>(V)) {
Expression exp = create_expression(U);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (InsertElementInst* U = dyn_cast<InsertElementInst>(V)) {
Expression exp = create_expression(U);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (SelectInst* U = dyn_cast<SelectInst>(V)) {
Expression exp = create_expression(U);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (CastInst* U = dyn_cast<CastInst>(V)) {
Expression exp = create_expression(U);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else if (GetElementPtrInst* U = dyn_cast<GetElementPtrInst>(V)) {
Expression exp = create_expression(U);
uint32_t& e = expressionNumbering[exp];
if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
Owen Anderson
committed
} else {
Owen Anderson
committed
return nextValueNumber++;
}
}
/// lookup - Returns the value number of the specified value. Fails if
/// the value has not yet been numbered.
uint32_t ValueTable::lookup(Value *V) const {
Owen Anderson
committed
DenseMap<Value*, uint32_t>::iterator VI = valueNumbering.find(V);
assert(VI != valueNumbering.end() && "Value not numbered?");
return VI->second;
Owen Anderson
committed
}
/// clear - Remove all entries from the ValueTable
void ValueTable::clear() {
valueNumbering.clear();
expressionNumbering.clear();
nextValueNumber = 1;
}
/// erase - Remove a value from the value numbering
void ValueTable::erase(Value *V) {
valueNumbering.erase(V);
}
Bill Wendling
committed
/// verifyRemoved - Verify that the value is removed from all internal data
/// structures.
void ValueTable::verifyRemoved(const Value *V) const {
for (DenseMap<Value*, uint32_t>::iterator
I = valueNumbering.begin(), E = valueNumbering.end(); I != E; ++I) {
assert(I->first != V && "Inst still occurs in value numbering map!");
}
}
Owen Anderson
committed
//===----------------------------------------------------------------------===//
Owen Anderson
committed
//===----------------------------------------------------------------------===//
Owen Anderson
committed
namespace {
struct ValueNumberScope {
Owen Anderson
committed
ValueNumberScope* parent;
DenseMap<uint32_t, Value*> table;
Owen Anderson
committed
ValueNumberScope(ValueNumberScope* p) : parent(p) { }
};
}
Owen Anderson
committed
namespace {
class GVN : public FunctionPass {
Owen Anderson
committed
bool runOnFunction(Function &F);
public:
static char ID; // Pass identification, replacement for typeid
GVN() : FunctionPass(&ID) { }
Owen Anderson
committed
private:
MemoryDependenceAnalysis *MD;
DominatorTree *DT;
Owen Anderson
committed
ValueTable VN;
Owen Anderson
committed
DenseMap<BasicBlock*, ValueNumberScope*> localAvail;
Owen Anderson
committed
// This transformation requires dominator postdominator info
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DominatorTree>();
AU.addRequired<MemoryDependenceAnalysis>();
AU.addRequired<AliasAnalysis>();
Owen Anderson
committed
AU.addPreserved<DominatorTree>();
AU.addPreserved<AliasAnalysis>();
Owen Anderson
committed
}
Owen Anderson
committed
// Helper fuctions
// FIXME: eliminate or document these better
bool processLoad(LoadInst* L,
Chris Lattner
committed
SmallVectorImpl<Instruction*> &toErase);
bool processInstruction(Instruction *I,
Chris Lattner
committed
SmallVectorImpl<Instruction*> &toErase);
Chris Lattner
committed
SmallVectorImpl<Instruction*> &toErase);
bool processBlock(BasicBlock *BB);
Owen Anderson
committed
void dump(DenseMap<uint32_t, Value*>& d);
Value *CollapsePhi(PHINode* p);
Owen Anderson
committed
bool performPRE(Function& F);
Value *lookupNumber(BasicBlock *BB, uint32_t num);
void cleanupGlobalSets();
Bill Wendling
committed
void verifyRemoved(const Instruction *I) const;
Owen Anderson
committed
};
Owen Anderson
committed
char GVN::ID = 0;
}
// createGVNPass - The public interface to this file...
FunctionPass *llvm::createGVNPass() { return new GVN(); }
static RegisterPass<GVN> X("gvn",
"Global Value Numbering");
Owen Anderson
committed
void GVN::dump(DenseMap<uint32_t, Value*>& d) {
Owen Anderson
committed
for (DenseMap<uint32_t, Value*>::iterator I = d.begin(),
E = d.end(); I != E; ++I) {
Owen Anderson
committed
printf("%d\n", I->first);
I->second->dump();
}
printf("}\n");
}
static bool isSafeReplacement(PHINode* p, Instruction *inst) {
if (!isa<PHINode>(inst))
return true;
for (Instruction::use_iterator UI = p->use_begin(), E = p->use_end();
UI != E; ++UI)
if (PHINode* use_phi = dyn_cast<PHINode>(UI))
if (use_phi->getParent() == inst->getParent())
return false;
Value *GVN::CollapsePhi(PHINode *PN) {
Value *ConstVal = PN->hasConstantValue(DT);
if (!ConstVal) return 0;
Instruction *Inst = dyn_cast<Instruction>(ConstVal);
if (!Inst)
return ConstVal;
if (DT->dominates(Inst, PN))
if (isSafeReplacement(PN, Inst))
return Inst;
/// IsValueFullyAvailableInBlock - Return true if we can prove that the value
/// we're analyzing is fully available in the specified block. As we go, keep
/// track of which blocks we know are fully alive in FullyAvailableBlocks. This
/// map is actually a tri-state map with the following values:
/// 0) we know the block *is not* fully available.
/// 1) we know the block *is* fully available.
/// 2) we do not know whether the block is fully available or not, but we are
/// currently speculating that it will be.
/// 3) we are speculating for this block and have used that to speculate for
/// other blocks.
static bool IsValueFullyAvailableInBlock(BasicBlock *BB,
DenseMap<BasicBlock*, char> &FullyAvailableBlocks) {
// Optimistically assume that the block is fully available and check to see
// if we already know about this block in one lookup.
std::pair<DenseMap<BasicBlock*, char>::iterator, char> IV =
FullyAvailableBlocks.insert(std::make_pair(BB, 2));
// If the entry already existed for this block, return the precomputed value.
if (!IV.second) {
// If this is a speculative "available" value, mark it as being used for
// speculation of other blocks.
if (IV.first->second == 2)
IV.first->second = 3;
return IV.first->second != 0;
}
// Otherwise, see if it is fully available in all predecessors.
pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
// If this block has no predecessors, it isn't live-in here.
if (PI == PE)
for (; PI != PE; ++PI)
// If the value isn't fully available in one of our predecessors, then it
// isn't fully available in this block either. Undo our previous
// optimistic assumption and bail out.
if (!IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks))
return true;
// SpeculationFailure - If we get here, we found out that this is not, after
// all, a fully-available block. We have a problem if we speculated on this and
// used the speculation to mark other blocks as available.
SpeculationFailure:
char &BBVal = FullyAvailableBlocks[BB];
// If we didn't speculate on this, just return with it set to false.
if (BBVal == 2) {
BBVal = 0;
return false;
}
// If we did speculate on this value, we could have blocks set to 1 that are
// incorrect. Walk the (transitive) successors of this block and mark them as
// 0 if set to one.
SmallVector<BasicBlock*, 32> BBWorklist;
BBWorklist.push_back(BB);
while (!BBWorklist.empty()) {
BasicBlock *Entry = BBWorklist.pop_back_val();
// Note that this sets blocks to 0 (unavailable) if they happen to not
// already be in FullyAvailableBlocks. This is safe.
char &EntryVal = FullyAvailableBlocks[Entry];
if (EntryVal == 0) continue; // Already unavailable.
// Mark as unavailable.
EntryVal = 0;
for (succ_iterator I = succ_begin(Entry), E = succ_end(Entry); I != E; ++I)
BBWorklist.push_back(*I);
}
/// CanCoerceMustAliasedValueToLoad - Return true if
/// CoerceAvailableValueToLoadType will succeed.
static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal,
const Type *LoadTy,
const TargetData &TD) {
// If the loaded or stored value is an first class array or struct, don't try
// to transform them. We need to be able to bitcast to integer.
if (isa<StructType>(LoadTy) || isa<ArrayType>(LoadTy) ||
isa<StructType>(StoredVal->getType()) ||
isa<ArrayType>(StoredVal->getType()))
return false;
// The store has to be at least as big as the load.
if (TD.getTypeSizeInBits(StoredVal->getType()) <
TD.getTypeSizeInBits(LoadTy))
return false;
return true;
}
/// CoerceAvailableValueToLoadType - If we saw a store of a value to memory, and
/// then a load from a must-aliased pointer of a different type, try to coerce
/// the stored value. LoadedTy is the type of the load we want to replace and
/// InsertPt is the place to insert new instructions.
///
/// If we can't do it, return null.
static Value *CoerceAvailableValueToLoadType(Value *StoredVal,
const Type *LoadedTy,
Instruction *InsertPt,
const TargetData &TD) {
if (!CanCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, TD))
return 0;
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
const Type *StoredValTy = StoredVal->getType();
uint64_t StoreSize = TD.getTypeSizeInBits(StoredValTy);
uint64_t LoadSize = TD.getTypeSizeInBits(LoadedTy);
// If the store and reload are the same size, we can always reuse it.
if (StoreSize == LoadSize) {
if (isa<PointerType>(StoredValTy) && isa<PointerType>(LoadedTy)) {
// Pointer to Pointer -> use bitcast.
return new BitCastInst(StoredVal, LoadedTy, "", InsertPt);
}
// Convert source pointers to integers, which can be bitcast.
if (isa<PointerType>(StoredValTy)) {
StoredValTy = TD.getIntPtrType(StoredValTy->getContext());
StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt);
}
const Type *TypeToCastTo = LoadedTy;
if (isa<PointerType>(TypeToCastTo))
TypeToCastTo = TD.getIntPtrType(StoredValTy->getContext());
if (StoredValTy != TypeToCastTo)
StoredVal = new BitCastInst(StoredVal, TypeToCastTo, "", InsertPt);
// Cast to pointer if the load needs a pointer type.
if (isa<PointerType>(LoadedTy))
StoredVal = new IntToPtrInst(StoredVal, LoadedTy, "", InsertPt);
return StoredVal;
}
// If the loaded value is smaller than the available value, then we can
// extract out a piece from it. If the available value is too small, then we
// can't do anything.
assert(StoreSize >= LoadSize && "CanCoerceMustAliasedValueToLoad fail");
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
// Convert source pointers to integers, which can be manipulated.
if (isa<PointerType>(StoredValTy)) {
StoredValTy = TD.getIntPtrType(StoredValTy->getContext());
StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt);
}
// Convert vectors and fp to integer, which can be manipulated.
if (!isa<IntegerType>(StoredValTy)) {
StoredValTy = IntegerType::get(StoredValTy->getContext(), StoreSize);
StoredVal = new BitCastInst(StoredVal, StoredValTy, "", InsertPt);
}
// If this is a big-endian system, we need to shift the value down to the low
// bits so that a truncate will work.
if (TD.isBigEndian()) {
Constant *Val = ConstantInt::get(StoredVal->getType(), StoreSize-LoadSize);
StoredVal = BinaryOperator::CreateLShr(StoredVal, Val, "tmp", InsertPt);
}
// Truncate the integer to the right size now.
const Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadSize);
StoredVal = new TruncInst(StoredVal, NewIntTy, "trunc", InsertPt);
if (LoadedTy == NewIntTy)
return StoredVal;
// If the result is a pointer, inttoptr.
if (isa<PointerType>(LoadedTy))
return new IntToPtrInst(StoredVal, LoadedTy, "inttoptr", InsertPt);
// Otherwise, bitcast.
return new BitCastInst(StoredVal, LoadedTy, "bitcast", InsertPt);
}
/// GetBaseWithConstantOffset - Analyze the specified pointer to see if it can
/// be expressed as a base pointer plus a constant offset. Return the base and
/// offset to the caller.
static Value *GetBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
const TargetData &TD) {
Operator *PtrOp = dyn_cast<Operator>(Ptr);
if (PtrOp == 0) return Ptr;
// Just look through bitcasts.
if (PtrOp->getOpcode() == Instruction::BitCast)
return GetBaseWithConstantOffset(PtrOp->getOperand(0), Offset, TD);
// If this is a GEP with constant indices, we can look through it.
GEPOperator *GEP = dyn_cast<GEPOperator>(PtrOp);
if (GEP == 0 || !GEP->hasAllConstantIndices()) return Ptr;
gep_type_iterator GTI = gep_type_begin(GEP);
for (User::op_iterator I = GEP->idx_begin(), E = GEP->idx_end(); I != E;
++I, ++GTI) {
ConstantInt *OpC = cast<ConstantInt>(*I);
if (OpC->isZero()) continue;
// Handle a struct and array indices which add their offset to the pointer.
if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
Offset += TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType());
Offset += OpC->getSExtValue()*Size;
}
}
// Re-sign extend from the pointer size if needed to get overflow edge cases
// right.
unsigned PtrSize = TD.getPointerSizeInBits();
if (PtrSize < 64)
Offset = (Offset << (64-PtrSize)) >> (64-PtrSize);
return GetBaseWithConstantOffset(GEP->getPointerOperand(), Offset, TD);
}
/// AnalyzeLoadFromClobberingStore - This function is called when we have a
/// memdep query of a load that ends up being a clobbering store. This means
/// that the store *may* provide bits used by the load but we can't be sure
/// because the pointers don't mustalias. Check this case to see if there is
/// anything more we can do before we give up. This returns -1 if we have to
/// give up, or a byte number in the stored value of the piece that feeds the
/// load.
static int AnalyzeLoadFromClobberingStore(LoadInst *L, StoreInst *DepSI,
const TargetData &TD) {
// If the loaded or stored value is an first class array or struct, don't try
// to transform them. We need to be able to bitcast to integer.
if (isa<StructType>(L->getType()) || isa<ArrayType>(L->getType()) ||
isa<StructType>(DepSI->getOperand(0)->getType()) ||
isa<ArrayType>(DepSI->getOperand(0)->getType()))
return -1;
int64_t StoreOffset = 0, LoadOffset = 0;
Value *StoreBase =
GetBaseWithConstantOffset(DepSI->getPointerOperand(), StoreOffset, TD);
GetBaseWithConstantOffset(L->getPointerOperand(), LoadOffset, TD);
if (StoreBase != LoadBase)
return -1;
// If the load and store are to the exact same address, they should have been
// a must alias. AA must have gotten confused.
// FIXME: Study to see if/when this happens.
if (LoadOffset == StoreOffset) {
#if 0
errs() << "STORE/LOAD DEP WITH COMMON POINTER MISSED:\n"
<< "Base = " << *StoreBase << "\n"
<< "Store Ptr = " << *DepSI->getPointerOperand() << "\n"
<< "Store Offs = " << StoreOffset << " - " << *DepSI << "\n"
<< "Load Ptr = " << *L->getPointerOperand() << "\n"
<< "Load Offs = " << LoadOffset << " - " << *L << "\n\n";
errs() << "'" << L->getParent()->getParent()->getName() << "'"
<< *L->getParent();
#endif
return -1;
}
// If the load and store don't overlap at all, the store doesn't provide
// anything to the load. In this case, they really don't alias at all, AA
// must have gotten confused.
// FIXME: Investigate cases where this bails out, e.g. rdar://7238614. Then
// remove this check, as it is duplicated with what we have below.
uint64_t StoreSize = TD.getTypeSizeInBits(DepSI->getOperand(0)->getType());
uint64_t LoadSize = TD.getTypeSizeInBits(L->getType());
if ((StoreSize & 7) | (LoadSize & 7))
return -1;
StoreSize >>= 3; // Convert to bytes.
LoadSize >>= 3;
bool isAAFailure = false;
if (StoreOffset < LoadOffset) {
isAAFailure = StoreOffset+int64_t(StoreSize) <= LoadOffset;