[llvm] r278548 - [PPC] Memoize getValueBits. NFC.
Tim Shen via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 12 11:40:04 PDT 2016
Author: timshen
Date: Fri Aug 12 13:40:04 2016
New Revision: 278548
URL: http://llvm.org/viewvc/llvm-project?rev=278548&view=rev
Log:
[PPC] Memoize getValueBits. NFC.
Summary: It triggers exponential behavior when the DAG has many branches.
Reviewers: hfinkel, kbarton
Subscribers: iteratee, nemanjai, echristo
Differential Revision: https://reviews.llvm.org/D23428
Modified:
llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=278548&r1=278547&r2=278548&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Aug 12 13:40:04 2016
@@ -912,84 +912,95 @@ class BitPermutationSelector {
}
};
- // Return true if something interesting was deduced, return false if we're
+ using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
+ using ValueBitsMemoizer =
+ DenseMap<SDValue, std::unique_ptr<ValueBitsMemoizedValue>>;
+ ValueBitsMemoizer Memoizer;
+
+ // Return a pair of bool and a SmallVector pointer to a memoization entry.
+ // The bool is true if something interesting was deduced, otherwise if we're
// providing only a generic representation of V (or something else likewise
- // uninteresting for instruction selection).
- bool getValueBits(SDValue V, SmallVector<ValueBit, 64> &Bits) {
+ // uninteresting for instruction selection) through the SmallVector.
+ std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(SDValue V,
+ unsigned NumBits) {
+ auto &ValueEntry = Memoizer[V];
+ if (ValueEntry)
+ return std::make_pair(ValueEntry->first, &ValueEntry->second);
+ ValueEntry.reset(new ValueBitsMemoizedValue());
+ bool &Interesting = ValueEntry->first;
+ SmallVector<ValueBit, 64> &Bits = ValueEntry->second;
+ Bits.resize(NumBits);
+
switch (V.getOpcode()) {
default: break;
case ISD::ROTL:
if (isa<ConstantSDNode>(V.getOperand(1))) {
unsigned RotAmt = V.getConstantOperandVal(1);
- SmallVector<ValueBit, 64> LHSBits(Bits.size());
- getValueBits(V.getOperand(0), LHSBits);
+ const auto &LHSBits = *getValueBits(V.getOperand(0), NumBits).second;
- for (unsigned i = 0; i < Bits.size(); ++i)
- Bits[i] = LHSBits[i < RotAmt ? i + (Bits.size() - RotAmt) : i - RotAmt];
+ for (unsigned i = 0; i < NumBits; ++i)
+ Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
- return true;
+ return std::make_pair(Interesting = true, &Bits);
}
break;
case ISD::SHL:
if (isa<ConstantSDNode>(V.getOperand(1))) {
unsigned ShiftAmt = V.getConstantOperandVal(1);
- SmallVector<ValueBit, 64> LHSBits(Bits.size());
- getValueBits(V.getOperand(0), LHSBits);
+ const auto &LHSBits = *getValueBits(V.getOperand(0), NumBits).second;
- for (unsigned i = ShiftAmt; i < Bits.size(); ++i)
+ for (unsigned i = ShiftAmt; i < NumBits; ++i)
Bits[i] = LHSBits[i - ShiftAmt];
for (unsigned i = 0; i < ShiftAmt; ++i)
Bits[i] = ValueBit(ValueBit::ConstZero);
- return true;
+ return std::make_pair(Interesting = true, &Bits);
}
break;
case ISD::SRL:
if (isa<ConstantSDNode>(V.getOperand(1))) {
unsigned ShiftAmt = V.getConstantOperandVal(1);
- SmallVector<ValueBit, 64> LHSBits(Bits.size());
- getValueBits(V.getOperand(0), LHSBits);
+ const auto &LHSBits = *getValueBits(V.getOperand(0), NumBits).second;
- for (unsigned i = 0; i < Bits.size() - ShiftAmt; ++i)
+ for (unsigned i = 0; i < NumBits - ShiftAmt; ++i)
Bits[i] = LHSBits[i + ShiftAmt];
- for (unsigned i = Bits.size() - ShiftAmt; i < Bits.size(); ++i)
+ for (unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
Bits[i] = ValueBit(ValueBit::ConstZero);
- return true;
+ return std::make_pair(Interesting = true, &Bits);
}
break;
case ISD::AND:
if (isa<ConstantSDNode>(V.getOperand(1))) {
uint64_t Mask = V.getConstantOperandVal(1);
- SmallVector<ValueBit, 64> LHSBits(Bits.size());
- bool LHSTrivial = getValueBits(V.getOperand(0), LHSBits);
+ const SmallVector<ValueBit, 64> *LHSBits;
+ // Mark this as interesting, only if the LHS was also interesting. This
+ // prevents the overall procedure from matching a single immediate 'and'
+ // (which is non-optimal because such an and might be folded with other
+ // things if we don't select it here).
+ std::tie(Interesting, LHSBits) = getValueBits(V.getOperand(0), NumBits);
- for (unsigned i = 0; i < Bits.size(); ++i)
+ for (unsigned i = 0; i < NumBits; ++i)
if (((Mask >> i) & 1) == 1)
- Bits[i] = LHSBits[i];
+ Bits[i] = (*LHSBits)[i];
else
Bits[i] = ValueBit(ValueBit::ConstZero);
- // Mark this as interesting, only if the LHS was also interesting. This
- // prevents the overall procedure from matching a single immediate 'and'
- // (which is non-optimal because such an and might be folded with other
- // things if we don't select it here).
- return LHSTrivial;
+ return std::make_pair(Interesting, &Bits);
}
break;
case ISD::OR: {
- SmallVector<ValueBit, 64> LHSBits(Bits.size()), RHSBits(Bits.size());
- getValueBits(V.getOperand(0), LHSBits);
- getValueBits(V.getOperand(1), RHSBits);
+ const auto &LHSBits = *getValueBits(V.getOperand(0), NumBits).second;
+ const auto &RHSBits = *getValueBits(V.getOperand(1), NumBits).second;
bool AllDisjoint = true;
- for (unsigned i = 0; i < Bits.size(); ++i)
+ for (unsigned i = 0; i < NumBits; ++i)
if (LHSBits[i].isZero())
Bits[i] = RHSBits[i];
else if (RHSBits[i].isZero())
@@ -1002,14 +1013,14 @@ class BitPermutationSelector {
if (!AllDisjoint)
break;
- return true;
+ return std::make_pair(Interesting = true, &Bits);
}
}
- for (unsigned i = 0; i < Bits.size(); ++i)
+ for (unsigned i = 0; i < NumBits; ++i)
Bits[i] = ValueBit(V, i);
- return false;
+ return std::make_pair(Interesting = false, &Bits);
}
// For each value (except the constant ones), compute the left-rotate amount
@@ -1909,9 +1920,12 @@ public:
// rotate-and-shift/shift/and/or instructions, using a set of heuristics
// known to produce optimial code for common cases (like i32 byte swapping).
SDNode *Select(SDNode *N) {
- Bits.resize(N->getValueType(0).getSizeInBits());
- if (!getValueBits(SDValue(N, 0), Bits))
+ Memoizer.clear();
+ auto Result =
+ getValueBits(SDValue(N, 0), N->getValueType(0).getSizeInBits());
+ if (!Result.first)
return nullptr;
+ Bits = std::move(*Result.second);
DEBUG(dbgs() << "Considering bit-permutation-based instruction"
" selection for: ");
More information about the llvm-commits
mailing list