Index: lib/Transforms/Scalar/EarlyCSE.cpp =================================================================== --- lib/Transforms/Scalar/EarlyCSE.cpp +++ lib/Transforms/Scalar/EarlyCSE.cpp @@ -54,18 +54,24 @@ namespace { /// \brief Struct representing the available values in the scoped hash table. struct SimpleValue { - Instruction *Inst; + Value *Val; - SimpleValue(Instruction *I) : Inst(I) { - assert((isSentinel() || canHandle(I)) && "Inst can't be handled!"); + SimpleValue(Value *V) : Val(V) { + assert((isSentinel() || canHandle(V)) && "Value can't be handled!"); } bool isSentinel() const { - return Inst == DenseMapInfo::getEmptyKey() || - Inst == DenseMapInfo::getTombstoneKey(); + return Val == DenseMapInfo::getEmptyKey() || + Val == DenseMapInfo::getTombstoneKey(); } - static bool canHandle(Instruction *Inst) { + static bool canHandle(Value *Val) { + Instruction *Inst = dyn_cast(Val); + // TODO: We reject all non-instruction values so far, but will accept them + // in follow-up patch. This is done to diagnose the reason of potential + // problems with transition from working with instructions only to values. + if (!Inst) + return false; // This can only handle non-void readnone functions. if (CallInst *CI = dyn_cast(Inst)) return CI->doesNotAccessMemory() && !CI->getType()->isVoidTy(); @@ -81,10 +87,10 @@ namespace llvm { template <> struct DenseMapInfo { static inline SimpleValue getEmptyKey() { - return DenseMapInfo::getEmptyKey(); + return DenseMapInfo::getEmptyKey(); } static inline SimpleValue getTombstoneKey() { - return DenseMapInfo::getTombstoneKey(); + return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(SimpleValue Val); static bool isEqual(SimpleValue LHS, SimpleValue RHS); @@ -92,7 +98,7 @@ } unsigned DenseMapInfo::getHashValue(SimpleValue Val) { - Instruction *Inst = Val.Inst; + Instruction *Inst = cast(Val.Val); // Hash in all of the operands as pointers. if (BinaryOperator *BinOp = dyn_cast(Inst)) { Value *LHS = BinOp->getOperand(0); @@ -139,10 +145,12 @@ } bool DenseMapInfo::isEqual(SimpleValue LHS, SimpleValue RHS) { - Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; - if (LHS.isSentinel() || RHS.isSentinel()) - return LHSI == RHSI; + return LHS.Val == RHS.Val; + + // Otherwise try to prove equality of instructions. + Instruction *LHSI = cast(LHS.Val); + Instruction *RHSI = cast(RHS.Val); if (LHSI->getOpcode() != RHSI->getOpcode()) return false; @@ -592,19 +600,19 @@ if (BasicBlock *Pred = BB->getSinglePredecessor()) { auto *BI = dyn_cast(Pred->getTerminator()); if (BI && BI->isConditional()) { - auto *CondInst = dyn_cast(BI->getCondition()); - if (CondInst && SimpleValue::canHandle(CondInst)) { + auto *Cond = BI->getCondition(); + if (SimpleValue::canHandle(Cond)) { assert(BI->getSuccessor(0) == BB || BI->getSuccessor(1) == BB); auto *TorF = (BI->getSuccessor(0) == BB) ? ConstantInt::getTrue(BB->getContext()) : ConstantInt::getFalse(BB->getContext()); - AvailableValues.insert(CondInst, TorF); + AvailableValues.insert(Cond, TorF); DEBUG(dbgs() << "EarlyCSE CVP: Add conditional value for '" - << CondInst->getName() << "' as " << *TorF << " in " + << Cond->getName() << "' as " << *TorF << " in " << BB->getName() << "\n"); // Replace all dominated uses with the known value. if (unsigned Count = replaceDominatedUsesWith( - CondInst, TorF, DT, BasicBlockEdge(Pred, BB))) { + Cond, TorF, DT, BasicBlockEdge(Pred, BB))) { Changed = true; NumCSECVP = NumCSECVP + Count; } @@ -638,11 +646,10 @@ // and this pass will not bother with its removal. However, we should mark // its condition as true for all dominated blocks. if (match(Inst, m_Intrinsic())) { - auto *CondI = - dyn_cast(cast(Inst)->getArgOperand(0)); - if (CondI && SimpleValue::canHandle(CondI)) { + auto *Cond = cast(Inst)->getArgOperand(0); + if (SimpleValue::canHandle(Cond)) { DEBUG(dbgs() << "EarlyCSE considering assumption: " << *Inst << '\n'); - AvailableValues.insert(CondI, ConstantInt::getTrue(BB->getContext())); + AvailableValues.insert(Cond, ConstantInt::getTrue(BB->getContext())); } else DEBUG(dbgs() << "EarlyCSE skipping assumption: " << *Inst << '\n'); continue; @@ -662,27 +669,25 @@ continue; if (match(Inst, m_Intrinsic())) { - if (auto *CondI = - dyn_cast(cast(Inst)->getArgOperand(0))) { - if (SimpleValue::canHandle(CondI)) { - // Do we already know the actual value of this condition? - if (auto *KnownCond = AvailableValues.lookup(CondI)) { - // Is the condition known to be true? - if (isa(KnownCond) && - cast(KnownCond)->isOneValue()) { - DEBUG(dbgs() << "EarlyCSE removing guard: " << *Inst << '\n'); - removeMSSA(Inst); - Inst->eraseFromParent(); - Changed = true; - continue; - } else - // Use the known value if it wasn't true. - cast(Inst)->setArgOperand(0, KnownCond); - } - // The condition we're on guarding here is true for all dominated - // locations. - AvailableValues.insert(CondI, ConstantInt::getTrue(BB->getContext())); + auto *Cond = cast(Inst)->getArgOperand(0); + if (SimpleValue::canHandle(Cond)) { + // Do we already know the actual value of this condition? + if (auto *KnownCond = AvailableValues.lookup(Cond)) { + // Is the condition known to be true? + if (isa(KnownCond) && + cast(KnownCond)->isOneValue()) { + DEBUG(dbgs() << "EarlyCSE removing guard: " << *Inst << '\n'); + removeMSSA(Inst); + Inst->eraseFromParent(); + Changed = true; + continue; + } else + // Use the known value if it wasn't true. + cast(Inst)->setArgOperand(0, KnownCond); } + // The condition we're on guarding here is true for all dominated + // locations. + AvailableValues.insert(Cond, ConstantInt::getTrue(BB->getContext())); } // Guard intrinsics read all memory, but don't write any memory.