Skip to content

Commit

Permalink
Try to optimize large arrays of integers
Browse files Browse the repository at this point in the history
  • Loading branch information
cor3ntin committed Dec 23, 2019
1 parent f0604e7 commit 4e08c35
Show file tree
Hide file tree
Showing 23 changed files with 741 additions and 145 deletions.
111 changes: 109 additions & 2 deletions clang/include/clang/AST/Expr.h
Expand Up @@ -4388,7 +4388,28 @@ class SourceLocExpr final : public Expr {
/// Since many initializer lists have the same syntactic and semantic forms,
/// getSyntacticForm() may return NULL, indicating that the current
/// semantic initializer list also serves as its syntactic form.
class InitListExpr : public Expr {

class InitListExpr;
class AbstractInitListExpr : public Expr {
public:
AbstractInitListExpr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack);
explicit AbstractInitListExpr(StmtClass SC, EmptyShell);

unsigned getNumInits() const LLVM_READONLY;
SourceLocation getInitBeginLoc(unsigned Index) const LLVM_READONLY;
SourceRange getInitSourceRange(unsigned Index) const LLVM_READONLY;
QualType getInitType(unsigned Index) const LLVM_READONLY;
bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const LLVM_READONLY;

static bool classof(const Stmt *T) {
return T->getStmtClass() == InitListExprClass ||
T->getStmtClass() == ListOfLiteralExprClass;
}

};

class InitListExpr : public AbstractInitListExpr {
// FIXME: Eliminate this vector in favor of ASTContext allocation
typedef ASTVector<Stmt *> InitExprsTy;
InitExprsTy InitExprs;
Expand Down Expand Up @@ -4416,7 +4437,7 @@ class InitListExpr : public Expr {

/// Build an empty initializer list.
explicit InitListExpr(EmptyShell Empty)
: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
: AbstractInitListExpr(InitListExprClass, Empty), AltForm(nullptr, true) { }

unsigned getNumInits() const { return InitExprs.size(); }

Expand Down Expand Up @@ -4604,6 +4625,92 @@ class InitListExpr : public Expr {
friend class ASTStmtWriter;
};


class ListOfLiteralExpr final: public AbstractInitListExpr,
private llvm::TrailingObjects<ListOfLiteralExpr, unsigned, char>{
SourceLocation LBraceLoc, RBraceLoc;
QualType InitsType;
unsigned InitCount = 0;
unsigned NumBytePerElement = 0;
friend TrailingObjects;

explicit ListOfLiteralExpr(ASTContext &Context,
SourceLocation LBraceLoc,
ArrayRef<uint64_t> Values,
QualType Ty,
SourceLocation RBraceLoc);

explicit ListOfLiteralExpr(const ASTContext &Context);

public:
static ListOfLiteralExpr* Create(ASTContext &Context,
SourceLocation LBraceLoc,
ArrayRef<uint64_t> Values,
QualType Ty,
SourceLocation RBraceLoc);

static ListOfLiteralExpr* CreateEmpty(const ASTContext &Ctx, unsigned Bytes);


static bool classof(const Stmt *T) {
return T->getStmtClass() == ListOfLiteralExprClass;
}


unsigned getNumInits() const;
void setNumInits(unsigned);

QualType getInitsType() const;
void setInitsType(const ASTContext & Context, QualType);

llvm::APInt getInit(unsigned) const;
void setInit(unsigned Index, uint64_t Value);

// Fast path to fill an APValue
void getMultipleInit(APValue*, unsigned Size, unsigned Bits) const;

SourceLocation getBeginLoc() const { return LBraceLoc; }
SourceLocation getEndLoc() const { return LBraceLoc; }

SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }


uint64_t *getElementsAsUint64() { return reinterpret_cast<uint64_t*>(getTrailingObjects<char>()); }
const uint64_t *getElementsAsUint64() const { return reinterpret_cast<const uint64_t*>(getTrailingObjects<char>()); }
unsigned sizeOfElementsAsUint64() const {
return numTrailingObjects(OverloadToken<char>()) / sizeof (uint64_t);
}

// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
private:
template <typename T>
llvm::APInt DoGetInit(unsigned) const;
template <typename T>
void DoGetMultipleInit(APValue* Array, unsigned Size, unsigned Bits) const;
template <typename T>
void DoSetInit(unsigned, uint64_t);

unsigned numTrailingObjects(OverloadToken<unsigned>) const {
return 1;
}

unsigned numTrailingObjects(OverloadToken<char>) const {
return *getTrailingObjects<unsigned>();
}

static unsigned numBytesForType(const ASTContext & Context, const QualType & Ty);
};


/// Represents a C99 designated initializer expression.
///
/// A designated initializer expression (C99 6.7.8) contains one or
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Expand Up @@ -2547,6 +2547,7 @@ DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
DEF_TRAVERSE_STMT(ListOfLiteralExpr, {})
DEF_TRAVERSE_STMT(NoInitExpr, {})
DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
// FIXME: The source expression of the OVE should be listed as
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/StmtNodes.td
Expand Up @@ -84,7 +84,9 @@ def ExplicitCastExpr : StmtNode<CastExpr, 1>;
def CStyleCastExpr : StmtNode<ExplicitCastExpr>;
def CompoundLiteralExpr : StmtNode<Expr>;
def ExtVectorElementExpr : StmtNode<Expr>;
def InitListExpr : StmtNode<Expr>;
def AbstractInitListExpr : StmtNode<Expr, 1>;
def InitListExpr : StmtNode<AbstractInitListExpr>;
def ListOfLiteralExpr : StmtNode<AbstractInitListExpr>;
def DesignatedInitExpr : StmtNode<Expr>;
def DesignatedInitUpdateExpr : StmtNode<Expr>;
def ImplicitValueInitExpr : StmtNode<Expr>;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Lex/LiteralSupport.h
Expand Up @@ -100,7 +100,7 @@ class NumericLiteralParser {
/// matches Val's input width. If there is an overflow (i.e., if the unsigned
/// value read is larger than the APInt's bits will hold), set Val to the low
/// bits of the result and return true. Otherwise, return false.
bool GetIntegerValue(llvm::APInt &Val);
bool GetIntegerValue(llvm::APInt &Val) const;

/// GetFloatValue - Convert this numeric literal to a floating value, using
/// the specified APFloat fltSemantics (specifying float, double, etc).
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Parse/Parser.h
Expand Up @@ -1899,6 +1899,7 @@ class Parser : public CodeCompletionHandler {
return ParseBraceInitializer();
}
bool MayBeDesignationStart();
ExprResult ParseListOfLiteralsInitializer();
ExprResult ParseBraceInitializer();
ExprResult ParseInitializerWithPotentialDesignator();

Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Sema/Initialization.h
Expand Up @@ -674,7 +674,7 @@ class InitializationKind {
if (!Init) return CreateDefault(Loc);
if (!DirectInit)
return CreateCopy(Loc, Init->getBeginLoc());
if (isa<InitListExpr>(Init))
if (isa<InitListExpr>(Init) || isa<ListOfLiteralExpr>(Init))
return CreateDirectList(Loc, Init->getBeginLoc(), Init->getEndLoc());
return CreateDirect(Loc, Init->getBeginLoc(), Init->getEndLoc());
}
Expand Down Expand Up @@ -830,6 +830,9 @@ class InitializationSequence {
/// Perform list-initialization without a constructor.
SK_ListInitialization,

/// Perform list-initialization without a constructor.
SK_ListLiteralInitialization,

/// Unwrap the single-element initializer list for a reference.
SK_UnwrapInitList,

Expand Down Expand Up @@ -1274,6 +1277,10 @@ class InitializationSequence {
/// Add a list-initialization step.
void AddListInitializationStep(QualType T);

/// Add a list-initialization step.
void AddListLiteralInitializationStep(QualType T);


/// Add a constructor-initialization step.
///
/// \param FromInitList The constructor call is syntactically an initializer
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Sema/Sema.h
Expand Up @@ -140,6 +140,7 @@ namespace clang {
class ModuleLoader;
class MultiLevelTemplateArgumentList;
class NamedDecl;
class NumericLiteralParser;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCCompatibleAliasDecl;
Expand Down Expand Up @@ -4638,6 +4639,7 @@ class Sema final {
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);

ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
bool CreateIntegerLiteralValue(llvm::APInt & ResultVal, QualType & Ty, const Token &Tok, const NumericLiteralParser & Literal);
ExprResult ActOnCharacterConstant(const Token &Tok,
Scope *UDLScope = nullptr);
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
Expand Down Expand Up @@ -4846,6 +4848,12 @@ class Sema final {
SourceLocation RParenLoc,
Expr *LiteralExpr);

ExprResult ActOnListOfLiteral(SourceLocation LBraceLoc,
ArrayRef<uint64_t> StringToks,
QualType Ty,
SourceLocation RBraceLoc);


ExprResult ActOnInitList(SourceLocation LBraceLoc,
MultiExprArg InitArgList,
SourceLocation RBraceLoc);
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Expand Up @@ -1867,6 +1867,7 @@ namespace serialization {
EXPR_COAWAIT,
EXPR_COYIELD,
EXPR_DEPENDENT_COAWAIT,
EXPR_INIT_LITERALS_LIST
};

/// The kinds of designators that can occur in a
Expand Down

0 comments on commit 4e08c35

Please sign in to comment.