Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -912,84 +912,94 @@ } }; + using ValueBitsMemoizedValue = std::pair>; + using ValueBitsMemoizer = + DenseMap>; + ValueBitsMemoizer Memoizer; + // Return true if something interesting was deduced, return false if we're // providing only a generic representation of V (or something else likewise // uninteresting for instruction selection). - bool getValueBits(SDValue V, SmallVector &Bits) { + std::pair *> 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 &Bits = ValueEntry->second; + Bits.resize(NumBits); + switch (V.getOpcode()) { default: break; case ISD::ROTL: if (isa(V.getOperand(1))) { unsigned RotAmt = V.getConstantOperandVal(1); - SmallVector 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(V.getOperand(1))) { unsigned ShiftAmt = V.getConstantOperandVal(1); - SmallVector 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(V.getOperand(1))) { unsigned ShiftAmt = V.getConstantOperandVal(1); - SmallVector 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(V.getOperand(1))) { uint64_t Mask = V.getConstantOperandVal(1); - SmallVector LHSBits(Bits.size()); - bool LHSTrivial = getValueBits(V.getOperand(0), LHSBits); + const SmallVector *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 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 +1012,14 @@ 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 @@ -1910,9 +1920,12 @@ // 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: ");