diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-30 17:37:31 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-30 17:37:31 +0000 | 
| commit | ee2f195dd3e40f49698ca4dc2666ec09c770e80d (patch) | |
| tree | 66fa9a69e5789356dfe844991e64bac9222f3a35 /lib/Transforms | |
| parent | ab44ce3d598882e51a25eb82eb7ae6308de85ae6 (diff) | |
Notes
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 67abc31169880..5e9f40019ce8c 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 3b036a6ac430e..2b83b8426d147 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: | 
