[llvm] r267025 - [RegisterBankInfo] Change the representation of the partial mappings.

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 11:09:37 PDT 2016


Author: qcolombet
Date: Thu Apr 21 13:09:34 2016
New Revision: 267025

URL: http://llvm.org/viewvc/llvm-project?rev=267025&view=rev
Log:
[RegisterBankInfo] Change the representation of the partial mappings.

Instead of holding a mask, hold two value: the start index and the
length of the mapping. This is a more compact representation, although
less powerful. That being said, arbitrary masks would not have worked
for the generic so do not allow them in the first place.

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
    llvm/trunk/lib/CodeGen/GlobalISel/RegBankSelect.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h?rev=267025&r1=267024&r2=267025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h Thu Apr 21 13:09:34 2016
@@ -36,20 +36,33 @@ class RegisterBankInfo {
 public:
   /// Helper struct that represents how a value is partially mapped
   /// into a register.
-  /// The Mask is used to represent this partial mapping. Ones represent
-  /// where the value lives in RegBank and the width of the Mask represents
-  /// the size of the whole value.
+  /// The StartIdx and Length represent what region of the orginal
+  /// value this partial mapping covers.
+  /// This can be represented as a Mask of contiguous bit starting
+  /// at StartIdx bit and spanning Length bits.
+  /// StartIdx is the number of bits from the less significant bits.
   struct PartialMapping {
-    /// Mask where the partial value lives.
-    APInt Mask;
+    /// Number of bits at which this partial mapping starts in the
+    /// original value.  The bits are counted from less significant
+    /// bits to most significant bits.
+    unsigned StartIdx;
+    /// Length of this mapping in bits. This is how many bits this
+    /// partial mapping covers in the original value:
+    /// from StartIdx to StartIdx + Length -1.
+    unsigned Length;
     /// Register bank where the partial value lives.
     const RegisterBank *RegBank;
 
     PartialMapping() = default;
 
     /// Provide a shortcut for quickly building PartialMapping.
-    PartialMapping(const APInt &Mask, const RegisterBank &RegBank)
-        : Mask(Mask), RegBank(&RegBank) {}
+    PartialMapping(unsigned StartIdx, unsigned Length,
+                   const RegisterBank &RegBank)
+        : StartIdx(StartIdx), Length(Length), RegBank(&RegBank) {}
+
+    /// \return the index of in the original value of the most
+    /// significant bit that this partial mapping covers.
+    unsigned getHighBitIdx() const { return StartIdx + Length - 1; }
 
     /// Print this partial mapping on dbgs() stream.
     void dump() const;

Modified: llvm/trunk/lib/CodeGen/GlobalISel/RegBankSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/RegBankSelect.cpp?rev=267025&r1=267024&r2=267025&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/RegBankSelect.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/RegBankSelect.cpp Thu Apr 21 13:09:34 2016
@@ -63,7 +63,7 @@ RegBankSelect::repairReg(unsigned Reg,
   assert(ValMapping.BreakDown.size() == 1 &&
          "Support for complex break down not supported yet");
   const RegisterBankInfo::PartialMapping &PartialMap = ValMapping.BreakDown[0];
-  assert(PartialMap.Mask.getBitWidth() ==
+  assert(PartialMap.Length ==
              (TargetRegisterInfo::isPhysicalRegister(Reg)
                   ? TRI->getMinimalPhysRegClass(Reg)->getSize() * 8
                   : MRI->getSize(Reg)) &&
@@ -111,8 +111,7 @@ RegBankSelect::repairReg(unsigned Reg,
   }
 
   // Create a new temporary to hold the repaired value.
-  unsigned NewReg =
-      MRI->createGenericVirtualRegister(PartialMap.Mask.getBitWidth());
+  unsigned NewReg = MRI->createGenericVirtualRegister(PartialMap.Length);
   // Set the registers for the source and destination of the copy.
   unsigned Src = Reg, Dst = NewReg;
   // If this is a definition that we repair, the copy will be

Modified: llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp?rev=267025&r1=267024&r2=267025&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp Thu Apr 21 13:09:34 2016
@@ -365,27 +365,14 @@ void RegisterBankInfo::PartialMapping::d
 
 void RegisterBankInfo::PartialMapping::verify() const {
   assert(RegBank && "Register bank not set");
-  // Check what is the minimum width that will live into RegBank.
-  // RegBank will have to, at least, accomodate all the bits between the first
-  // and last bits active in Mask.
-  // If Mask is zero, then ActiveWidth is 0.
-  unsigned ActiveWidth = 0;
-  // Otherwise, remove the trailing and leading zeros from the bitwidth.
-  // 0..0 ActiveWidth 0..0.
-  if (Mask.getBoolValue())
-    ActiveWidth = Mask.getBitWidth() - Mask.countLeadingZeros() -
-                  Mask.countTrailingZeros();
-  (void)ActiveWidth;
-  assert(ActiveWidth <= Mask.getBitWidth() &&
-         "Wrong computation of ActiveWidth, overflow?");
-  assert(RegBank->getSize() >= ActiveWidth &&
-         "Register bank too small for Mask");
+  assert(Length && "Empty mapping");
+  assert((StartIdx < getHighBitIdx()) && "Overflow, switch to APInt?");
+  // Check if the minimum width fits into RegBank.
+  assert(RegBank->getSize() >= Length && "Register bank too small for Mask");
 }
 
 void RegisterBankInfo::PartialMapping::print(raw_ostream &OS) const {
-  SmallString<128> MaskStr;
-  Mask.toString(MaskStr, /*Radix*/ 16, /*Signed*/ 0, /*formatAsCLiteral*/ true);
-  OS << "Mask(" << Mask.getBitWidth() << ") = " << MaskStr << ", RegBank = ";
+  OS << "[" << StartIdx << ", " << getHighBitIdx() << "], RegBank = ";
   if (RegBank)
     OS << *RegBank;
   else
@@ -394,18 +381,27 @@ void RegisterBankInfo::PartialMapping::p
 
 void RegisterBankInfo::ValueMapping::verify(unsigned ExpectedBitWidth) const {
   assert(!BreakDown.empty() && "Value mapped nowhere?!");
-  unsigned ValueBitWidth = BreakDown.back().Mask.getBitWidth();
-  assert(ValueBitWidth == ExpectedBitWidth && "BitWidth does not match");
-  APInt ValueMask(ValueBitWidth, 0);
+  unsigned OrigValueBitWidth = 0;
   for (const RegisterBankInfo::PartialMapping &PartMap : BreakDown) {
-    // Check that all the partial mapping have the same bitwidth.
-    assert(PartMap.Mask.getBitWidth() == ValueBitWidth &&
-           "Value does not have the same size accross the partial mappings");
-    // Check that the union of the partial mappings covers the whole value.
-    ValueMask |= PartMap.Mask;
     // Check that each register bank is big enough to hold the partial value:
     // this check is done by PartialMapping::verify
     PartMap.verify();
+    // The original value should completely be mapped.
+    // Thus the maximum accessed index + 1 is the size of the original value.
+    OrigValueBitWidth =
+        std::max(OrigValueBitWidth, PartMap.getHighBitIdx() + 1);
+  }
+  assert(OrigValueBitWidth == ExpectedBitWidth && "BitWidth does not match");
+  APInt ValueMask(OrigValueBitWidth, 0);
+  for (const RegisterBankInfo::PartialMapping &PartMap : BreakDown) {
+    // Check that the union of the partial mappings covers the whole value,
+    // without overlaps.
+    // The high bit is exclusive in the APInt API, thus getHighBitIdx + 1.
+    APInt PartMapMask = APInt::getBitsSet(OrigValueBitWidth, PartMap.StartIdx,
+                                          PartMap.getHighBitIdx() + 1);
+    ValueMask ^= PartMapMask;
+    assert((ValueMask & PartMapMask) == PartMapMask &&
+           "Some partial mappings overlap");
   }
   assert(ValueMask.isAllOnesValue() && "Value is not fully mapped");
 }
@@ -430,12 +426,10 @@ void RegisterBankInfo::InstructionMappin
     unsigned OpIdx, unsigned MaskSize, const RegisterBank &RegBank) {
   // Build the value mapping.
   assert(MaskSize <= RegBank.getSize() && "Register bank is too small");
-  APInt Mask(MaskSize, 0);
-  // The value is represented by all the bits.
-  Mask.flipAllBits();
 
   // Create the mapping object.
-  getOperandMapping(OpIdx).BreakDown.push_back(PartialMapping(Mask, RegBank));
+  getOperandMapping(OpIdx).BreakDown.push_back(
+      PartialMapping(0, MaskSize, RegBank));
 }
 
 void RegisterBankInfo::InstructionMapping::verify(




More information about the llvm-commits mailing list