From 673a9742603a6dc34b7f739f1321059dc6090a88 Mon Sep 17 00:00:00 2001 From: Sebastian Graf Date: Tue, 29 Jan 2013 22:38:12 +0100 Subject: [PATCH] Un-unroll static array, [David Nadlinger] Note that DtoStructLiteralValues was/is used only once across the codebase. --- gen/structs.cpp | 65 ++++++++++++------------------------------------- gen/structs.h | 4 +-- gen/toir.cpp | 4 +-- 3 files changed, 20 insertions(+), 53 deletions(-) diff --git a/gen/structs.cpp b/gen/structs.cpp index 78b37212..43a4e5bb 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -149,39 +149,23 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) ////////////////////////////////////////////////////////////////////////////////////////// // helper function that adds zero bytes to a vector of constants -size_t add_zeros(std::vector& values, size_t diff) +extern size_t add_zeros(std::vector& values, size_t diff); + +// return a constant array of type arrTypeD initialized with a constant value, or that constant value +LLConstant* FillSArrayDims(Type* arrTypeD, LLConstant* init) { - size_t n = values.size(); - bool is64 = global.params.is64bit; - while (diff) + if (arrTypeD->ty == Tsarray) { - if (is64 && diff % 8 == 0) - { - values.push_back(LLConstant::getNullValue(llvm::Type::getInt64Ty(gIR->context()))); - diff -= 8; - } - else if (diff % 4 == 0) - { - values.push_back(LLConstant::getNullValue(llvm::Type::getInt32Ty(gIR->context()))); - diff -= 4; - } - else if (diff % 2 == 0) - { - values.push_back(LLConstant::getNullValue(llvm::Type::getInt16Ty(gIR->context()))); - diff -= 2; - } - else - { - values.push_back(LLConstant::getNullValue(llvm::Type::getInt8Ty(gIR->context()))); - diff -= 1; - } + init = FillSArrayDims(arrTypeD->nextOf(), init); + size_t dim = static_cast(arrTypeD)->dim->toUInteger(); + LLArrayType* arrty = LLArrayType::get(init->getType(), dim); + return LLConstantArray::get(arrty, std::vector(dim, init)); } - return values.size() - n; + return init; } -std::vector DtoStructLiteralValues(const StructDeclaration* sd, - const std::vector& inits, - bool isConst) +std::vector DtoStructLiteralValues(const StructDeclaration* sd, + const std::vector& inits) { // get arrays size_t nvars = sd->fields.dim; @@ -200,7 +184,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, } // vector of values to build aggregate from - std::vector values; + std::vector values; // offset trackers size_t lastoffset = 0; @@ -264,24 +248,8 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, assert(nextVar == var); - // add any 0 padding needed before this field - if (!isConst && os > lastoffset + lastsize) - { - //printf("added %lu zeros\n", os - lastoffset - lastsize); - add_zeros(values, os - lastoffset - lastsize); - } - - size_t repCount = 1; - // compute repCount to fill each array dimension - for (Type *varType = var->type; - varType->ty == Tsarray; - varType = varType->nextOf()) - { - repCount *= static_cast(varType)->dim->toUInteger(); - } - - // add the expression values - std::fill_n(std::back_inserter(values), repCount, inits[i]); + LLConstant* init = FillSArrayDims(var->type, inits[i]); + values.push_back(init); // update offsets lastoffset = os; @@ -289,8 +257,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, // sometimes size of the initializer is less than size of the variable, // so make sure that lastsize is correct if (inits[i]->getType()->isSized()) - lastsize = ceil(gDataLayout->getTypeSizeInBits(inits[i]->getType()) / 8.0); - else + sz = ceil(gDataLayout->getTypeSizeInBits(init->getType()) / 8.0); #endif lastsize = sz; diff --git a/gen/structs.h b/gen/structs.h index 165a3d46..8613744a 100644 --- a/gen/structs.h +++ b/gen/structs.h @@ -40,8 +40,8 @@ void DtoResolveStruct(StructDeclaration* sd); llvm::Constant* DtoConstStructInitializer(StructInitializer* si); /// Build values for a struct literal. -std::vector DtoStructLiteralValues(const StructDeclaration* sd, - const std::vector& inits, bool isConst = false); +std::vector DtoStructLiteralValues(const StructDeclaration* sd, + const std::vector& inits); /// Returns a boolean=true if the two structs are equal. llvm::Value* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs); diff --git a/gen/toir.cpp b/gen/toir.cpp index 6e5bd2d2..afa46cf8 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -3046,7 +3046,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) sd->codegen(Type::sir); // get inits - std::vector inits(sd->fields.dim, NULL); + std::vector inits(sd->fields.dim, NULL); size_t nexprs = elements->dim;; Expression** exprs = (Expression**)elements->data; @@ -3056,7 +3056,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) inits[i] = exprs[i]->toConstElem(p); // vector of values to build aggregate from - std::vector values = DtoStructLiteralValues(sd, inits, true); + std::vector values = DtoStructLiteralValues(sd, inits); // we know those values are constants.. cast them std::vector constvals(values.size(), NULL);