r209297 - Make the parent-map use significantly less memory.
Jordan Rose
jordan_rose at apple.com
Wed May 21 09:10:36 PDT 2014
You might want to bump up the size of the SmallVector too. Right now you're dynamically allocating a SmallVector<T, 1>, and immediately putting two things into it. Alternately, you could use a std::vector, which has a smaller sizeof itself.
Jordan
On May 21, 2014, at 6:28 , Manuel Klimek <klimek at google.com> wrote:
> Author: klimek
> Date: Wed May 21 08:28:59 2014
> New Revision: 209297
>
> URL: http://llvm.org/viewvc/llvm-project?rev=209297&view=rev
> Log:
> Make the parent-map use significantly less memory.
>
> On test files I ran this on, memory consumption overall went down from
> 2.5G to 2G, without performance regressions.
> I also investigated making DynTypedNode by itself smaller (by pulling
> out pointers for everything that doesn't fit in 8 bytes). This led to
> another 200-300MB saved, but also introduced a significant regression in
> performance due to the memory management overhead.
>
> Modified:
> cfe/trunk/include/clang/AST/ASTContext.h
> cfe/trunk/lib/AST/ASTContext.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=209297&r1=209296&r2=209297&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Wed May 21 08:28:59 2014
> @@ -424,7 +424,9 @@ public:
> typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
>
> /// \brief Maps from a node to its parents.
> - typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
> + typedef llvm::DenseMap<const void *,
> + llvm::PointerUnion<ast_type_traits::DynTypedNode *,
> + ParentVector *>> ParentMap;
>
> /// \brief Returns the parents of the given node.
> ///
> @@ -2293,6 +2295,7 @@ private:
> friend class DeclContext;
> friend class DeclarationNameTable;
> void ReleaseDeclContextMaps();
> + void ReleaseParentMapEntries();
>
> std::unique_ptr<ParentMap> AllParents;
>
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=209297&r1=209296&r2=209297&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Wed May 21 08:28:59 2014
> @@ -755,6 +755,8 @@ ASTContext::ASTContext(LangOptions& LOpt
> }
>
> ASTContext::~ASTContext() {
> + ReleaseParentMapEntries();
> +
> // Release the DenseMaps associated with DeclContext objects.
> // FIXME: Is this the ideal solution?
> ReleaseDeclContextMaps();
> @@ -789,6 +791,18 @@ ASTContext::~ASTContext() {
> llvm::DeleteContainerSeconds(MangleNumberingContexts);
> }
>
> +void ASTContext::ReleaseParentMapEntries() {
> + if (!AllParents) return;
> + for (const auto &Entry : *AllParents) {
> + if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
> + delete Entry.second.get<ast_type_traits::DynTypedNode *>();
> + } else {
> + assert(Entry.second.is<ParentVector *>());
> + delete Entry.second.get<ParentVector *>();
> + }
> + }
> +}
> +
> void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
> Deallocations[Callback].push_back(Data);
> }
> @@ -8162,7 +8176,7 @@ namespace {
> bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
> if (!Node)
> return true;
> - if (ParentStack.size() > 0)
> + if (ParentStack.size() > 0) {
> // FIXME: Currently we add the same parent multiple times, for example
> // when we visit all subexpressions of template instantiations; this is
> // suboptimal, bug benign: the only way to visit those is with
> @@ -8171,7 +8185,23 @@ namespace {
> // map. The main problem there is to implement hash functions /
> // comparison operators for all types that DynTypedNode supports that
> // do not have pointer identity.
> - (*Parents)[Node].push_back(ParentStack.back());
> + auto &NodeOrVector = (*Parents)[Node];
> + if (NodeOrVector.isNull()) {
> + NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
> + } else if (NodeOrVector
> + .template is<ast_type_traits::DynTypedNode *>()) {
> + auto *Node =
> + NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
> + auto *Vector = new ASTContext::ParentVector(1, *Node);
> + Vector->push_back(ParentStack.back());
> + NodeOrVector = Vector;
> + delete Node;
> + } else {
> + assert(NodeOrVector.template is<ASTContext::ParentVector *>());
> + NodeOrVector.template get<ASTContext::ParentVector *>()->push_back(
> + ParentStack.back());
> + }
> + }
> ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
> bool Result = (this ->* traverse) (Node);
> ParentStack.pop_back();
> @@ -8209,7 +8239,11 @@ ASTContext::getParents(const ast_type_tr
> if (I == AllParents->end()) {
> return ParentVector();
> }
> - return I->second;
> + if (I->second.is<ast_type_traits::DynTypedNode *>()) {
> + return ParentVector(1, *I->second.get<ast_type_traits::DynTypedNode *>());
> + }
> + const auto &Parents = *I->second.get<ParentVector *>();
> + return ParentVector(Parents.begin(), Parents.end());
> }
>
> bool
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list