summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2016-04-21 18:09:34 +0000
committerQuentin Colombet <qcolombet@apple.com>2016-04-21 18:09:34 +0000
commit0e5ff58567be2a08f690c0b6878dbf8a02b50d9c (patch)
tree7d791dd7576e74a256783b72fb5ae0e373fc6d17 /llvm/lib/CodeGen
parent8d1052f55cf807afc4fb21734d36f166b83ae4ea (diff)
downloadbcm5719-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.cpp5
-rw-r--r--llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp54
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(
OpenPOWER on IntegriCloud