diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 633b5b349b8..86238b6c847 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -43,16 +43,15 @@ static inline bool isScalar(MVT VT) { return !VT.isVector(); } -template -static bool berase_if(MachineValueTypeSet &S, Predicate P) { +template +static bool berase_if(std::set &S, Predicate P) { bool Erased = false; - // It is ok to iterate over MachineValueTypeSet and remove elements from it - // at the same time. - for (MVT T : S) { - if (!P(T)) - continue; - Erased = true; - S.erase(T); + for (auto I = S.begin(); I != S.end(); ) { + if (P(*I)) { + Erased = true; + I = S.erase(I); + } else + ++I; } return Erased; } @@ -126,7 +125,7 @@ bool TypeSetByHwMode::constrain(const TypeSetByHwMode &VTS) { unsigned M = I.first; if (M == DefaultMode || hasMode(M)) continue; - Map.insert({M, Map.at(DefaultMode)}); + Map[M] = Map[DefaultMode]; Changed = true; } } @@ -184,9 +183,7 @@ std::string TypeSetByHwMode::getAsString() const { } std::string TypeSetByHwMode::getAsString(const SetType &S) { - std::vector Types; - for (MVT T : S) - Types.push_back(T); + std::vector Types(S.begin(), S.end()); array_pod_sort(Types.begin(), Types.end()); std::stringstream str; @@ -205,12 +202,6 @@ bool TypeSetByHwMode::operator==(const TypeSetByHwMode &VTS) const { if (HaveDefault != VTS.hasDefault()) return false; - if (isSimple()) { - if (VTS.isSimple()) - return *begin() == *VTS.begin(); - return false; - } - std::set Modes; for (auto &I : *this) Modes.insert(I.first); @@ -262,31 +253,18 @@ bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) { // For example // { iPTR } * { i32 } -> { i32 } // { iPTR } * { i32 i64 } -> { iPTR } - // and - // { iPTR i32 } * { i32 } -> { i32 } - // { iPTR i32 } * { i32 i64 } -> { i32 i64 } - // { iPTR i32 } * { i32 i64 i128 } -> { iPTR i32 } - // Compute the difference between the two sets in such a way that the - // iPTR is in the set that is being subtracted. This is to see if there - // are any extra scalars in the set without iPTR that are not in the - // set containing iPTR. Then the iPTR could be considered a "wildcard" - // matching these scalars. If there is only one such scalar, it would - // replace the iPTR, if there are more, the iPTR would be retained. SetType Diff; if (InP) { - Diff = Out; - berase_if(Diff, [&In](MVT T) { return In.count(T); }); - // Pre-remove these elements and rely only on InP/OutP to determine - // whether a change has been made. + std::copy_if(Out.begin(), Out.end(), std::inserter(Diff, Diff.end()), + [&In](MVT T) { return !In.count(T); }); berase_if(Out, [&Diff](MVT T) { return Diff.count(T); }); } else { - Diff = In; - berase_if(Diff, [&Out](MVT T) { return Out.count(T); }); + std::copy_if(In.begin(), In.end(), std::inserter(Diff, Diff.end()), + [&Out](MVT T) { return !Out.count(T); }); Out.erase(MVT::iPTR); } - // The actual intersection. bool Changed = berase_if(Out, Int); unsigned NumD = Diff.size(); if (NumD == 0) @@ -298,9 +276,8 @@ bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) { // being replaced). Changed |= OutP; } else { - // Multiple elements from Out are now replaced with iPTR. Out.insert(MVT::iPTR); - Changed |= !OutP; + Changed |= InP; } return Changed; } @@ -781,12 +758,13 @@ void TypeInfer::expandOverloads(TypeSetByHwMode &VTS) { void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out, const TypeSetByHwMode::SetType &Legal) { std::set Ovs; - for (MVT T : Out) { - if (!T.isOverloaded()) + for (auto I = Out.begin(); I != Out.end(); ) { + if (I->isOverloaded()) { + Ovs.insert(*I); + I = Out.erase(I); continue; - Ovs.insert(T); - // MachineValueTypeSet allows iteration and erasing. - Out.erase(T); + } + ++I; } for (MVT Ov : Ovs) { @@ -827,15 +805,13 @@ void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out, } TypeSetByHwMode TypeInfer::getLegalTypes() { - if (!LegalTypesCached) { - // Stuff all types from all modes into the default mode. - const TypeSetByHwMode <S = TP.getDAGPatterns().getLegalTypes(); - for (const auto &I : LTS) - LegalCache.insert(I.second); - LegalTypesCached = true; - } TypeSetByHwMode VTS; - VTS.getOrCreate(DefaultMode) = LegalCache; + TypeSetByHwMode::SetType &DS = VTS.getOrCreate(DefaultMode); + const TypeSetByHwMode <S = TP.getDAGPatterns().getLegalTypes(); + + // Stuff all types from all modes into the default mode. + for (const auto &I : LTS) + DS.insert(I.second.begin(), I.second.end()); return VTS; } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 310fbfcc790..bc25419e556 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -21,160 +21,24 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MathExtras.h" #include -#include #include #include #include namespace llvm { + class Record; + class Init; + class ListInit; + class DagInit; + class SDNodeInfo; + class TreePattern; + class TreePatternNode; + class CodeGenDAGPatterns; + class ComplexPattern; -class Record; -class Init; -class ListInit; -class DagInit; -class SDNodeInfo; -class TreePattern; -class TreePatternNode; -class CodeGenDAGPatterns; -class ComplexPattern; - -/// This represents a set of MVTs. Since the underlying type for the MVT -/// is uint8_t, there are at most 256 values. To reduce the number of memory -/// allocations and deallocations, represent the set as a sequence of bits. -/// To reduce the allocations even further, make MachineValueTypeSet own -/// the storage and use std::array as the bit container. -struct MachineValueTypeSet { - static_assert(std::is_same::type, - uint8_t>::value, - "Change uint8_t here to the SimpleValueType's type"); - static unsigned constexpr Capacity = std::numeric_limits::max()+1; - using WordType = uint64_t; - static unsigned constexpr WordWidth = 8*sizeof(WordType); - static unsigned constexpr NumWords = Capacity/WordWidth; - static_assert(NumWords*WordWidth == Capacity, - "Capacity should be a multiple of WordWidth"); - - LLVM_ATTRIBUTE_ALWAYS_INLINE - MachineValueTypeSet() { - clear(); - } - - LLVM_ATTRIBUTE_ALWAYS_INLINE - unsigned size() const { - unsigned Count = 0; - for (WordType W : Words) - Count += countPopulation(W); - return Count; - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - void clear() { - std::memset(Words.data(), 0, NumWords*sizeof(WordType)); - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - bool empty() const { - for (WordType W : Words) - if (W != 0) - return false; - return true; - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - unsigned count(MVT T) const { - return (Words[T.SimpleTy / WordWidth] >> (T.SimpleTy % WordWidth)) & 1; - } - std::pair insert(MVT T) { - bool V = count(T.SimpleTy); - Words[T.SimpleTy / WordWidth] |= WordType(1) << (T.SimpleTy % WordWidth); - return {*this, V}; - } - MachineValueTypeSet &insert(const MachineValueTypeSet &S) { - for (unsigned i = 0; i != NumWords; ++i) - Words[i] |= S.Words[i]; - return *this; - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - void erase(MVT T) { - Words[T.SimpleTy / WordWidth] &= ~(WordType(1) << (T.SimpleTy % WordWidth)); - } - - struct const_iterator { - LLVM_ATTRIBUTE_ALWAYS_INLINE - MVT operator*() const { - assert(Pos != Capacity); - return MVT::SimpleValueType(Pos); - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - const_iterator(const MachineValueTypeSet *S, bool End) : Set(S) { - Pos = End ? Capacity : find_from_pos(0); - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - const_iterator &operator++() { - assert(Pos != Capacity); - Pos = find_from_pos(Pos+1); - return *this; - } - - LLVM_ATTRIBUTE_ALWAYS_INLINE - bool operator==(const const_iterator &It) const { - return Set == It.Set && Pos == It.Pos; - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - bool operator!=(const const_iterator &It) const { - return !operator==(It); - } - - private: - unsigned find_from_pos(unsigned P) const { - unsigned SkipWords = P / WordWidth; - unsigned SkipBits = P % WordWidth; - unsigned Count = SkipWords * WordWidth; - - // If P is in the middle of a word, process it manually here, because - // the trailing bits need to be masked off to use findFirstSet. - if (SkipBits != 0) { - WordType W = Set->Words[SkipWords]; - W &= maskLeadingOnes(WordWidth-SkipBits); - if (W != 0) - return Count + findFirstSet(W); - Count += WordWidth; - SkipWords++; - } - - for (unsigned i = SkipWords; i != NumWords; ++i) { - WordType W = Set->Words[i]; - if (W != 0) - return Count + findFirstSet(W); - Count += WordWidth; - } - return Capacity; - } - - const MachineValueTypeSet *Set; - unsigned Pos; - }; - - LLVM_ATTRIBUTE_ALWAYS_INLINE - const_iterator begin() const { return const_iterator(this, false); } - LLVM_ATTRIBUTE_ALWAYS_INLINE - const_iterator end() const { return const_iterator(this, true); } - - LLVM_ATTRIBUTE_ALWAYS_INLINE - bool operator==(const MachineValueTypeSet &S) const { - return Words == S.Words; - } - LLVM_ATTRIBUTE_ALWAYS_INLINE - bool operator!=(const MachineValueTypeSet &S) const { - return !operator==(S); - } - -private: - friend struct const_iterator; - std::array Words; -}; - -struct TypeSetByHwMode : public InfoByHwMode { - using SetType = MachineValueTypeSet; +struct TypeSetByHwMode : public InfoByHwMode> { + typedef std::set SetType; TypeSetByHwMode() = default; TypeSetByHwMode(const TypeSetByHwMode &VTS) = default; @@ -192,23 +56,19 @@ struct TypeSetByHwMode : public InfoByHwMode { bool isValueTypeByHwMode(bool AllowEmpty) const; ValueTypeByHwMode getValueTypeByHwMode() const; - - LLVM_ATTRIBUTE_ALWAYS_INLINE bool isMachineValueType() const { return isDefaultOnly() && Map.begin()->second.size() == 1; } - LLVM_ATTRIBUTE_ALWAYS_INLINE MVT getMachineValueType() const { assert(isMachineValueType()); return *Map.begin()->second.begin(); } bool isPossible() const; - - LLVM_ATTRIBUTE_ALWAYS_INLINE bool isDefaultOnly() const { - return Map.size() == 1 && Map.begin()->first == DefaultMode; + return Map.size() == 1 && + Map.begin()->first == DefaultMode; } bool insert(const ValueTypeByHwMode &VVT); @@ -318,10 +178,6 @@ struct TypeInfer { private: TypeSetByHwMode getLegalTypes(); - - /// Cached legal types. - bool LegalTypesCached = false; - TypeSetByHwMode::SetType LegalCache = {}; }; /// Set type used to track multiply used variables in patterns diff --git a/utils/TableGen/InfoByHwMode.h b/utils/TableGen/InfoByHwMode.h index 71149e8da19..d20bdabf7ec 100644 --- a/utils/TableGen/InfoByHwMode.h +++ b/utils/TableGen/InfoByHwMode.h @@ -63,30 +63,23 @@ struct InfoByHwMode { typedef typename MapType::const_iterator const_iterator; InfoByHwMode() = default; - InfoByHwMode(const MapType &M) : Map(M) {} + InfoByHwMode(const MapType &&M) : Map(M) {} - LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin() { return Map.begin(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end() { return Map.end(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator begin() const { return Map.begin(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator end() const { return Map.end(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const { return Map.empty(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE bool hasDefault() const { return hasMode(DefaultMode); } InfoT &get(unsigned Mode) { if (!hasMode(Mode)) { assert(hasMode(DefaultMode)); - Map.insert({Mode, Map.at(DefaultMode)}); + Map[Mode] = Map[DefaultMode]; } - return Map.at(Mode); + return Map[Mode]; } const InfoT &get(unsigned Mode) const { auto F = Map.find(Mode); @@ -96,11 +89,9 @@ struct InfoByHwMode { return F->second; } - LLVM_ATTRIBUTE_ALWAYS_INLINE bool isSimple() const { return Map.size() == 1 && Map.begin()->first == DefaultMode; } - LLVM_ATTRIBUTE_ALWAYS_INLINE InfoT getSimple() const { assert(isSimple()); return Map.begin()->second;