mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-30 07:00:46 +03:00
Merge branch 'master' into merge-2.068
This commit is contained in:
commit
b63a5e3cf8
18 changed files with 88 additions and 49 deletions
|
@ -876,7 +876,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
// Create the param here and set it to a "dummy" alloca that
|
||||
// we do not store to here.
|
||||
irparam = getIrParameter(vd, true);
|
||||
irparam->value = DtoAlloca(vd->type, vd->ident->toChars());
|
||||
irparam->value = DtoAlloca(vd, vd->ident->toChars());
|
||||
}
|
||||
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
|
||||
|
@ -141,7 +159,12 @@ void DtoDeleteArray(Loc& loc, DValue* arr)
|
|||
|
||||
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)
|
||||
|
@ -149,7 +172,7 @@ llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* nam
|
|||
LLType* lltype = DtoType(type);
|
||||
llvm::AllocaInst* ai = new llvm::AllocaInst(
|
||||
lltype, DtoConstUint(arraysize), name, gIR->topallocapoint());
|
||||
ai->setAlignment(type->alignsize());
|
||||
ai->setAlignment(DtoAlignment(type));
|
||||
return ai;
|
||||
}
|
||||
|
||||
|
@ -195,7 +218,7 @@ LLValue* DtoAllocaDump(LLValue* val, int alignment, 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)
|
||||
|
@ -869,11 +892,9 @@ void DtoResolveVariable(VarDeclaration* vd)
|
|||
vd->isThreadlocal());
|
||||
getIrGlobal(vd)->value = gvar;
|
||||
|
||||
// Set the alignment (it is important not to use type->alignsize because
|
||||
// VarDeclarations can have an align() attribute independent of the type
|
||||
// as well).
|
||||
if (vd->alignment != STRUCTALIGN_DEFAULT)
|
||||
gvar->setAlignment(vd->alignment);
|
||||
// Set the alignment and use the target pointer size as lower bound.
|
||||
unsigned alignment = std::max(DtoAlignment(vd), gDataLayout->getPointerSize());
|
||||
gvar->setAlignment(alignment);
|
||||
|
||||
IF_LOG Logger::cout() << *gvar << '\n';
|
||||
}
|
||||
|
@ -928,8 +949,10 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
LLType* lltype = DtoType(type);
|
||||
if(gDataLayout->getTypeSizeInBits(lltype) == 0)
|
||||
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
|
||||
else
|
||||
else if (type != vd->type)
|
||||
allocainst = DtoAlloca(type, vd->toChars());
|
||||
else
|
||||
allocainst = DtoAlloca(vd, vd->toChars());
|
||||
|
||||
irLocal->value = allocainst;
|
||||
|
||||
|
@ -1106,7 +1129,7 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
|
|||
// alloca if necessary
|
||||
if (!addr && (!irLocal || !irLocal->value))
|
||||
{
|
||||
addr = DtoAlloca(var->type, var->toChars());
|
||||
addr = DtoAlloca(var, var->toChars());
|
||||
// add debug info
|
||||
if (!irLocal)
|
||||
irLocal = getIrLocal(var, true);
|
||||
|
|
|
@ -31,8 +31,12 @@ void DtoDeleteClass(Loc& loc, DValue* inst);
|
|||
void DtoDeleteInterface(Loc& loc, DValue* inst);
|
||||
void DtoDeleteArray(Loc& loc, DValue* arr);
|
||||
|
||||
unsigned DtoAlignment(Type* type);
|
||||
unsigned DtoAlignment(VarDeclaration* vd);
|
||||
|
||||
// emit an alloca
|
||||
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* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name = "");
|
||||
LLValue* DtoGcMalloc(Loc& loc, LLType* lltype, const char* name = "");
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "gen/logger.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irfunction.h"
|
||||
#include "ir/irtypeaggr.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
|
||||
/****************************************************************************************/
|
||||
|
@ -361,24 +362,17 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd)
|
|||
|
||||
IF_LOG Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
|
||||
|
||||
typedef std::vector<LLType*> TypeVec;
|
||||
TypeVec types;
|
||||
AggrTypeBuilder builder(false);
|
||||
|
||||
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)
|
||||
types.push_back(innerFrameType->getElementType(i));
|
||||
builder.addType(innerFrameType->getElementType(i), ptrSize);
|
||||
// Add frame pointer type for last frame
|
||||
types.push_back(LLPointerType::getUnqual(innerFrameType));
|
||||
}
|
||||
|
||||
if (Logger::enabled() && depth != 0)
|
||||
{
|
||||
Logger::println("Frame types: ");
|
||||
LOG_SCOPE;
|
||||
for (TypeVec::iterator i = types.begin(); i != types.end(); ++i)
|
||||
Logger::cout() << **i << '\n';
|
||||
builder.addType(LLPointerType::getUnqual(innerFrameType), ptrSize);
|
||||
}
|
||||
|
||||
// Add the direct nested variables of this function, and update their indices to match.
|
||||
|
@ -388,10 +382,16 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd)
|
|||
I != E; ++I)
|
||||
{
|
||||
VarDeclaration* vd = *I;
|
||||
|
||||
unsigned alignment = DtoAlignment(vd);
|
||||
if (alignment > 1)
|
||||
builder.alignCurrentOffset(alignment);
|
||||
|
||||
IrLocal& irLocal = *getIrLocal(vd, true);
|
||||
irLocal.nestedIndex = types.size();
|
||||
irLocal.nestedIndex = builder.currentFieldIndex();
|
||||
irLocal.nestedDepth = depth;
|
||||
|
||||
LLType* t = NULL;
|
||||
if (vd->isParameter() && getIrParameter(vd)->arg)
|
||||
{
|
||||
// Parameters that are part of the LLVM signature will have
|
||||
|
@ -407,29 +407,32 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd)
|
|||
{
|
||||
// This will be copied to the nesting frame.
|
||||
if (lazy)
|
||||
types.push_back(irparam->value->getType()->getContainedType(0));
|
||||
t = irparam->value->getType()->getContainedType(0);
|
||||
else
|
||||
types.push_back(DtoMemType(vd->type));
|
||||
t = DtoMemType(vd->type);
|
||||
}
|
||||
else
|
||||
types.push_back(irparam->value->getType());
|
||||
t = irparam->value->getType();
|
||||
}
|
||||
else if (isSpecialRefVar(vd))
|
||||
types.push_back(DtoType(vd->type->pointerTo()));
|
||||
t = DtoType(vd->type->pointerTo());
|
||||
else
|
||||
types.push_back(DtoMemType(vd->type));
|
||||
t = DtoMemType(vd->type);
|
||||
|
||||
builder.addType(t, getTypeAllocSize(t));
|
||||
|
||||
IF_LOG Logger::cout() << "Nested var '" << vd->toChars()
|
||||
<< "' of type " << *types.back() << "\n";
|
||||
<< "' of type " << *t << "\n";
|
||||
}
|
||||
|
||||
LLStructType* frameType = LLStructType::create(gIR->context(), types,
|
||||
LLStructType* frameType = LLStructType::create(gIR->context(), builder.defaultTypes(),
|
||||
std::string("nest.") + fd->toChars());
|
||||
|
||||
IF_LOG Logger::cout() << "frameType = " << *frameType << '\n';
|
||||
|
||||
// Store type in IrFunction
|
||||
irFunc.frameType = frameType;
|
||||
irFunc.frameTypeAlignment = builder.overallAlignment();
|
||||
}
|
||||
else // no captured variables
|
||||
{
|
||||
|
@ -438,6 +441,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd)
|
|||
// Propagate context arg properties if the context arg is passed on unmodified.
|
||||
IrFunction& parentIrFunc = *getIrFunc(parentFunc);
|
||||
irFunc.frameType = parentIrFunc.frameType;
|
||||
irFunc.frameTypeAlignment = parentIrFunc.frameTypeAlignment;
|
||||
irFunc.depth = parentIrFunc.depth;
|
||||
}
|
||||
}
|
||||
|
@ -457,13 +461,18 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
unsigned depth = irfunction->depth;
|
||||
LLStructType *frameType = irfunction->frameType;
|
||||
// Create frame for current function and append to frames list
|
||||
// FIXME: alignment ?
|
||||
LLValue* frame = 0;
|
||||
bool needsClosure = fd->needsClosure();
|
||||
if (needsClosure)
|
||||
{
|
||||
// FIXME: alignment ?
|
||||
frame = DtoGcMalloc(fd->loc, frameType, ".frame");
|
||||
}
|
||||
else
|
||||
frame = DtoRawAlloca(frameType, 0, ".frame");
|
||||
{
|
||||
unsigned alignment = std::max(getABITypeAlign(frameType), irfunction->frameTypeAlignment);
|
||||
frame = DtoRawAlloca(frameType, alignment, ".frame");
|
||||
}
|
||||
|
||||
// copy parent frames into beginning
|
||||
if (depth != 0) {
|
||||
|
|
|
@ -44,7 +44,7 @@ static std::string getProgram(const char* name, const cl::opt<std::string>* opt,
|
|||
if (opt && opt->getNumOccurrences() > 0 && opt->length() > 0 && (prog = opt->c_str()))
|
||||
path = findProgramByName(prog);
|
||||
|
||||
if (path.empty() && envVar && (prog = getenv(envVar)))
|
||||
if (path.empty() && envVar && (prog = getenv(envVar)) && prog[0] != '\0')
|
||||
path = findProgramByName(prog);
|
||||
|
||||
if (path.empty())
|
||||
|
|
|
@ -103,7 +103,7 @@ void RTTIBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* ma
|
|||
LLGlobalVariable* G = new LLGlobalVariable(
|
||||
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
|
||||
SET_COMDAT(G, gIR->module);
|
||||
G->setAlignment(valtype->alignsize());
|
||||
G->setAlignment(DtoAlignment(valtype));
|
||||
|
||||
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(
|
||||
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
|
||||
SET_COMDAT(G, gIR->module);
|
||||
G->setAlignment(valtype->alignsize());
|
||||
G->setAlignment(DtoAlignment(valtype));
|
||||
|
||||
push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo())));
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "target.h"
|
||||
#include "gen/abi.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
#include <assert.h>
|
||||
|
@ -59,8 +60,7 @@ unsigned Target::alignsize (Type* type)
|
|||
|
||||
unsigned Target::fieldalign (Type* type)
|
||||
{
|
||||
// LDC_FIXME: Verify this.
|
||||
return type->alignsize();
|
||||
return DtoAlignment(type);
|
||||
}
|
||||
|
||||
// sizes based on those from tollvm.cpp:DtoMutexType()
|
||||
|
|
|
@ -663,7 +663,7 @@ private:
|
|||
|
||||
LLValue* var = retvar;
|
||||
if (!var)
|
||||
var = DtoRawAlloca(llArgType->getContainedType(0), resulttype->alignsize(), ".rettmp");
|
||||
var = DtoRawAlloca(llArgType->getContainedType(0), DtoAlignment(resulttype), ".rettmp");
|
||||
|
||||
args.push_back(var);
|
||||
attrs.add(index + 1, irFty.arg_sret->attrs);
|
||||
|
|
|
@ -504,7 +504,7 @@ public:
|
|||
se->globalVar = finalGlobalVar;
|
||||
}
|
||||
se->globalVar->setInitializer(constValue);
|
||||
se->globalVar->setAlignment(e->e1->type->alignsize());
|
||||
se->globalVar->setAlignment(DtoAlignment(se->type));
|
||||
|
||||
result = se->globalVar;
|
||||
}
|
||||
|
|
|
@ -2590,7 +2590,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
llvm::Value* storage = DtoRawAlloca(llStoType, e->type->alignsize(), "arrayliteral");
|
||||
llvm::Value* storage = DtoRawAlloca(llStoType, DtoAlignment(e->type), "arrayliteral");
|
||||
initializeArrayLiteral(p, e, storage);
|
||||
result = new DImValue(e->type, storage);
|
||||
}
|
||||
|
|
|
@ -723,7 +723,7 @@ size_t getTypeAllocSize(LLType* t)
|
|||
return gDataLayout->getTypeAllocSize(t);
|
||||
}
|
||||
|
||||
unsigned char getABITypeAlign(LLType* t)
|
||||
unsigned int getABITypeAlign(LLType* t)
|
||||
{
|
||||
return gDataLayout->getABITypeAlignment(t);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ size_t getTypePaddedSize(LLType* t);
|
|||
size_t getTypeAllocSize(LLType* t);
|
||||
|
||||
// type alignments
|
||||
unsigned char getABITypeAlign(LLType* t);
|
||||
unsigned int getABITypeAlign(LLType* t);
|
||||
|
||||
// pair type helpers
|
||||
LLValue* DtoAggrPair(LLType* type, LLValue* V1, LLValue* V2, const char* name = "");
|
||||
|
|
|
@ -483,7 +483,7 @@ public:
|
|||
b.push_funcptr(xpostblit);
|
||||
|
||||
//uint m_align;
|
||||
b.push_uint(tc->alignsize());
|
||||
b.push_uint(DtoAlignment(tc));
|
||||
|
||||
if (global.params.is64bit)
|
||||
{
|
||||
|
|
|
@ -58,10 +58,7 @@ LLGlobalVariable * IrAggr::getInitSymbol()
|
|||
gIR->module, init_type, true, llvm::GlobalValue::ExternalLinkage, NULL, initname);
|
||||
|
||||
// set alignment
|
||||
init->setAlignment(type->alignsize());
|
||||
StructDeclaration *sd = aggrdecl->isStructDeclaration();
|
||||
if (sd && sd->alignment != STRUCTALIGN_DEFAULT)
|
||||
init->setAlignment(sd->alignment);
|
||||
init->setAlignment(DtoAlignment(type));
|
||||
|
||||
return init;
|
||||
}
|
||||
|
|
|
@ -423,6 +423,7 @@ IrFunction::IrFunction(FuncDeclaration* fd) {
|
|||
|
||||
nestedVar = NULL;
|
||||
frameType = NULL;
|
||||
frameTypeAlignment = 0;
|
||||
depth = -1;
|
||||
nestedContextCreated = false;
|
||||
|
||||
|
|
|
@ -411,6 +411,7 @@ struct IrFunction {
|
|||
|
||||
llvm::Value* nestedVar; // alloca for the nested context of this function
|
||||
llvm::StructType* frameType; // type of nested context
|
||||
unsigned frameTypeAlignment; // its alignment
|
||||
// number of enclosing functions with variables accessed by nested functions
|
||||
// (-1 if neither this function nor any enclosing ones access variables from enclosing functions)
|
||||
int depth;
|
||||
|
|
|
@ -50,7 +50,7 @@ bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v2)
|
|||
}
|
||||
|
||||
AggrTypeBuilder::AggrTypeBuilder(bool packed) :
|
||||
m_offset(0), m_fieldIndex(0), m_packed(packed)
|
||||
m_offset(0), m_fieldIndex(0), m_overallAlignment(0), m_packed(packed)
|
||||
{
|
||||
m_defaultTypes.reserve(32);
|
||||
}
|
||||
|
@ -192,6 +192,8 @@ void AggrTypeBuilder::addAggregate(AggregateDeclaration *ad)
|
|||
|
||||
void AggrTypeBuilder::alignCurrentOffset(unsigned alignment)
|
||||
{
|
||||
m_overallAlignment = std::max(alignment, m_overallAlignment);
|
||||
|
||||
unsigned aligned = (m_offset + alignment - 1) & ~(alignment - 1);
|
||||
if (m_offset < aligned) {
|
||||
m_fieldIndex += add_zeros(m_defaultTypes, m_offset, aligned);
|
||||
|
|
|
@ -43,11 +43,13 @@ public:
|
|||
unsigned currentFieldIndex() const { return m_fieldIndex; }
|
||||
std::vector<llvm::Type*> defaultTypes() const { return m_defaultTypes; }
|
||||
VarGEPIndices varGEPIndices() const { return m_varGEPIndices; }
|
||||
unsigned overallAlignment() const { return m_overallAlignment; }
|
||||
protected:
|
||||
std::vector<llvm::Type*> m_defaultTypes;
|
||||
VarGEPIndices m_varGEPIndices;
|
||||
unsigned m_offset;
|
||||
unsigned m_fieldIndex;
|
||||
unsigned m_overallAlignment;
|
||||
bool m_packed;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue