From fb29a708670749baf1b0fc446db3047592823557 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Mon, 2 Feb 2015 18:35:10 +0000 Subject: [PATCH] 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 --- include/llvm/ADT/STLExtras.h | 30 +++++++++++++++++ utils/TableGen/CodeGenRegisters.cpp | 23 +++++++------ utils/TableGen/CodeGenRegisters.h | 45 +++++++++----------------- utils/TableGen/RegisterInfoEmitter.cpp | 4 +-- 4 files changed, 59 insertions(+), 43 deletions(-) diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 4e56e4d7447..3ae572c4ea0 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -24,6 +24,7 @@ #include #include #include // for std::pair +#include namespace llvm { @@ -558,6 +559,35 @@ struct pair_hash { } }; +/// A functor like C++14's std::less in its absence. +struct less { + template bool operator()(A &&a, B &&b) const { + return std::forward(a) < std::forward(b); + } +}; + +/// A functor like C++14's std::equal in its absence. +struct equal { + template bool operator()(A &&a, B &&b) const { + return std::forward(a) == std::forward(b); + } +}; + +/// Binary functor that adapts to any other binary functor after dereferencing +/// operands. +template 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 + auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) { + assert(lhs); + assert(rhs); + return func(*lhs, *rhs); + } +}; + } // End llvm namespace #endif diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 40d421fbe0e..2302eb7e5cf 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -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()); + M.erase(std::unique(M.begin(), M.end(), deref()), 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()); } 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()); } /// 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()); // 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 SubReg2SetMap; + deref> SubReg2SetMap; // Compute the set of registers supporting each SubRegIndex. SubReg2SetMap SRSets; diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 244b3495633..7c723d93a23 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -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 CompMap; + typedef std::map> 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 SubRegMap; + typedef std::map> + 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 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; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 0dbf61d1888..5a6694ea7f1 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -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 SubRegIdxVec; - SequenceToOffsetTable SubRegIdxSeqs; + SequenceToOffsetTable> SubRegIdxSeqs; SmallVector SubRegIdxLists(Regs.size()); SequenceToOffsetTable RegStrings; @@ -1205,7 +1205,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Compress the sub-reg index lists. typedef std::vector IdxList; SmallVector SuperRegIdxLists(RegisterClasses.size()); - SequenceToOffsetTable SuperRegIdxSeqs; + SequenceToOffsetTable> SuperRegIdxSeqs; BitVector MaskBV(RegisterClasses.size()); for (const auto &RC : RegisterClasses) {