diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/NewGVN.cpp | 55 | ||||
-rw-r--r-- | lib/Transforms/Vectorize/LoopVectorize.cpp | 21 |
2 files changed, 26 insertions, 50 deletions
diff --git a/lib/Transforms/Scalar/NewGVN.cpp b/lib/Transforms/Scalar/NewGVN.cpp index 67abc3116988..5e9f40019ce8 100644 --- a/lib/Transforms/Scalar/NewGVN.cpp +++ b/lib/Transforms/Scalar/NewGVN.cpp @@ -377,7 +377,6 @@ private: int StoreCount = 0; }; -struct HashedExpression; namespace llvm { template <> struct DenseMapInfo<const Expression *> { static const Expression *getEmptyKey() { @@ -391,41 +390,25 @@ template <> struct DenseMapInfo<const Expression *> { return reinterpret_cast<const Expression *>(Val); } static unsigned getHashValue(const Expression *E) { - return static_cast<unsigned>(E->getHashValue()); + return static_cast<unsigned>(E->getComputedHash()); } - static unsigned getHashValue(const HashedExpression &HE); - static bool isEqual(const HashedExpression &LHS, const Expression *RHS); static bool isEqual(const Expression *LHS, const Expression *RHS) { if (LHS == RHS) return true; if (LHS == getTombstoneKey() || RHS == getTombstoneKey() || LHS == getEmptyKey() || RHS == getEmptyKey()) return false; + // Compare hashes before equality. This is *not* what the hashtable does, + // since it is computing it modulo the number of buckets, whereas we are + // using the full hash keyspace. Since the hashes are precomputed, this + // check is *much* faster than equality. + if (LHS->getComputedHash() != RHS->getComputedHash()) + return false; return *LHS == *RHS; } }; } // end namespace llvm -// This is just a wrapper around Expression that computes the hash value once at -// creation time. Hash values for an Expression can't change once they are -// inserted into the DenseMap (it breaks DenseMap), so they must be immutable at -// that point anyway. -struct HashedExpression { - const Expression *E; - unsigned HashVal; - HashedExpression(const Expression *E) - : E(E), HashVal(DenseMapInfo<const Expression *>::getHashValue(E)) {} -}; - -unsigned -DenseMapInfo<const Expression *>::getHashValue(const HashedExpression &HE) { - return HE.HashVal; -} -bool DenseMapInfo<const Expression *>::isEqual(const HashedExpression &LHS, - const Expression *RHS) { - return isEqual(LHS.E, RHS); -} - namespace { class NewGVN { Function &F; @@ -707,7 +690,7 @@ private: void markPredicateUsersTouched(Instruction *); void markValueLeaderChangeTouched(CongruenceClass *CC); void markMemoryLeaderChangeTouched(CongruenceClass *CC); - void markPhiOfOpsChanged(const HashedExpression &HE); + void markPhiOfOpsChanged(const Expression *E); void addPredicateUsers(const PredicateBase *, Instruction *) const; void addMemoryUsers(const MemoryAccess *To, MemoryAccess *U) const; void addAdditionalUsers(Value *To, Value *User) const; @@ -956,8 +939,12 @@ const Expression *NewGVN::checkSimplificationResults(Expression *E, if (CC && CC->getDefiningExpr()) { // If we simplified to something else, we need to communicate // that we're users of the value we simplified to. - if (I != V) - addAdditionalUsers(V, I); + if (I != V) { + // Don't add temporary instructions to the user lists. + if (!AllTempInstructions.count(I)) + addAdditionalUsers(V, I); + } + if (I) DEBUG(dbgs() << "Simplified " << *I << " to " << " expression " << *CC->getDefiningExpr() << "\n"); @@ -2195,8 +2182,8 @@ void NewGVN::moveValueToNewCongruenceClass(Instruction *I, const Expression *E, // For a given expression, mark the phi of ops instructions that could have // changed as a result. -void NewGVN::markPhiOfOpsChanged(const HashedExpression &HE) { - touchAndErase(ExpressionToPhiOfOps, HE); +void NewGVN::markPhiOfOpsChanged(const Expression *E) { + touchAndErase(ExpressionToPhiOfOps, E); } // Perform congruence finding on a given value numbering expression. @@ -2210,14 +2197,13 @@ void NewGVN::performCongruenceFinding(Instruction *I, const Expression *E) { assert(!IClass->isDead() && "Found a dead class"); CongruenceClass *EClass = nullptr; - HashedExpression HE(E); if (const auto *VE = dyn_cast<VariableExpression>(E)) { EClass = ValueToClass.lookup(VE->getVariableValue()); } else if (isa<DeadExpression>(E)) { EClass = TOPClass; } if (!EClass) { - auto lookupResult = ExpressionToClass.insert_as({E, nullptr}, HE); + auto lookupResult = ExpressionToClass.insert({E, nullptr}); // If it's not in the value table, create a new congruence class. if (lookupResult.second) { @@ -2268,7 +2254,7 @@ void NewGVN::performCongruenceFinding(Instruction *I, const Expression *E) { << "\n"); if (ClassChanged) { moveValueToNewCongruenceClass(I, E, IClass, EClass); - markPhiOfOpsChanged(HE); + markPhiOfOpsChanged(E); } markUsersTouched(I); @@ -2502,9 +2488,8 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge, // Clone the instruction, create an expression from it, and see if we // have a leader. Instruction *ValueOp = I->clone(); - auto Iter = TempToMemory.end(); if (MemAccess) - Iter = TempToMemory.insert({ValueOp, MemAccess}).first; + TempToMemory.insert({ValueOp, MemAccess}); for (auto &Op : ValueOp->operands()) { Op = Op->DoPHITranslation(PHIBlock, PredBB); @@ -2523,7 +2508,7 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge, AllTempInstructions.erase(ValueOp); ValueOp->deleteValue(); if (MemAccess) - TempToMemory.erase(Iter); + TempToMemory.erase(ValueOp); if (!E) return nullptr; FoundVal = findPhiOfOpsLeader(E, PredBB); diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 3b036a6ac430..2b83b8426d14 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -7173,7 +7173,7 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, unsigned VF) { // Note: Even if all instructions are scalarized, return true if any memory // accesses appear in the loop to get benefits from address folding etc. bool TypeNotScalarized = - VF > 1 && VectorTy->isVectorTy() && TTI.getNumberOfParts(VectorTy) < VF; + VF > 1 && !VectorTy->isVoidTy() && TTI.getNumberOfParts(VectorTy) < VF; return VectorizationCostTy(C, TypeNotScalarized); } @@ -7312,7 +7312,7 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I, Type *RetTy = I->getType(); if (canTruncateToMinimalBitwidth(I, VF)) RetTy = IntegerType::get(RetTy->getContext(), MinBWs[I]); - VectorTy = isScalarAfterVectorization(I, VF) ? RetTy : ToVectorTy(RetTy, VF); + VectorTy = ToVectorTy(RetTy, VF); auto SE = PSE.getSE(); // TODO: We need to estimate the cost of intrinsic calls. @@ -7445,10 +7445,9 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I, } else if (Legal->isUniform(Op2)) { Op2VK = TargetTransformInfo::OK_UniformValue; } - SmallVector<const Value *, 4> Operands(I->operand_values()); - unsigned N = isScalarAfterVectorization(I, VF) ? VF : 1; - return N * TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK, - Op2VK, Op1VP, Op2VP, Operands); + SmallVector<const Value *, 4> Operands(I->operand_values()); + return TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK, + Op2VK, Op1VP, Op2VP, Operands); } case Instruction::Select: { SelectInst *SI = cast<SelectInst>(I); @@ -7471,15 +7470,7 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I, } case Instruction::Store: case Instruction::Load: { - unsigned Width = VF; - if (Width > 1) { - InstWidening Decision = getWideningDecision(I, Width); - assert(Decision != CM_Unknown && - "CM decision should be taken at this point"); - if (Decision == CM_Scalarize) - Width = 1; - } - VectorTy = ToVectorTy(getMemInstValueType(I), Width); + VectorTy = ToVectorTy(getMemInstValueType(I), VF); return getMemoryInstructionCost(I, VF); } case Instruction::ZExt: |