]> granicus.if.org Git - llvm/commitdiff
Revert "[LoopVectorize][PowerPC] Estimate int and float register pressure separately...
authorJinsong Ji <jji@us.ibm.com>
Tue, 8 Oct 2019 17:32:56 +0000 (17:32 +0000)
committerJinsong Ji <jji@us.ibm.com>
Tue, 8 Oct 2019 17:32:56 +0000 (17:32 +0000)
Also Revert "[LoopVectorize] Fix non-debug builds after rL374017"

This reverts commit 9f41deccc0e648a006c9f38e11919f181b6c7e0a.
This reverts commit 18b6fe07bcf44294f200bd2b526cb737ed275c04.

The patch is breaking PowerPC internal build, checked with author, reverting
on behalf of him for now due to timezone.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374091 91177308-0d34-0410-b5e6-96231b3b80d8

21 files changed:
include/llvm/Analysis/TargetTransformInfo.h
include/llvm/Analysis/TargetTransformInfoImpl.h
include/llvm/CodeGen/BasicTTIImpl.h
lib/Analysis/TargetTransformInfo.cpp
lib/Target/AArch64/AArch64TargetTransformInfo.h
lib/Target/ARM/ARMTargetTransformInfo.h
lib/Target/PowerPC/PPCTargetTransformInfo.cpp
lib/Target/PowerPC/PPCTargetTransformInfo.h
lib/Target/SystemZ/SystemZTargetTransformInfo.cpp
lib/Target/SystemZ/SystemZTargetTransformInfo.h
lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp
lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h
lib/Target/X86/X86TargetTransformInfo.cpp
lib/Target/X86/X86TargetTransformInfo.h
lib/Target/XCore/XCoreTargetTransformInfo.h
lib/Transforms/Scalar/LoopStrengthReduce.cpp
lib/Transforms/Vectorize/LoopVectorize.cpp
lib/Transforms/Vectorize/SLPVectorizer.cpp
test/Transforms/LoopVectorize/PowerPC/reg-usage.ll [deleted file]
test/Transforms/LoopVectorize/X86/reg-usage-debug.ll
test/Transforms/LoopVectorize/X86/reg-usage.ll

index abea2afe26b7535766dcfc4154e4c594a173e358..6da2d7f43bc42d59d0838084d46f2d4dc210496f 100644 (file)
@@ -788,23 +788,10 @@ public:
   /// Additional properties of an operand's values.
   enum OperandValueProperties { OP_None = 0, OP_PowerOf2 = 1 };
 
-  /// \return the number of registers in the target-provided register class.
-  unsigned getNumberOfRegisters(unsigned ClassID) const;
-
-  /// \return the target-provided register class ID for the provided type,
-  /// accounting for type promotion and other type-legalization techniques that the target might apply.
-  /// However, it specifically does not account for the scalarization or splitting of vector types.
-  /// Should a vector type require scalarization or splitting into multiple underlying vector registers,
-  /// that type should be mapped to a register class containing no registers.
-  /// Specifically, this is designed to provide a simple, high-level view of the register allocation
-  /// later performed by the backend. These register classes don't necessarily map onto the
-  /// register classes used by the backend.
-  /// FIXME: It's not currently possible to determine how many registers
-  /// are used by the provided type.
-  unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const;
-
-  /// \return the target-provided register class name
-  const char* getRegisterClassName(unsigned ClassID) const;
+  /// \return The number of scalar or vector registers that the target has.
+  /// If 'Vectors' is true, it returns the number of vector registers. If it is
+  /// set to false, it returns the number of scalar registers.
+  unsigned getNumberOfRegisters(bool Vector) const;
 
   /// \return The width of the largest scalar or vector register type.
   unsigned getRegisterBitWidth(bool Vector) const;
@@ -1256,9 +1243,7 @@ public:
                             Type *Ty) = 0;
   virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
                             Type *Ty) = 0;
-  virtual unsigned getNumberOfRegisters(unsigned ClassID) const = 0;
-  virtual unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const = 0;
-  virtual const char* getRegisterClassName(unsigned ClassID) const = 0;
+  virtual unsigned getNumberOfRegisters(bool Vector) = 0;
   virtual unsigned getRegisterBitWidth(bool Vector) const = 0;
   virtual unsigned getMinVectorRegisterBitWidth() = 0;
   virtual bool shouldMaximizeVectorBandwidth(bool OptSize) const = 0;
@@ -1601,14 +1586,8 @@ public:
                     Type *Ty) override {
     return Impl.getIntImmCost(IID, Idx, Imm, Ty);
   }
