mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-10 12:59:21 +03:00
Introduce DtoAlignment() and overload DtoAlloca() for VarDeclarations
Trying to get the alignment right by using the first non-default one in the following order of descending priority: VarDeclaration::alignment [variables only of course] Type::alignment() Type::alignsize() This fixes `align(x) struct S { ... }`.
This commit is contained in:
parent
8211be11de
commit
05c10d9107
11 changed files with 48 additions and 23 deletions
|
@ -876,7 +876,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
// Create the param here and set it to a "dummy" alloca that
|
// Create the param here and set it to a "dummy" alloca that
|
||||||
// we do not store to here.
|
// we do not store to here.
|
||||||
irparam = getIrParameter(vd, true);
|
irparam = getIrParameter(vd, true);
|
||||||
irparam->value = DtoAlloca(vd->type, vd->ident->toChars());
|
irparam->value = DtoAlloca(vd, vd->ident->toChars());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,6 +134,24 @@ void DtoDeleteArray(Loc& loc, DValue* arr)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ALIGNMENT HELPERS
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
unsigned DtoAlignment(Type* type)
|
||||||
|
{
|
||||||
|
structalign_t alignment = type->alignment();
|
||||||
|
if (alignment == STRUCTALIGN_DEFAULT)
|
||||||
|
alignment = type->alignsize();
|
||||||
|
return (alignment == STRUCTALIGN_DEFAULT ? 0 : alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned DtoAlignment(VarDeclaration* vd)
|
||||||
|
{
|
||||||
|
return vd->alignment == STRUCTALIGN_DEFAULT ? DtoAlignment(vd->type) : vd->alignment;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ALLOCA HELPERS
|
// ALLOCA HELPERS
|
||||||
|
@ -141,7 +159,12 @@ void DtoDeleteArray(Loc& loc, DValue* arr)
|
||||||
|
|
||||||
llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
|
llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
|
||||||
{
|
{
|
||||||
return DtoRawAlloca(DtoMemType(type), type->alignsize(), name);
|
return DtoRawAlloca(DtoMemType(type), DtoAlignment(type), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::AllocaInst* DtoAlloca(VarDeclaration* vd, const char* name)
|
||||||
|
{
|
||||||
|
return DtoRawAlloca(DtoMemType(vd->type), DtoAlignment(vd), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name)
|
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name)
|
||||||
|
@ -149,7 +172,7 @@ llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* nam
|
||||||
LLType* lltype = DtoType(type);
|
LLType* lltype = DtoType(type);
|
||||||
llvm::AllocaInst* ai = new llvm::AllocaInst(
|
llvm::AllocaInst* ai = new llvm::AllocaInst(
|
||||||
lltype, DtoConstUint(arraysize), name, gIR->topallocapoint());
|
lltype, DtoConstUint(arraysize), name, gIR->topallocapoint());
|
||||||
ai->setAlignment(type->alignsize());
|
ai->setAlignment(DtoAlignment(type));
|
||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +218,7 @@ LLValue* DtoAllocaDump(LLValue* val, int alignment, const char* name)
|
||||||
|
|
||||||
LLValue* DtoAllocaDump(LLValue* val, Type* asType, const char* name)
|
LLValue* DtoAllocaDump(LLValue* val, Type* asType, const char* name)
|
||||||
{
|
{
|
||||||
return DtoAllocaDump(val, DtoType(asType), asType->alignsize(), name);
|
return DtoAllocaDump(val, DtoType(asType), DtoAlignment(asType), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue* DtoAllocaDump(LLValue* val, LLType* asType, int alignment, const char* name)
|
LLValue* DtoAllocaDump(LLValue* val, LLType* asType, int alignment, const char* name)
|
||||||
|
@ -872,8 +895,7 @@ void DtoResolveVariable(VarDeclaration* vd)
|
||||||
// Set the alignment (it is important not to use type->alignsize because
|
// Set the alignment (it is important not to use type->alignsize because
|
||||||
// VarDeclarations can have an align() attribute independent of the type
|
// VarDeclarations can have an align() attribute independent of the type
|
||||||
// as well).
|
// as well).
|
||||||
if (vd->alignment != STRUCTALIGN_DEFAULT)
|
gvar->setAlignment(DtoAlignment(vd));
|
||||||
gvar->setAlignment(vd->alignment);
|
|
||||||
|
|
||||||
IF_LOG Logger::cout() << *gvar << '\n';
|
IF_LOG Logger::cout() << *gvar << '\n';
|
||||||
}
|
}
|
||||||
|
@ -928,8 +950,10 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
||||||
LLType* lltype = DtoType(type);
|
LLType* lltype = DtoType(type);
|
||||||
if(gDataLayout->getTypeSizeInBits(lltype) == 0)
|
if(gDataLayout->getTypeSizeInBits(lltype) == 0)
|
||||||
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
|
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
|
||||||
else
|
else if (type != vd->type)
|
||||||
allocainst = DtoAlloca(type, vd->toChars());
|
allocainst = DtoAlloca(type, vd->toChars());
|
||||||
|
else
|
||||||
|
allocainst = DtoAlloca(vd, vd->toChars());
|
||||||
|
|
||||||
irLocal->value = allocainst;
|
irLocal->value = allocainst;
|
||||||
|
|
||||||
|
@ -1106,7 +1130,7 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
|
||||||
// alloca if necessary
|
// alloca if necessary
|
||||||
if (!addr && (!irLocal || !irLocal->value))
|
if (!addr && (!irLocal || !irLocal->value))
|
||||||
{
|
{
|
||||||
addr = DtoAlloca(var->type, var->toChars());
|
addr = DtoAlloca(var, var->toChars());
|
||||||
// add debug info
|
// add debug info
|
||||||
if (!irLocal)
|
if (!irLocal)
|
||||||
irLocal = getIrLocal(var, true);
|
irLocal = getIrLocal(var, true);
|
||||||
|
@ -1355,7 +1379,7 @@ bool hasUnalignedFields(Type* t)
|
||||||
{
|
{
|
||||||
t = t->toBasetype();
|
t = t->toBasetype();
|
||||||
if (t->ty == Tsarray) {
|
if (t->ty == Tsarray) {
|
||||||
assert(t->nextOf()->size() % t->nextOf()->alignsize() == 0);
|
assert(t->nextOf()->size() % DtoAlignment(t->nextOf()) == 0);
|
||||||
return hasUnalignedFields(t->nextOf());
|
return hasUnalignedFields(t->nextOf());
|
||||||
} else if (t->ty != Tstruct)
|
} else if (t->ty != Tstruct)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1371,7 +1395,7 @@ bool hasUnalignedFields(Type* t)
|
||||||
for (unsigned i = 0; i < sym->fields.dim; i++)
|
for (unsigned i = 0; i < sym->fields.dim; i++)
|
||||||
{
|
{
|
||||||
VarDeclaration* f = static_cast<VarDeclaration*>(sym->fields.data[i]);
|
VarDeclaration* f = static_cast<VarDeclaration*>(sym->fields.data[i]);
|
||||||
unsigned a = f->type->alignsize() - 1;
|
unsigned a = DtoAlignment(f) - 1;
|
||||||
if (((f->offset + a) & ~a) != f->offset)
|
if (((f->offset + a) & ~a) != f->offset)
|
||||||
return true;
|
return true;
|
||||||
else if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type))
|
else if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type))
|
||||||
|
|
|
@ -31,8 +31,12 @@ void DtoDeleteClass(Loc& loc, DValue* inst);
|
||||||
void DtoDeleteInterface(Loc& loc, DValue* inst);
|
void DtoDeleteInterface(Loc& loc, DValue* inst);
|
||||||
void DtoDeleteArray(Loc& loc, DValue* arr);
|
void DtoDeleteArray(Loc& loc, DValue* arr);
|
||||||
|
|
||||||
|
unsigned DtoAlignment(Type* type);
|
||||||
|
unsigned DtoAlignment(VarDeclaration* vd);
|
||||||
|
|
||||||
// emit an alloca
|
// emit an alloca
|
||||||
llvm::AllocaInst* DtoAlloca(Type* type, const char* name = "");
|
llvm::AllocaInst* DtoAlloca(Type* type, const char* name = "");
|
||||||
|
llvm::AllocaInst* DtoAlloca(VarDeclaration* vd, const char* name = "");
|
||||||
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name = "");
|
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name = "");
|
||||||
llvm::AllocaInst* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name = "");
|
llvm::AllocaInst* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name = "");
|
||||||
LLValue* DtoGcMalloc(Loc& loc, LLType* lltype, const char* name = "");
|
LLValue* DtoGcMalloc(Loc& loc, LLType* lltype, const char* name = "");
|
||||||
|
|
|
@ -103,7 +103,7 @@ void RTTIBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* ma
|
||||||
LLGlobalVariable* G = new LLGlobalVariable(
|
LLGlobalVariable* G = new LLGlobalVariable(
|
||||||
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
|
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
|
||||||
SET_COMDAT(G, gIR->module);
|
SET_COMDAT(G, gIR->module);
|
||||||
G->setAlignment(valtype->alignsize());
|
G->setAlignment(DtoAlignment(valtype));
|
||||||
|
|
||||||
push_void_array(getTypePaddedSize(CI->getType()), G);
|
push_void_array(getTypePaddedSize(CI->getType()), G);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, D
|
||||||
LLGlobalVariable* G = new LLGlobalVariable(
|
LLGlobalVariable* G = new LLGlobalVariable(
|
||||||
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
|
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
|
||||||
SET_COMDAT(G, gIR->module);
|
SET_COMDAT(G, gIR->module);
|
||||||
G->setAlignment(valtype->alignsize());
|
G->setAlignment(DtoAlignment(valtype));
|
||||||
|
|
||||||
push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo())));
|
push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo())));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "gen/abi.h"
|
#include "gen/abi.h"
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -59,8 +60,7 @@ unsigned Target::alignsize (Type* type)
|
||||||
|
|
||||||
unsigned Target::fieldalign (Type* type)
|
unsigned Target::fieldalign (Type* type)
|
||||||
{
|
{
|
||||||
// LDC_FIXME: Verify this.
|
return DtoAlignment(type);
|
||||||
return type->alignsize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sizes based on those from tollvm.cpp:DtoMutexType()
|
// sizes based on those from tollvm.cpp:DtoMutexType()
|
||||||
|
|
|
@ -663,7 +663,7 @@ private:
|
||||||
|
|
||||||
LLValue* var = retvar;
|
LLValue* var = retvar;
|
||||||
if (!var)
|
if (!var)
|
||||||
var = DtoRawAlloca(llArgType->getContainedType(0), resulttype->alignsize(), ".rettmp");
|
var = DtoRawAlloca(llArgType->getContainedType(0), DtoAlignment(resulttype), ".rettmp");
|
||||||
|
|
||||||
args.push_back(var);
|
args.push_back(var);
|
||||||
attrs.add(index + 1, irFty.arg_sret->attrs);
|
attrs.add(index + 1, irFty.arg_sret->attrs);
|
||||||
|
|
|
@ -503,7 +503,7 @@ public:
|
||||||
se->globalVar = finalGlobalVar;
|
se->globalVar = finalGlobalVar;
|
||||||
}
|
}
|
||||||
se->globalVar->setInitializer(constValue);
|
se->globalVar->setInitializer(constValue);
|
||||||
se->globalVar->setAlignment(e->e1->type->alignsize());
|
se->globalVar->setAlignment(DtoAlignment(se->type));
|
||||||
|
|
||||||
result = se->globalVar;
|
result = se->globalVar;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2587,7 +2587,7 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llvm::Value* storage = DtoRawAlloca(llStoType, e->type->alignsize(), "arrayliteral");
|
llvm::Value* storage = DtoRawAlloca(llStoType, DtoAlignment(e->type), "arrayliteral");
|
||||||
initializeArrayLiteral(p, e, storage);
|
initializeArrayLiteral(p, e, storage);
|
||||||
result = new DImValue(e->type, storage);
|
result = new DImValue(e->type, storage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,7 +483,7 @@ public:
|
||||||
b.push_funcptr(xpostblit);
|
b.push_funcptr(xpostblit);
|
||||||
|
|
||||||
//uint m_align;
|
//uint m_align;
|
||||||
b.push_uint(tc->alignsize());
|
b.push_uint(DtoAlignment(tc));
|
||||||
|
|
||||||
if (global.params.is64bit)
|
if (global.params.is64bit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,10 +58,7 @@ LLGlobalVariable * IrAggr::getInitSymbol()
|
||||||
gIR->module, init_type, true, llvm::GlobalValue::ExternalLinkage, NULL, initname);
|
gIR->module, init_type, true, llvm::GlobalValue::ExternalLinkage, NULL, initname);
|
||||||
|
|
||||||
// set alignment
|
// set alignment
|
||||||
init->setAlignment(type->alignsize());
|
init->setAlignment(DtoAlignment(type));
|
||||||
StructDeclaration *sd = aggrdecl->isStructDeclaration();
|
|
||||||
if (sd && sd->alignment != STRUCTALIGN_DEFAULT)
|
|
||||||
init->setAlignment(sd->alignment);
|
|
||||||
|
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,7 +223,7 @@ bool IrTypeAggr::isPacked(AggregateDeclaration* ad)
|
||||||
for (unsigned i = 0; i < ad->fields.dim; i++)
|
for (unsigned i = 0; i < ad->fields.dim; i++)
|
||||||
{
|
{
|
||||||
VarDeclaration* vd = static_cast<VarDeclaration*>(ad->fields.data[i]);
|
VarDeclaration* vd = static_cast<VarDeclaration*>(ad->fields.data[i]);
|
||||||
unsigned a = vd->type->alignsize() - 1;
|
unsigned a = DtoAlignment(vd) - 1;
|
||||||
if (((vd->offset + a) & ~a) != vd->offset)
|
if (((vd->offset + a) & ~a) != vd->offset)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue