diff options
| author | Quentin Colombet <qcolombet@apple.com> | 2016-04-21 18:09:34 +0000 |
|---|---|---|
| committer | Quentin Colombet <qcolombet@apple.com> | 2016-04-21 18:09:34 +0000 |
| commit | 0e5ff58567be2a08f690c0b6878dbf8a02b50d9c (patch) | |
| tree | 7d791dd7576e74a256783b72fb5ae0e373fc6d17 /llvm/lib/CodeGen | |
| parent | 8d1052f55cf807afc4fb21734d36f166b83ae4ea (diff) | |
| download | bcm5719-llvm-0e5ff58567be2a08f690c0b6878dbf8a02b50d9c.tar.gz bcm5719-llvm-0e5ff58567be2a08f690c0b6878dbf8a02b50d9c.zip | |
[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.
llvm-svn: 267025
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 54 |
2 files changed, 26 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp index f31b2cc9db0..4504d18b33e 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -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 diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 68173e955fd..9cd6af0ac85 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -365,27 +365,14 @@ void RegisterBankInfo::PartialMapping::dump() const { 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::print(raw_ostream &OS) const { 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::InstructionMapping::setOperandMapping( 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( |

