mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 09:31:03 +03:00
Rework packed-ness of IR aggregates
Base it on the IR alignments of the fields only. Also fix the alignment of variables captured by ref (=> pointer alignment, not the pointee's) and captured lazy params (=> delegate alignment) in nested frames, something that cropped up with a new assertion.
This commit is contained in:
parent
9dd4d5a2ab
commit
d16fba3030
9 changed files with 92 additions and 117 deletions
|
@ -381,62 +381,66 @@ static void DtoCreateNestedContextType(FuncDeclaration *fd) {
|
|||
IF_LOG Logger::cout() << "Function " << fd->toChars() << " has depth "
|
||||
<< depth << '\n';
|
||||
|
||||
AggrTypeBuilder builder(false);
|
||||
AggrTypeBuilder builder;
|
||||
|
||||
if (depth != 0) {
|
||||
assert(innerFrameType);
|
||||
unsigned ptrSize = gDataLayout->getPointerSize();
|
||||
// Add frame pointer types for all but last frame
|
||||
for (unsigned i = 0; i < (depth - 1); ++i) {
|
||||
builder.addType(innerFrameType->getElementType(i), ptrSize);
|
||||
builder.addType(innerFrameType->getElementType(i), target.ptrsize);
|
||||
}
|
||||
// Add frame pointer type for last frame
|
||||
builder.addType(LLPointerType::getUnqual(innerFrameType), ptrSize);
|
||||
builder.addType(LLPointerType::getUnqual(innerFrameType), target.ptrsize);
|
||||
}
|
||||
|
||||
// Add the direct nested variables of this function, and update their
|
||||
// indices to match.
|
||||
// TODO: optimize ordering for minimal space usage?
|
||||
unsigned maxAlignment = 1;
|
||||
for (auto vd : fd->closureVars) {
|
||||
unsigned alignment = DtoAlignment(vd);
|
||||
if (alignment > 1) {
|
||||
builder.alignCurrentOffset(alignment);
|
||||
}
|
||||
|
||||
const bool isParam = vd->isParameter();
|
||||
|
||||
IrLocal &irLocal =
|
||||
*(isParam ? getIrParameter(vd, true) : getIrLocal(vd, true));
|
||||
irLocal.nestedIndex = builder.currentFieldIndex();
|
||||
irLocal.nestedDepth = depth;
|
||||
|
||||
LLType *t = nullptr;
|
||||
unsigned alignment = 0;
|
||||
if (captureByRef(vd)) {
|
||||
t = DtoType(vd->type->pointerTo());
|
||||
alignment = target.ptrsize;
|
||||
} else if (isParam && (vd->storage_class & STClazy)) {
|
||||
// the type is a delegate (LL struct)
|
||||
auto tf = TypeFunction::create(nullptr, vd->type, VARARGnone, LINK::d);
|
||||
auto td = TypeDelegate::create(tf);
|
||||
t = DtoType(td);
|
||||
alignment = target.ptrsize;
|
||||
} else {
|
||||
t = DtoMemType(vd->type);
|
||||
alignment = DtoAlignment(vd);
|
||||
}
|
||||
|
||||
if (alignment > 1) {
|
||||
builder.alignCurrentOffset(alignment);
|
||||
maxAlignment = std::max(maxAlignment, alignment);
|
||||
}
|
||||
|
||||
IrLocal &irLocal =
|
||||
*(isParam ? getIrParameter(vd, true) : getIrLocal(vd, true));
|
||||
irLocal.nestedIndex = builder.currentFieldIndex();
|
||||
irLocal.nestedDepth = depth;
|
||||
|
||||
builder.addType(t, getTypeAllocSize(t));
|
||||
|
||||
IF_LOG Logger::cout() << "Nested var '" << vd->toChars() << "' of type "
|
||||
<< *t << "\n";
|
||||
}
|
||||
|
||||
LLStructType *frameType =
|
||||
LLStructType::create(gIR->context(), builder.defaultTypes(),
|
||||
std::string("nest.") + fd->toChars());
|
||||
LLStructType *frameType = LLStructType::create(
|
||||
gIR->context(), builder.defaultTypes(),
|
||||
std::string("nest.") + fd->toChars(), builder.isPacked());
|
||||
|
||||
IF_LOG Logger::cout() << "frameType = " << *frameType << '\n';
|
||||
|
||||
// Store type in IrFunction
|
||||
irFunc.frameType = frameType;
|
||||
irFunc.frameTypeAlignment = builder.overallAlignment();
|
||||
irFunc.frameTypeAlignment = maxAlignment;
|
||||
}
|
||||
|
||||
void DtoCreateNestedContext(FuncGenState &funcGen) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue