1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

Switch SmallSetVector to use DenseSet when it overflows its inline space.

Summary:
SetVector already used DenseSet, but SmallSetVector used std::set.  This
leads to surprising performance differences.  Moreover, it means that
the set of key types accepted by SetVector and SmallSetVector are
quite different!

In order to make this change, we had to convert some callsites that used
SmallSetVector<std::string, N> to use SmallSetVector<CachedHashString, N>
instead.

Reviewers: timshen

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D25648

llvm-svn: 284887
This commit is contained in:
Justin Lebar 2016-10-21 21:45:01 +00:00
parent d4e3f0bc43
commit f5bab4e23c
3 changed files with 25 additions and 21 deletions

View File

@ -282,7 +282,8 @@ private:
/// \brief A SetVector that performs no allocations if smaller than /// \brief A SetVector that performs no allocations if smaller than
/// a certain size. /// a certain size.
template <typename T, unsigned N> template <typename T, unsigned N>
class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > { class SmallSetVector
: public SetVector<T, SmallVector<T, N>, SmallDenseSet<T, N>> {
public: public:
SmallSetVector() {} SmallSetVector() {}

View File

@ -97,6 +97,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "CodeGenTarget.h" #include "CodeGenTarget.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
@ -1822,10 +1823,11 @@ void MatchableInfo::buildAliasResultOperands() {
} }
} }
static unsigned getConverterOperandID(const std::string &Name, static unsigned
SmallSetVector<std::string, 16> &Table, getConverterOperandID(const std::string &Name,
SmallSetVector<CachedHashString, 16> &Table,
bool &IsNew) { bool &IsNew) {
IsNew = Table.insert(Name); IsNew = Table.insert(CachedHashString(Name));
unsigned ID = IsNew ? Table.size() - 1 : find(Table, Name) - Table.begin(); unsigned ID = IsNew ? Table.size() - 1 : find(Table, Name) - Table.begin();
@ -1838,8 +1840,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
std::vector<std::unique_ptr<MatchableInfo>> &Infos, std::vector<std::unique_ptr<MatchableInfo>> &Infos,
bool HasMnemonicFirst, bool HasOptionalOperands, bool HasMnemonicFirst, bool HasOptionalOperands,
raw_ostream &OS) { raw_ostream &OS) {
SmallSetVector<std::string, 16> OperandConversionKinds; SmallSetVector<CachedHashString, 16> OperandConversionKinds;
SmallSetVector<std::string, 16> InstructionConversionKinds; SmallSetVector<CachedHashString, 16> InstructionConversionKinds;
std::vector<std::vector<uint8_t> > ConversionTable; std::vector<std::vector<uint8_t> > ConversionTable;
size_t MaxRowLength = 2; // minimum is custom converter plus terminator. size_t MaxRowLength = 2; // minimum is custom converter plus terminator.
@ -1911,9 +1913,9 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// Pre-populate the operand conversion kinds with the standard always // Pre-populate the operand conversion kinds with the standard always
// available entries. // available entries.
OperandConversionKinds.insert("CVT_Done"); OperandConversionKinds.insert(CachedHashString("CVT_Done"));
OperandConversionKinds.insert("CVT_Reg"); OperandConversionKinds.insert(CachedHashString("CVT_Reg"));
OperandConversionKinds.insert("CVT_Tied"); OperandConversionKinds.insert(CachedHashString("CVT_Tied"));
enum { CVT_Done, CVT_Reg, CVT_Tied }; enum { CVT_Done, CVT_Reg, CVT_Tied };
for (auto &II : Infos) { for (auto &II : Infos) {
@ -1925,13 +1927,13 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
II->ConversionFnKind = Signature; II->ConversionFnKind = Signature;
// Check if we have already generated this signature. // Check if we have already generated this signature.
if (!InstructionConversionKinds.insert(Signature)) if (!InstructionConversionKinds.insert(CachedHashString(Signature)))
continue; continue;
// Remember this converter for the kind enum. // Remember this converter for the kind enum.
unsigned KindID = OperandConversionKinds.size(); unsigned KindID = OperandConversionKinds.size();
OperandConversionKinds.insert("CVT_" + OperandConversionKinds.insert(
getEnumNameForToken(AsmMatchConverter)); CachedHashString("CVT_" + getEnumNameForToken(AsmMatchConverter)));
// Add the converter row for this instruction. // Add the converter row for this instruction.
ConversionTable.emplace_back(); ConversionTable.emplace_back();
@ -2113,7 +2115,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// Save the signature. If we already have it, don't add a new row // Save the signature. If we already have it, don't add a new row
// to the table. // to the table.
if (!InstructionConversionKinds.insert(Signature)) if (!InstructionConversionKinds.insert(CachedHashString(Signature)))
continue; continue;
// Add the row to the table. // Add the row to the table.
@ -2130,14 +2132,14 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// Output the operand conversion kind enum. // Output the operand conversion kind enum.
OS << "enum OperatorConversionKind {\n"; OS << "enum OperatorConversionKind {\n";
for (const std::string &Converter : OperandConversionKinds) for (const auto &Converter : OperandConversionKinds)
OS << " " << Converter << ",\n"; OS << " " << Converter << ",\n";
OS << " CVT_NUM_CONVERTERS\n"; OS << " CVT_NUM_CONVERTERS\n";
OS << "};\n\n"; OS << "};\n\n";
// Output the instruction conversion kind enum. // Output the instruction conversion kind enum.
OS << "enum InstructionConversionKind {\n"; OS << "enum InstructionConversionKind {\n";
for (const std::string &Signature : InstructionConversionKinds) for (const auto &Signature : InstructionConversionKinds)
OS << " " << Signature << ",\n"; OS << " " << Signature << ",\n";
OS << " CVT_NUM_SIGNATURES\n"; OS << " CVT_NUM_SIGNATURES\n";
OS << "};\n\n"; OS << "};\n\n";

View File

@ -14,6 +14,7 @@
#include "CodeGenTarget.h" #include "CodeGenTarget.h"
#include "llvm/ADT/APInt.h" #include "llvm/ADT/APInt.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
@ -66,8 +67,8 @@ typedef std::vector<uint8_t> DecoderTable;
typedef uint32_t DecoderFixup; typedef uint32_t DecoderFixup;
typedef std::vector<DecoderFixup> FixupList; typedef std::vector<DecoderFixup> FixupList;
typedef std::vector<FixupList> FixupScopeList; typedef std::vector<FixupList> FixupScopeList;
typedef SmallSetVector<std::string, 16> PredicateSet; typedef SmallSetVector<CachedHashString, 16> PredicateSet;
typedef SmallSetVector<std::string, 16> DecoderSet; typedef SmallSetVector<CachedHashString, 16> DecoderSet;
struct DecoderTableInfo { struct DecoderTableInfo {
DecoderTable Table; DecoderTable Table;
FixupScopeList FixupStack; FixupScopeList FixupStack;
@ -1106,7 +1107,7 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
// overkill for now, though. // overkill for now, though.
// Make sure the predicate is in the table. // Make sure the predicate is in the table.
Decoders.insert(StringRef(Decoder)); Decoders.insert(CachedHashString(Decoder));
// Now figure out the index for when we write out the table. // Now figure out the index for when we write out the table.
DecoderSet::const_iterator P = find(Decoders, Decoder.str()); DecoderSet::const_iterator P = find(Decoders, Decoder.str());
return (unsigned)(P - Decoders.begin()); return (unsigned)(P - Decoders.begin());
@ -1179,9 +1180,9 @@ unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
// overkill for now, though. // overkill for now, though.
// Make sure the predicate is in the table. // Make sure the predicate is in the table.
TableInfo.Predicates.insert(Predicate.str()); TableInfo.Predicates.insert(CachedHashString(Predicate));
// Now figure out the index for when we write out the table. // Now figure out the index for when we write out the table.
PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate.str()); PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
return (unsigned)(P - TableInfo.Predicates.begin()); return (unsigned)(P - TableInfo.Predicates.begin());
} }