-  unsigned getNumberOfRegisters(unsigned ClassID) const override {
-    return Impl.getNumberOfRegisters(ClassID);
-  }
-  unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const override {
-    return Impl.getRegisterClassForType(Vector, Ty);
-  }
-  const char* getRegisterClassName(unsigned ClassID) const override {
-    return Impl.getRegisterClassName(ClassID);
+  unsigned getNumberOfRegisters(bool Vector) override {
+    return Impl.getNumberOfRegisters(Vector);
   }
   unsigned getRegisterBitWidth(bool Vector) const override {
     return Impl.getRegisterBitWidth(Vector);
index f850d9a7bb567750ce9b89112209765ca5ee2062..2f1011799f1371e2119a607753c76c2753718e10 100644 (file)
@@ -354,20 +354,7 @@ public:
     return TTI::TCC_Free;
   }
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const { return 8; }
-
-  unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const {
-    return Vector ? 1 : 0;
-  };
-
-  const char* getRegisterClassName(unsigned ClassID) const {
-    switch (ClassID) {
-      default:
-        return "Generic::Unknown Register Class";
-      case 0: return "Generic::ScalarRC";
-      case 1: return "Generic::VectorRC";
-    }
-  }
+  unsigned getNumberOfRegisters(bool Vector) { return 8; }
 
   unsigned getRegisterBitWidth(bool Vector) const { return 32; }
 
index 1cf9cc61f219eb39c943e31f880e94e9915b7629..75e0f844fd07597ff964cab3582ab2fbc8600023 100644 (file)
@@ -519,6 +519,8 @@ public:
   /// \name Vector TTI Implementations
   /// @{
 
+  unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; }
+
   unsigned getRegisterBitWidth(bool Vector) const { return 32; }
 
   /// Estimate the overhead of scalarizing an instruction. Insert and Extract
index aa93e1d034fdb5a02437add7b1bdf05f8d570308..f3d20ce984dbd09a832e4db65079fcf1f8ae1b11 100644 (file)
@@ -466,16 +466,8 @@ int TargetTransformInfo::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
   return Cost;
 }
 
