mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
STLExtras: Provide less/equal functors with templated function call operators, plus a deref'ing functor template utility
Similar to the C++14 void specializations of these templates, useful as a stop-gap until LLVM switches to '14. Example use-cases in tblgen because I saw some functors that looked like they could be simplified/refactored. Reviewers: dexonsmith Differential Revision: http://reviews.llvm.org/D7324 llvm-svn: 227828
This commit is contained in:
parent
d214bdeaff
commit
87c973c9d7
@ -24,6 +24,7 @@
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <utility> // for std::pair
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -558,6 +559,35 @@ struct pair_hash {
|
||||
}
|
||||
};
|
||||
|
||||
/// A functor like C++14's std::less<void> in its absence.
|
||||
struct less {
|
||||
template <typename A, typename B> bool operator()(A &&a, B &&b) const {
|
||||
return std::forward<A>(a) < std::forward<B>(b);
|
||||
}
|
||||
};
|
||||
|
||||
/// A functor like C++14's std::equal<void> in its absence.
|
||||
struct equal {
|
||||
template <typename A, typename B> bool operator()(A &&a, B &&b) const {
|
||||
return std::forward<A>(a) == std::forward<B>(b);
|
||||
}
|
||||
};
|
||||
|
||||
/// Binary functor that adapts to any other binary functor after dereferencing
|
||||
/// operands.
|
||||
template <typename T> struct deref {
|
||||
T func;
|
||||
// Could be further improved to cope with non-derivable functors and
|
||||
// non-binary functors (should be a variadic template member function
|
||||
// operator()).
|
||||
template <typename A, typename B>
|
||||
auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
|
||||
assert(lhs);
|
||||
assert(rhs);
|
||||
return func(*lhs, *rhs);
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -643,8 +643,8 @@ struct TupleExpander : SetTheory::Expander {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) {
|
||||
std::sort(M.begin(), M.end(), CodeGenRegister::Less());
|
||||
M.erase(std::unique(M.begin(), M.end(), CodeGenRegister::Equal()), M.end());
|
||||
std::sort(M.begin(), M.end(), deref<llvm::less>());
|
||||
M.erase(std::unique(M.begin(), M.end(), deref<llvm::equal>()), M.end());
|
||||
}
|
||||
|
||||
CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
||||
@ -756,7 +756,7 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
|
||||
|
||||
bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
|
||||
return std::binary_search(Members.begin(), Members.end(), Reg,
|
||||
CodeGenRegister::Less());
|
||||
deref<llvm::less>());
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
@ -789,10 +789,10 @@ operator<(const CodeGenRegisterClass::Key &B) const {
|
||||
static bool testSubClass(const CodeGenRegisterClass *A,
|
||||
const CodeGenRegisterClass *B) {
|
||||
return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 &&
|
||||
A->SpillSize <= B->SpillSize &&
|
||||
std::includes(A->getMembers().begin(), A->getMembers().end(),
|
||||
B->getMembers().begin(), B->getMembers().end(),
|
||||
CodeGenRegister::Less());
|
||||
A->SpillSize <= B->SpillSize &&
|
||||
std::includes(A->getMembers().begin(), A->getMembers().end(),
|
||||
B->getMembers().begin(), B->getMembers().end(),
|
||||
deref<llvm::less>());
|
||||
}
|
||||
|
||||
/// Sorting predicate for register classes. This provides a topological
|
||||
@ -1844,10 +1844,9 @@ void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
||||
const CodeGenRegister::Vec &Memb1 = RC1->getMembers();
|
||||
const CodeGenRegister::Vec &Memb2 = RC2->getMembers();
|
||||
CodeGenRegister::Vec Intersection;
|
||||
std::set_intersection(Memb1.begin(), Memb1.end(),
|
||||
Memb2.begin(), Memb2.end(),
|
||||
std::inserter(Intersection, Intersection.begin()),
|
||||
CodeGenRegister::Less());
|
||||
std::set_intersection(
|
||||
Memb1.begin(), Memb1.end(), Memb2.begin(), Memb2.end(),
|
||||
std::inserter(Intersection, Intersection.begin()), deref<llvm::less>());
|
||||
|
||||
// Skip disjoint class pairs.
|
||||
if (Intersection.empty())
|
||||
@ -1874,7 +1873,7 @@ void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
||||
void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
|
||||
// Map SubRegIndex to set of registers in RC supporting that SubRegIndex.
|
||||
typedef std::map<const CodeGenSubRegIndex *, CodeGenRegister::Vec,
|
||||
CodeGenSubRegIndex::Less> SubReg2SetMap;
|
||||
deref<llvm::less>> SubReg2SetMap;
|
||||
|
||||
// Compute the set of registers supporting each SubRegIndex.
|
||||
SubReg2SetMap SRSets;
|
||||
|
@ -73,17 +73,9 @@ namespace llvm {
|
||||
const std::string &getNamespace() const { return Namespace; }
|
||||
std::string getQualifiedName() const;
|
||||
|
||||
// Order CodeGenSubRegIndex pointers by EnumValue.
|
||||
struct Less {
|
||||
bool operator()(const CodeGenSubRegIndex *A,
|
||||
const CodeGenSubRegIndex *B) const {
|
||||
assert(A && B);
|
||||
return A->EnumValue < B->EnumValue;
|
||||
}
|
||||
};
|
||||
|
||||
// Map of composite subreg indices.
|
||||
typedef std::map<CodeGenSubRegIndex*, CodeGenSubRegIndex*, Less> CompMap;
|
||||
typedef std::map<CodeGenSubRegIndex *, CodeGenSubRegIndex *,
|
||||
deref<llvm::less>> CompMap;
|
||||
|
||||
// Returns the subreg index that results from composing this with Idx.
|
||||
// Returns NULL if this and Idx don't compose.
|
||||
@ -125,6 +117,11 @@ namespace llvm {
|
||||
CompMap Composed;
|
||||
};
|
||||
|
||||
inline bool operator<(const CodeGenSubRegIndex &A,
|
||||
const CodeGenSubRegIndex &B) {
|
||||
return A.EnumValue < B.EnumValue;
|
||||
}
|
||||
|
||||
/// CodeGenRegister - Represents a register definition.
|
||||
struct CodeGenRegister {
|
||||
Record *TheDef;
|
||||
@ -133,8 +130,8 @@ namespace llvm {
|
||||
bool CoveredBySubRegs;
|
||||
|
||||
// Map SubRegIndex -> Register.
|
||||
typedef std::map<CodeGenSubRegIndex*, CodeGenRegister*,
|
||||
CodeGenSubRegIndex::Less> SubRegMap;
|
||||
typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, deref<llvm::less>>
|
||||
SubRegMap;
|
||||
|
||||
CodeGenRegister(Record *R, unsigned Enum);
|
||||
|
||||
@ -232,23 +229,6 @@ namespace llvm {
|
||||
// Get the sum of this register's register unit weights.
|
||||
unsigned getWeight(const CodeGenRegBank &RegBank) const;
|
||||
|
||||
// Order CodeGenRegister pointers by EnumValue.
|
||||
struct Less {
|
||||
bool operator()(const CodeGenRegister *A,
|
||||
const CodeGenRegister *B) const {
|
||||
assert(A && B);
|
||||
return A->EnumValue < B->EnumValue;
|
||||
}
|
||||
};
|
||||
|
||||
struct Equal {
|
||||
bool operator()(const CodeGenRegister *A,
|
||||
const CodeGenRegister *B) const {
|
||||
assert(A && B);
|
||||
return A->EnumValue == B->EnumValue;
|
||||
}
|
||||
};
|
||||
|
||||
// Canonically ordered set.
|
||||
typedef std::vector<const CodeGenRegister*> Vec;
|
||||
|
||||
@ -274,6 +254,13 @@ namespace llvm {
|
||||
RegUnitLaneMaskList RegUnitLaneMasks;
|
||||
};
|
||||
|
||||
inline bool operator<(const CodeGenRegister &A, const CodeGenRegister &B) {
|
||||
return A.EnumValue < B.EnumValue;
|
||||
}
|
||||
|
||||
inline bool operator==(const CodeGenRegister &A, const CodeGenRegister &B) {
|
||||
return A.EnumValue == B.EnumValue;
|
||||
}
|
||||
|
||||
class CodeGenRegisterClass {
|
||||
CodeGenRegister::Vec Members;
|
||||
|
@ -815,7 +815,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// Keep track of sub-register names as well. These are not differentially
|
||||
// encoded.
|
||||
typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
|
||||
SequenceToOffsetTable<SubRegIdxVec, CodeGenSubRegIndex::Less> SubRegIdxSeqs;
|
||||
SequenceToOffsetTable<SubRegIdxVec, deref<llvm::less>> SubRegIdxSeqs;
|
||||
SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
|
||||
|
||||
SequenceToOffsetTable<std::string> RegStrings;
|
||||
@ -1205,7 +1205,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// Compress the sub-reg index lists.
|
||||
typedef std::vector<const CodeGenSubRegIndex*> IdxList;
|
||||
SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
|
||||
SequenceToOffsetTable<IdxList, CodeGenSubRegIndex::Less> SuperRegIdxSeqs;
|
||||
SequenceToOffsetTable<IdxList, deref<llvm::less>> SuperRegIdxSeqs;
|
||||
BitVector MaskBV(RegisterClasses.size());
|
||||
|
||||
for (const auto &RC : RegisterClasses) {
|
||||
|
Loading…
Reference in New Issue
Block a user