mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00: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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227828 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b265a82d58
commit
fb29a70867
@ -24,6 +24,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility> // for std::pair
|
#include <utility> // for std::pair
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace llvm {
|
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
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -643,8 +643,8 @@ struct TupleExpander : SetTheory::Expander {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) {
|
static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) {
|
||||||
std::sort(M.begin(), M.end(), CodeGenRegister::Less());
|
std::sort(M.begin(), M.end(), deref<llvm::less>());
|
||||||
M.erase(std::unique(M.begin(), M.end(), CodeGenRegister::Equal()), M.end());
|
M.erase(std::unique(M.begin(), M.end(), deref<llvm::equal>()), M.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
||||||
@ -756,7 +756,7 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
|
|||||||
|
|
||||||
bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
|
bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
|
||||||
return std::binary_search(Members.begin(), Members.end(), Reg,
|
return std::binary_search(Members.begin(), Members.end(), Reg,
|
||||||
CodeGenRegister::Less());
|
deref<llvm::less>());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -789,10 +789,10 @@ operator<(const CodeGenRegisterClass::Key &B) const {
|
|||||||
static bool testSubClass(const CodeGenRegisterClass *A,
|
static bool testSubClass(const CodeGenRegisterClass *A,
|
||||||
const CodeGenRegisterClass *B) {
|
const CodeGenRegisterClass *B) {
|
||||||
return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 &&
|
return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 &&
|
||||||
A->SpillSize <= B->SpillSize &&
|
A->SpillSize <= B->SpillSize &&
|
||||||
std::includes(A->getMembers().begin(), A->getMembers().end(),
|
std::includes(A->getMembers().begin(), A->getMembers().end(),
|
||||||
B->getMembers().begin(), B->getMembers().end(),
|
B->getMembers().begin(), B->getMembers().end(),
|
||||||
CodeGenRegister::Less());
|
deref<llvm::less>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sorting predicate for register classes. This provides a topological
|
/// 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 &Memb1 = RC1->getMembers();
|
||||||
const CodeGenRegister::Vec &Memb2 = RC2->getMembers();
|
const CodeGenRegister::Vec &Memb2 = RC2->getMembers();
|
||||||
CodeGenRegister::Vec Intersection;
|
CodeGenRegister::Vec Intersection;
|
||||||
std::set_intersection(Memb1.begin(), Memb1.end(),
|
std::set_intersection(
|
||||||
Memb2.begin(), Memb2.end(),
|
Memb1.begin(), Memb1.end(), Memb2.begin(), Memb2.end(),
|
||||||
std::inserter(Intersection, Intersection.begin()),
|
std::inserter(Intersection, Intersection.begin()), deref<llvm::less>());
|
||||||
CodeGenRegister::Less());
|
|
||||||
|
|
||||||
// Skip disjoint class pairs.
|
// Skip disjoint class pairs.
|
||||||
if (Intersection.empty())
|
if (Intersection.empty())
|
||||||
@ -1874,7 +1873,7 @@ void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
|||||||
void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
|
void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
|
||||||
// Map SubRegIndex to set of registers in RC supporting that SubRegIndex.
|
// Map SubRegIndex to set of registers in RC supporting that SubRegIndex.
|
||||||
typedef std::map<const CodeGenSubRegIndex *, CodeGenRegister::Vec,
|
typedef std::map<const CodeGenSubRegIndex *, CodeGenRegister::Vec,
|
||||||
CodeGenSubRegIndex::Less> SubReg2SetMap;
|
deref<llvm::less>> SubReg2SetMap;
|
||||||
|
|
||||||
// Compute the set of registers supporting each SubRegIndex.
|
// Compute the set of registers supporting each SubRegIndex.
|
||||||
SubReg2SetMap SRSets;
|
SubReg2SetMap SRSets;
|
||||||
|
@ -73,17 +73,9 @@ namespace llvm {
|
|||||||
const std::string &getNamespace() const { return Namespace; }
|
const std::string &getNamespace() const { return Namespace; }
|
||||||
std::string getQualifiedName() const;
|
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.
|
// 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 the subreg index that results from composing this with Idx.
|
||||||
// Returns NULL if this and Idx don't compose.
|
// Returns NULL if this and Idx don't compose.
|
||||||
@ -125,6 +117,11 @@ namespace llvm {
|
|||||||
CompMap Composed;
|
CompMap Composed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator<(const CodeGenSubRegIndex &A,
|
||||||
|
const CodeGenSubRegIndex &B) {
|
||||||
|
return A.EnumValue < B.EnumValue;
|
||||||
|
}
|
||||||
|
|
||||||
/// CodeGenRegister - Represents a register definition.
|
/// CodeGenRegister - Represents a register definition.
|
||||||
struct CodeGenRegister {
|
struct CodeGenRegister {
|
||||||
Record *TheDef;
|
Record *TheDef;
|
||||||
@ -133,8 +130,8 @@ namespace llvm {
|
|||||||
bool CoveredBySubRegs;
|
bool CoveredBySubRegs;
|
||||||
|
|
||||||
// Map SubRegIndex -> Register.
|
// Map SubRegIndex -> Register.
|
||||||
typedef std::map<CodeGenSubRegIndex*, CodeGenRegister*,
|
typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, deref<llvm::less>>
|
||||||
CodeGenSubRegIndex::Less> SubRegMap;
|
SubRegMap;
|
||||||
|
|
||||||
CodeGenRegister(Record *R, unsigned Enum);
|
CodeGenRegister(Record *R, unsigned Enum);
|
||||||
|
|
||||||
@ -232,23 +229,6 @@ namespace llvm {
|
|||||||
// Get the sum of this register's register unit weights.
|
// Get the sum of this register's register unit weights.
|
||||||
unsigned getWeight(const CodeGenRegBank &RegBank) const;
|
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.
|
// Canonically ordered set.
|
||||||
typedef std::vector<const CodeGenRegister*> Vec;
|
typedef std::vector<const CodeGenRegister*> Vec;
|
||||||
|
|
||||||
@ -274,6 +254,13 @@ namespace llvm {
|
|||||||
RegUnitLaneMaskList RegUnitLaneMasks;
|
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 {
|
class CodeGenRegisterClass {
|
||||||
CodeGenRegister::Vec Members;
|
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
|
// Keep track of sub-register names as well. These are not differentially
|
||||||
// encoded.
|
// encoded.
|
||||||
typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
|
typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
|
||||||
SequenceToOffsetTable<SubRegIdxVec, CodeGenSubRegIndex::Less> SubRegIdxSeqs;
|
SequenceToOffsetTable<SubRegIdxVec, deref<llvm::less>> SubRegIdxSeqs;
|
||||||
SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
|
SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
|
||||||
|
|
||||||
SequenceToOffsetTable<std::string> RegStrings;
|
SequenceToOffsetTable<std::string> RegStrings;
|
||||||
@ -1205,7 +1205,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
// Compress the sub-reg index lists.
|
// Compress the sub-reg index lists.
|
||||||
typedef std::vector<const CodeGenSubRegIndex*> IdxList;
|
typedef std::vector<const CodeGenSubRegIndex*> IdxList;
|
||||||
SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
|
SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
|
||||||
SequenceToOffsetTable<IdxList, CodeGenSubRegIndex::Less> SuperRegIdxSeqs;
|
SequenceToOffsetTable<IdxList, deref<llvm::less>> SuperRegIdxSeqs;
|
||||||
BitVector MaskBV(RegisterClasses.size());
|
BitVector MaskBV(RegisterClasses.size());
|
||||||
|
|
||||||
for (const auto &RC : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
|
Loading…
Reference in New Issue
Block a user