From 4990890fc9428f98bef90ba349203a648c592778 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Mon, 9 Jul 2012 10:04:07 +0000 Subject: [PATCH] Inline storage of attributes in AttributedStmt. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159925 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Attr.h | 40 ++++++++++++++----------- include/clang/AST/Stmt.h | 28 ++++++++++------- include/clang/Sema/Sema.h | 3 +- include/clang/Serialization/ASTWriter.h | 2 +- lib/AST/Stmt.cpp | 17 +++++++++++ lib/AST/StmtPrinter.cpp | 6 ++-- lib/Sema/SemaStmt.cpp | 8 ++--- lib/Sema/SemaStmtAttr.cpp | 2 +- lib/Sema/TreeTransform.h | 3 +- lib/Serialization/ASTReaderStmt.cpp | 9 ++++-- lib/Serialization/ASTWriter.cpp | 8 +++-- lib/Serialization/ASTWriterDecl.cpp | 3 +- lib/Serialization/ASTWriterStmt.cpp | 1 + 13 files changed, 85 insertions(+), 45 deletions(-) diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 95841801b6..27b44d4bd9 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -149,8 +149,10 @@ typedef SmallVector ConstAttrVec; /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only /// providing attributes that are of a specifc type. -template +template class specific_attr_iterator { + typedef typename Container::const_iterator Iterator; + /// Current - The current, underlying iterator. /// In order to ensure we don't dereference an invalid iterator unless /// specifically requested, we don't necessarily advance this all the @@ -158,14 +160,14 @@ class specific_attr_iterator { /// operation is acting on what should be a past-the-end iterator, /// then we offer no guarantees, but this way we do not dererence a /// past-the-end iterator when we move to a past-the-end position. - mutable AttrVec::const_iterator Current; + mutable Iterator Current; void AdvanceToNext() const { while (!isa(*Current)) ++Current; } - void AdvanceToNext(AttrVec::const_iterator I) const { + void AdvanceToNext(Iterator I) const { while (Current != I && !isa(*Current)) ++Current; } @@ -178,7 +180,7 @@ public: typedef std::ptrdiff_t difference_type; specific_attr_iterator() : Current() { } - explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { } + explicit specific_attr_iterator(Iterator i) : Current(i) { } reference operator*() const { AdvanceToNext(); @@ -213,23 +215,27 @@ public: } }; -template -inline specific_attr_iterator specific_attr_begin(const AttrVec& vec) { - return specific_attr_iterator(vec.begin()); +template +inline specific_attr_iterator + specific_attr_begin(const Container& container) { + return specific_attr_iterator(container.begin()); } -template -inline specific_attr_iterator specific_attr_end(const AttrVec& vec) { - return specific_attr_iterator(vec.end()); +template +inline specific_attr_iterator + specific_attr_end(const Container& container) { + return specific_attr_iterator(container.end()); } -template -inline bool hasSpecificAttr(const AttrVec& vec) { - return specific_attr_begin(vec) != specific_attr_end(vec); +template +inline bool hasSpecificAttr(const Container& container) { + return specific_attr_begin(container) != + specific_attr_end(container); } -template -inline T *getSpecificAttr(const AttrVec& vec) { - specific_attr_iterator i = specific_attr_begin(vec); - if (i != specific_attr_end(vec)) +template +inline SpecificAttr *getSpecificAttr(const Container& container) { + specific_attr_iterator i = + specific_attr_begin(container); + if (i != specific_attr_end(container)) return *i; else return 0; diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 1662ba87b4..14b28f8e3d 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -797,24 +797,32 @@ public: class AttributedStmt : public Stmt { Stmt *SubStmt; SourceLocation AttrLoc; - AttrVec Attrs; - // TODO: It can be done as Attr *Attrs[1]; and variable size array as in - // StringLiteral + unsigned NumAttrs; + const Attr *Attrs[1]; friend class ASTStmtReader; -public: - AttributedStmt(SourceLocation loc, const AttrVec &attrs, Stmt *substmt) - : Stmt(AttributedStmtClass), SubStmt(substmt), AttrLoc(loc), Attrs(attrs) { + AttributedStmt(SourceLocation Loc, ArrayRef Attrs, Stmt *SubStmt) + : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc), + NumAttrs(Attrs.size()) { + memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*)); } - // \brief Build an empty attributed statement. - explicit AttributedStmt(EmptyShell Empty) - : Stmt(AttributedStmtClass, Empty) { + explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) + : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) { + memset(Attrs, 0, NumAttrs * sizeof(Attr*)); } +public: + static AttributedStmt *Create(ASTContext &C, SourceLocation Loc, + ArrayRef Attrs, Stmt *SubStmt); + // \brief Build an empty attributed statement. + static AttributedStmt *CreateEmpty(ASTContext &C, unsigned NumAttrs); + SourceLocation getAttrLoc() const { return AttrLoc; } - const AttrVec &getAttrs() const { return Attrs; } + ArrayRef getAttrs() const { + return ArrayRef(Attrs, NumAttrs); + } Stmt *getSubStmt() { return SubStmt; } const Stmt *getSubStmt() const { return SubStmt; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index c1d0d63819..a48cde03ba 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2467,7 +2467,8 @@ public: StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt); - StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs, + StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, + ArrayRef Attrs, Stmt *SubStmt); StmtResult ActOnIfStmt(SourceLocation IfLoc, diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 830a163eed..d038d58aed 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -427,7 +427,7 @@ private: void WriteReferencedSelectorsPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, bool IsModule); - void WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record); + void WriteAttributes(ArrayRef Attrs, RecordDataImpl &Record); void ResolveDeclUpdatesBlocks(); void WriteDeclUpdatesBlocks(); void WriteDeclReplacementsBlock(); diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index b6bb528220..ff6374c2d8 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -273,6 +273,23 @@ const char *LabelStmt::getName() const { return getDecl()->getIdentifier()->getNameStart(); } +AttributedStmt *AttributedStmt::Create(ASTContext &C, SourceLocation Loc, + ArrayRef Attrs, + Stmt *SubStmt) { + void *Mem = C.Allocate(sizeof(AttributedStmt) + + sizeof(Attr*) * (Attrs.size() - 1), + llvm::alignOf()); + return new (Mem) AttributedStmt(Loc, Attrs, SubStmt); +} + +AttributedStmt *AttributedStmt::CreateEmpty(ASTContext &C, unsigned NumAttrs) { + assert(NumAttrs > 0 && "NumAttrs should be greater than zero"); + void *Mem = C.Allocate(sizeof(AttributedStmt) + + sizeof(Attr*) * (NumAttrs - 1), + llvm::alignOf()); + return new (Mem) AttributedStmt(EmptyShell(), NumAttrs); +} + // This is defined here to avoid polluting Stmt.h with importing Expr.h SourceRange ReturnStmt::getSourceRange() const { if (RetExpr) diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 8b989e6ae3..2f7cb55c7c 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -173,9 +173,9 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { OS << "[["; bool first = true; - for (AttrVec::const_iterator it = Node->getAttrs().begin(), - end = Node->getAttrs().end(); - it != end; ++it) { + for (ArrayRef::iterator it = Node->getAttrs().begin(), + end = Node->getAttrs().end(); + it != end; ++it) { if (!first) { OS << ", "; first = false; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 2db8b5da63..9be1d34dae 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -370,12 +370,10 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, } StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc, - const AttrVec &Attrs, + ArrayRef Attrs, Stmt *SubStmt) { - // Fill in the declaration and return it. Variable length will require to - // change this to AttributedStmt::Create(Context, ....); - // and probably using ArrayRef - AttributedStmt *LS = new (Context) AttributedStmt(AttrLoc, Attrs, SubStmt); + // Fill in the declaration and return it. + AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt); return Owned(LS); } diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp index 395b9d6259..3c15b7a8af 100644 --- a/lib/Sema/SemaStmtAttr.cpp +++ b/lib/Sema/SemaStmtAttr.cpp @@ -61,7 +61,7 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A, StmtResult Sema::ProcessStmtAttributes(Stmt *S, AttributeList *AttrList, SourceRange Range) { - AttrVec Attrs; + SmallVector Attrs; for (const AttributeList* l = AttrList; l; l = l->getNext()) { if (Attr *a = ProcessStmtAttribute(*this, S, *l, Range)) Attrs.push_back(a); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 3b41f758d9..b03f86bb0e 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1050,7 +1050,8 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs, + StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, + ArrayRef Attrs, Stmt *SubStmt) { return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 460841b2ff..7d56f10eb5 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -162,9 +162,12 @@ void ASTStmtReader::VisitLabelStmt(LabelStmt *S) { void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) { VisitStmt(S); + uint64_t NumAttrs = Record[Idx++]; AttrVec Attrs; Reader.ReadAttributes(F, Attrs, Record, Idx); - S->Attrs = Attrs; + assert(NumAttrs == S->NumAttrs); + assert(NumAttrs == Attrs.size()); + std::copy(Attrs.begin(), Attrs.end(), S->Attrs); S->SubStmt = Reader.ReadSubStmt(); S->AttrLoc = ReadSourceLocation(Record, Idx); } @@ -1648,7 +1651,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case STMT_ATTRIBUTED: - S = new (Context) AttributedStmt(Empty); + S = AttributedStmt::CreateEmpty( + Context, + /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]); break; case STMT_IF: diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 566c8b77f5..6a6863f17b 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -3086,10 +3086,12 @@ void ASTWriter::WriteMergedDecls() { //===----------------------------------------------------------------------===// /// \brief Write a record containing the given attributes. -void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) { +void ASTWriter::WriteAttributes(ArrayRef Attrs, + RecordDataImpl &Record) { Record.push_back(Attrs.size()); - for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ - const Attr * A = *i; + for (ArrayRef::iterator i = Attrs.begin(), + e = Attrs.end(); i != e; ++i){ + const Attr *A = *i; Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs AddSourceRange(A->getRange(), Record); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index d4ebc1c42a..96b602221e 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -151,7 +151,8 @@ void ASTDeclWriter::VisitDecl(Decl *D) { Record.push_back(D->isInvalidDecl()); Record.push_back(D->hasAttrs()); if (D->hasAttrs()) - Writer.WriteAttributes(D->getAttrs(), Record); + Writer.WriteAttributes(ArrayRef(D->getAttrs().begin(), + D->getAttrs().size()), Record); Record.push_back(D->isImplicit()); Record.push_back(D->isUsed(false)); Record.push_back(D->isReferenced()); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index aa24962b66..f63388fa2f 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -109,6 +109,7 @@ void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) { void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) { VisitStmt(S); + Record.push_back(S->getAttrs().size()); Writer.WriteAttributes(S->getAttrs(), Record); Writer.AddStmt(S->getSubStmt()); Writer.AddSourceLocation(S->getAttrLoc(), Record); -- 2.40.0