[llvm-branch-commits] [cfe-tag] r90721 - /cfe/tags/cremebrulee/cremebrulee-23.1/lib/Sema/SemaCodeComplete.cpp
Douglas Gregor
dgregor at apple.com
Sun Dec 6 13:49:26 PST 2009
Author: dgregor
Date: Sun Dec 6 15:49:26 2009
New Revision: 90721
URL: http://llvm.org/viewvc/llvm-project?rev=90721&view=rev
Log:
Merge performance improvements from 90661,90662,90663,90715,90719 to cremebrulee-23.1
Modified:
cfe/tags/cremebrulee/cremebrulee-23.1/lib/Sema/SemaCodeComplete.cpp
Modified: cfe/tags/cremebrulee/cremebrulee-23.1/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/tags/cremebrulee/cremebrulee-23.1/lib/Sema/SemaCodeComplete.cpp?rev=90721&r1=90720&r2=90721&view=diff
==============================================================================
--- cfe/tags/cremebrulee/cremebrulee-23.1/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/tags/cremebrulee/cremebrulee-23.1/lib/Sema/SemaCodeComplete.cpp Sun Dec 6 15:49:26 2009
@@ -45,11 +45,64 @@
/// the result set twice.
llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
+ typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
+
+ /// \brief An entry in the shadow map, which is optimized to store
+ /// a single (declaration, index) mapping (the common case) but
+ /// can also store a list of (declaration, index) mappings.
+ class ShadowMapEntry {
+ typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
+
+ /// \brief Contains either the solitary NamedDecl * or a vector
+ /// of (declaration, index) pairs.
+ llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
+
+ /// \brief When the entry contains a single declaration, this is
+ /// the index associated with that entry.
+ unsigned SingleDeclIndex;
+
+ public:
+ ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
+
+ void Add(NamedDecl *ND, unsigned Index) {
+ if (DeclOrVector.isNull()) {
+ // 0 - > 1 elements: just set the single element information.
+ DeclOrVector = ND;
+ SingleDeclIndex = Index;
+ return;
+ }
+
+ if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
+ // 1 -> 2 elements: create the vector of results and push in the
+ // existing declaration.
+ DeclIndexPairVector *Vec = new DeclIndexPairVector;
+ Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
+ DeclOrVector = Vec;
+ }
+
+ // Add the new element to the end of the vector.
+ DeclOrVector.get<DeclIndexPairVector*>()->push_back(
+ DeclIndexPair(ND, Index));
+ }
+
+ void Destroy() {
+ if (DeclIndexPairVector *Vec
+ = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
+ delete Vec;
+ DeclOrVector = ((NamedDecl *)0);
+ }
+ }
+
+ // Iteration.
+ class iterator;
+ iterator begin() const;
+ iterator end() const;
+ };
+
/// \brief A mapping from declaration names to the declarations that have
/// this name within a particular scope and their index within the list of
/// results.
- typedef std::multimap<DeclarationName,
- std::pair<NamedDecl *, unsigned> > ShadowMap;
+ typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
/// \brief The semantic analysis object for which results are being
/// produced.
@@ -117,6 +170,102 @@
};
}
+class ResultBuilder::ShadowMapEntry::iterator {
+ llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
+ unsigned SingleDeclIndex;
+
+public:
+ typedef DeclIndexPair value_type;
+ typedef value_type reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::input_iterator_tag iterator_category;
+
+ class pointer {
+ DeclIndexPair Value;
+
+ public:
+ pointer(const DeclIndexPair &Value) : Value(Value) { }
+
+ const DeclIndexPair *operator->() const {
+ return &Value;
+ }
+ };
+
+ iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
+
+ iterator(NamedDecl *SingleDecl, unsigned Index)
+ : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
+
+ iterator(const DeclIndexPair *Iterator)
+ : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
+
+ iterator &operator++() {
+ if (DeclOrIterator.is<NamedDecl *>()) {
+ DeclOrIterator = (NamedDecl *)0;
+ SingleDeclIndex = 0;
+ return *this;
+ }
+
+ const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
+ ++I;
+ DeclOrIterator = I;
+ return *this;
+ }
+
+ iterator operator++(int) {
+ iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ reference operator*() const {
+ if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
+ return reference(ND, SingleDeclIndex);
+
+ return *DeclOrIterator.get<const DeclIndexPair*>();
+ }
+
+ pointer operator->() const {
+ return pointer(**this);
+ }
+
+ friend bool operator==(const iterator &X, const iterator &Y) {
+ return X.DeclOrIterator.getOpaqueValue()
+ == Y.DeclOrIterator.getOpaqueValue() &&
+ X.SingleDeclIndex == Y.SingleDeclIndex;
+ }
+
+ friend bool operator!=(const iterator &X, const iterator &Y) {
+ return !(X == Y);
+ }
+};
+
+namespace llvm {
+ template<>
+ struct DenseMapInfo<ResultBuilder::ShadowMapEntry> {
+ static bool isPod() { return false; }
+ };
+}
+
+ResultBuilder::ShadowMapEntry::iterator
+ResultBuilder::ShadowMapEntry::begin() const {
+ if (DeclOrVector.isNull())
+ return iterator();
+
+ if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
+ return iterator(ND, SingleDeclIndex);
+
+ return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
+}
+
+ResultBuilder::ShadowMapEntry::iterator
+ResultBuilder::ShadowMapEntry::end() const {
+ if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
+ return iterator();
+
+ return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
+}
+
/// \brief Determines whether the given hidden result could be found with
/// some extra work, e.g., by qualifying the name.
///
@@ -241,14 +390,18 @@
return;
ShadowMap &SMap = ShadowMaps.back();
- ShadowMap::iterator I, IEnd;
- for (llvm::tie(I, IEnd) = SMap.equal_range(R.Declaration->getDeclName());
- I != IEnd; ++I) {
- NamedDecl *ND = I->second.first;
- unsigned Index = I->second.second;
+ ShadowMapEntry::iterator I, IEnd;
+ ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
+ if (NamePos != SMap.end()) {
+ I = NamePos->second.begin();
+ IEnd = NamePos->second.end();
+ }
+
+ for (; I != IEnd; ++I) {
+ NamedDecl *ND = I->first;
+ unsigned Index = I->second;
if (ND->getCanonicalDecl() == CanonDecl) {
// This is a redeclaration. Always pick the newer declaration.
- I->second.first = R.Declaration;
Results[Index].Declaration = R.Declaration;
// Pick the best rank of the two.
@@ -265,23 +418,28 @@
std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
--SMEnd;
for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
- for (llvm::tie(I, IEnd) = SM->equal_range(R.Declaration->getDeclName());
- I != IEnd; ++I) {
+ ShadowMapEntry::iterator I, IEnd;
+ ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
+ if (NamePos != SM->end()) {
+ I = NamePos->second.begin();
+ IEnd = NamePos->second.end();
+ }
+ for (; I != IEnd; ++I) {
// A tag declaration does not hide a non-tag declaration.
- if (I->second.first->getIdentifierNamespace() == Decl::IDNS_Tag &&
+ if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
(IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
Decl::IDNS_ObjCProtocol)))
continue;
// Protocols are in distinct namespaces from everything else.
- if (((I->second.first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
+ if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
|| (IDNS & Decl::IDNS_ObjCProtocol)) &&
- I->second.first->getIdentifierNamespace() != IDNS)
+ I->first->getIdentifierNamespace() != IDNS)
continue;
// The newly-added result is hidden by an entry in the shadow map.
if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
- I->second.first)) {
+ I->first)) {
// Note that this result was hidden.
R.Hidden = true;
R.QualifierIsInformative = false;
@@ -327,8 +485,7 @@
// Insert this result into the set of results and into the current shadow
// map.
- SMap.insert(std::make_pair(R.Declaration->getDeclName(),
- std::make_pair(R.Declaration, Results.size())));
+ SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Results.push_back(R);
}
@@ -339,6 +496,12 @@
/// \brief Exit from the current scope.
void ResultBuilder::ExitScope() {
+ for (ShadowMap::iterator E = ShadowMaps.back().begin(),
+ EEnd = ShadowMaps.back().end();
+ E != EEnd;
+ ++E)
+ E->second.Destroy();
+
ShadowMaps.pop_back();
}
@@ -1064,13 +1227,54 @@
typedef CodeCompleteConsumer::Result Result;
bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
- if (!X.getObjCSelector().isNull() && !Y.getObjCSelector().isNull()) {
- // Consider all selector kinds to be equivalent.
- } else if (X.getNameKind() != Y.getNameKind())
+ Selector XSel = X.getObjCSelector();
+ Selector YSel = Y.getObjCSelector();
+ if (!XSel.isNull() && !YSel.isNull()) {
+ // We are comparing two selectors.
+ unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
+ if (N == 0)
+ ++N;
+ for (unsigned I = 0; I != N; ++I) {
+ IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
+ IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
+ if (!XId || !YId)
+ return XId && !YId;
+
+ switch (XId->getName().compare_lower(YId->getName())) {
+ case -1: return true;
+ case 1: return false;
+ default: break;
+ }
+ }
+
+ return XSel.getNumArgs() < YSel.getNumArgs();
+ }
+
+ // For non-selectors, order by kind.
+ if (X.getNameKind() != Y.getNameKind())
return X.getNameKind() < Y.getNameKind();
- return llvm::LowercaseString(X.getAsString())
- < llvm::LowercaseString(Y.getAsString());
+ // Order identifiers by comparison of their lowercased names.
+ if (IdentifierInfo *XId = X.getAsIdentifierInfo())
+ return XId->getName().compare_lower(
+ Y.getAsIdentifierInfo()->getName()) < 0;
+
+ // Order overloaded operators by the order in which they appear
+ // in our list of operators.
+ if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
+ return XOp < Y.getCXXOverloadedOperator();
+
+ // Order C++0x user-defined literal operators lexically by their
+ // lowercased suffixes.
+ if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
+ return XLit->getName().compare_lower(
+ Y.getCXXLiteralIdentifier()->getName()) < 0;
+
+ // The only stable ordering we have is to turn the name into a
+ // string and then compare the lower-case strings. This is
+ // inefficient, but thankfully does not happen too often.
+ return llvm::StringRef(X.getAsString()).compare_lower(
+ Y.getAsString()) < 0;
}
bool operator()(const Result &X, const Result &Y) const {
@@ -1088,7 +1292,7 @@
: X.Pattern->getTypedText();
const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
: Y.Pattern->getTypedText();
- return strcmp(XStr, YStr) < 0;
+ return llvm::StringRef(XStr).compare_lower(YStr) < 0;
}
// Result kinds are ordered by decreasing importance.
@@ -1113,8 +1317,7 @@
Y.Declaration->getDeclName());
case Result::RK_Macro:
- return llvm::LowercaseString(X.Macro->getName()) <
- llvm::LowercaseString(Y.Macro->getName());
+ return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
case Result::RK_Keyword:
case Result::RK_Pattern:
More information about the llvm-branch-commits
mailing list