#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
#include <cstdio>
using namespace llvm;
static cl::opt<bool> EnablePRE("enable-pre",
cl::init(true), cl::Hidden);
-cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
+static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
//===----------------------------------------------------------------------===//
// ValueTable Class
/// two values.
namespace {
struct VISIBILITY_HIDDEN Expression {
- enum ExpressionOpcode { ADD, SUB, MUL, UDIV, SDIV, FDIV, UREM, SREM,
+ 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,
Expression::ExpressionOpcode ValueTable::getOpcode(BinaryOperator* BO) {
switch(BO->getOpcode()) {
default: // THIS SHOULD NEVER HAPPEN
- assert(0 && "Binary operator with unknown opcode?");
+ 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;
}
Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
- if (isa<ICmpInst>(C) || isa<VICmpInst>(C)) {
+ if (isa<ICmpInst>(C)) {
switch (C->getPredicate()) {
default: // THIS SHOULD NEVER HAPPEN
- assert(0 && "Comparison with unknown predicate?");
+ 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_SLT: return Expression::ICMPSLT;
case ICmpInst::ICMP_SLE: return Expression::ICMPSLE;
}
- }
- assert((isa<FCmpInst>(C) || isa<VFCmpInst>(C)) && "Unknown compare");
- switch (C->getPredicate()) {
- default: // THIS SHOULD NEVER HAPPEN
- assert(0 && "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;
+ } 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;
+ }
}
}
Expression::ExpressionOpcode ValueTable::getOpcode(CastInst* C) {
switch(C->getOpcode()) {
default: // THIS SHOULD NEVER HAPPEN
- assert(0 && "Cast operator with unknown opcode?");
+ 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;
// If the block is unreachable, just return undef, since this path
// can't actually occur at runtime.
if (!DT->isReachableFromEntry(BB))
- return Phis[BB] = UndefValue::get(orig->getType());
+ return Phis[BB] = Context->getUndef(orig->getType());
if (BasicBlock *Pred = BB->getSinglePredecessor()) {
Value *ret = GetValueForBlock(Pred, orig, Phis);
// If we had a phi translation failure, we'll have a single entry which is a
// clobber in the current block. Reject this early.
- if (Deps.size() == 1 && Deps[0].second.isClobber())
+ if (Deps.size() == 1 && Deps[0].second.isClobber()) {
+ DEBUG(
+ DOUT << "GVN: non-local load ";
+ WriteAsOperand(*DOUT.stream(), LI);
+ DOUT << " is clobbered by " << *Deps[0].second.getInst();
+ );
return false;
+ }
// Filter out useless results (non-locals, etc). Keep track of the blocks
// where we have a value available in repl, also keep track of whether we see
// Loading the allocation -> undef.
if (isa<AllocationInst>(DepInst)) {
ValuesPerBlock.push_back(std::make_pair(DepBB,
- UndefValue::get(LI->getType())));
+ Context->getUndef(LI->getType())));
continue;
}
BasicBlock *TmpBB = LoadBB;
bool isSinglePred = false;
+ bool allSingleSucc = true;
while (TmpBB->getSinglePredecessor()) {
isSinglePred = true;
TmpBB = TmpBB->getSinglePredecessor();
return false;
if (Blockers.count(TmpBB))
return false;
+ if (TmpBB->getTerminator()->getNumSuccessors() != 1)
+ allSingleSucc = false;
}
assert(TmpBB);
<< UnavailablePred->getName() << "': " << *LI);
return false;
}
-
+
+ // Make sure it is valid to move this load here. We have to watch out for:
+ // @1 = getelementptr (i8* p, ...
+ // test p and branch if == 0
+ // load @1
+ // It is valid to have the getelementptr before the test, even if p can be 0,
+ // as getelementptr only does address arithmetic.
+ // If we are not pushing the value through any multiple-successor blocks
+ // we do not have this case. Otherwise, check that the load is safe to
+ // put anywhere; this can be improved, but should be conservatively safe.
+ if (!allSingleSucc &&
+ !isSafeToLoadUnconditionally(LoadPtr, UnavailablePred->getTerminator()))
+ return false;
+
// Okay, we can eliminate this load by inserting a reload in the predecessor
// and using PHI construction to get the value in the other predecessors, do
// it.
// undef value. This can happen when loading for a fresh allocation with no
// intervening stores, for example.
if (isa<AllocationInst>(DepInst)) {
- L->replaceAllUsesWith(UndefValue::get(L->getType()));
+ L->replaceAllUsesWith(Context->getUndef(L->getType()));
toErase.push_back(L);
NumGVNLoad++;
return true;
BasicBlock* falseSucc = BI->getSuccessor(1);
if (trueSucc->getSinglePredecessor())
- localAvail[trueSucc]->table[condVN] = ConstantInt::getTrue();
+ localAvail[trueSucc]->table[condVN] = Context->getConstantIntTrue();
if (falseSucc->getSinglePredecessor())
- localAvail[falseSucc]->table[condVN] = ConstantInt::getFalse();
+ localAvail[falseSucc]->table[condVN] = Context->getConstantIntFalse();
return false;
// will be available in the predecessor by the time we need them. Any
// that weren't original present will have been instantiated earlier
// in this loop.
- Instruction* PREInstr = CurInst->clone();
+ Instruction* PREInstr = CurInst->clone(*Context);
bool success = true;
for (unsigned i = 0, e = CurInst->getNumOperands(); i != e; ++i) {
Value *Op = PREInstr->getOperand(i);