-unsigned TargetTransformInfo::getNumberOfRegisters(unsigned ClassID) const {
-  return TTIImpl->getNumberOfRegisters(ClassID);
-}
-
-unsigned TargetTransformInfo::getRegisterClassForType(bool Vector, Type *Ty) const {
-  return TTIImpl->getRegisterClassForType(Vector, Ty);
-}
-
-const char* TargetTransformInfo::getRegisterClassName(unsigned ClassID) const {
-  return TTIImpl->getRegisterClassName(ClassID);
+unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const {
+  return TTIImpl->getNumberOfRegisters(Vector);
 }
 
 unsigned TargetTransformInfo::getRegisterBitWidth(bool Vector) const {
index d5ef0e5bea3b79c8c8638e215eee0a213b4d100f..95cda63b01744668e2ce5becb6d7151014916f9c 100644 (file)
@@ -85,8 +85,7 @@ public:
 
   bool enableInterleavedAccessVectorization() { return true; }
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const {
-    bool Vector = (ClassID == 1);
+  unsigned getNumberOfRegisters(bool Vector) {
     if (Vector) {
       if (ST->hasNEON())
         return 32;
index b878ea3a171215d5d7ffa309026c23d0f1f9dfa6..47e98dac9f6bfbd1f1707010229233873305e2c6 100644 (file)
@@ -122,8 +122,7 @@ public:
   /// \name Vector TTI Implementations
   /// @{
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const {
-    bool Vector = (ClassID == 1);
+  unsigned getNumberOfRegisters(bool Vector) {
     if (Vector) {
       if (ST->hasNEON())
         return 16;
index 764335128d424d9a3ce6062446c3bbed0899325b..40e536687014b433dd90e65415f6f83d10182468 100644 (file)
@@ -594,37 +594,10 @@ bool PPCTTIImpl::enableInterleavedAccessVectorization() {
   return true;
 }
 
-unsigned PPCTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
-  assert(ClassID == GPRRC || ClassID == FPRRC ||
-         ClassID == VRRC || ClassID == VSXRC);
-  if (ST->hasVSX()) {
-    assert(ClassID == GPRRC || ClassID == VSXRC);
-    return ClassID == GPRRC ? 32 : 64;
-  }
-  assert(ClassID == GPRRC || ClassID == FPRRC || ClassID == VRRC);
-  return 32;
-}
-
-unsigned PPCTTIImpl::getRegisterClassForType(bool Vector, Type *Ty) const {
-  if (Vector)
-    return ST->hasVSX() ? VSXRC : VRRC;
-  else if (Ty && Ty->getScalarType()->isFloatTy())
-    return ST->hasVSX() ? VSXRC : FPRRC;
-  else
-    return GPRRC;
-}
-
-const char* PPCTTIImpl::getRegisterClassName(unsigned ClassID) const {
-
-  switch (ClassID) {
-    default:
-      llvm_unreachable("unknown register class");
-      return "PPC::unknown register class";
-    case GPRRC:       return "PPC::GPRRC";
-    case FPRRC:       return "PPC::FPRRC";
-    case VRRC:        return "PPC::VRRC";
-    case VSXRC:       return "PPC::VSXRC";
-  }
+unsigned PPCTTIImpl::getNumberOfRegisters(bool Vector) {
+  if (Vector && !ST->hasAltivec() && !ST->hasQPX())
+    return 0;
+  return ST->hasVSX() ? 64 : 32;
 }
 
 unsigned PPCTTIImpl::getRegisterBitWidth(bool Vector) const {
index 294c970f21fb522af36fd466171ee77fb0562154..5d76ee418b694e8028abdddefffd177f4aff80b9 100644 (file)
@@ -72,13 +72,7 @@ public:
   TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
                                                     bool IsZeroCmp) const;
   bool enableInterleavedAccessVectorization();
-
-  enum PPCRegisterClass {
-    GPRRC, FPRRC, VRRC, VSXRC
-  };
-  unsigned getNumberOfRegisters(unsigned ClassID) const;
-  unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const;
-  const char* getRegisterClassName(unsigned ClassID) const;
+  unsigned getNumberOfRegisters(bool Vector);
   unsigned getRegisterBitWidth(bool Vector) const;
   unsigned getCacheLineSize();
   unsigned getPrefetchDistance();
index 11c99aa111745e3be9092b3c8a307e4f3cb544d2..8d45e67d73c2660dd2e88af756147d84fc5ef26a 100644 (file)
@@ -304,8 +304,7 @@ bool SystemZTTIImpl::isLSRCostLess(TargetTransformInfo::LSRCost &C1,
              C2.ScaleCost, C2.SetupCost);
 }
 
-unsigned SystemZTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
-  bool Vector = (ClassID == 1);
+unsigned SystemZTTIImpl::getNumberOfRegisters(bool Vector) {
   if (!Vector)
     // Discount the stack pointer.  Also leave out %r0, since it can't
     // be used in an address.
index e59badeb944df91e7c5453070702ed8476e5d125..16ce2ef1d7a00589fbc610b41bd2974700e39789 100644 (file)
@@ -56,7 +56,7 @@ public:
   /// \name Vector TTI Implementations
   /// @{
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const;
+  unsigned getNumberOfRegisters(bool Vector);
   unsigned getRegisterBitWidth(bool Vector) const;
 
   unsigned getCacheLineSize() { return 256; }
index 1c53e90daea7b7b7320a77392b7f5edf40005540..46ef765ce0f4b382d91b3d3237a372daad4c5741 100644 (file)
@@ -25,11 +25,10 @@ WebAssemblyTTIImpl::getPopcntSupport(unsigned TyWidth) const {
   return TargetTransformInfo::PSK_FastHardware;
 }
 
-unsigned WebAssemblyTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
-  unsigned Result = BaseT::getNumberOfRegisters(ClassID);
+unsigned WebAssemblyTTIImpl::getNumberOfRegisters(bool Vector) {
+  unsigned Result = BaseT::getNumberOfRegisters(Vector);
 
   // For SIMD, use at least 16 registers, as a rough guess.
-  bool Vector = (ClassID == 1);
   if (Vector)
     Result = std::max(Result, 16u);
 
index f0ecc73e91de79214f9f2a3332d0aa1fa31b17bc..1b11b4b631eb930e051c87026b7063a1b2a0b4c1 100644 (file)
@@ -53,7 +53,7 @@ public:
   /// \name Vector TTI Implementations
   /// @{
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const;
+  unsigned getNumberOfRegisters(bool Vector);
   unsigned getRegisterBitWidth(bool Vector) const;
   unsigned getArithmeticInstrCost(
       unsigned Opcode, Type *Ty,
index 2f419b78f83cf89e65d00ee7b181e9d638778057..b634da1d51fbe6336f06c316018ddcdf70b98eba 100644 (file)
@@ -116,8 +116,7 @@ llvm::Optional<unsigned> X86TTIImpl::getCacheAssociativity(
   llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
 }
 
-unsigned X86TTIImpl::getNumberOfRegisters(unsigned ClassID) const {
-  bool Vector = (ClassID == 1);
+unsigned X86TTIImpl::getNumberOfRegisters(bool Vector) {
   if (Vector && !ST->hasSSE1())
     return 0;
 
index 3ff1896f5052c0e602c76c5d28dda38337f39d3f..9b948dbbb4cb96bd9296f8c5404e039abe83b734 100644 (file)
@@ -116,7 +116,7 @@ public:
   /// \name Vector TTI Implementations
   /// @{
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const;
+  unsigned getNumberOfRegisters(bool Vector);
   unsigned getRegisterBitWidth(bool Vector) const;
   unsigned getLoadStoreVecRegBitWidth(unsigned AS) const;
   unsigned getMaxInterleaveFactor(unsigned VF);
index 58df1f290ec9d77dcf0cf15e79bad42e2caf56c8..3fecaaa597224c3d10c25ff5bcccefbfca44bbee 100644 (file)
@@ -40,8 +40,7 @@ public:
       : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl()),
         TLI(ST->getTargetLowering()) {}
 
-  unsigned getNumberOfRegisters(unsigned ClassID) const {
-    bool Vector = (ClassID == 1);
+  unsigned getNumberOfRegisters(bool Vector) {
     if (Vector) {
       return 0;
     }
index 7f119175c4a820ea75c4b83ba46564d793a2e5e2..852bbefaf20b65563ab59da9524723a885cb9534 100644 (file)
@@ -1386,9 +1386,7 @@ void Cost::RateFormula(const Formula &F,
 
   // Treat every new register that exceeds TTI.getNumberOfRegisters() - 1 as
   // additional instruction (at least fill).
-  // TODO: Need distinguish register class?
-  unsigned TTIRegNum = TTI->getNumberOfRegisters(
-                       TTI->getRegisterClassForType(false, F.getType())) - 1;
+  unsigned TTIRegNum = TTI->getNumberOfRegisters(false) - 1;
   if (C.NumRegs > TTIRegNum) {
     // Cost already exceeded TTIRegNum, then only newly added register can add
     // new instructions.
index 18cc61f7a2b7937a737cf419ee23e1403e98704b..7e95038a5ebcfe72468fe3d6294694e7ac184224 100644 (file)
@@ -983,11 +983,10 @@ public:
   /// of a loop.
   struct RegisterUsage {
     /// Holds the number of loop invariant values that are used in the loop.
-    /// The key is ClassID of target-provided register class.
-    SmallMapVector<unsigned, unsigned, 4> LoopInvariantRegs;
+    unsigned LoopInvariantRegs;
+
     /// Holds the maximum number of concurrent live intervals in the loop.
-    /// The key is ClassID of target-provided register class.
-    SmallMapVector<unsigned, unsigned, 4> MaxLocalUsers;
+    unsigned MaxLocalUsers;
   };
 
   /// \return Returns information about the register usages of the loop for the
@@ -4963,14 +4962,9 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount) {
 
     // Select the largest VF which doesn't require more registers than existing
     // ones.
+    unsigned TargetNumRegisters = TTI.getNumberOfRegisters(true);
     for (int i = RUs.size() - 1; i >= 0; --i) {
-      bool Selected = true;
-      for (auto& pair : RUs[i].MaxLocalUsers) {
-        unsigned TargetNumRegisters = TTI.getNumberOfRegisters(pair.first);
-        if (pair.second > TargetNumRegisters)
-          Selected = false;
-      }
-      if (Selected) {
+      if (RUs[i].MaxLocalUsers <= TargetNumRegisters) {
         MaxVF = VFs[i];
         break;
       }
@@ -5121,12 +5115,22 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(unsigned VF,
   if (TC > 1 && TC < TinyTripCountInterleaveThreshold)
     return 1;
 
+  unsigned TargetNumRegisters = TTI.getNumberOfRegisters(VF > 1);
+  LLVM_DEBUG(dbgs() << "LV: The target has " << TargetNumRegisters
+                    << " registers\n");
+
+  if (VF == 1) {
+    if (ForceTargetNumScalarRegs.getNumOccurrences() > 0)
+      TargetNumRegisters = ForceTargetNumScalarRegs;
+  } else {
+    if (ForceTargetNumVectorRegs.getNumOccurrences() > 0)
+      TargetNumRegisters = ForceTargetNumVectorRegs;
+  }
+
   RegisterUsage R = calculateRegisterUsage({VF})[0];
   // We divide by these constants so assume that we have at least one
   // instruction that uses at least one register.
-  for (auto& pair : R.MaxLocalUsers) {
-    pair.second = std::max(pair.second, 1U);
-  }
+  R.MaxLocalUsers = std::max(R.MaxLocalUsers, 1U);
 
   // We calculate the interleave count using the following formula.
   // Subtract the number of loop invariants from the number of available
@@ -5139,35 +5143,13 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(unsigned VF,
   // We also want power of two interleave counts to ensure that the induction
   // variable of the vector loop wraps to zero, when tail is folded by masking;
   // this currently happens when OptForSize, in which case IC is set to 1 above.
-  unsigned IC = UINT_MAX;
+  unsigned IC = PowerOf2Floor((TargetNumRegisters - R.LoopInvariantRegs) /
+                              R.MaxLocalUsers);
 
-  for (auto& pair : R.MaxLocalUsers) {
-    unsigned TargetNumRegisters = TTI.getNumberOfRegisters(pair.first);
-    LLVM_DEBUG(dbgs() << "LV: The target has " << TargetNumRegisters
-                      << " registers of "
-                      << TTI.getRegisterClassName(pair.first) << " register class\n");
-    if (VF == 1) {
-      if (ForceTargetNumScalarRegs.getNumOccurrences() > 0)
-        TargetNumRegisters = ForceTargetNumScalarRegs;
-    } else {
-      if (ForceTargetNumVectorRegs.getNumOccurrences() > 0)
-        TargetNumRegisters = ForceTargetNumVectorRegs;
-    }
-    unsigned MaxLocalUsers = pair.second;
-    unsigned LoopInvariantRegs = 0;
-    if (R.LoopInvariantRegs.find(pair.first) != R.LoopInvariantRegs.end())
-      LoopInvariantRegs = R.LoopInvariantRegs[pair.first];
-
-    unsigned TmpIC = PowerOf2Floor((TargetNumRegisters - LoopInvariantRegs) / MaxLocalUsers);
-    // Don't count the induction variable as interleaved.
-    if (EnableIndVarRegisterHeur) {
-      TmpIC =
-          PowerOf2Floor((TargetNumRegisters - LoopInvariantRegs - 1) /
-                        std::max(1U, (MaxLocalUsers - 1)));
-    }
-
-    IC = std::min(IC, TmpIC);
-  }
+  // Don't count the induction variable as interleaved.
+  if (EnableIndVarRegisterHeur)
+    IC = PowerOf2Floor((TargetNumRegisters - R.LoopInvariantRegs - 1) /
+                       std::max(1U, (R.MaxLocalUsers - 1)));
 
   // Clamp the interleave ranges to reasonable counts.
   unsigned MaxInterleaveCount = TTI.getMaxInterleaveFactor(VF);
@@ -5349,7 +5331,7 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<unsigned> VFs) {
   const DataLayout &DL = TheFunction->getParent()->getDataLayout();
 
   SmallVector<RegisterUsage, 8> RUs(VFs.size());
-  SmallVector<SmallMapVector<unsigned, unsigned, 4>, 8> MaxUsages(VFs.size());
+  SmallVector<unsigned, 8> MaxUsages(VFs.size(), 0);
 
   LLVM_DEBUG(dbgs() << "LV(REG): Calculating max register usage:\n");
 
@@ -5379,45 +5361,21 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<unsigned> VFs) {
 
     // For each VF find the maximum usage of registers.
     for (unsigned j = 0, e = VFs.size(); j < e; ++j) {
-      // Count the number of live intervals.
-      SmallMapVector<unsigned, unsigned, 4> RegUsage;
-
       if (VFs[j] == 1) {
-        for (auto Inst : OpenIntervals) {
-          unsigned ClassID = TTI.getRegisterClassForType(false, Inst->getType());
-          if (RegUsage.find(ClassID) == RegUsage.end())
-            RegUsage[ClassID] = 1;
-          else
-            RegUsage[ClassID] += 1;
-        }
-      } else {
-        collectUniformsAndScalars(VFs[j]);
-        for (auto Inst : OpenIntervals) {
-          // Skip ignored values for VF > 1.
-          if (VecValuesToIgnore.find(Inst) != VecValuesToIgnore.end())
-            continue;
-          if (isScalarAfterVectorization(Inst, VFs[j])) {
-            unsigned ClassID = TTI.getRegisterClassForType(false, Inst->getType());
-            if (RegUsage.find(ClassID) == RegUsage.end())
-              RegUsage[ClassID] = 1;
-            else
-              RegUsage[ClassID] += 1;
-          } else {
-            unsigned ClassID = TTI.getRegisterClassForType(true, Inst->getType());
-            if (RegUsage.find(ClassID) == RegUsage.end())
-              RegUsage[ClassID] = GetRegUsage(Inst->getType(), VFs[j]);
-            else
-              RegUsage[ClassID] += GetRegUsage(Inst->getType(), VFs[j]);
-          }
-        }
+        MaxUsages[j] = std::max(MaxUsages[j], OpenIntervals.size());
+        continue;
       }
-    
-      for (auto& pair : RegUsage) {
-        if (MaxUsages[j].find(pair.first) != MaxUsages[j].end())
-          MaxUsages[j][pair.first] = std::max(MaxUsages[j][pair.first], pair.second);
-        else
-          MaxUsages[j][pair.first] = pair.second;
+      collectUniformsAndScalars(VFs[j]);
+      // Count the number of live intervals.
+      unsigned RegUsage = 0;
+      for (auto Inst : OpenIntervals) {
+        // Skip ignored values for VF > 1.
+        if (VecValuesToIgnore.find(Inst) != VecValuesToIgnore.end() ||
+            isScalarAfterVectorization(Inst, VFs[j]))
+          continue;
+        RegUsage += GetRegUsage(Inst->getType(), VFs[j]);
       }
+      MaxUsages[j] = std::max(MaxUsages[j], RegUsage);
     }
 
     LLVM_DEBUG(dbgs() << "LV(REG): At #" << i << " Interval # "
@@ -5428,34 +5386,18 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<unsigned> VFs) {
   }
 
   for (unsigned i = 0, e = VFs.size(); i < e; ++i) {
-    SmallMapVector<unsigned, unsigned, 4> Invariant;
-  
-    for (auto Inst : LoopInvariants) {
-      unsigned Usage = VFs[i] == 1 ? 1 : GetRegUsage(Inst->getType(), VFs[i]);
-      unsigned ClassID = TTI.getRegisterClassForType(VFs[i] > 1, Inst->getType());
-      if (Invariant.find(ClassID) == Invariant.end())
-        Invariant[ClassID] = Usage;
-      else
-        Invariant[ClassID] += Usage;
+    unsigned Invariant = 0;
+    if (VFs[i] == 1)
+      Invariant = LoopInvariants.size();
+    else {
+      for (auto Inst : LoopInvariants)
+        Invariant += GetRegUsage(Inst->getType(), VFs[i]);
     }
 
     LLVM_DEBUG(dbgs() << "LV(REG): VF = " << VFs[i] << '\n');
-    LLVM_DEBUG(dbgs() << "LV(REG): Found max usage: "
-                      << MaxUsages[i].size() << " item\n");
-    for (const auto& Pair : MaxUsages[i]) {
-      (void)Pair;
-      LLVM_DEBUG(dbgs() << "LV(REG): RegisterClass: "
-                        << TTI.getRegisterClassName(Pair.first)
-                        << ", " << Pair.second << " registers \n");
-    }
-    LLVM_DEBUG(dbgs() << "LV(REG): Found invariant usage: "
-                      << Invariant.size() << " item\n");
-    for (const auto& Pair : Invariant) {
-      (void)Pair;
-      LLVM_DEBUG(dbgs() << "LV(REG): RegisterClass: "
-                        << TTI.getRegisterClassName(Pair.first)
-                        << ", " << Pair.second << " registers \n");
-    }
+    LLVM_DEBUG(dbgs() << "LV(REG): Found max usage: " << MaxUsages[i] << '\n');
+    LLVM_DEBUG(dbgs() << "LV(REG): Found invariant usage: " << Invariant
+                      << '\n');
 
     RU.LoopInvariantRegs = Invariant;
     RU.MaxLocalUsers = MaxUsages[i];
@@ -7820,8 +7762,7 @@ bool LoopVectorizePass::runImpl(
   // The second condition is necessary because, even if the target has no
   // vector registers, loop vectorization may still enable scalar
   // interleaving.
-  if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true)) &&
-      TTI->getMaxInterleaveFactor(1) < 2)
+  if (!TTI->getNumberOfRegisters(true) && TTI->getMaxInterleaveFactor(1) < 2)
     return false;
 
   bool Changed = false;
index a22153bbed170eb62f88f2db88b9aedd378e3ee3..99428c6c5dee384ad2ec64204c3bf1798ee0ec96 100644 (file)
@@ -5237,7 +5237,7 @@ bool SLPVectorizerPass::runImpl(Function &F, ScalarEvolution *SE_,
 
   // If the target claims to have no vector registers don't attempt
   // vectorization.
-  if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true)))
+  if (!TTI->getNumberOfRegisters(true))
     return false;
 
   // Don't vectorize when the attribute NoImplicitFloat is used.
diff --git a/test/Transforms/LoopVectorize/PowerPC/reg-usage.ll b/test/Transforms/LoopVectorize/PowerPC/reg-usage.ll
deleted file mode 100644 (file)
index 55593c3..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-; RUN: opt < %s -debug-only=loop-vectorize -loop-vectorize -vectorizer-maximize-bandwidth -O2 -mtriple=powerpc64-unknown-linux -S -mcpu=pwr8 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PWR8
-; RUN: opt < %s -debug-only=loop-vectorize -loop-vectorize -vectorizer-maximize-bandwidth -O2 -mtriple=powerpc64le-unknown-linux -S -mcpu=pwr9 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PWR9
-; REQUIRES: asserts
-
-@a = global [1024 x i8] zeroinitializer, align 16
-@b = global [1024 x i8] zeroinitializer, align 16
-
-define i32 @foo() {
-;
-; CHECK-LABEL: foo
-
-; CHECK:      LV(REG): VF = 8
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 7 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK:      LV(REG): VF = 16
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 13 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-
-; CHECK-PWR8:      LV(REG): VF = 16
-; CHECK-PWR8-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-PWR8-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-PWR8-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 13 registers
-; CHECK-PWR8-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK-PWR8: Setting best plan to VF=16, UF=4
-
-; CHECK-PWR9:      LV(REG): VF = 8
-; CHECK-PWR9-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-PWR9-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-PWR9-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 7 registers
-; CHECK-PWR9-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK-PWR9: Setting best plan to VF=8, UF=8
-
-
-entry:
-  br label %for.body
-
-for.cond.cleanup:
-  %add.lcssa = phi i32 [ %add, %for.body ]
-  ret i32 %add.lcssa
-
-for.body:
-  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
-  %s.015 = phi i32 [ 0, %entry ], [ %add, %for.body ]
-  %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @a, i64 0, i64 %indvars.iv
-  %0 = load i8, i8* %arrayidx, align 1
-  %conv = zext i8 %0 to i32
-  %arrayidx2 = getelementptr inbounds [1024 x i8], [1024 x i8]* @b, i64 0, i64 %indvars.iv
-  %1 = load i8, i8* %arrayidx2, align 1
-  %conv3 = zext i8 %1 to i32
-  %sub = sub nsw i32 %conv, %conv3
-  %ispos = icmp sgt i32 %sub, -1
-  %neg = sub nsw i32 0, %sub
-  %2 = select i1 %ispos, i32 %sub, i32 %neg
-  %add = add nsw i32 %2, %s.015
-  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
-  %exitcond = icmp eq i64 %indvars.iv.next, 1024
-  br i1 %exitcond, label %for.cond.cleanup, label %for.body
-}
-
-define i32 @goo() {
-; For indvars.iv used in a computating chain only feeding into getelementptr or cmp,
-; it will not have vector version and the vector register usage will not exceed the
-; available vector register number.
-; CHECK-LABEL: goo
-; CHECK:      LV(REG): VF = 8
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 7 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK:      LV(REG): VF = 16
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 13 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK:      LV(REG): VF = 16
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 13 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-
-; CHECK: Setting best plan to VF=16, UF=4
-
-entry:
-  br label %for.body
-
-for.cond.cleanup:                                 ; preds = %for.body
-  %add.lcssa = phi i32 [ %add, %for.body ]
-  ret i32 %add.lcssa
-
-for.body:                                         ; preds = %for.body, %entry
-  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
-  %s.015 = phi i32 [ 0, %entry ], [ %add, %for.body ]
-  %tmp1 = add nsw i64 %indvars.iv, 3
-  %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @a, i64 0, i64 %tmp1
-  %tmp = load i8, i8* %arrayidx, align 1
-  %conv = zext i8 %tmp to i32
-  %tmp2 = add nsw i64 %indvars.iv, 2
-  %arrayidx2 = getelementptr inbounds [1024 x i8], [1024 x i8]* @b, i64 0, i64 %tmp2
-  %tmp3 = load i8, i8* %arrayidx2, align 1
-  %conv3 = zext i8 %tmp3 to i32
-  %sub = sub nsw i32 %conv, %conv3
-  %ispos = icmp sgt i32 %sub, -1
-  %neg = sub nsw i32 0, %sub
-  %tmp4 = select i1 %ispos, i32 %sub, i32 %neg
-  %add = add nsw i32 %tmp4, %s.015
-  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
-  %exitcond = icmp eq i64 %indvars.iv.next, 1024
-  br i1 %exitcond, label %for.cond.cleanup, label %for.body
-}
-
-define i64 @bar(i64* nocapture %a) {
-; CHECK-LABEL: bar
-; CHECK:      LV(REG): VF = 2
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 3 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 1 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-
-; CHECK: Setting best plan to VF=2, UF=12
-
-entry:
-  br label %for.body
-
-for.cond.cleanup:
-  %add2.lcssa = phi i64 [ %add2, %for.body ]
-  ret i64 %add2.lcssa
-
-for.body:
-  %i.012 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
-  %s.011 = phi i64 [ 0, %entry ], [ %add2, %for.body ]
-  %arrayidx = getelementptr inbounds i64, i64* %a, i64 %i.012
-  %0 = load i64, i64* %arrayidx, align 8
-  %add = add nsw i64 %0, %i.012
-  store i64 %add, i64* %arrayidx, align 8
-  %add2 = add nsw i64 %add, %s.011
-  %inc = add nuw nsw i64 %i.012, 1
-  %exitcond = icmp eq i64 %inc, 1024
-  br i1 %exitcond, label %for.cond.cleanup, label %for.body
-}
-
-@d = external global [0 x i64], align 8
-@e = external global [0 x i32], align 4
-@c = external global [0 x i32], align 4
-
-define void @hoo(i32 %n) {
-; CHECK-LABEL: hoo
-; CHECK:      LV(REG): VF = 4
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::VSXRC, 2 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK:      LV(REG): VF = 1
-; CHECK-NEXT: LV(REG): Found max usage: 1 item
-; CHECK-NEXT: LV(REG): RegisterClass: PPC::GPRRC, 2 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-; CHECK: Setting best plan to VF=1, UF=12
-
-entry:
-  br label %for.body
-
-for.body:                                         ; preds = %for.body, %entry
-  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
-  %arrayidx = getelementptr inbounds [0 x i64], [0 x i64]* @d, i64 0, i64 %indvars.iv
-  %tmp = load i64, i64* %arrayidx, align 8
-  %arrayidx1 = getelementptr inbounds [0 x i32], [0 x i32]* @e, i64 0, i64 %tmp
-  %tmp1 = load i32, i32* %arrayidx1, align 4
-  %arrayidx3 = getelementptr inbounds [0 x i32], [0 x i32]* @c, i64 0, i64 %indvars.iv
-  store i32 %tmp1, i32* %arrayidx3, align 4
-  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
-  %exitcond = icmp eq i64 %indvars.iv.next, 10000
-  br i1 %exitcond, label %for.end, label %for.body
-
-for.end:                                          ; preds = %for.body
-  ret void
-}
index b6254a4f8aa0495698b44f3dc2909e053993d1d1..8205092deffa208ad76cf37729555285c054e44a 100644 (file)
@@ -22,11 +22,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 ; CHECK: LV: Checking a loop in "test_g"
-; CHECK: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 2 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 1 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 2 registers
+; CHECK: LV(REG): Found max usage: 2
 
 define i32 @test_g(i32* nocapture readonly %a, i32 %n) local_unnamed_addr !dbg !6 {
 entry:
@@ -64,11 +60,7 @@ for.end:                                          ; preds = %for.end.loopexit, %
 }
 
 ; CHECK: LV: Checking a loop in "test"
-; CHECK: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 2 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 1 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 2 registers
+; CHECK: LV(REG): Found max usage: 2
 
 define i32 @test(i32* nocapture readonly %a, i32 %n) local_unnamed_addr {
 entry:
index cae9360e061334719f0a43d31b079ac4dd2724e4..9b276aa2bd7df2ff19d209e9bf95c8599220435e 100644 (file)
@@ -11,15 +11,9 @@ define i32 @foo() {
 ;
 ; CHECK-LABEL: foo
 ; CHECK:      LV(REG): VF = 8
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 7 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
+; CHECK-NEXT: LV(REG): Found max usage: 7
 ; CHECK:      LV(REG): VF = 16
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 13 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
+; CHECK-NEXT: LV(REG): Found max usage: 13
 
 entry:
   br label %for.body
@@ -53,15 +47,9 @@ define i32 @goo() {
 ; available vector register number.
 ; CHECK-LABEL: goo
 ; CHECK:      LV(REG): VF = 8
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 7 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
+; CHECK-NEXT: LV(REG): Found max usage: 7
 ; CHECK:      LV(REG): VF = 16
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 13 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
+; CHECK-NEXT: LV(REG): Found max usage: 13
 entry:
   br label %for.body
 
@@ -93,11 +81,8 @@ for.body:                                         ; preds = %for.body, %entry
 define i64 @bar(i64* nocapture %a) {
 ; CHECK-LABEL: bar
 ; CHECK:       LV(REG): VF = 2
-; CHECK-NEXT: LV(REG): Found max usage: 2 item
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::VectorRC, 3 registers
-; CHECK-NEXT: LV(REG): RegisterClass: Generic::ScalarRC, 1 registers
-; CHECK-NEXT: LV(REG): Found invariant usage: 0 item
-
+; CHECK:       LV(REG): Found max usage: 3
+;
 entry:
   br label %for.body
 
@@ -128,11 +113,8 @@ define void @hoo(i32 %n) {
 ; so the max usage of AVX512 vector register will be 2.
 ; AVX512F-LABEL: bar
 ; AVX512F:       LV(REG): VF = 16
-; AVX512F-CHECK: LV(REG): Found max usage: 2 item
-; AVX512F-CHECK: LV(REG): RegisterClass: Generic::ScalarRC, 2 registers
-; AVX512F-CHECK: LV(REG): RegisterClass: Generic::VectorRC, 2 registers
-; AVX512F-CHECK: LV(REG): Found invariant usage: 0 item
-
+; AVX512F:       LV(REG): Found max usage: 2
+;
 entry:
   br label %for.body