summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-04-02 17:06:16 -0400
committerGitHub <noreply@github.com>2020-04-02 17:06:16 -0400
commit00e1dba744dc8d09bc59d0a46f18076e3704c566 (patch)
treec22a1e0767af2bc46a351ba6b1bf9ee58d8b7791 /source
parent487d4a4f406c9dd9803ecdca02467d09ee1ecf4a (diff)
Optimize creation of memberDictionary (#1305)
* Improve performance of building members dictionary by adding when needed. * Fix unbounded-array-of-array-syntax.slang, that DISABLE_TEST now uses up an index. Use IGNORE_TEST. * Improve variable name. Small improvements. Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-check-modifier.cpp3
-rw-r--r--source/slang/slang-decl-defs.h15
-rw-r--r--source/slang/slang-lookup.cpp31
-rw-r--r--source/slang/slang-parser.cpp2
4 files changed, 32 insertions, 19 deletions
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 473b5e5da..97da31f39 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -189,8 +189,7 @@ namespace Slang
//
attrDecl->ParentDecl = parentDecl;
parentDecl->Members.add(attrDecl);
- parentDecl->memberDictionaryIsValid = false;
-
+
// Finally, we perform any required semantic checks on
// the newly constructed attribute decl.
//
diff --git a/source/slang/slang-decl-defs.h b/source/slang/slang-decl-defs.h
index b4c3bcfd4..7dc58539c 100644
--- a/source/slang/slang-decl-defs.h
+++ b/source/slang/slang-decl-defs.h
@@ -18,15 +18,20 @@ ABSTRACT_SYNTAX_CLASS(ContainerDecl, Decl)
return FilteredMemberList<T>(Members);
}
+ bool isMemberDictionaryValid() const { return dictionaryLastCount == Members.getCount(); }
+
+ void invalidateMemberDictionary() { dictionaryLastCount = -1; }
+
+ // Denotes how much of Members has been placed into the dictionary/transparentMembers.
+ // If this value equals the Members.getCount(), the dictionary is completely full and valid.
+ // If it's >= 0, then the Members after dictionaryLastCount are all that need to be added.
+ // If it < 0 it means that the dictionary/transparentMembers is invalid and needs to be recreated.
+ Index dictionaryLastCount = 0;
// Dictionary for looking up members by name.
// This is built on demand before performing lookup.
Dictionary<Name*, Decl*> memberDictionary;
-
- // Whether the `memberDictionary` is valid.
- // Should be set to `false` if any members get added/remoed.
- bool memberDictionaryIsValid = false;
-
+
// A list of transparent members, to be used in lookup
// Note: this is only valid if `memberDictionaryIsValid` is true
List<TransparentMemberInfo> transparentMembers;
diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp
index 6a2d31c32..5f2927ccb 100644
--- a/source/slang/slang-lookup.cpp
+++ b/source/slang/slang-lookup.cpp
@@ -30,24 +30,35 @@ struct BreadcrumbInfo
void buildMemberDictionary(ContainerDecl* decl)
{
// Don't rebuild if already built
- if (decl->memberDictionaryIsValid)
+ if (decl->isMemberDictionaryValid())
return;
- decl->memberDictionary.Clear();
- decl->transparentMembers.clear();
+ // If it's < 0 it means that the dictionaries are entirely invalid
+ if (decl->dictionaryLastCount < 0)
+ {
+ decl->dictionaryLastCount = 0;
+ decl->memberDictionary.Clear();
+ decl->transparentMembers.clear();
+ }
// are we a generic?
GenericDecl* genericDecl = as<GenericDecl>(decl);
- for (auto m : decl->Members)
+ const Index membersCount = decl->Members.getCount();
+
+ SLANG_ASSERT(decl->dictionaryLastCount >= 0 && decl->dictionaryLastCount <= membersCount);
+
+ for (Index i = decl->dictionaryLastCount; i < membersCount; ++i)
{
+ Decl* m = decl->Members[i];
+
auto name = m->getName();
// Add any transparent members to a separate list for lookup
if (m->HasModifier<TransparentModifier>())
{
TransparentMemberInfo info;
- info.decl = m.Ptr();
+ info.decl = m;
decl->transparentMembers.add(info);
}
@@ -59,17 +70,17 @@ void buildMemberDictionary(ContainerDecl* decl)
if (genericDecl && m == genericDecl->inner)
continue;
-
m->nextInContainerWithSameName = nullptr;
Decl* next = nullptr;
if (decl->memberDictionary.TryGetValue(name, next))
m->nextInContainerWithSameName = next;
- decl->memberDictionary[name] = m.Ptr();
-
+ decl->memberDictionary[name] = m;
}
- decl->memberDictionaryIsValid = true;
+
+ decl->dictionaryLastCount = membersCount;
+ SLANG_ASSERT(decl->isMemberDictionaryValid());
}
@@ -186,7 +197,7 @@ static void _lookUpDirectAndTransparentMembers(
ContainerDecl* containerDecl = containerDeclRef.getDecl();
// Ensure that the lookup dictionary in the container is up to date
- if (!containerDecl->memberDictionaryIsValid)
+ if (!containerDecl->isMemberDictionaryValid())
{
buildMemberDictionary(containerDecl);
}
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 03f53634d..4ce4c49b5 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -1080,8 +1080,6 @@ namespace Slang
{
member->ParentDecl = container.Ptr();
container->Members.add(member);
-
- container->memberDictionaryIsValid = false;
}
}