Merge remote-tracking branch 'upstream/llvm3.0'

This commit is contained in:
David Nadlinger
2011-11-12 19:47:56 +01:00
78 changed files with 1391 additions and 1049 deletions

View File

@@ -3117,6 +3117,9 @@ StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *
#endif
this->soffset = 0;
this->fillHoles = 1;
#if IN_LLVM
constType = NULL;
#endif
}
Expression *StructLiteralExp::syntaxCopy()

View File

@@ -66,6 +66,7 @@ struct DValue;
namespace llvm {
class Constant;
class ConstantInt;
class StructType;
}
#endif
@@ -537,6 +538,7 @@ struct StructLiteralExp : Expression
#elif IN_LLVM
DValue* toElem(IRState* irs);
llvm::Constant *toConstElem(IRState *irs);
llvm::StructType *constType;
#endif
};

View File

@@ -114,6 +114,9 @@ StructInitializer::StructInitializer(Loc loc)
: Initializer(loc)
{
ad = NULL;
#if IN_LLVM
ltype = NULL;
#endif
}
Initializer *StructInitializer::syntaxCopy()

View File

@@ -30,6 +30,12 @@ struct ExpInitializer;
struct HdrGenState;
#endif
#if IN_LLVM
namespace llvm {
class StructType;
}
#endif
struct Initializer : Object
{
Loc loc;
@@ -91,6 +97,9 @@ struct StructInitializer : Initializer
#endif
StructInitializer *isStructInitializer() { return this; }
#if IN_LLVM
llvm::StructType *ltype;
#endif
};
struct ArrayInitializer : Initializer

View File

@@ -153,7 +153,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
// LDC
llvmForceLogging = false;
moduleInfoVar = NULL;
moduleInfoType = new llvm::PATypeHolder(llvm::OpaqueType::get(llvm::getGlobalContext()));
moduleInfoType = llvm::StructType::create(llvm::getGlobalContext());
this->doDocComment = doDocComment;
this->doHdrGen = doHdrGen;
this->isRoot = false;

View File

@@ -35,7 +35,7 @@ namespace llvm {
class LLVMContext;
class Module;
class GlobalVariable;
class PATypeHolder;
class StructType;
}
#else
@@ -202,7 +202,7 @@ struct Module : Package
bool llvmForceLogging;
llvm::GlobalVariable* moduleInfoVar;
llvm::PATypeHolder* moduleInfoType;
llvm::StructType* moduleInfoType;
// array ops emitted in this module already
StringTable arrayfuncs;

View File

@@ -1205,7 +1205,64 @@ void PragmaDeclaration::semantic(Scope *sc)
}
llvm_internal = LLVMva_arg;
}
// pragma(fence) { templdecl(s) }
else if (ident == Id::fence)
{
if (args && args->dim > 0)
{
error("takes no parameters");
fatal();
}
llvm_internal = LLVMfence;
}
// pragma(atomic_load) { templdecl(s) }
else if (ident == Id::atomic_load)
{
if (args && args->dim > 0)
{
error("takes no parameters");
fatal();
}
llvm_internal = LLVMatomic_load;
}
// pragma(atomic_store) { templdecl(s) }
else if (ident == Id::atomic_store)
{
if (args && args->dim > 0)
{
error("takes no parameters");
fatal();
}
llvm_internal = LLVMatomic_store;
}
// pragma(atomic_cmp_xchg) { templdecl(s) }
else if (ident == Id::atomic_cmp_xchg)
{
if (args && args->dim > 0)
{
error("takes no parameters");
fatal();
}
llvm_internal = LLVMatomic_cmp_xchg;
}
// pragma(atomic_rmw, "string") { templdecl(s) }
else if (ident == Id::atomic_rmw)
{
Expression* expr = (Expression *)args->data[0];
expr = expr->semantic(sc);
if (!args || args->dim != 1 || !parseStringExp(expr, arg1str))
{
error("requires exactly 1 string literal parameter");
fatal();
}
llvm_internal = LLVMatomic_rmw;
}
// pragma(ldc, "string") { templdecl(s) }
else if (ident == Id::ldc)
{
@@ -1317,8 +1374,24 @@ void PragmaDeclaration::semantic(Scope *sc)
}
break;
case LLVMatomic_rmw:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error("the '%s' pragma is only allowed on template declarations", ident->toChars());
fatal();
}
break;
case LLVMva_start:
case LLVMva_arg:
case LLVMatomic_load:
case LLVMatomic_store:
case LLVMatomic_cmp_xchg:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
if (td->parameters->dim != 1)
@@ -1347,6 +1420,7 @@ void PragmaDeclaration::semantic(Scope *sc)
case LLVMva_copy:
case LLVMva_end:
case LLVMfence:
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
fd->llvmInternal = llvm_internal;

View File

@@ -3776,6 +3776,9 @@ StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *
#endif
this->soffset = 0;
this->fillHoles = 1;
#if IN_LLVM
constType = NULL;
#endif
}
Expression *StructLiteralExp::syntaxCopy()

View File

@@ -74,6 +74,7 @@ struct DValue;
namespace llvm {
class Constant;
class ConstantInt;
class StructType;
}
#endif
@@ -590,6 +591,7 @@ struct StructLiteralExp : Expression
#elif IN_LLVM
DValue* toElem(IRState* irs);
llvm::Constant *toConstElem(IRState *irs);
llvm::StructType *constType;
#endif
};

View File

@@ -1648,29 +1648,13 @@ void FuncDeclaration::semantic3(Scope *sc)
#if STRUCTTHISREF
if (ad->isStructDeclaration())
v = v->addressOf(sc);
#endif
#if IN_LLVM
//e = new AssertExp(loc, v, NULL);
// LDC: check for null this
//v = new ThisExp(0);
//v->type = vthis->type;
//v->var = vthis; // Error: Expression has no property var... in D1 typeof(v) == ThisExp
//NullExp *nv = new NullExp(0);
//nv->type = v->type;
//IdentityExp *ie = new IdentityExp(TOKnotidentity, 0, v, nv);
//ie->type = Type::tbool;
#endif
Expression *se = new StringExp(0, (char *)"null this");
se = se->semantic(sc);
#if !IN_LLVM
se->type = Type::tchar->arrayOf();
//#if IN_LLVM
// ee = new AssertExp(loc, ie, se);
//#else
#endif
e = new AssertExp(loc, v, se);
//#endif
}
if (ee)
{

View File

@@ -282,6 +282,11 @@ Msgtable msgtable[] =
{ "ldc" },
{ "allow_inline" },
{ "llvm_inline_asm" },
{ "fence" },
{ "atomic_load" },
{ "atomic_store" },
{ "atomic_cmp_xchg" },
{ "atomic_rmw" },
#endif
// For special functions

View File

@@ -114,6 +114,9 @@ StructInitializer::StructInitializer(Loc loc)
: Initializer(loc)
{
ad = NULL;
#if IN_LLVM
ltype = NULL;
#endif
}
Initializer *StructInitializer::syntaxCopy()

View File

@@ -28,6 +28,12 @@ struct ArrayInitializer;
struct ExpInitializer;
struct HdrGenState;
#if IN_LLVM
namespace llvm {
class StructType;
}
#endif
struct Initializer : Object
{
@@ -91,6 +97,9 @@ struct StructInitializer : Initializer
#endif
StructInitializer *isStructInitializer() { return this; }
#if IN_LLVM
llvm::StructType *ltype;
#endif
};
struct ArrayInitializer : Initializer

View File

@@ -213,7 +213,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
// LDC
llvmForceLogging = false;
moduleInfoVar = NULL;
moduleInfoType = new llvm::PATypeHolder(llvm::OpaqueType::get(llvm::getGlobalContext()));
moduleInfoType = llvm::StructType::create(llvm::getGlobalContext());
this->doDocComment = doDocComment;
this->doHdrGen = doHdrGen;
this->isRoot = false;

View File

@@ -35,7 +35,7 @@ namespace llvm {
class LLVMContext;
class Module;
class GlobalVariable;
class PATypeHolder;
class StructType;
}
#else
@@ -208,7 +208,7 @@ struct Module : Package
bool llvmForceLogging;
llvm::GlobalVariable* moduleInfoVar;
llvm::PATypeHolder* moduleInfoType;
llvm::StructType* moduleInfoType;
// array ops emitted in this module already
AA *arrayfuncs;

View File

@@ -106,6 +106,7 @@ enum BE
struct Statement : Object
{
Loc loc;
virtual ~Statement() {}
Statement(Loc loc);
virtual Statement *syntaxCopy();

View File

@@ -55,7 +55,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
#else
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn");
#endif
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
// aa param
LLValue* aaval = lvalue ? aa->getLVal() : aa->getRVal();
@@ -85,7 +85,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
}
// cast return value
const LLType* targettype = getPtrToType(DtoType(type));
LLType* targettype = getPtrToType(DtoType(type));
if (ret->getType() != targettype)
ret = DtoBitCast(ret, targettype);
@@ -109,7 +109,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
#if DMDV2
// module param
LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol();
const LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));
#else
// file param
@@ -123,7 +123,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
// call
llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds");
gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end());
gIR->CreateCallOrInvoke(errorfn, args);
// the function does not return
gIR->ir->CreateUnreachable();
@@ -152,7 +152,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
#else
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaIn");
#endif
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
if (Logger::enabled())
Logger::cout() << "_aaIn = " << *func << '\n';
@@ -182,7 +182,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in").getInstruction();
// cast return value
const LLType* targettype = DtoType(type);
LLType* targettype = DtoType(type);
if (ret->getType() != targettype)
ret = DtoBitCast(ret, targettype);
@@ -207,7 +207,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key)
#else
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaDel");
#endif
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
if (Logger::enabled())
Logger::cout() << "_aaDel = " << *func << '\n';
@@ -240,7 +240,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key)
args.push_back(pkey);
// call runtime
gIR->CreateCallOrInvoke(func, args.begin(), args.end());
gIR->CreateCallOrInvoke(func, args);
}
/////////////////////////////////////////////////////////////////////////////////////
@@ -251,7 +251,7 @@ LLValue* DtoAAEquals(Loc& loc, TOK op, DValue* l, DValue* r)
assert(t == r->getType()->toBasetype() && "aa equality is only defined for aas of same type");
#if DMDV2
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaEqual");
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
LLValue* aaval = DtoBitCast(l->getRVal(), funcTy->getParamType(1));
LLValue* abval = DtoBitCast(r->getRVal(), funcTy->getParamType(2));
@@ -259,7 +259,7 @@ LLValue* DtoAAEquals(Loc& loc, TOK op, DValue* l, DValue* r)
LLValue* res = gIR->CreateCallOrInvoke3(func, aaTypeInfo, aaval, abval, "aaEqRes").getInstruction();
#else
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaEq");
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
LLValue* aaval = DtoBitCast(l->getRVal(), funcTy->getParamType(0));
LLValue* abval = DtoBitCast(r->getRVal(), funcTy->getParamType(1));

View File

@@ -29,7 +29,7 @@ struct RemoveStructPadding : ABIRewrite {
}
/// return the transformed type for this rewrite
virtual const LLType* type(Type* dty, const LLType* t) {
virtual LLType* type(Type* dty, LLType* t) {
return DtoUnpaddedStructType(dty->toBasetype());
}
};
@@ -47,7 +47,7 @@ struct X87_complex_swap : ABIRewrite
{
return DtoAggrPairSwap(v->getRVal());
}
const LLType* type(Type*, const LLType* t)
LLType* type(Type*, LLType* t)
{
return t;
}
@@ -84,10 +84,10 @@ struct X86_struct_to_register : ABIRewrite
Logger::println("rewriting struct -> int");
assert(dv->isLVal());
LLValue* mem = dv->getLVal();
const LLType* t = LLIntegerType::get(gIR->context(), dty->size()*8);
LLType* t = LLIntegerType::get(gIR->context(), dty->size()*8);
return DtoLoad(DtoBitCast(mem, getPtrToType(t)));
}
const LLType* type(Type* t, const LLType*)
LLType* type(Type* t, LLType*)
{
size_t sz = t->size()*8;
return LLIntegerType::get(gIR->context(), sz);

View File

@@ -218,7 +218,7 @@ namespace {
// Okay, we may need to transform. Figure out a canonical type:
std::vector<const LLType*> parts;
std::vector<LLType*> parts;
unsigned size = ty->size();
@@ -301,14 +301,14 @@ struct X86_64_C_struct_rewrite : ABIRewrite {
DtoStore(rval, lval);
}
const LLType* pTy = getPtrToType(DtoType(dty));
LLType* pTy = getPtrToType(DtoType(dty));
return DtoLoad(DtoBitCast(lval, pTy), "get-result");
}
// Get struct from ABI-mangled representation, and store in the provided location.
void getL(Type* dty, DValue* v, llvm::Value* lval) {
LLValue* rval = v->getRVal();
const LLType* pTy = getPtrToType(rval->getType());
LLType* pTy = getPtrToType(rval->getType());
DtoStore(rval, DtoBitCast(lval, pTy));
}
@@ -328,12 +328,12 @@ struct X86_64_C_struct_rewrite : ABIRewrite {
LLType* abiTy = getAbiType(dty);
assert(abiTy && "Why are we rewriting a non-rewritten type?");
const LLType* pTy = getPtrToType(abiTy);
LLType* pTy = getPtrToType(abiTy);
return DtoLoad(DtoBitCast(lval, pTy), "put-result");
}
/// should return the transformed type for this rewrite
const LLType* type(Type* dty, const LLType* t)
LLType* type(Type* dty, LLType* t)
{
return getAbiType(dty);
}

View File

@@ -76,7 +76,7 @@ struct X86_cfloat_rewrite : ABIRewrite
}
// {float,float} -> i64
const LLType* type(Type*, const LLType* t)
LLType* type(Type*, LLType* t)
{
return LLType::getInt64Ty(gIR->context());
}

View File

@@ -27,7 +27,7 @@ struct ABIRewrite
virtual LLValue* put(Type* dty, DValue* v) = 0;
/// should return the transformed type for this rewrite
virtual const LLType* type(Type* dty, const LLType* t) = 0;
virtual LLType* type(Type* dty, LLType* t) = 0;
};
// interface called by codegen

View File

@@ -15,6 +15,7 @@
#include "gen/logger.h"
#include "gen/dvalue.h"
#include "ir/irmodule.h"
#include "ir/irtypestruct.h"
#include "gen/cl_options.h"
@@ -25,7 +26,7 @@ static LLValue *DtoSlice(DValue *dval)
LLValue *val = dval->getRVal();
if (dval->getType()->toBasetype()->ty == Tsarray) {
// Convert static array to slice
const LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context()));
LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context()));
LLValue *array = DtoRawAlloca(type, 0, ".array");
DtoStore(DtoArrayLen(dval), DtoGEPi(array, 0, 0, ".len"));
DtoStore(DtoBitCast(val, getVoidPtrType()), DtoGEPi(array, 0, 1, ".ptr"));
@@ -39,7 +40,7 @@ static LLValue *DtoSlice(DValue *dval)
static LLValue *DtoSlicePtr(DValue *dval)
{
Loc loc;
const LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context()));
LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context()));
Type *vt = dval->getType()->toBasetype();
if (vt->ty == Tarray)
return makeLValue(loc, dval);
@@ -55,30 +56,37 @@ static LLValue *DtoSlicePtr(DValue *dval)
//////////////////////////////////////////////////////////////////////////////////////////
const LLStructType* DtoArrayType(Type* arrayTy)
LLStructType* DtoArrayType(Type* arrayTy)
{
assert(arrayTy->nextOf());
const LLType* elemty = DtoType(arrayTy->nextOf());
LLType* elemty = DtoType(arrayTy->nextOf());
if (elemty == LLType::getVoidTy(gIR->context()))
elemty = LLType::getInt8Ty(gIR->context());
return LLStructType::get(gIR->context(), DtoSize_t(), getPtrToType(elemty), NULL);
llvm::SmallVector<LLType*, 2> elems;
elems.push_back(DtoSize_t());
elems.push_back(getPtrToType(elemty));
return LLStructType::get(gIR->context(), llvm::makeArrayRef(elems));
}
const LLStructType* DtoArrayType(const LLType* t)
LLStructType* DtoArrayType(LLType* t)
{
return LLStructType::get(gIR->context(), DtoSize_t(), getPtrToType(t), NULL);
llvm::SmallVector<LLType*, 2> elems;
elems.push_back(DtoSize_t());
elems.push_back(getPtrToType(t));
return LLStructType::get(gIR->context(), llvm::makeArrayRef(elems));
}
//////////////////////////////////////////////////////////////////////////////////////////
const LLArrayType* DtoStaticArrayType(Type* t)
LLArrayType* DtoStaticArrayType(Type* t)
{
t = t->toBasetype();
assert(t->ty == Tsarray);
TypeSArray* tsa = (TypeSArray*)t;
Type* tnext = tsa->nextOf();
const LLType* elemty = DtoType(tnext);
LLType* elemty = DtoType(tnext);
if (elemty == LLType::getVoidTy(gIR->context()))
elemty = LLType::getInt8Ty(gIR->context());
@@ -93,7 +101,7 @@ void DtoSetArrayToNull(LLValue* v)
LOG_SCOPE;
assert(isaPointer(v));
const LLType* t = v->getType()->getContainedType(0);
LLType* t = v->getType()->getContainedType(0);
DtoStore(LLConstant::getNullValue(t), v);
}
@@ -212,7 +220,7 @@ void DtoArrayAssign(DValue *array, DValue *value, int op)
args.push_back(DtoAggrPaint(DtoSlice(value), fn->getFunctionType()->getParamType(1)));
args.push_back(DtoAggrPaint(DtoSlice(array), fn->getFunctionType()->getParamType(2)));
LLCallSite call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".array");
LLCallSite call = gIR->CreateCallOrInvoke(fn, args, ".array");
call.setCallingConv(llvm::CallingConv::C);
}
@@ -236,7 +244,7 @@ void DtoArraySetAssign(Loc &loc, DValue *array, DValue *value, int op)
args.push_back(len);
args.push_back(DtoTypeInfoOf(array->type->toBasetype()->nextOf()->toBasetype()));
LLCallSite call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".newptr");
LLCallSite call = gIR->CreateCallOrInvoke(fn, args, ".newptr");
call.setCallingConv(llvm::CallingConv::C);
}
@@ -255,6 +263,85 @@ void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr)
//////////////////////////////////////////////////////////////////////////////////////////
// The function is almost identical copy of DtoConstArrayInitializer but it returns
// initializer type not the initializer itself.
// FIXME: is there any way to merge this next two functions?
LLType* DtoConstArrayInitializerType(ArrayInitializer* arrinit)
{
Type* arrty = arrinit->type->toBasetype();
if (arrty->ty != Tsarray)
return DtoType(arrinit->type);
TypeSArray* tsa = (TypeSArray*)arrty;
size_t arrlen = (size_t)tsa->dim->toInteger();
// get elem type
Type* elemty = arrty->nextOf();
LLType* llelemty = DtoTypeNotVoid(elemty);
// make sure the number of initializers is sane
if (arrinit->index.dim > arrlen || arrinit->dim > arrlen)
{
error(arrinit->loc, "too many initializers, %u, for array[%zu]", arrinit->index.dim, arrlen);
fatal();
}
// true if array elements differ in type, can happen with array of unions
bool mismatch = false;
// allocate room for types
std::vector<LLType*> types(arrlen, NULL);
// go through each initializer, they're not sorted by index by the frontend
size_t j = 0;
for (size_t i = 0; i < arrinit->index.dim; i++)
{
// get index
Expression* idx = (Expression*)arrinit->index.data[i];
// idx can be null, then it's just the next element
if (idx)
j = idx->toInteger();
assert(j < arrlen);
// get value
Initializer* val = (Initializer*)arrinit->value.data[i];
assert(val);
LLType* c = DtoConstInitializerType(elemty, val);
assert(c);
if (c != llelemty)
mismatch = true;
types[j] = c;
j++;
}
// fill out any null entries still left with default type
// element default types
LLType* deftype = DtoConstInitializerType(elemty, 0);
bool mismatch2 = (deftype != llelemty);
for (size_t i = 0; i < arrlen; i++)
{
if (types[i] != NULL)
continue;
types[i] = deftype;
if (mismatch2)
mismatch = true;
}
if (mismatch)
return LLStructType::get(gIR->context(), types); // FIXME should this pack?
else
return LLArrayType::get(deftype, arrlen);
}
//////////////////////////////////////////////////////////////////////////////////////////
LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
{
Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars());
@@ -283,7 +370,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
// get elem type
Type* elemty = arrty->nextOf();
const LLType* llelemty = DtoTypeNotVoid(elemty);
LLType* llelemty = DtoTypeNotVoid(elemty);
// true if array elements differ in type, can happen with array of unions
bool mismatch = false;
@@ -345,7 +432,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
LLConstant* constarr;
if (mismatch)
constarr = LLConstantStruct::get(gIR->context(), initvals, false); // FIXME should this pack?
constarr = LLConstantStruct::getAnon(gIR->context(), initvals); // FIXME should this pack?
else
constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals);
@@ -363,7 +450,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
#if DMDV2
if (arrty->ty == Tpointer)
// we need to return pointer to the static array.
return gvar;
return DtoBitCast(gvar, DtoType(arrty));
#endif
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
@@ -371,14 +458,14 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
gep = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(llelemty));
return DtoConstSlice(DtoConstSize_t(arrlen),gep);
return DtoConstSlice(DtoConstSize_t(arrlen), gep, arrty);
}
//////////////////////////////////////////////////////////////////////////////////////////
static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz)
{
assert(e->len != 0);
const LLType* t = e->ptr->getType()->getContainedType(0);
LLType* t = e->ptr->getType()->getContainedType(0);
sz = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(t)), e->len, "tmp");
return DtoBitCast(e->ptr, getVoidPtrType());
}
@@ -410,7 +497,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
LLValue* dstarr = get_slice_ptr(dst,sz1);
LLValue* srcarr = DtoBitCast(DtoArrayPtr(src), getVoidPtrType());
const LLType* arrayelemty = DtoTypeNotVoid(src->getType()->nextOf()->toBasetype());
LLType* arrayelemty = DtoTypeNotVoid(src->getType()->nextOf()->toBasetype());
LLValue* sz2 = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(arrayelemty)), DtoArrayLen(src), "tmp");
if (global.params.useAssert || global.params.useArrayBounds)
@@ -434,10 +521,14 @@ void DtoStaticArrayCopy(LLValue* dst, LLValue* src)
}
//////////////////////////////////////////////////////////////////////////////////////////
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr)
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr, Type *type)
{
LLConstant* values[2] = { dim, ptr };
return LLConstantStruct::get(gIR->context(), values, 2, false);
llvm::ArrayRef<LLConstant*> valuesRef = llvm::makeArrayRef(values, 2);
LLStructType *lltype = type ?
isaStruct(DtoType(type)) :
LLConstantStruct::getTypeForElements(gIR->context(), valuesRef);
return LLConstantStruct::get(lltype, valuesRef);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -468,7 +559,7 @@ static DSliceValue *getSlice(Type *arrayType, LLValue *array)
LLValue* newptr = DtoExtractValue(array, 1, ".ptr");
// cast pointer to wanted type
const LLType* dstType = DtoType(arrayType)->getContainedType(1);
LLType* dstType = DtoType(arrayType)->getContainedType(1);
if (newptr->getType() != dstType)
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
@@ -513,7 +604,7 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default
LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction();
// cast to wanted type
const LLType* dstType = DtoType(arrayType)->getContainedType(1);
LLType* dstType = DtoType(arrayType)->getContainedType(1);
if (newptr->getType() != dstType)
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
@@ -559,7 +650,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size
args.push_back(dims[i]->getRVal());
// call allocator
LLValue* newptr = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction();
LLValue* newptr = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction();
if (Logger::enabled())
Logger::cout() << "final ptr = " << *newptr << '\n';
@@ -584,7 +675,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size
LLValue* newptr = gIR->CreateCallOrInvoke3(fn, arrayTypeInfo, DtoConstSize_t(ndims), dimsArg, ".gc_mem").getInstruction();
// cast to wanted type
const LLType* dstType = DtoType(arrayType)->getContainedType(1);
LLType* dstType = DtoType(arrayType)->getContainedType(1);
if (newptr->getType() != dstType)
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
@@ -620,7 +711,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim)
#if DMDV2
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(2)));
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction();
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction();
return getSlice(arrayType, newArray);
@@ -633,7 +724,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim)
Logger::cout() << "arrPtr = " << *arrPtr << '\n';
args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp"));
LLValue* newptr = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction();
LLValue* newptr = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction();
if (newptr->getType() != arrPtr->getType())
newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
@@ -664,7 +755,7 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1)));
args.push_back(DtoConstSize_t(1));
LLValue* appendedArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
LLValue* appendedArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction();
appendedArray = DtoAggrPaint(appendedArray, DtoType(arrayType));
LLValue* val = DtoExtractValue(appendedArray, 1, ".ptr");
@@ -691,7 +782,7 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1)));
args.push_back(DtoBitCast(valueToAppend, getVoidPtrType()));
gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray");
gIR->CreateCallOrInvoke(fn, args, ".appendedArray");
}
#endif
@@ -719,7 +810,7 @@ DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
args.push_back(y);
// Call _d_arrayappendT
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction();
return getSlice(arrayType, newArray);
}
@@ -806,7 +897,7 @@ DSliceValue* DtoCatArrays(Type* arrayType, Expression* exp1, Expression* exp2)
args.push_back(val);
}
LLValue *newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
LLValue *newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction();
return getSlice(arrayType, newArray);
}
@@ -937,7 +1028,7 @@ DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp, const char *func)
args.push_back(DtoBitCast(valueToAppend->getRVal(), fn->getFunctionType()->getParamType(1)));
// Call function
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction();
return getSlice(arrayType, newArray);
}
@@ -1002,7 +1093,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue
args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2)));
}
LLCallSite call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp");
LLCallSite call = gIR->CreateCallOrInvoke(fn, args, "tmp");
return call.getInstruction();
}
@@ -1078,7 +1169,7 @@ LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r)
}
//////////////////////////////////////////////////////////////////////////////////////////
LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty)
LLValue* DtoArrayCastLength(LLValue* len, LLType* elemty, LLType* newelemty)
{
Logger::println("DtoArrayCastLength");
LOG_SCOPE;
@@ -1098,7 +1189,7 @@ LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* ne
args.push_back(LLConstantInt::get(DtoSize_t(), nsz, false));
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
return gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp").getInstruction();
return gIR->CreateCallOrInvoke(fn, args, "tmp").getInstruction();
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1184,7 +1275,7 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
Logger::println("DtoCastArray");
LOG_SCOPE;
const LLType* tolltype = DtoType(to);
LLType* tolltype = DtoType(to);
Type* totype = to->toBasetype();
Type* fromtype = u->getType()->toBasetype();
@@ -1211,8 +1302,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
if (Logger::enabled())
Logger::cout() << "to array" << '\n';
const LLType* ptrty = DtoArrayType(totype)->getContainedType(1);
const LLType* ety = DtoTypeNotVoid(fromtype->nextOf());
LLType* ptrty = DtoArrayType(totype)->getContainedType(1);
LLType* ety = DtoTypeNotVoid(fromtype->nextOf());
if (fromtype->ty == Tsarray) {
LLValue* uval = u->getRVal();
@@ -1221,7 +1312,7 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
assert(isaPointer(uval->getType()));
const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
if(arrty->getNumElements()*fromtype->nextOf()->size() % totype->nextOf()->size() != 0)
{
@@ -1258,8 +1349,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
assert(isaPointer(uval->getType()));
/*const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
/*LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
if(arrty->getNumElements()*fromtype->nextOf()->size() != tosize*totype->nextOf()->size())
{
error(loc, "invalid cast from '%s' to '%s', the sizes are not the same", fromtype->toChars(), totype->toChars());
@@ -1353,7 +1444,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun
#if DMDV2
// module param
LLValue *moduleInfoSymbol = funcmodule->moduleInfoSymbol();
const LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));
#else
// file param
@@ -1376,7 +1467,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun
// call
llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds");
gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end());
gIR->CreateCallOrInvoke(errorfn, args);
// the function does not return
gIR->ir->CreateUnreachable();

View File

@@ -5,12 +5,13 @@ struct ArrayInitializer;
struct DSliceValue;
const llvm::StructType* DtoArrayType(Type* arrayTy);
const llvm::StructType* DtoArrayType(const LLType* elemTy);
const llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy);
llvm::StructType* DtoArrayType(Type* arrayTy);
llvm::StructType* DtoArrayType(LLType* elemTy);
llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy);
LLType* DtoConstArrayInitializerType(ArrayInitializer* arrinit);
LLConstant* DtoConstArrayInitializer(ArrayInitializer* si);
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr);
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr, Type *type = 0);
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src);
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
@@ -45,7 +46,7 @@ LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r);
LLValue* DtoDynArrayIs(TOK op, DValue* l, DValue* r);
LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty);
LLValue* DtoArrayCastLength(LLValue* len, LLType* elemty, LLType* newelemty);
LLValue* DtoArrayLen(DValue* v);
LLValue* DtoArrayPtr(DValue* v);

View File

@@ -645,8 +645,8 @@ void AsmBlockStatement::toIR(IRState* p)
// build asm block
std::vector<LLValue*> outargs;
std::vector<LLValue*> inargs;
std::vector<const LLType*> outtypes;
std::vector<const LLType*> intypes;
std::vector<LLType*> outtypes;
std::vector<LLType*> intypes;
std::string out_c;
std::string in_c;
std::string clobbers;
@@ -714,14 +714,14 @@ void AsmBlockStatement::toIR(IRState* p)
Logger::println("constraints = \"%s\"", out_c.c_str());
// build return types
const LLType* retty;
LLType* retty;
if (asmblock->retn)
retty = asmblock->retty;
else
retty = llvm::Type::getVoidTy(gIR->context());
// build argument types
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.insert(types.end(), outtypes.begin(), outtypes.end());
types.insert(types.end(), intypes.begin(), intypes.end());
llvm::FunctionType* fty = llvm::FunctionType::get(retty, types, false);
@@ -746,7 +746,7 @@ void AsmBlockStatement::toIR(IRState* p)
llvm::InlineAsm* ia = llvm::InlineAsm::get(fty, code, out_c, true);
llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(),
llvm::CallInst* call = p->ir->CreateCall(ia, args,
retty == LLType::getVoidTy(gIR->context()) ? "" : "asm");
if (Logger::enabled())

View File

@@ -242,6 +242,31 @@ cl::list<std::string> mAttrs("mattr",
cl::opt<std::string> mTargetTriple("mtriple",
cl::desc("Override target triple"));
cl::opt<llvm::Reloc::Model> mRelocModel("relocation-model",
cl::desc("Relocation model"),
cl::init(llvm::Reloc::Default),
cl::values(
clEnumValN(llvm::Reloc::Default, "default",
"Target default relocation model"),
clEnumValN(llvm::Reloc::Static, "static",
"Non-relocatable code"),
clEnumValN(llvm::Reloc::PIC_, "pic",
"Fully relocatable, position independent code"),
clEnumValN(llvm::Reloc::DynamicNoPIC, "dynamic-no-pic",
"Relocatable external references, non-relocatable code"),
clEnumValEnd));
cl::opt<llvm::CodeModel::Model> mCodeModel("code-model",
cl::desc("Code model"),
cl::init(llvm::CodeModel::Default),
cl::values(
clEnumValN(llvm::CodeModel::Default, "default", "Target default code model"),
clEnumValN(llvm::CodeModel::Small, "small", "Small code model"),
clEnumValN(llvm::CodeModel::Kernel, "kernel", "Kernel code model"),
clEnumValN(llvm::CodeModel::Medium, "medium", "Medium code model"),
clEnumValN(llvm::CodeModel::Large, "large", "Large code model"),
clEnumValEnd));
// "Hidden debug switches"
// Are these ever used?

View File

@@ -7,6 +7,7 @@
#include <vector>
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CodeGen.h"
namespace opts {
namespace cl = llvm::cl;
@@ -43,6 +44,8 @@ namespace opts {
extern cl::opt<std::string> mCPU;
extern cl::list<std::string> mAttrs;
extern cl::opt<std::string> mTargetTriple;
extern cl::opt<llvm::Reloc::Model> mRelocModel;
extern cl::opt<llvm::CodeModel::Model> mCodeModel;
extern cl::opt<bool> singleObj;
extern cl::opt<bool> linkonceTemplates;

View File

@@ -165,7 +165,7 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
LLValue* dst = DtoGEPi(mem,0,idx,"tmp");
if (Logger::enabled())
Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
DtoStore(src, dst);
DtoStore(src, DtoBitCast(dst, getPtrToType(src->getType())));
}
// set the context for nested classes
else if (tc->sym->isNested() && tc->sym->vthis)
@@ -230,7 +230,7 @@ void DtoFinalizeClass(LLValue* inst)
LLSmallVector<LLValue*,1> arg;
arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
// call
gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end(), "");
gIR->CreateCallOrInvoke(fn, arg, "");
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -245,7 +245,7 @@ DValue* DtoCastClass(DValue* val, Type* _to)
// class -> pointer
if (to->ty == Tpointer) {
IF_LOG Logger::println("to pointer");
const LLType* tolltype = DtoType(_to);
LLType* tolltype = DtoType(_to);
LLValue* rval = DtoBitCast(val->getRVal(), tolltype);
return new DImValue(_to, rval);
}
@@ -304,7 +304,7 @@ DValue* DtoCastClass(DValue* val, Type* _to)
LLValue* v = val->getRVal();
LLValue* orig = v;
v = DtoGEPi(v, 0, i_index);
const LLType* ifType = DtoType(_to);
LLType* ifType = DtoType(_to);
if (Logger::enabled())
{
Logger::cout() << "V = " << *v << std::endl;
@@ -339,7 +339,7 @@ DValue* DtoCastClass(DValue* val, Type* _to)
// class -> class - static down cast
else if (tc->sym->isBaseOf(fc->sym,NULL)) {
Logger::println("static down cast");
const LLType* tolltype = DtoType(_to);
LLType* tolltype = DtoType(_to);
LLValue* rval = DtoBitCast(val->getRVal(), tolltype);
return new DImValue(_to, rval);
}
@@ -362,7 +362,7 @@ DValue* DtoDynamicCastObject(DValue* val, Type* _to)
ClassDeclaration::classinfo->codegen(Type::sir);
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast");
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
std::vector<LLValue*> args;
@@ -398,7 +398,7 @@ DValue* DtoCastInterfaceToObject(DValue* val, Type* to)
// Object _d_toObject(void* p)
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject");
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
// void* p
LLValue* tmp = val->getRVal();
@@ -427,7 +427,7 @@ DValue* DtoDynamicCastInterface(DValue* val, Type* _to)
ClassDeclaration::classinfo->codegen(Type::sir);
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast");
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
std::vector<LLValue*> args;
@@ -470,7 +470,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
assert(field);
// get the start pointer
const LLType* st = DtoType(cd->type);
LLType* st = DtoType(cd->type);
// cast to the struct type
src = DtoBitCast(src, st);
@@ -575,7 +575,7 @@ static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
return llvm::ConstantStruct::get(inits);
}
static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
static LLConstant* build_offti_array(ClassDeclaration* cd, LLType* arrayT)
{
IrStruct* irstruct = cd->ir.irStruct;
@@ -594,7 +594,7 @@ static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
return LLConstant::getNullValue( arrayT );
// array type
const llvm::ArrayType* arrTy = llvm::ArrayType::get(arrayInits[0]->getType(), nvars);
LLArrayType* arrTy = llvm::ArrayType::get(arrayInits[0]->getType(), nvars);
LLConstant* arrInit = LLConstantArray::get(arrTy, arrayInits);
// mangle
@@ -703,8 +703,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
LLConstant* c;
const LLType* voidPtr = getVoidPtrType();
const LLType* voidPtrPtr = getPtrToType(voidPtr);
LLType* voidPtr = getVoidPtrType();
LLType* voidPtrPtr = getPtrToType(voidPtr);
// byte[] init
if (cd->isInterfaceDeclaration())
@@ -713,7 +713,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
}
else
{
const LLType* cd_type = stripModifiers(cdty)->irtype->getPA();
LLType* cd_type = stripModifiers(cdty)->irtype->getType();
size_t initsz = getTypePaddedSize(cd_type);
b.push_void_array(initsz, ir->getInitSymbol());
}
@@ -809,13 +809,14 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
}*/
// build the initializer
LLConstant* finalinit = b.get_constant();
LLType *initType = ir->classInfo->getType()->getContainedType(0);
LLConstant* finalinit = b.get_constant(isaStruct(initType));
//Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
ir->constClassInfo = finalinit;
// sanity check
assert(finalinit->getType() == ir->classInfo->getType()->getContainedType(0) &&
assert(finalinit->getType() == initType &&
"__ClassZ initializer does not match the ClassInfo type");
// return initializer

View File

@@ -12,14 +12,17 @@
//////////////////////////////////////////////////////////////////////////////////////////
const llvm::StructType* DtoComplexType(Type* type)
llvm::StructType* DtoComplexType(Type* type)
{
Type* t = type->toBasetype();
const LLType* base = DtoComplexBaseType(t);
return llvm::StructType::get(gIR->context(), base, base, NULL);
LLType* base = DtoComplexBaseType(t);
llvm::SmallVector<LLType*, 2> types;
types.push_back(base);
types.push_back(base);
return llvm::StructType::get(gIR->context(), types);
}
const LLType* DtoComplexBaseType(Type* t)
LLType* DtoComplexBaseType(Type* t)
{
TY ty = t->toBasetype()->ty;
if (ty == Tcomplex32) {
@@ -83,7 +86,7 @@ LLValue* DtoImagPart(DValue* val)
DValue* DtoComplex(Loc& loc, Type* to, DValue* val)
{
const LLType* complexTy = DtoType(to);
LLType* complexTy = DtoType(to);
Type* baserety;
Type* baseimty;
@@ -444,7 +447,7 @@ DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to)
llvm::Value *re, *im;
DtoGetComplexParts(loc, val->getType(), val, re, im);
const LLType* toty = DtoComplexBaseType(to);
LLType* toty = DtoComplexBaseType(to);
if (to->size() < vty->size()) {
re = gIR->ir->CreateFPTrunc(re, toty, "tmp");

View File

@@ -1,8 +1,8 @@
#ifndef LDC_GEN_COMPLEX_H
#define LDC_GEN_COMPLEX_H
const llvm::StructType* DtoComplexType(Type* t);
const LLType* DtoComplexBaseType(Type* t);
llvm::StructType* DtoComplexType(Type* t);
LLType* DtoComplexBaseType(Type* t);
LLConstant* DtoConstComplex(Type* t, long double re, long double im);

View File

@@ -20,7 +20,7 @@ ConfigFile::ConfigFile()
ConfigFile::~ConfigFile()
{
delete cfg;
// delete cfg;
}

View File

@@ -6,11 +6,13 @@
#include "id.h"
#include "rmem.h"
#include "template.h"
#include "init.h"
#include "gen/irstate.h"
#include "gen/tollvm.h"
#include "gen/llvmhelpers.h"
#include "gen/logger.h"
#include "gen/todebug.h"
#include "ir/ir.h"
#include "ir/irvar.h"
@@ -129,14 +131,17 @@ void VarDeclaration::codegen(Ir* p)
bool _isconst = isConst();
#endif
Logger::println("Creating global variable");
const LLType* _type = this->ir.irGlobal->type.get();
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
assert(!ir.initialized);
ir.initialized = gIR->dmodule;
std::string _name(mangle());
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module,_type,_isconst,_linkage,NULL,_name,0,isThreadlocal());
LLType *_type = DtoConstInitializerType(type, init);
// create the global variable
LLGlobalVariable* gvar = new LLGlobalVariable(*gIR->module, _type, _isconst,
DtoLinkage(this), NULL, _name, 0, isThreadlocal());
this->ir.irGlobal->value = gvar;
// set the alignment
@@ -150,8 +155,31 @@ void VarDeclaration::codegen(Ir* p)
if (nakedUse)
gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
// initialize
DtoConstInitGlobal(this);
// assign the initializer
if (!(storage_class & STCextern) && mustDefineSymbol(this))
{
if (Logger::enabled())
{
Logger::println("setting initializer");
Logger::cout() << "global: " << *gvar << '\n';
#if 0
Logger::cout() << "init: " << *initVal << '\n';
#endif
}
// build the initializer
LLConstant *initVal = DtoConstInitializer(loc, type, init);
// set the initializer
assert(!ir.irGlobal->constInit);
ir.irGlobal->constInit = initVal;
gvar->setInitializer(initVal);
#ifndef DISABLE_DEBUG_INFO
// do debug info
if (global.params.symdebug)
DtoDwarfGlobalVariable(gvar, this);
#endif
}
}
}

View File

@@ -8,6 +8,7 @@
#include "declaration.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -9,6 +9,7 @@ handling is necessary, they hold enough information to do-the-right-thing (TM)
#include <cassert>
#include "root.h"
#include "mem.h"
struct Type;
struct Dsymbol;
@@ -50,7 +51,6 @@ struct DValue : Object
virtual DFieldValue* isField() { return NULL; }
virtual DSliceValue* isSlice() { return NULL; }
virtual DFuncValue* isFunc() { return NULL; }
protected:
DValue() {}
DValue(const DValue&) { }

View File

@@ -9,5 +9,10 @@ enum
LLVMva_copy,
LLVMva_end,
LLVMva_arg,
LLVMinline_asm
LLVMinline_asm,
LLVMfence,
LLVMatomic_store,
LLVMatomic_load,
LLVMatomic_cmp_xchg,
LLVMatomic_rmw
};

View File

@@ -26,7 +26,7 @@
using namespace llvm::Attribute;
const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
{
if (Logger::enabled())
Logger::println("DtoFunctionType(%s)", type->toChars());
@@ -187,7 +187,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
abi->doneWithFunctionType();
// build the function type
std::vector<const LLType*> argtypes;
std::vector<LLType*> argtypes;
argtypes.reserve(lidx);
if (f->fty.arg_sret) argtypes.push_back(f->fty.arg_sret->ltype);
@@ -209,7 +209,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
std::reverse(argtypes.begin() + beg, argtypes.end());
}
llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
LLFunctionType* functype = LLFunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
Logger::cout() << "Final function type: " << *functype << "\n";
@@ -218,10 +218,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
//////////////////////////////////////////////////////////////////////////////////////////
static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
static llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
{
TypeFunction* f = (TypeFunction*)fdecl->type;
const llvm::FunctionType* fty = 0;
LLFunctionType* fty = 0;
// create new ir funcTy
f->fty.reset();
@@ -244,7 +244,7 @@ static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
//////////////////////////////////////////////////////////////////////////////////////////
const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
{
// handle for C vararg intrinsics
if (fdecl->isVaIntrinsic())
@@ -256,7 +256,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
if (AggregateDeclaration* ad = fdecl->isMember2()) {
Logger::println("isMember = this is: %s", ad->type->toChars());
dthis = ad->type;
const LLType* thisty = DtoType(dthis);
LLType* thisty = DtoType(dthis);
//Logger::cout() << "this llvm type: " << *thisty << '\n';
if (ad->isStructDeclaration())
thisty = getPtrToType(thisty);
@@ -270,7 +270,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
dnest = Type::tvoid->pointerTo();
}
const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain());
LLFunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain());
return functype;
}
@@ -472,15 +472,15 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
else
mangled_name = fdecl->mangle();
llvm::Function* vafunc = 0;
LLFunction* vafunc = 0;
if (fdecl->isVaIntrinsic())
vafunc = DtoDeclareVaFunction(fdecl);
// construct function
const llvm::FunctionType* functype = DtoFunctionType(fdecl);
llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name);
LLFunctionType* functype = DtoFunctionType(fdecl);
LLFunction* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name);
if (!func) {
func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module);
func = LLFunction::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module);
} else if (func->getFunctionType() != functype) {
error(fdecl->loc, "Function type does not match previously declared function with the same mangled name: %s", fdecl->mangle());
}
@@ -756,7 +756,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
if (!refout && (!f->fty.args[i]->byref || lazy))
{
// alloca a stack slot for this first class value arg
const LLType* argt;
LLType* argt;
if (lazy)
argt = irloc->value->getType();
else
@@ -877,7 +877,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
//////////////////////////////////////////////////////////////////////////////////////////
const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl)
llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl)
{
Dsymbol* parent = fdecl->toParent();
ClassDeclaration* cd = parent->isClassDeclaration();

View File

@@ -13,10 +13,10 @@ namespace llvm
class Value;
}
const llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false);
const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl);
llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false);
llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl);
const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl);
llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl);
void DtoResolveFunction(FuncDeclaration* fdecl);
void DtoDeclareFunction(FuncDeclaration* fdecl);

View File

@@ -127,14 +127,14 @@ bool IRState::scopereturned()
LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, const char* Name)
{
LLSmallVector<LLValue*, 1> args;
return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
return CreateCallOrInvoke(Callee, args, Name);
}
LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name)
{
LLSmallVector<LLValue*, 1> args;
args.push_back(Arg1);
return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
return CreateCallOrInvoke(Callee, args, Name);
}
LLCallSite IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name)
@@ -142,7 +142,7 @@ LLCallSite IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue*
LLSmallVector<LLValue*, 2> args;
args.push_back(Arg1);
args.push_back(Arg2);
return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
return CreateCallOrInvoke(Callee, args, Name);
}
LLCallSite IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name)
@@ -151,7 +151,7 @@ LLCallSite IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue*
args.push_back(Arg1);
args.push_back(Arg2);
args.push_back(Arg3);
return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
return CreateCallOrInvoke(Callee, args, Name);
}
LLCallSite IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name)
@@ -161,7 +161,7 @@ LLCallSite IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue*
args.push_back(Arg2);
args.push_back(Arg3);
args.push_back(Arg4);
return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
return CreateCallOrInvoke(Callee, args, Name);
}

View File

@@ -90,7 +90,7 @@ struct IRAsmBlock
std::vector<Identifier*> internalLabels;
AsmBlockStatement* asmBlock;
const LLType* retty;
LLType* retty;
unsigned retn;
bool retemu; // emulate abi ret with a temporary
LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval
@@ -111,9 +111,9 @@ struct IRState
llvm::Module* module;
// interface info type, used in DtoInterfaceInfoType
const LLStructType* interfaceInfoType;
const LLStructType* mutexType;
const LLStructType* moduleRefType;
LLStructType* interfaceInfoType;
LLStructType* mutexType;
LLStructType* moduleRefType;
// helper to get the LLVMContext of the module
llvm::LLVMContext& context() const { return module->getContext(); }
@@ -148,8 +148,8 @@ struct IRState
// create a call or invoke, depending on the landing pad info
// the template function is defined further down in this file
template <typename InputIterator>
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name="");
template <typename T>
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const T& args, const char* Name="");
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const char* Name="");
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name="");
llvm::CallSite CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name="");
@@ -196,8 +196,8 @@ struct IRState
std::vector<LLConstant*> usedArray;
};
template <typename InputIterator>
llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name)
template <typename T>
llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, const T &args, const char* Name)
{
llvm::BasicBlock* pad = func()->gen->landingPad;
if(pad)
@@ -206,13 +206,13 @@ llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBeg
LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee);
if (funcval && (funcval->isIntrinsic() || funcval->doesNotThrow()))
{
llvm::CallInst* call = ir->CreateCall(Callee, ArgBegin, ArgEnd, Name);
llvm::CallInst* call = ir->CreateCall(Callee, args, Name);
call->setAttributes(funcval->getAttributes());
return call;
}
llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create(gIR->context(), "postinvoke", topfunc(), scopeend());
llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, ArgBegin, ArgEnd, Name);
llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, args, Name);
if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
invoke->setAttributes(fn->getAttributes());
scope() = IRScope(postinvoke, scopeend());
@@ -220,7 +220,7 @@ llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBeg
}
else
{
llvm::CallInst* call = ir->CreateCall(Callee, ArgBegin, ArgEnd, Name);
llvm::CallInst* call = ir->CreateCall(Callee, args, Name);
if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
call->setAttributes(fn->getAttributes());
return call;

View File

@@ -47,8 +47,6 @@ using llvm::IRBuilder;
#define LLConstantInt llvm::ConstantInt
#define LLConstantFP llvm::ConstantFP
#define LLPATypeHolder llvm::PATypeHolder
#define LLCallSite llvm::CallSite
#define LLSmallVector llvm::SmallVector

View File

@@ -51,7 +51,7 @@ void DtoDeleteMemory(LLValue* ptr)
LLSmallVector<LLValue*,1> arg;
arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp"));
// call
gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
gIR->CreateCallOrInvoke(fn, arg);
}
void DtoDeleteClass(LLValue* inst)
@@ -68,7 +68,7 @@ void DtoDeleteClass(LLValue* inst)
#endif
arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
// call
gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
gIR->CreateCallOrInvoke(fn, arg);
}
void DtoDeleteInterface(LLValue* inst)
@@ -79,7 +79,7 @@ void DtoDeleteInterface(LLValue* inst)
LLSmallVector<LLValue*,1> arg;
arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
// call
gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
gIR->CreateCallOrInvoke(fn, arg);
}
#if DMDV2
@@ -95,7 +95,7 @@ void DtoDeleteArray(DValue* arr)
arg.push_back(DtoBitCast(DtoTypeInfoOf(arr->type->nextOf()), fn->getFunctionType()->getParamType(1)));
// call
gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
gIR->CreateCallOrInvoke(fn, arg);
}
#else
@@ -111,7 +111,7 @@ void DtoDeleteArray(DValue* arr)
arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp"));
// call
gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
gIR->CreateCallOrInvoke(fn, arg);
}
#endif
@@ -124,7 +124,7 @@ void DtoDeleteArray(DValue* arr)
llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
{
const llvm::Type* lltype = DtoType(type);
LLType* lltype = DtoType(type);
llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint());
ai->setAlignment(type->alignsize());
return ai;
@@ -132,14 +132,14 @@ llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name)
{
const llvm::Type* lltype = DtoType(type);
LLType* lltype = DtoType(type);
llvm::AllocaInst* ai = new llvm::AllocaInst(
lltype, DtoConstUint(arraysize), name, gIR->topallocapoint());
ai->setAlignment(type->alignsize());
return ai;
}
llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name)
llvm::AllocaInst* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name)
{
llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint());
if (alignment)
@@ -147,16 +147,16 @@ llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const
return ai;
}
LLValue* DtoGcMalloc(const llvm::Type* lltype, const char* name)
LLValue* DtoGcMalloc(LLType* lltype, const char* name)
{
// get runtime function
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemory");
// parameters
LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype));
// call runtime allocator
LLValue* mem = gIR->CreateCallOrInvoke(fn, size, name).getInstruction();
// cast
return DtoBitCast(mem, getPtrToType(lltype), name);
// get runtime function
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemory");
// parameters
LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype));
// call runtime allocator
LLValue* mem = gIR->CreateCallOrInvoke(fn, size, name).getInstruction();
// cast
return DtoBitCast(mem, getPtrToType(lltype), name);
}
/****************************************************************************************/
@@ -197,7 +197,7 @@ void DtoAssert(Module* M, Loc loc, DValue* msg)
args.push_back(c);
// call
gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
gIR->CreateCallOrInvoke(fn, args);
#ifndef DISABLE_DEBUG_INFO
// end debug info
@@ -500,7 +500,7 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op)
LLValue* r = rhs->getRVal();
if (Logger::enabled())
Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
const LLType* lit = l->getType()->getContainedType(0);
LLType* lit = l->getType()->getContainedType(0);
if (r->getType() != lit) {
r = DtoCast(loc, rhs, lhs->getType())->getRVal();
if (Logger::enabled())
@@ -532,12 +532,12 @@ DValue* DtoNullValue(Type* type)
{
Type* basetype = type->toBasetype();
TY basety = basetype->ty;
const LLType* lltype = DtoType(basetype);
LLType* lltype = DtoType(basetype);
// complex, needs to be first since complex are also floating
if (basetype->iscomplex())
{
const LLType* basefp = DtoComplexBaseType(basetype);
LLType* basefp = DtoComplexBaseType(basetype);
LLValue* res = DtoAggrPair(DtoType(type), LLConstant::getNullValue(basefp), LLConstant::getNullValue(basefp));
return new DImValue(type, res);
}
@@ -574,7 +574,7 @@ DValue* DtoNullValue(Type* type)
DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to)
{
const LLType* tolltype = DtoType(_to);
LLType* tolltype = DtoType(_to);
Type* to = _to->toBasetype();
Type* from = val->getType()->toBasetype();
@@ -635,7 +635,7 @@ DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to)
DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to)
{
const LLType* tolltype = DtoType(to);
LLType* tolltype = DtoType(to);
Type* totype = to->toBasetype();
Type* fromtype = val->getType()->toBasetype();
@@ -670,7 +670,7 @@ DValue* DtoCastFloat(Loc& loc, DValue* val, Type* to)
if (val->getType() == to)
return val;
const LLType* tolltype = DtoType(to);
LLType* tolltype = DtoType(to);
Type* totype = to->toBasetype();
Type* fromtype = val->getType()->toBasetype();
@@ -913,8 +913,9 @@ void DtoConstInitGlobal(VarDeclaration* vd)
IrGlobal* glob = vd->ir.irGlobal;
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(glob->value);
// refine the global's opaque type to the type of the initializer
llvm::cast<LLOpaqueType>(glob->type.get())->refineAbstractTypeTo(initVal->getType());
//if (LLStructType *st = isaStruct(glob->type)) {
// st->setBody(initVal);
//}
assert(!glob->constInit);
glob->constInit = initVal;
@@ -1050,7 +1051,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
}
#endif
const LLType* lltype = DtoType(vd->type);
LLType* lltype = DtoType(vd->type);
llvm::Value* allocainst;
if(gTargetData->getTypeSizeInBits(lltype) == 0)
@@ -1254,6 +1255,60 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
// INITIALIZER HELPERS
////////////////////////////////////////////////////////////////////////////////////////*/
LLType* DtoConstInitializerType(Type* type, Initializer* init)
{
if (type->ty == Ttypedef) {
TypeTypedef *td = (TypeTypedef*)type;
if (td->sym->init)
return DtoConstInitializerType(td->sym->basetype, td->sym->init);
}
type = type->toBasetype();
if (type->ty == Tsarray)
{
if (!init)
{
TypeSArray *tsa = (TypeSArray*)type;
LLType *llnext = DtoConstInitializerType(type->nextOf(), init);
return LLArrayType::get(llnext, tsa->dim->toUInteger());
}
else if (ArrayInitializer* ai = init->isArrayInitializer())
{
return DtoConstArrayInitializerType(ai);
}
}
else if (type->ty == Tstruct)
{
if (!init)
{
LdefaultInit:
TypeStruct *ts = (TypeStruct*)type;
DtoResolveStruct(ts->sym);
return ts->sym->ir.irStruct->getDefaultInit()->getType();
}
else if (ExpInitializer* ex = init->isExpInitializer())
{
if (ex->exp->op == TOKstructliteral) {
StructLiteralExp* le = (StructLiteralExp*)ex->exp;
if (!le->constType)
le->constType = LLStructType::create(gIR->context(), std::string(type->toChars()) + "_init");
return le->constType;
} else if (ex->exp->op == TOKvar) {
if (((VarExp*)ex->exp)->var->isStaticStructInitDeclaration())
goto LdefaultInit;
}
}
else if (StructInitializer* si = init->isStructInitializer())
{
if (!si->ltype)
si->ltype = LLStructType::create(gIR->context(), std::string(type->toChars()) + "_init");
return si->ltype;
}
}
return DtoTypeNotVoid(type);
}
LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
{
LLConstant* _init = 0; // may return zero
@@ -1265,7 +1320,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
else if (ExpInitializer* ex = init->isExpInitializer())
{
Logger::println("const expression initializer");
_init = DtoConstExpInit(loc, type, ex->exp);;
_init = DtoConstExpInit(loc, type, ex->exp);
}
else if (StructInitializer* si = init->isStructInitializer())
{
@@ -1281,7 +1336,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
else if (init->isVoidInitializer())
{
Logger::println("const void initializer");
const LLType* ty = DtoType(type);
LLType* ty = DtoTypeNotVoid(type);
_init = LLConstant::getNullValue(ty);
}
else {
@@ -1325,7 +1380,7 @@ DValue* DtoInitializer(LLValue* target, Initializer* init)
static LLConstant* expand_to_sarray(Type *base, Expression* exp)
{
Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
const LLType* dstTy = DtoType(base);
LLType* dstTy = DtoType(base);
if (Logger::enabled())
Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
@@ -1355,7 +1410,7 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp)
std::vector<LLConstant*> inits;
while (i--)
{
const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
inits.clear();
inits.insert(inits.end(), dims[i], val);
val = LLConstantArray::get(arrty, inits);
@@ -1623,7 +1678,7 @@ size_t realignOffset(size_t offset, Type* type)
// we cannot get the llvm alignment if the type is still opaque, this can happen in some
// forward reference situations, so when this happens we fall back to manual padding.
// also handle arbitrary "by-value" opaques nested inside aggregates.
const llvm::Type* T = DtoType(type);
LLType* T = DtoType(type);
if (!T->isSized())
{
return offset;
@@ -1652,89 +1707,89 @@ size_t realignOffset(size_t offset, Type* type)
Type * stripModifiers( Type * type )
{
#if DMDV2
if (type->ty == Tfunction)
return type;
Type *t = type;
while (t->mod)
{
switch (t->mod)
{
case MODconst:
t = type->cto;
break;
case MODshared:
t = type->sto;
break;
case MODimmutable:
t = type->ito;
break;
case MODshared | MODconst:
t = type->scto;
break;
case MODwild:
t = type->wto;
break;
case MODshared | MODwild:
t = type->swto;
break;
default:
assert(0 && "Unhandled type modifier");
}
if (type->ty == Tfunction)
return type;
Type *t = type;
while (t->mod)
{
switch (t->mod)
{
case MODconst:
t = type->cto;
break;
case MODshared:
t = type->sto;
break;
case MODimmutable:
t = type->ito;
break;
case MODshared | MODconst:
t = type->scto;
break;
case MODwild:
t = type->wto;
break;
case MODshared | MODwild:
t = type->swto;
break;
default:
assert(0 && "Unhandled type modifier");
}
if (!t)
{
unsigned sz = type->sizeTy[type->ty];
t = (Type *)malloc(sz);
memcpy(t, type, sz);
t->mod = 0;
t->deco = NULL;
t->arrayof = NULL;
t->pto = NULL;
t->rto = NULL;
t->cto = NULL;
t->ito = NULL;
t->sto = NULL;
t->scto = NULL;
t->wto = NULL;
t->swto = NULL;
t->vtinfo = NULL;
t = t->merge();
if (!t)
{
unsigned sz = type->sizeTy[type->ty];
t = (Type *)malloc(sz);
memcpy(t, type, sz);
t->mod = 0;
t->deco = NULL;
t->arrayof = NULL;
t->pto = NULL;
t->rto = NULL;
t->cto = NULL;
t->ito = NULL;
t->sto = NULL;
t->scto = NULL;
t->wto = NULL;
t->swto = NULL;
t->vtinfo = NULL;
t = t->merge();
t->fixTo(type);
switch (type->mod)
{
case MODconst:
t->cto = type;
break;
t->fixTo(type);
switch (type->mod)
{
case MODconst:
t->cto = type;
break;
case MODimmutable:
t->ito = type;
break;
case MODimmutable:
t->ito = type;
break;
case MODshared:
t->sto = type;
break;
case MODshared:
t->sto = type;
break;
case MODshared | MODconst:
t->scto = type;
break;
case MODshared | MODconst:
t->scto = type;
break;
case MODwild:
t->wto = type;
break;
case MODwild:
t->wto = type;
break;
case MODshared | MODwild:
t->swto = type;
break;
case MODshared | MODwild:
t->swto = type;
break;
default:
assert(0);
}
}
}
return t;
default:
assert(0);
}
}
}
return t;
#else
return type;
return type;
#endif
}
@@ -1796,4 +1851,3 @@ void callPostblit(Loc &loc, Expression *exp, LLValue *val)
}
}
#endif

View File

@@ -44,8 +44,8 @@ void DtoDeleteArray(DValue* arr);
// emit an alloca
llvm::AllocaInst* DtoAlloca(Type* type, const char* name = "");
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name = "");
llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name = "");
LLValue* DtoGcMalloc(const llvm::Type* lltype, const char* name = "");
llvm::AllocaInst* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name = "");
LLValue* DtoGcMalloc(LLType* lltype, const char* name = "");
// assertion generator
void DtoAssert(Module* M, Loc loc, DValue* msg);
@@ -102,6 +102,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration);
LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr = 0);
// initializer helpers
LLType* DtoConstInitializerType(Type* type, Initializer* init);
LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init);
LLConstant* DtoConstExpInit(Loc loc, Type* t, Expression* exp);
DValue* DtoInitializer(LLValue* target, Initializer* init);
@@ -174,7 +175,7 @@ DValue* DtoVaArg(Loc& loc, Type* type, Expression* valistArg);
LLValue* DtoCallableValue(DValue* fn);
///
const LLFunctionType* DtoExtractFunctionType(const LLType* type);
LLFunctionType* DtoExtractFunctionType(LLType* type);
///
void DtoBuildDVarArgList(std::vector<LLValue*>& args, llvm::AttrListPtr& palist, TypeFunction* tf, Expressions* arguments, size_t argidx);

View File

@@ -20,7 +20,7 @@
void Stream::writeType(std::ostream& OS, const llvm::Type& Ty) {
llvm::raw_os_ostream raw(OS);
llvm::WriteTypeSymbolic(raw, &Ty, gIR->module);
Ty.print(raw);
}
void Stream::writeValue(std::ostream& OS, const llvm::Value& V) {

View File

@@ -7,11 +7,11 @@
#include "llvm/LinkAllVMCore.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/MC/SubtargetFeature.h"
#include <stdio.h>
#include <stdlib.h>
@@ -448,13 +448,12 @@ int main(int argc, char** argv)
// Allocate target machine.
// First initialize the native target and any additionally specified ones.
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
#define LLVM_TARGET(A) LLVMInitialize##A##TargetInfo(); LLVMInitialize##A##Target(); LLVMInitialize##A##AsmPrinter();
// this is defined to be LLVM_TARGET(target name 1) LLVM_TARGET(target name 2) ...
LDC_TARGETS
#undef LLVM_TARGET
// first initialize llvm
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllTargetMCs();
const llvm::Target *theTarget = NULL;
// Check whether the user has explicitly specified an architecture to compile for.
@@ -492,9 +491,8 @@ LDC_TARGETS
if (mCPU.size() || mAttrs.size())
{
llvm::SubtargetFeatures Features;
Features.setCPU(mCPU);
for (unsigned i = 0; i != mAttrs.size(); ++i)
Features.AddFeature(mAttrs[i]);
Features.AddFeature(mAttrs[i]);
FeaturesStr = Features.getString();
}
@@ -503,7 +501,8 @@ LDC_TARGETS
//assert(target.get() && "Could not allocate target machine!");
//gTargetMachine = target.get();
llvm::TargetMachine* target = theTarget->createTargetMachine(triple, FeaturesStr);
llvm::TargetMachine* target = theTarget->createTargetMachine(triple, mCPU, FeaturesStr,
mRelocModel, mCodeModel);
gTargetMachine = target;
gTargetData = target->getTargetData();

View File

@@ -201,7 +201,7 @@ void emitABIReturnAsmStmt(IRAsmBlock* asmblock, Loc loc, FuncDeclaration* fdecl)
IRAsmStmt* as = new IRAsmStmt;
const LLType* llretTy = DtoType(fdecl->type->nextOf());
LLType* llretTy = DtoType(fdecl->type->nextOf());
asmblock->retty = llretTy;
asmblock->retn = 1;
@@ -388,7 +388,7 @@ DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments
LLSmallVector<llvm::Value*, 8> args;
args.reserve(n-2);
std::vector<const llvm::Type*> argtypes;
std::vector<LLType*> argtypes;
argtypes.reserve(n-2);
for (size_t i = 2; i < n; i++)
@@ -400,14 +400,14 @@ DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments
// build asm function type
Type* type = fd->type->nextOf()->toBasetype();
const llvm::Type* ret_type = DtoType(type);
LLType* ret_type = DtoType(type);
llvm::FunctionType* FT = llvm::FunctionType::get(ret_type, argtypes, false);
// build asm call
bool sideeffect = true;
llvm::InlineAsm* ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect);
llvm::Value* rv = gIR->ir->CreateCall(ia, args.begin(), args.end(), "");
llvm::Value* rv = gIR->ir->CreateCall(ia, args, "");
// work around missing tuple support for users of the return value
if (type->ty == Tstruct)

View File

@@ -392,7 +392,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
Logger::println("has nested frame");
// start with adding all enclosing parent frames until a static parent is reached
const LLStructType* innerFrameType = NULL;
LLStructType* innerFrameType = NULL;
unsigned depth = -1;
if (!fd->isStatic()) {
if (FuncDeclaration* parfd = getParentFunc(fd, true)) {
@@ -408,7 +408,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
typedef std::vector<const LLType*> TypeVec;
typedef std::vector<LLType*> TypeVec;
TypeVec types;
if (depth != 0) {
assert(innerFrameType);
@@ -444,7 +444,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
// so handle those cases specially by storing a pointer instead of a value.
assert(vd->ir.irLocal->value);
LLValue* value = vd->ir.irLocal->value;
const LLType* type = value->getType();
LLType* type = value->getType();
if (llvm::isa<llvm::AllocaInst>(llvm::GetUnderlyingObject(value)))
// This will be copied to the nesting frame.
type = type->getContainedType(0);
@@ -461,8 +461,8 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
}
}
const LLStructType* frameType = LLStructType::get(gIR->context(), types);
gIR->module->addTypeName(std::string("nest.") + fd->toChars(), frameType);
LLStructType* frameType = LLStructType::create(gIR->context(), types,
std::string("nest.") + fd->toChars());
Logger::cout() << "frameType = " << *frameType << '\n';
@@ -521,7 +521,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
int nelems = fd->nestedVars.size() + nparelems;
// make array type for nested vars
const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems);
LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems);
// alloca it
// FIXME align ?
@@ -580,7 +580,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
{
IrFunction* irfunction = fd->ir.irFunc;
unsigned depth = irfunction->depth;
const llvm::StructType *frameType = irfunction->frameType;
LLStructType *frameType = irfunction->frameType;
// Create frame for current function and append to frames list
// FIXME: alignment ?
LLValue* frame = 0;

View File

@@ -10,6 +10,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Transforms/IPO.h"
#include "root.h" // error()
#include <cstring> // strcmp();
@@ -174,7 +175,6 @@ static void addPassesForOptLevel(PassManager& pm) {
if (optimizeLevel >= 3)
{
addPass(pm, createArgumentPromotionPass());
addPass(pm, createTailDuplicationPass());
addPass(pm, createSimplifyLibCallsPass());
addPass(pm, createInstructionCombiningPass());
addPass(pm, createJumpThreadingPass());
@@ -202,7 +202,6 @@ static void addPassesForOptLevel(PassManager& pm) {
addPass(pm, createDeadStoreEliminationPass());
addPass(pm, createAggressiveDCEPass());
addPass(pm, createCFGSimplificationPass());
addPass(pm, createDeadTypeEliminationPass());
addPass(pm, createConstantMergePass());
}

View File

@@ -93,10 +93,10 @@ Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
unsigned Align, IRBuilder<> &B) {
Module *M = Caller->getParent();
const Type* intTy = Len->getType();
const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
const Type *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy};
Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys, 3);
Type* intTy = Len->getType();
Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
Type *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy};
Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, llvm::makeArrayRef(Tys, 3));
return B.CreateCall5(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
ConstantInt::get(B.getInt32Ty(), Align), B.getFalse());

View File

@@ -63,7 +63,7 @@ void RTTIBuilder::push_string(const char* str)
void RTTIBuilder::push_null_void_array()
{
const llvm::Type* T = DtoType(Type::tvoid->arrayOf());
LLType* T = DtoType(Type::tvoid->arrayOf());
inits.push_back(getNullValue(T));
}
@@ -143,18 +143,30 @@ void RTTIBuilder::push_funcptr(FuncDeclaration* fd, Type* castto)
void RTTIBuilder::finalize(IrGlobal* tid)
{
// create the inititalizer
LLConstant* tiInit = LLConstantStruct::get(gIR->context(), &inits[0], inits.size(), false);
finalize(tid->type, tid->value);
}
// refine global type
llvm::cast<llvm::OpaqueType>(tid->type.get())->refineAbstractTypeTo(tiInit->getType());
void RTTIBuilder::finalize(LLType* type, LLValue* value)
{
llvm::ArrayRef<LLConstant*> inits = llvm::makeArrayRef(this->inits);
LLStructType *st = isaStruct(type);
assert(st);
// set struct body
std::vector<LLType*> types;
for (int i = 0, n = inits.size(); i < n; ++i)
types.push_back(inits[i]->getType());
st->setBody(types);
// create the inititalizer
LLConstant* tiInit = LLConstantStruct::get(st, inits);
// set the initializer
isaGlobalVar(tid->value)->setInitializer(tiInit);
isaGlobalVar(value)->setInitializer(tiInit);
}
LLConstant* RTTIBuilder::get_constant()
LLConstant* RTTIBuilder::get_constant(LLStructType *initType)
{
// just return the inititalizer
return LLConstantStruct::get(gIR->context(), &inits[0], inits.size(), false);
return LLConstantStruct::get(initType, inits);
}

View File

@@ -56,9 +56,10 @@ struct RTTIBuilder
/// Creates the initializer constant and assigns it to the global.
void finalize(IrGlobal* tid);
void finalize(LLType* type, LLValue* value);
/// Creates the initializer constant and assigns it to the global.
llvm::Constant* get_constant();
llvm::Constant* get_constant(LLStructType *initType);
};
#endif

View File

@@ -70,7 +70,7 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name
LLVM_D_InitRuntime();
}
llvm::Function* fn = target->getFunction(name);
LLFunction* fn = target->getFunction(name);
if (fn)
return fn;
@@ -81,8 +81,8 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name
//return NULL;
}
const llvm::FunctionType* fnty = fn->getFunctionType();
llvm::Function* resfn = llvm::cast<llvm::Function>(target->getOrInsertFunction(name, fnty));
LLFunctionType* fnty = fn->getFunctionType();
LLFunction* resfn = llvm::cast<llvm::Function>(target->getOrInsertFunction(name, fnty));
resfn->setAttributes(fn->getAttributes());
return resfn;
}
@@ -91,7 +91,7 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name
llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name)
{
llvm::GlobalVariable* gv = target->getNamedGlobal(name);
LLGlobalVariable* gv = target->getNamedGlobal(name);
if (gv) {
return gv;
}
@@ -106,46 +106,65 @@ llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char*
LLVM_D_InitRuntime();
}
llvm::GlobalVariable* g = M->getNamedGlobal(name);
LLGlobalVariable* g = M->getNamedGlobal(name);
if (!g) {
error("Runtime global '%s' was not found", name);
fatal();
//return NULL;
}
const llvm::PointerType* t = g->getType();
return new llvm::GlobalVariable(*target, t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName());
LLPointerType* t = g->getType();
return new LLGlobalVariable(*target, t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName());
}
//////////////////////////////////////////////////////////////////////////////////////////////////
static const LLType* rt_ptr(const LLType* t)
static LLType* rt_ptr(LLType* t)
{
return getPtrToType(t);
}
static const LLType* rt_array(const LLType* elemty)
static LLType* rt_array(LLType* elemty)
{
return llvm::StructType::get(gIR->context(), DtoSize_t(), rt_ptr(elemty), NULL);
llvm::SmallVector<LLType*, 2> types;
types.push_back(DtoSize_t());
types.push_back(rt_ptr(elemty));
return LLStructType::get(gIR->context(), llvm::makeArrayRef(types));
}
static const LLType* rt_dg1()
static LLType* rt_dg1()
{
std::vector<const LLType*> types;
llvm::SmallVector<LLType*, 2> types;
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::getInt32Ty(gIR->context()), types, false);
return llvm::StructType::get(gIR->context(), rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty), NULL);
LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), types, false);
types.clear();
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
types.push_back(rt_ptr(fty));
return LLStructType::get(gIR->context(), types);
}
static const LLType* rt_dg2()
static LLType* rt_dg2()
{
std::vector<const LLType*> types;
llvm::SmallVector<LLType*, 3> types;
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::getInt32Ty(gIR->context()), types, false);
return llvm::StructType::get(gIR->context(), rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty), NULL);
LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), types, false);
types.clear();
types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
types.push_back(rt_ptr(fty));
return LLStructType::get(gIR->context(), types);
}
static LLType* rt_complex(LLType* type)
{
llvm::SmallVector<LLType*, 2> types;
types.push_back(type);
types.push_back(type);
return llvm::StructType::get(gIR->context(), types);
}
static void LLVM_D_BuildRuntimeModule()
@@ -154,42 +173,42 @@ static void LLVM_D_BuildRuntimeModule()
M = new llvm::Module("ldc internal runtime", gIR->context());
Logger::println("building basic types");
const LLType* voidTy = LLType::getVoidTy(gIR->context());
const LLType* boolTy = LLType::getInt1Ty(gIR->context());
const LLType* byteTy = LLType::getInt8Ty(gIR->context());
const LLType* shortTy = LLType::getInt16Ty(gIR->context());
const LLType* intTy = LLType::getInt32Ty(gIR->context());
const LLType* longTy = LLType::getInt64Ty(gIR->context());
const LLType* sizeTy = DtoSize_t();
LLType* voidTy = LLType::getVoidTy(gIR->context());
LLType* boolTy = LLType::getInt1Ty(gIR->context());
LLType* byteTy = LLType::getInt8Ty(gIR->context());
LLType* shortTy = LLType::getInt16Ty(gIR->context());
LLType* intTy = LLType::getInt32Ty(gIR->context());
LLType* longTy = LLType::getInt64Ty(gIR->context());
LLType* sizeTy = DtoSize_t();
Logger::println("building float types");
const LLType* floatTy = LLType::getFloatTy(gIR->context());
const LLType* doubleTy = LLType::getDoubleTy(gIR->context());
const LLType* realTy;
LLType* floatTy = LLType::getFloatTy(gIR->context());
LLType* doubleTy = LLType::getDoubleTy(gIR->context());
LLType* realTy;
if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64))
realTy = LLType::getX86_FP80Ty(gIR->context());
else
realTy = LLType::getDoubleTy(gIR->context());
const LLType* cfloatTy = llvm::StructType::get(gIR->context(), floatTy, floatTy, NULL);
const LLType* cdoubleTy = llvm::StructType::get(gIR->context(), doubleTy, doubleTy, NULL);
const LLType* crealTy = llvm::StructType::get(gIR->context(), realTy, realTy, NULL);
LLType* cfloatTy = rt_complex(floatTy);
LLType* cdoubleTy = rt_complex(doubleTy);
LLType* crealTy = rt_complex(realTy);
Logger::println("building aggr types");
const LLType* voidPtrTy = rt_ptr(byteTy);
const LLType* voidArrayTy = rt_array(byteTy);
const LLType* voidArrayPtrTy = getPtrToType(voidArrayTy);
const LLType* stringTy = voidArrayTy;
const LLType* wstringTy = rt_array(shortTy);
const LLType* dstringTy = rt_array(intTy);
LLType* voidPtrTy = rt_ptr(byteTy);
LLType* voidArrayTy = rt_array(byteTy);
LLType* voidArrayPtrTy = getPtrToType(voidArrayTy);
LLType* stringTy = DtoType(Type::tchar->arrayOf());
LLType* wstringTy = DtoType(Type::twchar->arrayOf());
LLType* dstringTy = DtoType(Type::tdchar->arrayOf());
Logger::println("building class types");
const LLType* objectTy = DtoType(ClassDeclaration::object->type);
const LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type);
const LLType* typeInfoTy = DtoType(Type::typeinfo->type);
LLType* objectTy = DtoType(ClassDeclaration::object->type);
LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type);
LLType* typeInfoTy = DtoType(Type::typeinfo->type);
Logger::println("building aa type");
const LLType* aaTy = rt_ptr(llvm::OpaqueType::get(gIR->context()));
LLType* aaTy = rt_ptr(LLStructType::get(gIR->context()));
Logger::println("building functions");
@@ -238,10 +257,10 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_assert( char[] file, uint line )
{
llvm::StringRef fname("_d_assert");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(stringTy);
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -254,14 +273,14 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_array_bounds");
llvm::StringRef fname2("_d_switch_error");
std::vector<const LLType*> types;
std::vector<LLType*> types;
#if DMDV2
types.push_back(getPtrToType(DtoType(Module::moduleinfo->type)));
#else
types.push_back(stringTy);
#endif
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -269,11 +288,11 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_assert_msg( char[] msg, char[] file, uint line )
{
llvm::StringRef fname("_d_assert_msg");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(stringTy);
types.push_back(stringTy);
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -285,9 +304,9 @@ static void LLVM_D_BuildRuntimeModule()
// void* _d_allocmemory(size_t sz)
{
llvm::StringRef fname("_d_allocmemory");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias);
}
@@ -295,9 +314,9 @@ static void LLVM_D_BuildRuntimeModule()
// void* _d_allocmemoryT(TypeInfo ti)
{
llvm::StringRef fname("_d_allocmemoryT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias);
}
@@ -309,10 +328,10 @@ static void LLVM_D_BuildRuntimeModule()
llvm::StringRef fname("_d_newarrayT");
llvm::StringRef fname2("_d_newarrayiT");
llvm::StringRef fname3("_d_newarrayvT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
@@ -327,11 +346,11 @@ static void LLVM_D_BuildRuntimeModule()
llvm::StringRef fname("_d_newarraymT");
llvm::StringRef fname2("_d_newarraymiT");
llvm::StringRef fname3("_d_newarraymvT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(sizeTy);
types.push_back(rt_ptr(sizeTy));
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias_3_NoCapture);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
@@ -345,10 +364,10 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_newarrayT");
llvm::StringRef fname2("_d_newarrayiT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -357,10 +376,10 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_newarraymT");
llvm::StringRef fname2("_d_newarraymiT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -375,16 +394,16 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_arraysetlengthT");
llvm::StringRef fname2("_d_arraysetlengthiT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(sizeTy);
#if DMDV2
types.push_back(voidArrayPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
#else
types.push_back(sizeTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
#endif
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
@@ -394,68 +413,68 @@ static void LLVM_D_BuildRuntimeModule()
// byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n)
{
llvm::StringRef fname("_d_arrayappendcTX");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(voidArrayPtrTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y)
{
llvm::StringRef fname("_d_arrayappendT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(voidArrayPtrTy);
types.push_back(voidArrayTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// void[] _d_arrayappendcd(ref char[] x, dchar c)
{
llvm::StringRef fname("_d_arrayappendcd");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(getPtrToType(stringTy));
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// void[] _d_arrayappendwd(ref wchar[] x, dchar c)
{
llvm::StringRef fname("_d_arrayappendwd");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(getPtrToType(wstringTy));
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y)
{
llvm::StringRef fname("_d_arraycatT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(voidArrayTy);
types.push_back(voidArrayTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// byte[] _d_arraycatnT(TypeInfo ti, uint n, ...)
{
llvm::StringRef fname("_d_arraycatnT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
#else // DMDV1
// byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element)
{
llvm::StringRef fname("_d_arrayappendcT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(voidPtrTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
#endif
@@ -463,9 +482,9 @@ static void LLVM_D_BuildRuntimeModule()
// Object _d_allocclass(ClassInfo ci)
{
llvm::StringRef fname(_d_allocclass);
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(classInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias);
}
@@ -475,10 +494,10 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_delarray_t(Array *p, TypeInfo ti)
{
llvm::StringRef fname("_d_delarray_t");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(voidArrayPtrTy);
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -487,10 +506,10 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_delarray(size_t plength, void* pdata)
{
llvm::StringRef fname("_d_delarray");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(sizeTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -508,9 +527,9 @@ static void LLVM_D_BuildRuntimeModule()
llvm::StringRef fname("_d_delmemory");
llvm::StringRef fname2("_d_delinterface");
llvm::StringRef fname3("_d_callfinalizer");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
@@ -520,13 +539,13 @@ static void LLVM_D_BuildRuntimeModule()
// D2: void _d_delclass(Object* p)
{
llvm::StringRef fname("_d_delclass");
std::vector<const LLType*> types;
std::vector<LLType*> types;
#if DMDV2
types.push_back(rt_ptr(objectTy));
#else
types.push_back(objectTy);
#endif
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -543,7 +562,7 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(sizeTy);
types.push_back(voidPtrTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_3_NoCapture);
}
@@ -557,10 +576,10 @@ static void LLVM_D_BuildRuntimeModule()
{ \
llvm::StringRef fname(a); \
llvm::StringRef fname2(b); \
std::vector<const LLType*> types; \
std::vector<LLType*> types; \
types.push_back(TY); \
types.push_back(rt_dg1()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
@@ -574,10 +593,10 @@ static void LLVM_D_BuildRuntimeModule()
{ \
llvm::StringRef fname(a); \
llvm::StringRef fname2(b); \
std::vector<const LLType*> types; \
std::vector<LLType*> types; \
types.push_back(TY); \
types.push_back(rt_dg2()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
@@ -590,10 +609,10 @@ static void LLVM_D_BuildRuntimeModule()
{ \
llvm::StringRef fname(a); \
llvm::StringRef fname2(b); \
std::vector<const LLType*> types; \
std::vector<LLType*> types; \
types.push_back(TY); \
types.push_back(rt_dg1()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
@@ -606,10 +625,10 @@ static void LLVM_D_BuildRuntimeModule()
{ \
llvm::StringRef fname(a); \
llvm::StringRef fname2(b); \
std::vector<const LLType*> types; \
std::vector<LLType*> types; \
types.push_back(TY); \
types.push_back(rt_dg2()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
@@ -626,11 +645,11 @@ static void LLVM_D_BuildRuntimeModule()
// size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
{
llvm::StringRef fname("_d_array_cast_len");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(sizeTy);
types.push_back(sizeTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadNone);
}
@@ -646,11 +665,11 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_arrayassign");
llvm::StringRef fname2("_d_arrayctor");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(voidArrayTy);
types.push_back(voidArrayTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -660,12 +679,12 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_arraysetassign");
llvm::StringRef fname2("_d_arraysetctor");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(voidPtrTy);
types.push_back(voidPtrTy);
types.push_back(sizeTy);
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
@@ -682,9 +701,9 @@ static void LLVM_D_BuildRuntimeModule()
// Object _d_toObject(void* p)
{
llvm::StringRef fname("_d_toObject");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly_NoUnwind);
}
@@ -693,10 +712,10 @@ static void LLVM_D_BuildRuntimeModule()
// Object _d_interface_cast(void* p, ClassInfo c)
{
llvm::StringRef fname("_d_interface_cast");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(voidPtrTy);
types.push_back(classInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly_NoUnwind);
}
@@ -705,10 +724,10 @@ static void LLVM_D_BuildRuntimeModule()
// Object _d_dynamic_cast(Object o, ClassInfo c)
{
llvm::StringRef fname("_d_dynamic_cast");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(objectTy);
types.push_back(classInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly_NoUnwind);
}
@@ -722,9 +741,9 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_adReverseChar");
llvm::StringRef fname2("_adSortChar");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(stringTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(stringTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(stringTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -734,9 +753,9 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_adReverseWchar");
llvm::StringRef fname2("_adSortWchar");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(wstringTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(wstringTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(wstringTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -744,10 +763,10 @@ static void LLVM_D_BuildRuntimeModule()
// void[] _adReverse(void[] a, size_t szelem)
{
llvm::StringRef fname("_adReverse");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(byteTy));
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoUnwind);
}
@@ -755,10 +774,10 @@ static void LLVM_D_BuildRuntimeModule()
// void[] _adDupT(TypeInfo ti, void[] a)
{
llvm::StringRef fname("_adDupT");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(rt_array(byteTy));
const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -767,11 +786,11 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname(_adEq);
llvm::StringRef fname2(_adCmp);
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(byteTy));
types.push_back(rt_array(byteTy));
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
@@ -781,10 +800,10 @@ static void LLVM_D_BuildRuntimeModule()
// int _adCmpChar(void[] a1, void[] a2)
{
llvm::StringRef fname("_adCmpChar");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(byteTy));
types.push_back(rt_array(byteTy));
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly_NoUnwind);
}
@@ -792,10 +811,10 @@ static void LLVM_D_BuildRuntimeModule()
// void[] _adSort(void[] a, TypeInfo ti)
{
llvm::StringRef fname("_adSort");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(byteTy));
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -806,9 +825,9 @@ static void LLVM_D_BuildRuntimeModule()
// size_t _aaLen(AA aa)
{
llvm::StringRef fname("_aaLen");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly_NoUnwind_1_NoCapture);
}
@@ -823,12 +842,12 @@ static void LLVM_D_BuildRuntimeModule()
#else
llvm::StringRef fname("_aaGet");
#endif
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(typeInfoTy);
types.push_back(sizeTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_4_NoCapture);
}
@@ -843,11 +862,11 @@ static void LLVM_D_BuildRuntimeModule()
#else
llvm::StringRef fname("_aaIn");
#endif
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(typeInfoTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly_1_3_NoCapture);
}
@@ -862,11 +881,11 @@ static void LLVM_D_BuildRuntimeModule()
#else
llvm::StringRef fname("_aaDel");
#endif
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(typeInfoTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_3_NoCapture);
}
@@ -874,11 +893,11 @@ static void LLVM_D_BuildRuntimeModule()
// void[] _aaValues(AA aa, size_t keysize, size_t valuesize)
{
llvm::StringRef fname("_aaValues");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(sizeTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias_1_NoCapture);
}
@@ -886,20 +905,20 @@ static void LLVM_D_BuildRuntimeModule()
// void* _aaRehash(AA* paa, TypeInfo keyti)
{
llvm::StringRef fname("_aaRehash");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// void[] _aaKeys(AA aa, size_t keysize)
{
llvm::StringRef fname("_aaKeys");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(sizeTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_NoAlias_1_NoCapture);
}
@@ -907,11 +926,11 @@ static void LLVM_D_BuildRuntimeModule()
// int _aaApply(AA aa, size_t keysize, dg_t dg)
{
llvm::StringRef fname("_aaApply");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(sizeTy);
types.push_back(rt_dg1());
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_NoCapture);
}
@@ -919,11 +938,11 @@ static void LLVM_D_BuildRuntimeModule()
// int _aaApply2(AA aa, size_t keysize, dg2_t dg)
{
llvm::StringRef fname("_aaApply2");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(sizeTy);
types.push_back(rt_dg2());
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_NoCapture);
}
@@ -932,33 +951,33 @@ static void LLVM_D_BuildRuntimeModule()
// int _aaEqual(TypeInfo_AssociativeArray ti, AA e1, AA e2)
{
llvm::StringRef fname("_aaEqual");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(aaTy);
types.push_back(aaTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_2_NoCapture);
}
// BB* _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values)
{
llvm::StringRef fname("_d_assocarrayliteralTX");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(typeInfoTy);
types.push_back(voidArrayTy);
types.push_back(voidArrayTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
#else
// int _aaEq(AA aa, AA ab, TypeInfo_AssociativeArray ti)
{
llvm::StringRef fname("_aaEq");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(aaTy);
types.push_back(aaTy);
types.push_back(typeInfoTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_2_NoCapture);
}
@@ -973,8 +992,8 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_moduleCtor");
llvm::StringRef fname2("_moduleDtor");
std::vector<const LLType*> types;
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
std::vector<LLType*> types;
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -986,9 +1005,9 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_throw_exception(Object e)
{
llvm::StringRef fname("_d_throw_exception");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(objectTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -999,10 +1018,10 @@ static void LLVM_D_BuildRuntimeModule()
// int _d_switch_string(char[][] table, char[] ca)
{
llvm::StringRef fname("_d_switch_string");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(stringTy));
types.push_back(stringTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly);
}
@@ -1010,10 +1029,10 @@ static void LLVM_D_BuildRuntimeModule()
// int _d_switch_ustring(wchar[][] table, wchar[] ca)
{
llvm::StringRef fname("_d_switch_ustring");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(wstringTy));
types.push_back(wstringTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly);
}
@@ -1021,10 +1040,10 @@ static void LLVM_D_BuildRuntimeModule()
// int _d_switch_dstring(dchar[][] table, dchar[] ca)
{
llvm::StringRef fname("_d_switch_dstring");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_array(dstringTy));
types.push_back(dstringTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_ReadOnly);
}
@@ -1038,9 +1057,9 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_criticalenter");
llvm::StringRef fname2("_d_criticalexit");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(rt_ptr(DtoMutexType()));
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
@@ -1050,9 +1069,9 @@ static void LLVM_D_BuildRuntimeModule()
{
llvm::StringRef fname("_d_monitorenter");
llvm::StringRef fname2("_d_monitorexit");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(objectTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_NoCapture);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
@@ -1066,22 +1085,22 @@ static void LLVM_D_BuildRuntimeModule()
// int _d_eh_personality(int ver, int actions, ulong eh_class, ptr eh_info, ptr context)
{
llvm::StringRef fname("_d_eh_personality");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(intTy);
types.push_back(intTy);
types.push_back(longTy);
types.push_back(voidPtrTy);
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// void _d_eh_resume_unwind(ptr exc_struct)
{
llvm::StringRef fname("_d_eh_resume_unwind");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -1092,9 +1111,9 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_invariant(Object o)
{
llvm::StringRef fname("_d_invariant");
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(objectTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
@@ -1102,7 +1121,7 @@ static void LLVM_D_BuildRuntimeModule()
// void _d_hidden_func()
{
llvm::StringRef fname("_d_hidden_func");
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, false);
LLFunctionType* fty = llvm::FunctionType::get(voidTy, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
#endif

View File

@@ -947,19 +947,19 @@ void SwitchStatement::toIR(IRState* p)
inits[i] = c->str->toConstElem(p);
}
// build static array for ptr or final array
const LLType* elemTy = DtoType(condition->type);
const llvm::ArrayType* arrTy = llvm::ArrayType::get(elemTy, inits.size());
LLType* elemTy = DtoType(condition->type);
LLArrayType* arrTy = llvm::ArrayType::get(elemTy, inits.size());
LLConstant* arrInit = LLConstantArray::get(arrTy, inits);
llvm::GlobalVariable* arr = new llvm::GlobalVariable(*gIR->module, arrTy, true, llvm::GlobalValue::InternalLinkage, arrInit, ".string_switch_table_data");
LLGlobalVariable* arr = new llvm::GlobalVariable(*gIR->module, arrTy, true, llvm::GlobalValue::InternalLinkage, arrInit, ".string_switch_table_data");
const LLType* elemPtrTy = getPtrToType(elemTy);
LLType* elemPtrTy = getPtrToType(elemTy);
LLConstant* arrPtr = llvm::ConstantExpr::getBitCast(arr, elemPtrTy);
// build the static table
std::vector<const LLType*> types;
std::vector<LLType*> types;
types.push_back(DtoSize_t());
types.push_back(elemPtrTy);
const llvm::StructType* sTy = llvm::StructType::get(gIR->context(), types);
LLStructType* sTy = llvm::StructType::get(gIR->context(), types);
std::vector<LLConstant*> sinits;
sinits.push_back(DtoConstSize_t(inits.size()));
sinits.push_back(arrPtr);
@@ -1164,7 +1164,7 @@ void ForeachStatement::toIR(IRState* p)
Logger::println("aggr = %s", aggr->toChars());
// key
const LLType* keytype = key ? DtoType(key->type) : DtoSize_t();
LLType* keytype = key ? DtoType(key->type) : DtoSize_t();
LLValue* keyvar;
if (key)
keyvar = DtoRawVarDeclaration(key);
@@ -1524,7 +1524,7 @@ void WithStatement::toIR(IRState* p)
static LLConstant* generate_unique_critical_section()
{
const LLType* Mty = DtoMutexType();
LLType* Mty = DtoMutexType();
return new llvm::GlobalVariable(*gIR->module, Mty, false, llvm::GlobalValue::InternalLinkage, LLConstant::getNullValue(Mty), ".uniqueCS");
}
@@ -1627,7 +1627,7 @@ void SwitchErrorStatement::toIR(IRState* p)
#if DMDV2
// module param
LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol();
const LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));
#else
// file param
@@ -1640,7 +1640,7 @@ void SwitchErrorStatement::toIR(IRState* p)
args.push_back(c);
// call
gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
gIR->CreateCallOrInvoke(fn, args);
gIR->ir->CreateUnreachable();
}

View File

@@ -1,7 +1,6 @@
#include <algorithm>
#include "gen/llvm.h"
#include "llvm/AbstractTypeUser.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ManagedStatic.h"
@@ -126,7 +125,7 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
assert(field);
// get the start pointer
const LLType* st = getPtrToType(DtoType(sd->type));
LLType* st = getPtrToType(DtoType(sd->type));
// cast to the formal struct type
src = DtoBitCast(src, st);
@@ -185,7 +184,9 @@ size_t add_zeros(std::vector<llvm::Value*>& values, size_t diff)
return values.size() - n;
}
std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd, const std::vector<llvm::Value*>& inits)
std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd,
const std::vector<llvm::Value*>& inits,
bool isConst)
{
// get arrays
size_t nvars = sd->fields.dim;
@@ -269,7 +270,7 @@ std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd, co
assert(nextVar == var);
// add any 0 padding needed before this field
if (os > lastoffset + lastsize)
if (!isConst && os > lastoffset + lastsize)
{
//printf("added %lu zeros\n", os - lastoffset - lastsize);
add_zeros(values, os - lastoffset - lastsize);
@@ -296,7 +297,7 @@ std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd, co
}
// fill out rest with default initializers
const LLType* structtype = DtoType(sd->type);
LLType* structtype = DtoType(sd->type);
size_t structsize = getTypePaddedSize(structtype);
// FIXME: this could probably share some code with the above
@@ -348,7 +349,7 @@ std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd, co
LLType* DtoUnpaddedStructType(Type* dty) {
assert(dty->ty == Tstruct);
typedef llvm::DenseMap<Type*, llvm::PATypeHolder> CacheT;
typedef llvm::DenseMap<Type*, llvm::StructType*> CacheT;
static llvm::ManagedStatic<CacheT> cache;
CacheT::iterator it = cache->find(dty);
if (it != cache->end())
@@ -357,11 +358,11 @@ LLType* DtoUnpaddedStructType(Type* dty) {
TypeStruct* sty = (TypeStruct*) dty;
Array& fields = sty->sym->fields;
std::vector<const LLType*> types;
std::vector<LLType*> types;
for (unsigned i = 0; i < fields.dim; i++) {
VarDeclaration* vd = (VarDeclaration*) fields.data[i];
const LLType* fty;
LLType* fty;
if (vd->type->ty == Tstruct) {
// Nested structs are the only members that can contain padding
fty = DtoUnpaddedStructType(vd->type);
@@ -370,7 +371,7 @@ LLType* DtoUnpaddedStructType(Type* dty) {
}
types.push_back(fty);
}
LLType* Ty = LLStructType::get(gIR->context(), types);
LLStructType* Ty = LLStructType::get(gIR->context(), types);
cache->insert(std::make_pair(dty, Ty));
return Ty;
}

View File

@@ -10,7 +10,9 @@ void DtoResolveStruct(StructDeclaration* sd);
LLConstant* DtoConstStructInitializer(StructInitializer* si);
/// Build values for a struct literal.
std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd, const std::vector<llvm::Value*>& inits);
std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd,
const std::vector<llvm::Value*>& inits,
bool isConst = false);
/// Returns a boolean=true if the two structs are equal.
LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs);

View File

@@ -63,7 +63,7 @@ llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l)
DValue* DtoVaArg(Loc& loc, Type* type, Expression* valistArg)
{
DValue* expelem = valistArg->toElem(gIR);
const LLType* llt = DtoType(type);
LLType* llt = DtoType(type);
if (DtoIsPassedByRef(type))
llt = getPtrToType(llt);
// issue a warning for broken va_arg instruction.
@@ -106,13 +106,13 @@ LLValue* DtoCallableValue(DValue* fn)
//////////////////////////////////////////////////////////////////////////////////////////
const LLFunctionType* DtoExtractFunctionType(const LLType* type)
LLFunctionType* DtoExtractFunctionType(LLType* type)
{
if (const LLFunctionType* fty = isaFunction(type))
if (LLFunctionType* fty = isaFunction(type))
return fty;
else if (const LLPointerType* pty = isaPointer(type))
else if (LLPointerType* pty = isaPointer(type))
{
if (const LLFunctionType* fty = isaFunction(pty->getElementType()))
if (LLFunctionType* fty = isaFunction(pty->getElementType()))
return fty;
}
return NULL;
@@ -120,7 +120,7 @@ const LLFunctionType* DtoExtractFunctionType(const LLType* type)
//////////////////////////////////////////////////////////////////////////////////////////
static LLValue *fixArgument(DValue *argval, TypeFunction* tf, const LLType *callableArgType, int argIndex)
static LLValue *fixArgument(DValue *argval, TypeFunction* tf, LLType *callableArgType, int argIndex)
{
#if 0
if (Logger::enabled()) {
@@ -179,12 +179,12 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
std::vector<llvm::AttributeWithIndex>& attrs,
TypeFunction* tf, Expressions* arguments,
size_t argidx,
const LLFunctionType* callableTy)
LLFunctionType* callableTy)
{
Logger::println("doing d-style variadic arguments");
LOG_SCOPE
std::vector<const LLType*> vtypes;
std::vector<LLType*> vtypes;
// number of non variadic args
int begin = Parameter::dim(tf->parameters);
@@ -211,7 +211,7 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
{
// ok then... so we build some type that is big enough
// and aligned to PTRSIZE
std::vector<const LLType*> gah;
std::vector<LLType*> gah;
gah.reserve(asz/PTRSIZE);
size_t gah_sz = 0;
while (gah_sz < asz)
@@ -223,7 +223,7 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
}
}
}
const LLStructType* vtype = LLStructType::get(gIR->context(), vtypes);
LLStructType* vtype = LLStructType::get(gIR->context(), vtypes);
if (Logger::enabled())
Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
@@ -242,8 +242,8 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
}
// build type info array
const LLType* typeinfotype = DtoType(Type::typeinfo->type);
const LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements());
LLType* typeinfotype = DtoType(Type::typeinfo->type);
LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements());
llvm::GlobalVariable* typeinfomem =
new llvm::GlobalVariable(*gIR->module, typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage");
@@ -265,8 +265,8 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
std::vector<LLConstant*> pinits;
pinits.push_back(DtoConstSize_t(vtype->getNumElements()));
pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype)));
const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf());
tiinits = LLConstantStruct::get(gIR->context(), pinits, false);
LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf());
tiinits = LLConstantStruct::get(isaStruct(tiarrty), pinits);
LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty,
true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array");
@@ -341,7 +341,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// get callee llvm value
LLValue* callable = DtoCallableValue(fnval);
const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType());
LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType());
assert(callableTy);
// if (Logger::enabled())
@@ -373,7 +373,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// return in hidden ptr is first
if (retinptr)
{
LLValue* retvar = DtoRawAlloca(argiter->get()->getContainedType(0), resulttype->alignsize(), ".rettmp");
LLValue* retvar = DtoRawAlloca((*argiter)->getContainedType(0), resulttype->alignsize(), ".rettmp");
++argiter;
args.push_back(retvar);
@@ -391,7 +391,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// ... which can be a 'this' argument
if (thiscall && dfnval && dfnval->vthis)
{
LLValue* thisarg = DtoBitCast(dfnval->vthis, argiter->get());
LLValue* thisarg = DtoBitCast(dfnval->vthis, *argiter);
++argiter;
args.push_back(thisarg);
}
@@ -407,7 +407,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
{
ctxarg = gIR->ir->CreateExtractValue(fnval->getRVal(), 0, ".ptr");
}
ctxarg = DtoBitCast(ctxarg, argiter->get());
ctxarg = DtoBitCast(ctxarg, *argiter);
++argiter;
args.push_back(ctxarg);
}
@@ -575,7 +575,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
#endif
// call the function
LLCallSite call = gIR->CreateCallOrInvoke(callable, args.begin(), args.end(), varname);
LLCallSite call = gIR->CreateCallOrInvoke(callable, args, varname);
// get return value
LLValue* retllval = (retinptr) ? args[0] : call.getInstruction();

View File

@@ -65,7 +65,7 @@ llvm::DIFile DtoDwarfFile(Loc loc)
static llvm::DIType dwarfBasicType(Type* type)
{
Type* t = type->toBasetype();
const LLType* T = DtoType(type);
LLType* T = DtoType(type);
// find encoding
unsigned id;
@@ -97,7 +97,7 @@ static llvm::DIType dwarfBasicType(Type* type)
static llvm::DIType dwarfPointerType(Type* type)
{
const LLType* T = DtoType(type);
LLType* T = DtoType(type);
Type* t = type->toBasetype();
assert(t->ty == Tpointer && "only pointers allowed for debug info in dwarfPointerType");
@@ -121,7 +121,7 @@ static llvm::DIType dwarfPointerType(Type* type)
static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile file, const char* c_name, unsigned offset)
{
const LLType* T = DtoType(type);
LLType* T = DtoType(type);
Type* t = type->toBasetype();
// find base type
@@ -131,6 +131,7 @@ static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile fi
basetype = llvm::DIType(NULL);
return gIR->dibuilder.createMemberType(
llvm::DIDescriptor(file),
c_name, // name
file, // file
linnum, // line number
@@ -168,7 +169,7 @@ static void add_base_fields(
static llvm::DIType dwarfCompositeType(Type* type)
{
const LLType* T = DtoType(type);
LLType* T = DtoType(type);
Type* t = type->toBasetype();
// defaults
@@ -266,8 +267,7 @@ static llvm::DIType dwarfCompositeType(Type* type)
}
}
llvm::DIArray elemsArray =
gIR->dibuilder.getOrCreateArray(elems.data(), elems.size());
llvm::DIArray elemsArray = gIR->dibuilder.getOrCreateArray(elems);
llvm::DIType ret;
if (t->ty == Tclass) {
@@ -334,7 +334,7 @@ static void dwarfDeclare(LLValue* var, llvm::DIVariable divar)
llvm::DIType dwarfArrayType(Type* type) {
const LLType* T = DtoType(type);
LLType* T = DtoType(type);
Type* t = type->toBasetype();
llvm::DIFile file = DtoDwarfFile(Loc(gIR->dmodule, 0));
@@ -352,7 +352,7 @@ llvm::DIType dwarfArrayType(Type* type) {
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
0, // What here?
gIR->dibuilder.getOrCreateArray(elems.data(), elems.size())
gIR->dibuilder.getOrCreateArray(elems)
);
}
@@ -557,4 +557,11 @@ void DtoDwarfValue(LLValue* var, VarDeclaration* vd)
instr->setDebugLoc(gIR->ir->getCurrentDebugLocation());
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void DtoDwarfModuleEnd()
{
gIR->dibuilder.finalize();
}
#endif

View File

@@ -48,6 +48,8 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd);
*/
llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
void DtoDwarfModuleEnd();
#endif // DISABLE_DEBUG_INFO

View File

@@ -167,7 +167,7 @@ DValue* VarExp::toElem(IRState* p)
Logger::println("TypeInfoDeclaration");
tid->codegen(Type::sir);
assert(tid->ir.getIrValue());
const LLType* vartype = DtoType(type);
LLType* vartype = DtoType(type);
LLValue* m = tid->ir.getIrValue();
if (m->getType() != getPtrToType(vartype))
m = p->ir->CreateBitCast(m, vartype, "tmp");
@@ -208,9 +208,8 @@ DValue* VarExp::toElem(IRState* p)
Logger::println("a normal variable");
// take care of forward references of global variables
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
if (vd->isDataseg() || (vd->storage_class & STCextern))
vd->codegen(Type::sir);
}
LLValue* val;
@@ -224,10 +223,8 @@ DValue* VarExp::toElem(IRState* p)
fatal();
}
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
DtoConstInitGlobal(vd);
if (vd->isDataseg() || (vd->storage_class & STCextern))
val = DtoBitCast(val, DtoType(type->pointerTo()));
}
return new DVarValue(type, vd, val);
}
@@ -289,7 +286,7 @@ LLConstant* VarExp::toConstElem(IRState* p)
if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
{
const LLType* vartype = DtoType(type);
LLType* vartype = DtoType(type);
LLConstant* m = DtoTypeInfoOf(ti->tinfo, false);
if (m->getType() != getPtrToType(vartype))
m = llvm::ConstantExpr::getBitCast(m, vartype);
@@ -332,7 +329,7 @@ LLConstant* IntegerExp::toConstElem(IRState* p)
{
Logger::print("IntegerExp::toConstElem: %s @ %s\n", toChars(), type->toChars());
LOG_SCOPE;
const LLType* t = DtoType(type);
LLType* t = DtoType(type);
if (isaPointer(t)) {
Logger::println("pointer");
LLConstant* i = LLConstantInt::get(DtoSize_t(),(uint64_t)value,false);
@@ -382,7 +379,7 @@ LLConstant* NullExp::toConstElem(IRState* p)
{
Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars());
LOG_SCOPE;
const LLType* t = DtoType(type);
LLType* t = DtoType(type);
if (type->ty == Tarray) {
assert(isaStruct(t));
return llvm::ConstantAggregateZero::get(t);
@@ -441,9 +438,9 @@ DValue* StringExp::toElem(IRState* p)
Type* dtype = type->toBasetype();
Type* cty = dtype->nextOf()->toBasetype();
const LLType* ct = DtoTypeNotVoid(cty);
LLType* ct = DtoTypeNotVoid(cty);
//printf("ct = %s\n", type->nextOf()->toChars());
const LLArrayType* at = LLArrayType::get(ct,len+1);
LLArrayType* at = LLArrayType::get(ct,len+1);
LLConstant* _init;
if (cty->size() == 1) {
@@ -485,10 +482,10 @@ DValue* StringExp::toElem(IRState* p)
if (dtype->ty == Tarray) {
LLConstant* clen = LLConstantInt::get(DtoSize_t(),len,false);
return new DImValue(type, DtoConstSlice(clen, arrptr));
return new DImValue(type, DtoConstSlice(clen, arrptr, dtype));
}
else if (dtype->ty == Tsarray) {
const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
return new DVarValue(type, emem);
}
@@ -513,8 +510,8 @@ LLConstant* StringExp::toConstElem(IRState* p)
bool nullterm = (t->ty != Tsarray);
size_t endlen = nullterm ? len+1 : len;
const LLType* ct = DtoTypeNotVoid(cty);
const LLArrayType* at = LLArrayType::get(ct,endlen);
LLType* ct = DtoTypeNotVoid(cty);
LLArrayType* at = LLArrayType::get(ct,endlen);
LLConstant* _init;
if (cty->size() == 1) {
@@ -564,7 +561,7 @@ LLConstant* StringExp::toConstElem(IRState* p)
}
else if (t->ty == Tarray) {
LLConstant* clen = LLConstantInt::get(DtoSize_t(),len,false);
return DtoConstSlice(clen, arrptr);
return DtoConstSlice(clen, arrptr, type);
}
assert(0);
@@ -678,7 +675,7 @@ LLConstant* AddExp::toConstElem(IRState* p)
if (e1->type->ty == Tpointer && e2->type->isintegral()) {
LLConstant *ptr = e1->toConstElem(p);
LLConstant *index = e2->toConstElem(p);
ptr = llvm::ConstantExpr::getGetElementPtr(ptr, &index, 1);
ptr = llvm::ConstantExpr::getGetElementPtr(ptr, llvm::makeArrayRef(&index, 1));
return ptr;
}
@@ -730,7 +727,7 @@ LLConstant* MinExp::toConstElem(IRState* p)
LLConstant *ptr = e1->toConstElem(p);
LLConstant *index = e2->toConstElem(p);
index = llvm::ConstantExpr::getNeg(index);
ptr = llvm::ConstantExpr::getGetElementPtr(ptr, &index, 1);
ptr = llvm::ConstantExpr::getGetElementPtr(ptr, llvm::makeArrayRef(&index, 1));
return ptr;
}
@@ -938,6 +935,77 @@ DValue* CallExp::toElem(IRState* p)
if (expv->getType()->toBasetype()->ty != Tint32)
expv = DtoCast(loc, expv, Type::tint32);
return new DImValue(type, p->ir->CreateAlloca(LLType::getInt8Ty(gIR->context()), expv->getRVal(), ".alloca"));
// fence instruction
} else if (fndecl->llvmInternal == LLVMfence) {
gIR->ir->CreateFence(llvm::AtomicOrdering(((Expression*)arguments->data[0])->toInteger()));
return NULL;
// atomic store instruction
} else if (fndecl->llvmInternal == LLVMatomic_store) {
Expression* exp1 = (Expression*)arguments->data[0];
Expression* exp2 = (Expression*)arguments->data[1];
int atomicOrdering = ((Expression*)arguments->data[2])->toInteger();
LLValue* val = exp1->toElem(p)->getRVal();
LLValue* ptr = exp2->toElem(p)->getRVal();
llvm::StoreInst* ret = gIR->ir->CreateStore(val, ptr, "tmp");
ret->setAtomic(llvm::AtomicOrdering(atomicOrdering));
ret->setAlignment(exp1->type->alignsize());
return NULL;
// atomic load instruction
} else if (fndecl->llvmInternal == LLVMatomic_load) {
Expression* exp = (Expression*)arguments->data[0];
int atomicOrdering = ((Expression*)arguments->data[1])->toInteger();
LLValue* ptr = exp->toElem(p)->getRVal();
Type* retType = exp->type->nextOf();
llvm::LoadInst* val = gIR->ir->CreateLoad(ptr, "tmp");
val->setAlignment(retType->alignsize());
val->setAtomic(llvm::AtomicOrdering(atomicOrdering));
return new DImValue(retType, val);
// cmpxchg instruction
} else if (fndecl->llvmInternal == LLVMatomic_cmp_xchg) {
Expression* exp1 = (Expression*)arguments->data[0];
Expression* exp2 = (Expression*)arguments->data[1];
Expression* exp3 = (Expression*)arguments->data[2];
int atomicOrdering = ((Expression*)arguments->data[3])->toInteger();
LLValue* ptr = exp1->toElem(p)->getRVal();
LLValue* cmp = exp2->toElem(p)->getRVal();
LLValue* val = exp3->toElem(p)->getRVal();
LLValue* ret = gIR->ir->CreateAtomicCmpXchg(ptr, cmp, val, llvm::AtomicOrdering(atomicOrdering));
return new DImValue(exp3->type, ret);
// atomicrmw instruction
} else if (fndecl->llvmInternal == LLVMatomic_rmw) {
static char *ops[] = {
"xchg",
"add",
"sub",
"and",
"nand",
"or",
"xor",
"max",
"min",
"umax",
"umin",
0
};
int op = 0;
for (; ; ++op) {
if (ops[op] == 0) {
error("unknown atomic_rmw operation %s", fndecl->intrinsicName.c_str());
return NULL;
}
if (fndecl->intrinsicName == ops[op])
break;
}
Expression* exp1 = (Expression*)arguments->data[0];
Expression* exp2 = (Expression*)arguments->data[1];
int atomicOrdering = ((Expression*)arguments->data[2])->toInteger();
LLValue* ptr = exp1->toElem(p)->getRVal();
LLValue* val = exp2->toElem(p)->getRVal();
LLValue* ret = gIR->ir->CreateAtomicRMW(llvm::AtomicRMWInst::BinOp(op), ptr, val,
llvm::AtomicOrdering(atomicOrdering));
return new DImValue(exp2->type, ret);
}
}
return DtoCallFunction(loc, type, fnval, arguments);
@@ -974,7 +1042,7 @@ LLConstant* CastExp::toConstElem(IRState* p)
LOG_SCOPE;
LLConstant* res;
const LLType* lltype = DtoType(type);
LLType* lltype = DtoType(type);
Type* tb = to->toBasetype();
// string literal to dyn array:
@@ -1100,7 +1168,7 @@ LLConstant* AddrExp::toConstElem(IRState* p)
vd->codegen(Type::sir);
LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue());
assert(llc);
return llc;
return DtoBitCast(llc, DtoType(type));
}
// static function
else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration())
@@ -2073,7 +2141,7 @@ DValue* AndAndExp::toElem(IRState* p)
// No need to create a PHI node.
resval = ubool;
} else {
llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), "andandval");
llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), 2, "andandval");
// If we jumped over evaluation of the right-hand side,
// the result is false. Otherwise it's the value of the right-hand side.
phi->addIncoming(LLConstantInt::getFalse(gIR->context()), oldblock);
@@ -2120,7 +2188,7 @@ DValue* OrOrExp::toElem(IRState* p)
// No need to create a PHI node.
resval = ubool;
} else {
llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), "ororval");
llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), 2, "ororval");
// If we jumped over evaluation of the right-hand side,
// the result is true. Otherwise, it's the value of the right-hand side.
phi->addIncoming(LLConstantInt::getTrue(gIR->context()), oldblock);
@@ -2202,10 +2270,10 @@ DValue* DelegateExp::toElem(IRState* p)
if(func->isStatic())
error("can't take delegate of static function %s, it does not require a context ptr", func->toChars());
const LLPointerType* int8ptrty = getPtrToType(LLType::getInt8Ty(gIR->context()));
LLPointerType* int8ptrty = getPtrToType(LLType::getInt8Ty(gIR->context()));
assert(type->toBasetype()->ty == Tdelegate);
const LLType* dgty = DtoType(type);
LLType* dgty = DtoType(type);
DValue* u = e1->toElem(p);
LLValue* uval;
@@ -2251,7 +2319,7 @@ DValue* DelegateExp::toElem(IRState* p)
castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
return new DImValue(type, DtoAggrPair(castcontext, castfptr, ".dg"));
return new DImValue(type, DtoAggrPair(DtoType(type), castcontext, castfptr, ".dg"));
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2502,7 +2570,7 @@ DValue* FuncExp::toElem(IRState* p)
assert(fd->ir.irFunc->func);
if(fd->tok == TOKdelegate) {
const LLType* dgty = DtoType(type);
LLType* dgty = DtoType(type);
LLValue* cval;
IrFunction* irfn = p->func();
@@ -2582,13 +2650,13 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
size_t len = elements->dim;
// llvm target type
const LLType* llType = DtoType(arrayType);
LLType* llType = DtoType(arrayType);
if (Logger::enabled())
Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
// llvm storage type
const LLType* llElemType = DtoTypeNotVoid(elemType);
const LLType* llStoType = LLArrayType::get(llElemType, len);
LLType* llElemType = DtoTypeNotVoid(elemType);
LLType* llStoType = LLArrayType::get(llElemType, len);
if (Logger::enabled())
Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
@@ -2646,7 +2714,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
Type* elemt = bt->nextOf();
// build llvm array type
const LLArrayType* arrtype = LLArrayType::get(DtoTypeNotVoid(elemt), elements->dim);
LLArrayType* arrtype = LLArrayType::get(DtoTypeNotVoid(elemt), elements->dim);
// dynamic arrays can occur here as well ...
bool dyn = (bt->ty != Tsarray);
@@ -2660,7 +2728,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
}
// build the constant array initialize
const LLArrayType *t = elements->dim == 0 ?
LLArrayType *t = elements->dim == 0 ?
arrtype :
LLArrayType::get(vals.front()->getType(), elements->dim);
LLConstant* initval = LLConstantArray::get(t, vals);
@@ -2815,15 +2883,22 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
inits[i] = exprs[i]->toConstElem(p);
// vector of values to build aggregate from
std::vector<LLValue*> values = DtoStructLiteralValues(sd, inits);
std::vector<LLValue*> values = DtoStructLiteralValues(sd, inits, true);
// we know those values are constants.. cast them
std::vector<LLConstant*> constvals(values.size(), NULL);
for (size_t i = 0; i < values.size(); ++i)
std::vector<LLType*> types(values.size(), NULL);
for (size_t i = 0; i < values.size(); ++i) {
constvals[i] = llvm::cast<LLConstant>(values[i]);
types[i] = values[i]->getType();
}
// return constant struct
return LLConstantStruct::get(gIR->context(), constvals, sd->ir.irStruct->packed);
if (!constType)
constType = LLStructType::get(gIR->context(), types);
else
constType->setBody(types);
return LLConstantStruct::get(constType, llvm::makeArrayRef(constvals));
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2892,12 +2967,12 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
Type* indexType = ((TypeAArray*)aatype)->index;
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assocarrayliteralTX");
const llvm::FunctionType* funcTy = func->getFunctionType();
LLFunctionType* funcTy = func->getFunctionType();
LLValue* aaTypeInfo = DtoTypeInfoOf(stripModifiers(aatype));
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
const LLArrayType* arrtype = LLArrayType::get(DtoType(indexType), keys->dim);
LLArrayType* arrtype = LLArrayType::get(DtoType(indexType), keys->dim);
LLConstant* initval = LLConstantArray::get(arrtype, keysInits);
LLConstant* globalstore = new LLGlobalVariable(*gIR->module, arrtype, false, LLGlobalValue::InternalLinkage, initval, ".aaKeysStorage");
LLConstant* slice = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2);
@@ -2986,7 +3061,7 @@ DValue* TypeExp::toElem(IRState *p)
DValue* TupleExp::toElem(IRState *p)
{
Logger::print("TupleExp::toElem() %s\n", toChars());
std::vector<const LLType*> types(exps->dim, NULL);
std::vector<LLType*> types(exps->dim, NULL);
for (size_t i = 0; i < exps->dim; i++)
{
Expression *el = (Expression *)exps->data[i];

View File

@@ -51,7 +51,7 @@ unsigned DtoShouldExtend(Type* type)
return llvm::Attribute::None;
}
const LLType* DtoType(Type* t)
LLType* DtoType(Type* t)
{
t = stripModifiers( t );
@@ -177,12 +177,12 @@ const LLType* DtoType(Type* t)
//////////////////////////////////////////////////////////////////////////////////////////
/*
const LLType* DtoStructTypeFromArguments(Arguments* arguments)
LLType* DtoStructTypeFromArguments(Arguments* arguments)
{
if (!arguments)
return LLType::getVoidTy(gIR->context());
std::vector<const LLType*> types;
std::vector<LLType*> types;
for (size_t i = 0; i < arguments->dim; i++)
{
Argument *arg = (Argument *)arguments->data[i];
@@ -196,9 +196,9 @@ const LLType* DtoStructTypeFromArguments(Arguments* arguments)
//////////////////////////////////////////////////////////////////////////////////////////
const LLType* DtoTypeNotVoid(Type* t)
LLType* DtoTypeNotVoid(Type* t)
{
const LLType* lt = DtoType(t);
LLType* lt = DtoType(t);
if (lt == LLType::getVoidTy(gIR->context()))
return LLType::getInt8Ty(gIR->context());
return lt;
@@ -367,8 +367,8 @@ llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym)
LLValue* DtoPointedType(LLValue* ptr, LLValue* val)
{
const LLType* ptrTy = ptr->getType()->getContainedType(0);
const LLType* valTy = val->getType();
LLType* ptrTy = ptr->getType()->getContainedType(0);
LLType* valTy = val->getType();
// ptr points to val's type
if (ptrTy == valTy)
{
@@ -379,8 +379,8 @@ LLValue* DtoPointedType(LLValue* ptr, LLValue* val)
{
// val is integer
assert(valTy->isIntegerTy());
const LLIntegerType* pt = llvm::cast<const LLIntegerType>(ptrTy);
const LLIntegerType* vt = llvm::cast<const LLIntegerType>(valTy);
LLIntegerType* pt = llvm::cast<LLIntegerType>(ptrTy);
LLIntegerType* vt = llvm::cast<LLIntegerType>(valTy);
if (pt->getBitWidth() < vt->getBitWidth()) {
return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb());
}
@@ -399,10 +399,10 @@ LLValue* DtoPointedType(LLValue* ptr, LLValue* val)
//////////////////////////////////////////////////////////////////////////////////////////
const LLIntegerType* DtoSize_t()
LLIntegerType* DtoSize_t()
{
// the type of size_t does not change once set
static const LLIntegerType* t = NULL;
static LLIntegerType* t = NULL;
if (t == NULL)
t = (global.params.is64bit) ? LLType::getInt64Ty(gIR->context()) : LLType::getInt32Ty(gIR->context());
return t;
@@ -422,7 +422,7 @@ LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::B
LLSmallVector<LLValue*,2> v(2);
v[0] = i0;
v[1] = i1;
return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb());
return llvm::GetElementPtrInst::Create(ptr, v, var?var:"tmp", bb?bb:gIR->scopebb());
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -439,7 +439,7 @@ LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var, llvm::
LLSmallVector<LLValue*,2> v(2);
v[0] = DtoConstUint(i0);
v[1] = DtoConstUint(i1);
return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb());
return llvm::GetElementPtrInst::Create(ptr, v, var?var:"tmp", bb?bb:gIR->scopebb());
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -456,11 +456,11 @@ void DtoMemSet(LLValue* dst, LLValue* val, LLValue* nbytes)
{
dst = DtoBitCast(dst,getVoidPtrType());
const LLType* intTy = DtoSize_t();
const LLType *VoidPtrTy = getVoidPtrType();
const LLType *Tys[2] ={VoidPtrTy, intTy};
LLType* intTy = DtoSize_t();
LLType *VoidPtrTy = getVoidPtrType();
LLType *Tys[2] ={VoidPtrTy, intTy};
llvm::Function* fn = llvm::Intrinsic::getDeclaration(gIR->module,
llvm::Intrinsic::memset, Tys, 2);
llvm::Intrinsic::memset, llvm::makeArrayRef(Tys, 2));
gIR->ir->CreateCall5(fn, dst, val, nbytes, DtoConstUint(1), DtoConstBool(false), "");
}
@@ -479,11 +479,11 @@ void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes, unsigned align)
dst = DtoBitCast(dst,getVoidPtrType());
src = DtoBitCast(src,getVoidPtrType());
const LLType* intTy = DtoSize_t();
const LLType *VoidPtrTy = getVoidPtrType();
const LLType *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy};
LLType* intTy = DtoSize_t();
LLType *VoidPtrTy = getVoidPtrType();
LLType *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy};
llvm::Function* fn = llvm::Intrinsic::getDeclaration(gIR->module,
llvm::Intrinsic::memcpy, Tys, 3);
llvm::Intrinsic::memcpy, llvm::makeArrayRef(Tys, 3));
gIR->ir->CreateCall5(fn, dst, src, nbytes, DtoConstUint(align), DtoConstBool(false), "");
}
@@ -497,11 +497,11 @@ LLValue* DtoMemCmp(LLValue* lhs, LLValue* rhs, LLValue* nbytes)
LLFunction* fn = gIR->module->getFunction("memcmp");
if (!fn)
{
std::vector<const LLType*> params(3);
std::vector<LLType*> params(3);
params[0] = getVoidPtrType();
params[1] = getVoidPtrType();
params[2] = DtoSize_t();
const LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), params, false);
LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), params, false);
fn = LLFunction::Create(fty, LLGlobalValue::ExternalLinkage, "memcmp", gIR->module);
}
@@ -531,7 +531,8 @@ void DtoAggrCopy(LLValue* dst, LLValue* src)
void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device)
{
llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier);
// FIXME: implement me
/*llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier);
assert(fn != NULL);
LLSmallVector<LLValue*, 5> llargs;
@@ -541,7 +542,7 @@ void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device)
llargs.push_back(DtoConstBool(ss));
llargs.push_back(DtoConstBool(device));
llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
llvm::CallInst::Create(fn, llargs, "", gIR->scopebb());*/
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -569,7 +570,7 @@ llvm::ConstantInt* DtoConstUbyte(unsigned char i)
LLConstant* DtoConstFP(Type* t, long double value)
{
const LLType* llty = DtoType(t);
LLType* llty = DtoType(t);
assert(llty->isFloatingPointTy());
if(llty == LLType::getFloatTy(gIR->context()) || llty == LLType::getDoubleTy(gIR->context()))
@@ -595,7 +596,8 @@ LLConstant* DtoConstString(const char* str)
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
return DtoConstSlice(
DtoConstSize_t(s.size()),
llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2)
llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2),
Type::tchar->arrayOf()
);
}
LLConstant* DtoConstStringPtr(const char* str, const char* section)
@@ -646,7 +648,7 @@ void DtoAlignedStore(LLValue* src, LLValue* dst)
//////////////////////////////////////////////////////////////////////////////////////////
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name)
LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name)
{
if (v->getType() == t)
return v;
@@ -654,7 +656,7 @@ LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name)
return gIR->ir->CreateBitCast(v, t, name ? name : "tmp");
}
LLConstant* DtoBitCast(LLConstant* v, const LLType* t)
LLConstant* DtoBitCast(LLConstant* v, LLType* t)
{
if (v->getType() == t)
return v;
@@ -675,42 +677,42 @@ LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name)
//////////////////////////////////////////////////////////////////////////////////////////
const LLPointerType* isaPointer(LLValue* v)
LLPointerType* isaPointer(LLValue* v)
{
return llvm::dyn_cast<LLPointerType>(v->getType());
}
const LLPointerType* isaPointer(const LLType* t)
LLPointerType* isaPointer(LLType* t)
{
return llvm::dyn_cast<LLPointerType>(t);
}
const LLArrayType* isaArray(LLValue* v)
LLArrayType* isaArray(LLValue* v)
{
return llvm::dyn_cast<LLArrayType>(v->getType());
}
const LLArrayType* isaArray(const LLType* t)
LLArrayType* isaArray(LLType* t)
{
return llvm::dyn_cast<LLArrayType>(t);
}
const LLStructType* isaStruct(LLValue* v)
LLStructType* isaStruct(LLValue* v)
{
return llvm::dyn_cast<LLStructType>(v->getType());
}
const LLStructType* isaStruct(const LLType* t)
LLStructType* isaStruct(LLType* t)
{
return llvm::dyn_cast<LLStructType>(t);
}
const LLFunctionType* isaFunction(LLValue* v)
LLFunctionType* isaFunction(LLValue* v)
{
return llvm::dyn_cast<LLFunctionType>(v->getType());
}
const LLFunctionType* isaFunction(const LLType* t)
LLFunctionType* isaFunction(LLType* t)
{
return llvm::dyn_cast<LLFunctionType>(t);
}
@@ -737,73 +739,73 @@ llvm::GlobalVariable* isaGlobalVar(LLValue* v)
//////////////////////////////////////////////////////////////////////////////////////////
const LLPointerType* getPtrToType(const LLType* t)
LLPointerType* getPtrToType(LLType* t)
{
if (t == LLType::getVoidTy(gIR->context()))
t = LLType::getInt8Ty(gIR->context());
return LLPointerType::get(t, 0);
}
const LLPointerType* getVoidPtrType()
LLPointerType* getVoidPtrType()
{
return getPtrToType(LLType::getInt8Ty(gIR->context()));
}
llvm::ConstantPointerNull* getNullPtr(const LLType* t)
llvm::ConstantPointerNull* getNullPtr(LLType* t)
{
const LLPointerType* pt = llvm::cast<LLPointerType>(t);
LLPointerType* pt = llvm::cast<LLPointerType>(t);
return llvm::ConstantPointerNull::get(pt);
}
LLConstant* getNullValue(const LLType* t)
LLConstant* getNullValue(LLType* t)
{
return LLConstant::getNullValue(t);
}
//////////////////////////////////////////////////////////////////////////////////////////
size_t getTypeBitSize(const LLType* t)
size_t getTypeBitSize(LLType* t)
{
return gTargetData->getTypeSizeInBits(t);
}
size_t getTypeStoreSize(const LLType* t)
size_t getTypeStoreSize(LLType* t)
{
return gTargetData->getTypeStoreSize(t);
}
size_t getTypePaddedSize(const LLType* t)
size_t getTypePaddedSize(LLType* t)
{
size_t sz = gTargetData->getTypeAllocSize(t);
//Logger::cout() << "abi type size of: " << *t << " == " << sz << '\n';
return sz;
}
size_t getTypeAllocSize(const LLType* t)
size_t getTypeAllocSize(LLType* t)
{
return gTargetData->getTypeAllocSize(t);
}
unsigned char getABITypeAlign(const LLType* t)
unsigned char getABITypeAlign(LLType* t)
{
return gTargetData->getABITypeAlignment(t);
}
unsigned char getPrefTypeAlign(const LLType* t)
unsigned char getPrefTypeAlign(LLType* t)
{
return gTargetData->getPrefTypeAlignment(t);
}
const LLType* getBiggestType(const LLType** begin, size_t n)
LLType* getBiggestType(LLType** begin, size_t n)
{
const LLType* bigTy = 0;
LLType* bigTy = 0;
size_t bigSize = 0;
size_t bigAlign = 0;
const LLType** end = begin+n;
LLType** end = begin+n;
while (begin != end)
{
const LLType* T = *begin;
LLType* T = *begin;
size_t sz = getTypePaddedSize(T);
size_t ali = getABITypeAlign(T);
@@ -823,21 +825,21 @@ const LLType* getBiggestType(const LLType** begin, size_t n)
//////////////////////////////////////////////////////////////////////////////////////////
const LLStructType* DtoInterfaceInfoType()
LLStructType* DtoInterfaceInfoType()
{
if (gIR->interfaceInfoType)
return gIR->interfaceInfoType;
// build interface info type
std::vector<const LLType*> types;
std::vector<LLType*> types;
// ClassInfo classinfo
ClassDeclaration* cd2 = ClassDeclaration::classinfo;
DtoResolveClass(cd2);
types.push_back(DtoType(cd2->type));
// void*[] vtbl
std::vector<const LLType*> vtbltypes;
std::vector<LLType*> vtbltypes;
vtbltypes.push_back(DtoSize_t());
const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::getInt8Ty(gIR->context())));
LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::getInt8Ty(gIR->context())));
vtbltypes.push_back(byteptrptrty);
types.push_back(LLStructType::get(gIR->context(), vtbltypes));
// int offset
@@ -850,7 +852,7 @@ const LLStructType* DtoInterfaceInfoType()
//////////////////////////////////////////////////////////////////////////////////////////
const LLStructType* DtoMutexType()
LLStructType* DtoMutexType()
{
if (gIR->mutexType)
return gIR->mutexType;
@@ -859,7 +861,7 @@ const LLStructType* DtoMutexType()
if (global.params.os == OSWindows)
{
// CRITICAL_SECTION.sizeof == 68
std::vector<const LLType*> types(17, LLType::getInt32Ty(gIR->context()));
std::vector<LLType*> types(17, LLType::getInt32Ty(gIR->context()));
return LLStructType::get(gIR->context(), types);
}
@@ -870,50 +872,44 @@ const LLStructType* DtoMutexType()
}
// pthread_fastlock
std::vector<const LLType*> types2;
std::vector<LLType*> types2;
types2.push_back(DtoSize_t());
types2.push_back(LLType::getInt32Ty(gIR->context()));
const LLStructType* fastlock = LLStructType::get(gIR->context(), types2);
LLStructType* fastlock = LLStructType::get(gIR->context(), types2);
// pthread_mutex
std::vector<const LLType*> types1;
std::vector<LLType*> types1;
types1.push_back(LLType::getInt32Ty(gIR->context()));
types1.push_back(LLType::getInt32Ty(gIR->context()));
types1.push_back(getVoidPtrType());
types1.push_back(LLType::getInt32Ty(gIR->context()));
types1.push_back(fastlock);
const LLStructType* pmutex = LLStructType::get(gIR->context(), types1);
LLStructType* pmutex = LLStructType::get(gIR->context(), types1);
// D_CRITICAL_SECTION
LLOpaqueType* opaque = LLOpaqueType::get(gIR->context());
std::vector<const LLType*> types;
types.push_back(getPtrToType(opaque));
LLStructType* mutex = LLStructType::create(gIR->context(), "D_CRITICAL_SECTION");
std::vector<LLType*> types;
types.push_back(getPtrToType(mutex));
types.push_back(pmutex);
mutex->setBody(types);
gIR->mutexType = mutex;
// resolve type
pmutex = LLStructType::get(gIR->context(), types);
LLPATypeHolder pa(pmutex);
opaque->refineAbstractTypeTo(pa.get());
pmutex = isaStruct(pa.get());
gIR->mutexType = pmutex;
gIR->module->addTypeName("D_CRITICAL_SECTION", pmutex);
return pmutex;
}
//////////////////////////////////////////////////////////////////////////////////////////
const LLStructType* DtoModuleReferenceType()
LLStructType* DtoModuleReferenceType()
{
if (gIR->moduleRefType)
return gIR->moduleRefType;
// this is a recursive type so start out with the opaque
LLOpaqueType* opaque = LLOpaqueType::get(gIR->context());
// this is a recursive type so start out with a struct without body
LLStructType* st = LLStructType::create(gIR->context(), "ModuleReference");
// add members
std::vector<const LLType*> types;
types.push_back(getPtrToType(opaque));
std::vector<LLType*> types;
types.push_back(getPtrToType(st));
#if DMDV1
types.push_back(DtoType(Module::moduleinfo->type));
#else
@@ -921,20 +917,16 @@ const LLStructType* DtoModuleReferenceType()
#endif
// resolve type
const LLStructType* st = LLStructType::get(gIR->context(), types);
LLPATypeHolder pa(st);
opaque->refineAbstractTypeTo(pa.get());
st = isaStruct(pa.get());
st->setBody(types);
// done
gIR->moduleRefType = st;
gIR->module->addTypeName("ModuleReference", st);
return st;
}
//////////////////////////////////////////////////////////////////////////////////////////
LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name)
LLValue* DtoAggrPair(LLType* type, LLValue* V1, LLValue* V2, const char* name)
{
LLValue* res = llvm::UndefValue::get(type);
res = gIR->ir->CreateInsertValue(res, V1, 0, "tmp");
@@ -943,11 +935,14 @@ LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* n
LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name)
{
const LLType* t = LLStructType::get(gIR->context(), V1->getType(), V2->getType(), NULL);
llvm::SmallVector<LLType*, 2> types;
types.push_back(V1->getType());
types.push_back(V2->getType());
LLType* t = LLStructType::get(gIR->context(), types);
return DtoAggrPair(t, V1, V2, name);
}
LLValue* DtoAggrPaint(LLValue* aggr, const LLType* as)
LLValue* DtoAggrPaint(LLValue* aggr, LLType* as)
{
if (aggr->getType() == as)
return aggr;

View File

@@ -10,10 +10,10 @@
#include "gen/structs.h"
// D->LLVM type handling stuff
const LLType* DtoType(Type* t);
LLType* DtoType(Type* t);
// same as DtoType except it converts 'void' to 'i8'
const LLType* DtoTypeNotVoid(Type* t);
LLType* DtoTypeNotVoid(Type* t);
// returns true is the type must be passed by pointer
bool DtoIsPassedByRef(Type* type);
@@ -23,7 +23,7 @@ unsigned DtoShouldExtend(Type* type);
// tuple helper
// takes a arguments list and makes a struct type out of them
//const LLType* DtoStructTypeFromArguments(Arguments* arguments);
//LLType* DtoStructTypeFromArguments(Arguments* arguments);
// delegate helpers
LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs);
@@ -37,10 +37,10 @@ LLGlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym);
LLValue* DtoPointedType(LLValue* ptr, LLValue* val);
// some types
const LLIntegerType* DtoSize_t();
const LLStructType* DtoInterfaceInfoType();
const LLStructType* DtoMutexType();
const LLStructType* DtoModuleReferenceType();
LLIntegerType* DtoSize_t();
LLStructType* DtoInterfaceInfoType();
LLStructType* DtoMutexType();
LLStructType* DtoModuleReferenceType();
// getelementptr helpers
LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=0, llvm::BasicBlock* bb=NULL);
@@ -66,48 +66,48 @@ LLValue* DtoLoad(LLValue* src, const char* name=0);
LLValue* DtoAlignedLoad(LLValue* src, const char* name=0);
void DtoStore(LLValue* src, LLValue* dst);
void DtoAlignedStore(LLValue* src, LLValue* dst);
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
LLConstant* DtoBitCast(LLConstant* v, const LLType* t);
LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name=0);
LLConstant* DtoBitCast(LLConstant* v, LLType* t);
LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx, const char* name=0);
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name=0);
// llvm::dyn_cast wrappers
const LLPointerType* isaPointer(LLValue* v);
const LLPointerType* isaPointer(const LLType* t);
const LLArrayType* isaArray(LLValue* v);
const LLArrayType* isaArray(const LLType* t);
const LLStructType* isaStruct(LLValue* v);
const LLStructType* isaStruct(const LLType* t);
const LLFunctionType* isaFunction(LLValue* v);
const LLFunctionType* isaFunction(const LLType* t);
LLPointerType* isaPointer(LLValue* v);
LLPointerType* isaPointer(LLType* t);
LLArrayType* isaArray(LLValue* v);
LLArrayType* isaArray(LLType* t);
LLStructType* isaStruct(LLValue* v);
LLStructType* isaStruct(LLType* t);
LLFunctionType* isaFunction(LLValue* v);
LLFunctionType* isaFunction(LLType* t);
LLConstant* isaConstant(LLValue* v);
LLConstantInt* isaConstantInt(LLValue* v);
llvm::Argument* isaArgument(LLValue* v);
LLGlobalVariable* isaGlobalVar(LLValue* v);
// llvm::T::get(...) wrappers
const LLPointerType* getPtrToType(const LLType* t);
const LLPointerType* getVoidPtrType();
llvm::ConstantPointerNull* getNullPtr(const LLType* t);
LLConstant* getNullValue(const LLType* t);
LLPointerType* getPtrToType(LLType* t);
LLPointerType* getVoidPtrType();
llvm::ConstantPointerNull* getNullPtr(LLType* t);
LLConstant* getNullValue(LLType* t);
// type sizes
size_t getTypeBitSize(const LLType* t);
size_t getTypeStoreSize(const LLType* t);
size_t getTypePaddedSize(const LLType* t);
size_t getTypeAllocSize(const LLType* t);
size_t getTypeBitSize(LLType* t);
size_t getTypeStoreSize(LLType* t);
size_t getTypePaddedSize(LLType* t);
size_t getTypeAllocSize(LLType* t);
// type alignments
unsigned char getABITypeAlign(const LLType* t);
unsigned char getPrefTypeAlign(const LLType* t);
unsigned char getABITypeAlign(LLType* t);
unsigned char getPrefTypeAlign(LLType* t);
// get biggest type, for unions ...
const LLType* getBiggestType(const LLType** begin, size_t n);
LLType* getBiggestType(LLType** begin, size_t n);
// pair type helpers
LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name = 0);
LLValue* DtoAggrPair(LLType* type, LLValue* V1, LLValue* V2, const char* name = 0);
LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name = 0);
LLValue* DtoAggrPaint(LLValue* aggr, const LLType* as);
LLValue* DtoAggrPaint(LLValue* aggr, LLType* as);
LLValue* DtoAggrPairSwap(LLValue* aggr);
/**

View File

@@ -67,8 +67,8 @@ static llvm::cl::opt<bool> noVerify("noverify",
//////////////////////////////////////////////////////////////////////////////////////////
// fwd decl
void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out);
void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath);
void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out,
llvm::TargetMachine::CodeGenFileType fileType);
//////////////////////////////////////////////////////////////////////////////////////////
@@ -158,6 +158,12 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir)
}
}
// finilize debugging
#ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfModuleEnd();
#endif
// generate ModuleInfo
genmoduleinfo();
@@ -244,20 +250,17 @@ void writeModule(llvm::Module* m, std::string filename)
}
// write native assembly
if (global.params.output_s || global.params.output_o) {
if (global.params.output_s) {
LLPath spath = LLPath(filename);
spath.eraseSuffix();
spath.appendSuffix(std::string(global.s_ext));
if (!global.params.output_s) {
spath.createTemporaryFileOnDisk();
}
Logger::println("Writing native asm to: %s\n", spath.c_str());
std::string err;
{
llvm::raw_fd_ostream out(spath.c_str(), err);
if (err.empty())
{
write_asm_to_file(*gTargetMachine, *m, out);
emit_file(*gTargetMachine, *m, out, llvm::TargetMachine::CGFT_AssemblyFile);
}
else
{
@@ -265,15 +268,23 @@ void writeModule(llvm::Module* m, std::string filename)
fatal();
}
}
}
// call gcc to convert assembly to object file
if (global.params.output_o) {
LLPath objpath = LLPath(filename);
assemble(spath, objpath);
}
if (!global.params.output_s) {
spath.eraseFromDisk();
if (global.params.output_o) {
LLPath objpath = LLPath(filename);
Logger::println("Writing object file to: %s\n", objpath.c_str());
std::string err;
{
llvm::raw_fd_ostream out(objpath.c_str(), err);
if (err.empty())
{
emit_file(*gTargetMachine, *m, out, llvm::TargetMachine::CGFT_ObjectFile);
}
else
{
error("cannot write object file: %s", err.c_str());
fatal();
}
}
}
}
@@ -281,7 +292,8 @@ void writeModule(llvm::Module* m, std::string filename)
/* ================================================================== */
// based on llc code, University of Illinois Open Source License
void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out)
void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out,
llvm::TargetMachine::CodeGenFileType fileType)
{
using namespace llvm;
@@ -302,7 +314,7 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f
LastArg = CodeGenOpt::Aggressive;
llvm::formatted_raw_ostream fout(out);
if (Target.addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, LastArg))
if (Target.addPassesToEmitFile(Passes, fout, fileType, LastArg))
assert(0 && "no support for asm output");
Passes.doInitialization();
@@ -320,72 +332,6 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f
//assert(rmod);
}
/* ================================================================== */
// uses gcc to make an obj out of an assembly file
// based on llvm-ld code, University of Illinois Open Source License
void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath)
{
using namespace llvm;
sys::Path gcc = getGcc();
// Run GCC to assemble and link the program into native code.
//
// Note:
// We can't just assemble and link the file with the system assembler
// and linker because we don't know where to put the _start symbol.
// GCC mysteriously knows how to do it.
std::vector<std::string> args;
args.push_back(gcc.str());
args.push_back("-fno-strict-aliasing");
args.push_back("-O3");
args.push_back("-c");
args.push_back("-xassembler");
args.push_back(asmpath.str());
args.push_back("-o");
args.push_back(objpath.str());
//FIXME: only use this if needed?
args.push_back("-fpic");
//FIXME: enforce 64 bit
if (global.params.is64bit)
args.push_back("-m64");
else
// Assume 32-bit?
args.push_back("-m32");
// Now that "args" owns all the std::strings for the arguments, call the c_str
// method to get the underlying string array. We do this game so that the
// std::string array is guaranteed to outlive the const char* array.
std::vector<const char *> Args;
for (unsigned i = 0, e = args.size(); i != e; ++i)
Args.push_back(args[i].c_str());
Args.push_back(0);
if (Logger::enabled()) {
Logger::println("Assembling with: ");
std::vector<const char*>::const_iterator I = Args.begin(), E = Args.end();
Stream logstr = Logger::cout();
for (; I != E; ++I)
if (*I)
logstr << "'" << *I << "'" << " ";
logstr << "\n" << std::flush;
}
// Run the compiler to assembly the program.
std::string ErrMsg;
int R = sys::Program::ExecuteAndWait(
gcc, &Args[0], 0, 0, 0, 0, &ErrMsg);
if (R)
{
error("Failed to invoke gcc. %s", ErrMsg.c_str());
fatal();
}
}
/* ================================================================== */
static llvm::Function* build_module_function(const std::string &name, const std::list<FuncDeclaration*> &funcs,
@@ -399,8 +345,8 @@ static llvm::Function* build_module_function(const std::string &name, const std:
return funcs.front()->ir.irFunc->func;
}
std::vector<const LLType*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false);
std::vector<LLType*> argsTy;
LLFunctionType* fnTy = LLFunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false);
assert(gIR->module->getFunction(name) == NULL);
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
fn->setCallingConv(DtoCallingConv(0, LINKd));
@@ -498,7 +444,7 @@ static llvm::Function* build_module_shared_dtor()
static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
{
// build ctor type
const LLFunctionType* fty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<const LLType*>(), false);
LLFunctionType* fty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<LLType*>(), false);
// build ctor name
std::string fname = "_D";
@@ -509,7 +455,7 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
LLFunction* ctor = LLFunction::Create(fty, LLGlobalValue::InternalLinkage, fname, gIR->module);
// provide the default initializer
const LLStructType* modulerefTy = DtoModuleReferenceType();
LLStructType* modulerefTy = DtoModuleReferenceType();
std::vector<LLConstant*> mrefvalues;
mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0)));
mrefvalues.push_back(llvm::ConstantExpr::getBitCast(moduleinfo, modulerefTy->getContainedType(1)));
@@ -523,7 +469,7 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
// make sure _Dmodule_ref is declared
LLConstant* mref = gIR->module->getNamedGlobal("_Dmodule_ref");
const LLType *modulerefPtrTy = getPtrToType(modulerefTy);
LLType *modulerefPtrTy = getPtrToType(modulerefTy);
if (!mref)
mref = new LLGlobalVariable(*gIR->module, modulerefPtrTy, false, LLGlobalValue::ExternalLinkage, NULL, "_Dmodule_ref");
mref = DtoBitCast(mref, getPtrToType(modulerefPtrTy));
@@ -563,7 +509,7 @@ llvm::GlobalVariable* Module::moduleInfoSymbol()
MIname.append("8__ModuleZ");
if (gIR->dmodule != this) {
const LLType* moduleinfoTy = DtoType(moduleinfo->type);
LLType* moduleinfoTy = DtoType(moduleinfo->type);
LLGlobalVariable *var = gIR->module->getGlobalVariable(MIname);
if (!var)
var = new llvm::GlobalVariable(*gIR->module, moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
@@ -575,7 +521,7 @@ llvm::GlobalVariable* Module::moduleInfoSymbol()
// declare global
// flags will be modified at runtime so can't make it constant
moduleInfoVar = new llvm::GlobalVariable(*gIR->module, moduleInfoType->get(), false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
moduleInfoVar = new llvm::GlobalVariable(*gIR->module, moduleInfoType, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
return moduleInfoVar;
}
@@ -630,8 +576,8 @@ void Module::genmoduleinfo()
RTTIBuilder b(moduleinfo);
// some types
const LLType* moduleinfoTy = moduleinfo->type->irtype->getPA();
const LLType* classinfoTy = ClassDeclaration::classinfo->type->irtype->getPA();
LLType* moduleinfoTy = moduleinfo->type->irtype->getType();
LLType* classinfoTy = ClassDeclaration::classinfo->type->irtype->getType();
// name
b.push_string(toPrettyChars());
@@ -656,7 +602,7 @@ void Module::genmoduleinfo()
// has import array?
if (!importInits.empty())
{
const llvm::ArrayType* importArrTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size());
llvm::ArrayType* importArrTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size());
c = LLConstantArray::get(importArrTy, importInits);
std::string m_name("_D");
m_name.append(mangle());
@@ -707,7 +653,7 @@ void Module::genmoduleinfo()
// has class array?
if (!classInits.empty())
{
const llvm::ArrayType* classArrTy = llvm::ArrayType::get(getPtrToType(classinfoTy), classInits.size());
llvm::ArrayType* classArrTy = llvm::ArrayType::get(getPtrToType(classinfoTy), classInits.size());
c = LLConstantArray::get(classArrTy, classInits);
std::string m_name("_D");
m_name.append(mangle());
@@ -726,7 +672,7 @@ void Module::genmoduleinfo()
b.push_uint(mi_flags);
// function pointer type for next three fields
const LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<const LLType*>(), false));
LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<LLType*>(), false));
// ctor
#if DMDV2
@@ -772,7 +718,7 @@ void Module::genmoduleinfo()
b.push(c);
// index + reserved void*[1]
const LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 2);
LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 2);
c = getNullValue(AT);
b.push(c);
@@ -787,19 +733,17 @@ void Module::genmoduleinfo()
}*/
// create and set initializer
LLConstant* constMI = b.get_constant();
llvm::cast<llvm::OpaqueType>(moduleInfoType->get())->refineAbstractTypeTo(constMI->getType());
moduleInfoSymbol()->setInitializer(constMI);
b.finalize(moduleInfoType, moduleInfoSymbol());
// build the modulereference and ctor for registering it
LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol());
// register this ctor in the magic llvm.global_ctors appending array
const LLFunctionType* magicfty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<const LLType*>(), false);
std::vector<const LLType*> magictypes;
LLFunctionType* magicfty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<LLType*>(), false);
std::vector<LLType*> magictypes;
magictypes.push_back(LLType::getInt32Ty(gIR->context()));
magictypes.push_back(getPtrToType(magicfty));
const LLStructType* magicsty = LLStructType::get(gIR->context(), magictypes);
LLStructType* magicsty = LLStructType::get(gIR->context(), magictypes);
// make the constant element
std::vector<LLConstant*> magicconstants;
@@ -808,7 +752,7 @@ void Module::genmoduleinfo()
LLConstant* magicinit = LLConstantStruct::get(magicsty, magicconstants);
// declare the appending array
const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(magicsty, 1);
llvm::ArrayType* appendArrTy = llvm::ArrayType::get(magicsty, 1);
std::vector<LLConstant*> appendInits(1, magicinit);
LLConstant* appendInit = LLConstantArray::get(appendArrTy, appendInits);
std::string appendName("llvm.global_ctors");

View File

@@ -303,12 +303,16 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
LOG_SCOPE;
IrGlobal* irg = new IrGlobal(tid);
if (tid->tinfo->builtinTypeInfo()) // this is a declaration of a builtin __initZ var
irg->type = Type::typeinfo->type->irtype->getType();
else
irg->type = LLStructType::create(gIR->context(), tid->toPrettyChars());
std::string mangle(tid->mangle());
irg->value = gIR->module->getGlobalVariable(mangle);
if (!irg->value)
irg->value = new llvm::GlobalVariable(*gIR->module, irg->type.get(), true,
irg->value = new llvm::GlobalVariable(*gIR->module, irg->type, true,
TYPEINFO_LINKAGE_TYPE, NULL, mangle);
tid->ir.irGlobal = irg;
@@ -360,9 +364,6 @@ void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
// this is a declaration of a builtin __initZ var
if (tid->tinfo->builtinTypeInfo()) {
// fixup the global
const llvm::Type* rty = Type::typeinfo->type->irtype->getPA();
llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
LLGlobalVariable* g = isaGlobalVar(irg->value);
g->setLinkage(llvm::GlobalValue::ExternalLinkage);
return;
@@ -446,7 +447,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
// otherwise emit a void[] with the default initializer
else
{
const LLType* memty = DtoType(sd->memtype);
LLType* memty = DtoType(sd->memtype);
#if DMDV2
LLConstant* C = LLConstantInt::get(memty, sd->defaultval->toInteger(), !sd->memtype->isunsigned());
#else
@@ -611,7 +612,7 @@ void TypeInfoStructDeclaration::llvmDefine()
// void[] init
// never emit a null array, even for zero initialized typeinfo
// the size() method uses this array!
size_t init_size = getTypeStoreSize(tc->irtype->getPA());
size_t init_size = getTypeStoreSize(tc->irtype->getType());
b.push_void_array(init_size, irstruct->getInitSymbol());
// toX functions ground work
@@ -802,7 +803,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
std::vector<LLConstant*> arrInits;
arrInits.reserve(dim);
const LLType* tiTy = DtoType(Type::typeinfo->type);
LLType* tiTy = DtoType(Type::typeinfo->type);
for (size_t i = 0; i < dim; i++)
{
@@ -811,7 +812,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
}
// build array
const LLArrayType* arrTy = LLArrayType::get(tiTy, dim);
LLArrayType* arrTy = LLArrayType::get(tiTy, dim);
LLConstant* arrC = LLConstantArray::get(arrTy, arrInits);
RTTIBuilder b(Type::typeinfotypelist);

View File

@@ -38,7 +38,7 @@ LLGlobalVariable * IrStruct::getVtblSymbol()
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl);
const LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl();
LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl();
vtbl = new llvm::GlobalVariable(
*gIR->module, vtblTy, true, _linkage, NULL, initname);
@@ -71,15 +71,15 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol()
// classinfos cannot be constants since they're used a locks for synchronized
classInfo = new llvm::GlobalVariable(
*gIR->module, tc->getPA().get(), false, _linkage, NULL, initname);
*gIR->module, tc->getType(), false, _linkage, NULL, initname);
#if USE_METADATA
// Generate some metadata on this ClassInfo if it's for a class.
ClassDeclaration* classdecl = aggrdecl->isClassDeclaration();
if (classdecl && !aggrdecl->isInterfaceDeclaration()) {
// Gather information
const LLType* type = DtoType(aggrdecl->type);
const LLType* bodyType = llvm::cast<LLPointerType>(type)->getElementType();
LLType* type = DtoType(aggrdecl->type);
LLType* bodyType = llvm::cast<LLPointerType>(type)->getElementType();
bool hasDestructor = (classdecl->dtor != NULL);
bool hasCustomDelete = (classdecl->aggDelete != NULL);
// Construct the fields
@@ -112,10 +112,10 @@ LLGlobalVariable * IrStruct::getInterfaceArraySymbol()
"don't implement any interfaces");
VarDeclarationIter idx(ClassDeclaration::classinfo->fields, 3);
const llvm::Type* InterfaceTy = DtoType(idx->type->nextOf());
LLType* InterfaceTy = DtoType(idx->type->nextOf());
// create Interface[N]
const llvm::ArrayType* array_type = llvm::ArrayType::get(InterfaceTy,n);
LLArrayType* array_type = llvm::ArrayType::get(InterfaceTy,n);
// put it in a global
std::string name("_D");
@@ -202,17 +202,18 @@ LLConstant * IrStruct::getVtblInit()
}
// build the constant struct
constVtbl = LLConstantStruct::get(gIR->context(), constants, false);
LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl();
constVtbl = LLConstantStruct::get(isaStruct(vtblTy), constants);
#if 0
IF_LOG Logger::cout() << "constVtbl type: " << *constVtbl->getType() << std::endl;
IF_LOG Logger::cout() << "vtbl type: " << *stripModifiers(type)->irtype->isClass()->getVtbl() << std::endl;
#endif
#if 1
#if 0
size_t nc = constants.size();
const LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl();
for (size_t i = 0; i < nc; ++i)
{
if (constVtbl->getOperand(i)->getType() != vtblTy->getContainedType(i))
@@ -220,7 +221,7 @@ LLConstant * IrStruct::getVtblInit()
Logger::cout() << "type mismatch for entry # " << i << " in vtbl initializer" << std::endl;
constVtbl->getOperand(i)->dump();
vtblTy->getContainedType(i)->dump(gIR->module);
vtblTy->getContainedType(i)->dump();
}
}
@@ -307,18 +308,11 @@ void IrStruct::addBaseClassInits(
inter_idx++;
}
}
// tail padding?
if (offset < base->structsize)
{
add_zeros(constants, base->structsize - offset);
offset = base->structsize;
}
}
//////////////////////////////////////////////////////////////////////////////
LLConstant * IrStruct::createClassDefaultInitializer()
std::vector<llvm::Constant*> IrStruct::createClassDefaultInitializer()
{
ClassDeclaration* cd = aggrdecl->isClassDeclaration();
assert(cd && "invalid class aggregate");
@@ -345,10 +339,11 @@ LLConstant * IrStruct::createClassDefaultInitializer()
// add data members recursively
addBaseClassInits(constants, cd, offset, field_index);
// build the constant
llvm::Constant* definit = LLConstantStruct::get(gIR->context(), constants, false);
// tail padding?
if (offset < cd->structsize)
add_zeros(constants, cd->structsize - offset);
return definit;
return constants;
}
//////////////////////////////////////////////////////////////////////////////
@@ -413,7 +408,7 @@ llvm::GlobalVariable * IrStruct::getInterfaceVtbl(BaseClass * b, bool new_instan
}
// build the vtbl constant
llvm::Constant* vtbl_constant = LLConstantStruct::get(gIR->context(), constants, false);
llvm::Constant* vtbl_constant = LLConstantStruct::getAnon(gIR->context(), constants, false);
// create the global variable to hold it
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl);
@@ -470,9 +465,12 @@ LLConstant * IrStruct::getClassInfoInterfaces()
LLSmallVector<LLConstant*, 6> constants;
constants.reserve(cd->vtblInterfaces->dim);
const LLType* classinfo_type = DtoType(ClassDeclaration::classinfo->type);
const LLType* voidptrptr_type = DtoType(
LLType* classinfo_type = DtoType(ClassDeclaration::classinfo->type);
LLType* voidptrptr_type = DtoType(
Type::tvoid->pointerTo()->pointerTo());
VarDeclarationIter idx(ClassDeclaration::classinfo->fields, 3);
LLStructType* interface_type = isaStruct(DtoType(idx->type->nextOf()));
assert(interface_type);
for (size_t i = 0; i < n; ++i)
{
@@ -510,21 +508,15 @@ LLConstant * IrStruct::getClassInfoInterfaces()
// create Interface struct
LLConstant* inits[3] = { ci, vtb, off };
LLConstant* entry = LLConstantStruct::get(gIR->context(), inits, 3, false);
LLConstant* entry = LLConstantStruct::get(interface_type, llvm::makeArrayRef(inits, 3));
constants.push_back(entry);
}
// create Interface[N]
const llvm::ArrayType* array_type = llvm::ArrayType::get(
constants[0]->getType(),
n);
LLArrayType* array_type = llvm::ArrayType::get(interface_type, n);
LLConstant* arr = LLConstantArray::get(
array_type,
&constants[0],
n);
// apply the initializer
// create and apply initializer
LLConstant* arr = LLConstantArray::get(array_type, constants);
classInterfacesArray->setInitializer(arr);
// return null, only baseclass provide interfaces

View File

@@ -89,7 +89,7 @@ struct IrFunction : IrBase
llvm::Value* nestArg; // nested function 'this' arg
llvm::Value* nestedVar; // nested var alloca
const llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array)
llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array)
// 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;

View File

@@ -23,7 +23,7 @@ struct IrFuncTyArg : IrBase
Type* type;
/// This is the final LLVM Type used for the parameter/return value type
const llvm::Type* ltype;
llvm::Type* ltype;
/** These are the final LLVM attributes used for the function.
* Must be valid for the LLVM Type and byref setting */

View File

@@ -105,57 +105,20 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB)
IRScope savedscope = gIR->scope();
gIR->scope() = IRScope(inBB,savedscope.end);
// eh_ptr = llvm.eh.exception();
llvm::Function* eh_exception_fn = GET_INTRINSIC_DECL(eh_exception);
LLValue* eh_ptr = gIR->ir->CreateCall(eh_exception_fn);
// build selector arguments
LLSmallVector<LLValue*, 6> selectorargs;
// put in classinfos in the right order
bool hasFinally = false;
bool hasCatch = false;
std::deque<IRLandingPadInfo>::iterator it = infos.begin(), end = infos.end();
for(; it != end; ++it)
{
if(it->finallyBody)
hasFinally = true;
else
{
hasCatch = true;
assert(it->catchType);
assert(it->catchType->ir.irStruct);
selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol());
}
}
// if there's a finally, the eh table has to have a 0 action
if(hasFinally)
selectorargs.push_back(DtoConstUint(0));
// personality fn
llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality");
LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context())));
selectorargs.insert(selectorargs.begin(), personality_fn_arg);
// create landingpad
LLType *retType = LLStructType::get(LLType::getInt8PtrTy(gIR->context()), LLType::getInt32Ty(gIR->context()), NULL);
llvm::LandingPadInst *landingPad = gIR->ir->CreateLandingPad(retType, personality_fn, 0);
LLValue* eh_ptr = DtoExtractValue(landingPad, 0);
LLValue* eh_sel = DtoExtractValue(landingPad, 1);
// eh storage target
selectorargs.insert(selectorargs.begin(), eh_ptr);
// if there is a catch and some catch allocated storage, store exception object
if(hasCatch && catch_var)
{
const LLType* objectTy = DtoType(ClassDeclaration::object->type);
gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var);
}
// eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>);
llvm::Function* eh_selector_fn = GET_INTRINSIC_DECL(eh_selector);
LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end());
// emit finallys and 'if' chain to catch the exception
// add landingpad clauses, emit finallys and 'if' chain to catch the exception
llvm::Function* eh_typeid_for_fn = GET_INTRINSIC_DECL(eh_typeid_for);
std::deque<IRLandingPadInfo> infos = this->infos;
std::stack<size_t> nInfos = this->nInfos;
std::deque<IRLandingPadInfo>::reverse_iterator rit, rend = infos.rend();
bool isFirstCatch = true;
for(rit = infos.rbegin(); rit != rend; ++rit)
{
// if it's a finally, emit its code
@@ -165,14 +128,28 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB)
this->infos.resize(n);
this->nInfos.pop();
rit->finallyBody->toIR(gIR);
landingPad->setCleanup(true);
}
// otherwise it's a catch and we'll add a if-statement
else
{
// if it is a first catch and some catch allocated storage, store exception object
if(isFirstCatch && catch_var)
{
LLType* objectTy = DtoType(ClassDeclaration::object->type);
gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var);
isFirstCatch = false;
}
// create next block
llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend());
LLValue *classInfo = DtoBitCast(rit->catchType->ir.irStruct->getClassInfoSymbol(),
getPtrToType(DtoType(Type::tint8)));
// get class info symbol
LLValue *classInfo = rit->catchType->ir.irStruct->getClassInfoSymbol();
// add that symbol as landing pad clause
landingPad->addClause(classInfo);
// call llvm.eh.typeid.for to get class info index in the exception table
classInfo = DtoBitCast(classInfo, getPtrToType(DtoType(Type::tint8)));
LLValue *eh_id = gIR->ir->CreateCall(eh_typeid_for_fn, classInfo);
// check exception selector (eh_sel) against the class info index
gIR->ir->CreateCondBr(gIR->ir->CreateICmpEQ(eh_sel, eh_id), rit->target, next);
gIR->scope() = IRScope(next, gIR->scopeend());
}
@@ -187,6 +164,7 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB)
gIR->ir->CreateCall(unwind_resume_fn, eh_ptr);
gIR->ir->CreateUnreachable();
// restore scope
gIR->scope() = savedscope;
}

View File

@@ -20,7 +20,7 @@
IrStruct::IrStruct(AggregateDeclaration* aggr)
: diCompositeType(NULL),
init_pa(llvm::OpaqueType::get(gIR->context()))
init_type(LLStructType::create(gIR->context(), std::string(aggr->toPrettyChars()) + "_init"))
{
aggrdecl = aggr;
@@ -58,7 +58,7 @@ LLGlobalVariable * IrStruct::getInitSymbol()
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl);
init = new llvm::GlobalVariable(
*gIR->module, init_pa.get(), true, _linkage, NULL, initname);
*gIR->module, init_type, true, _linkage, NULL, initname);
// set alignment
init->setAlignment(type->alignsize());
@@ -73,17 +73,20 @@ llvm::Constant * IrStruct::getDefaultInit()
if (constInit)
return constInit;
if (type->ty == Tstruct)
{
constInit = createStructDefaultInitializer();
}
else
{
constInit = createClassDefaultInitializer();
}
std::vector<LLConstant*> constants = type->ty == Tstruct ?
createStructDefaultInitializer() :
createClassDefaultInitializer();
llvm::OpaqueType* o = llvm::cast<llvm::OpaqueType>(init_pa.get());
o->refineAbstractTypeTo(constInit->getType());
// set initializer type body
std::vector<LLType*> types;
std::vector<LLConstant*>::iterator itr = constants.begin(), end = constants.end();
for (; itr != end; ++itr)
types.push_back((*itr)->getType());
init_type->setBody(types, packed);
// build constant struct
constInit = LLConstantStruct::get(init_type, constants);
IF_LOG Logger::cout() << "final default initializer: " << *constInit << std::endl;
return constInit;
}
@@ -142,7 +145,7 @@ size_t add_zeros(std::vector<llvm::Constant*>& constants, size_t diff)
// Matches the way the type is built in IrTypeStruct
// maybe look at unifying the interface.
LLConstant * IrStruct::createStructDefaultInitializer()
std::vector<llvm::Constant*> IrStruct::createStructDefaultInitializer()
{
IF_LOG Logger::println("Building default initializer for %s", aggrdecl->toPrettyChars());
LOG_SCOPE;
@@ -195,13 +198,7 @@ LLConstant * IrStruct::createStructDefaultInitializer()
add_zeros(constants, aggrdecl->structsize - offset);
}
// build constant struct
llvm::Constant* definit = LLConstantStruct::get(gIR->context(), constants, packed);
#if 0
IF_LOG Logger::cout() << "final default initializer: " << *definit << std::endl;
#endif
return definit;
return constants;
}
//////////////////////////////////////////////////////////////////////////////
@@ -383,9 +380,22 @@ LLConstant * IrStruct::createStructInitializer(StructInitializer * si)
add_zeros(constants, diff);
}
// get initializer type
LLStructType* &ltype = si->ltype;
if (!ltype || ltype->isOpaque()) {
std::vector<LLConstant*>::iterator itr, end = constants.end();
std::vector<LLType*> types;
for (itr = constants.begin(); itr != end; ++itr)
types.push_back((*itr)->getType());
if (!ltype)
ltype = LLStructType::get(gIR->context(), types);
else
ltype->setBody(types);
}
// build constant
assert(!constants.empty());
llvm::Constant* c = LLConstantStruct::get(gIR->context(), &constants[0], constants.size(), packed);
llvm::Constant* c = LLConstantStruct::get(ltype, constants);
IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl;
return c;
}

View File

@@ -65,19 +65,19 @@ struct IrStruct : IrBase
//////////////////////////////////////////////////////////////////////////
protected:
/// Static default initializer global.
llvm::GlobalVariable* init;
LLGlobalVariable* init;
/// Static default initializer constant.
LLConstant* constInit;
/// Static default initialier type holder.
llvm::PATypeHolder init_pa;
/// Static default initialier type.
LLStructType* init_type;
/// Vtbl global.
llvm::GlobalVariable* vtbl;
LLGlobalVariable* vtbl;
/// Vtbl initializer constant.
LLConstant* constVtbl;
/// ClassInfo global.
llvm::GlobalVariable* classInfo;
LLGlobalVariable* classInfo;
/// ClassInfo initializer constant.
LLConstant* constClassInfo;
@@ -102,10 +102,10 @@ protected:
//////////////////////////////////////////////////////////////////////////
/// Create static default initializer for struct.
LLConstant* createStructDefaultInitializer();
std::vector<llvm::Constant*> createStructDefaultInitializer();
/// Create static default initializer for class.
LLConstant* createClassDefaultInitializer();
std::vector<llvm::Constant*> createClassDefaultInitializer();
/// Returns vtbl for interface implementation, creates it if not already built.
llvm::GlobalVariable* getInterfaceVtbl(

View File

@@ -11,14 +11,14 @@
//////////////////////////////////////////////////////////////////////////////
extern const llvm::Type* DtoType(Type* dt);
extern const llvm::Type* DtoSize_t();
extern LLType* DtoType(Type* dt);
extern LLType* DtoSize_t();
//////////////////////////////////////////////////////////////////////////////
IrType::IrType(Type* dt, const llvm::Type* lt)
IrType::IrType(Type* dt, LLType* lt)
: dtype(dt),
pa(lt)
type(lt)
{
assert(dt && "null D Type");
assert(lt && "null LLVM Type");
@@ -39,16 +39,26 @@ IrTypeBasic::IrTypeBasic(Type * dt)
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeBasic::buildType()
llvm::Type * IrTypeBasic::buildType()
{
return pa.get();
return type;
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeBasic::basic2llvm(Type* t)
LLType* IrTypeBasic::getComplexType(llvm::LLVMContext& ctx, LLType* type)
{
const llvm::Type* t2;
llvm::SmallVector<LLType*, 2> types;
types.push_back(type);
types.push_back(type);
return llvm::StructType::get(ctx, types);
}
//////////////////////////////////////////////////////////////////////////////
llvm::Type * IrTypeBasic::basic2llvm(Type* t)
{
LLType* t2;
llvm::LLVMContext& ctx = llvm::getGlobalContext();
@@ -99,19 +109,20 @@ const llvm::Type * IrTypeBasic::basic2llvm(Type* t)
else
return llvm::Type::getDoubleTy(ctx);
case Tcomplex32:
case Tcomplex32: {
t2 = llvm::Type::getFloatTy(ctx);
return llvm::StructType::get(ctx, t2, t2, NULL);
return getComplexType(ctx, t2);
}
case Tcomplex64:
t2 = llvm::Type::getDoubleTy(ctx);
return llvm::StructType::get(ctx, t2, t2, NULL);
return getComplexType(ctx, t2);
case Tcomplex80:
t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64)
? llvm::Type::getX86_FP80Ty(ctx)
: llvm::Type::getDoubleTy(ctx);
return llvm::StructType::get(ctx, t2, t2, NULL);
return getComplexType(ctx, t2);
case Tbool:
return llvm::Type::getInt1Ty(ctx);
@@ -126,26 +137,24 @@ const llvm::Type * IrTypeBasic::basic2llvm(Type* t)
//////////////////////////////////////////////////////////////////////////////
IrTypePointer::IrTypePointer(Type * dt)
: IrType(dt, llvm::OpaqueType::get(llvm::getGlobalContext()))
: IrType(dt, pointer2llvm(dt))
{
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypePointer::buildType()
llvm::Type * IrTypePointer::buildType()
{
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(
pointer2llvm(dtype));
return pa.get();
return type;
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypePointer::pointer2llvm(Type * dt)
llvm::Type * IrTypePointer::pointer2llvm(Type * dt)
{
assert(dt->ty == Tpointer && "not pointer type");
const llvm::Type* elemType = DtoType(dt->nextOf());
LLType* elemType = DtoType(dt->nextOf());
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
return llvm::PointerType::get(elemType, 0);
@@ -156,27 +165,25 @@ const llvm::Type * IrTypePointer::pointer2llvm(Type * dt)
//////////////////////////////////////////////////////////////////////////////
IrTypeSArray::IrTypeSArray(Type * dt)
: IrType(dt, llvm::OpaqueType::get(llvm::getGlobalContext()))
: IrType(dt, sarray2llvm(dt))
{
assert(dt->ty == Tsarray && "not static array type");
TypeSArray* tsa = (TypeSArray*)dt;
}
//////////////////////////////////////////////////////////////////////////////
llvm::Type * IrTypeSArray::buildType()
{
return type;
}
//////////////////////////////////////////////////////////////////////////////
llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
{
assert(t->ty == Tsarray && "not static array type");
TypeSArray* tsa = (TypeSArray*)t;
dim = (uint64_t)tsa->dim->toUInteger();
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeSArray::buildType()
{
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(
sarray2llvm(dtype));
return pa.get();
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
{
const llvm::Type* elemType = DtoType(t->nextOf());
LLType* elemType = DtoType(t->nextOf());
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
return llvm::ArrayType::get(elemType, dim == 0 ? 1 : dim);
@@ -187,36 +194,34 @@ const llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
//////////////////////////////////////////////////////////////////////////////
IrTypeArray::IrTypeArray(Type * dt)
: IrType(dt, llvm::OpaqueType::get(llvm::getGlobalContext()))
: IrType(dt, array2llvm(dt))
{
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeArray::buildType()
llvm::Type * IrTypeArray::buildType()
{
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(
array2llvm(dtype));
return pa.get();
return type;
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeArray::array2llvm(Type * t)
llvm::Type * IrTypeArray::array2llvm(Type * t)
{
assert(t->ty == Tarray && "not dynamic array type");
// get .ptr type
const llvm::Type* elemType = DtoType(t->nextOf());
LLType* elemType = DtoType(t->nextOf());
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
elemType = llvm::PointerType::get(elemType, 0);
// create struct type
const llvm::Type* at = llvm::StructType::get(llvm::getGlobalContext(), DtoSize_t(), elemType, NULL);
// name dynamic array types
Type::sir->getState()->module->addTypeName(t->toChars(), at);
llvm::SmallVector<LLType*, 2> types;
types.push_back(DtoSize_t());
types.push_back(elemType);
LLType* at = llvm::StructType::get(llvm::getGlobalContext(), types/*, t->toChars()*/);
return at;
}

View File

@@ -26,7 +26,7 @@ class IrType
{
public:
///
IrType(Type* dt, const llvm::Type* lt);
IrType(Type* dt, llvm::Type* lt);
///
virtual IrTypeAggr* isAggr() { return NULL; }
@@ -50,19 +50,19 @@ public:
///
Type* getD() { return dtype; }
///
virtual const llvm::Type* get() { return pa.get(); }
virtual llvm::Type* get() { return type; }
///
llvm::PATypeHolder& getPA() { return pa; }
llvm::Type* getType() { return type; }
///
virtual const llvm::Type* buildType() = 0;
virtual llvm::Type* buildType() = 0;
protected:
///
Type* dtype;
/// LLVM type holder.
llvm::PATypeHolder pa;
/// LLVM type.
llvm::Type* type;
};
//////////////////////////////////////////////////////////////////////////////
@@ -78,11 +78,13 @@ public:
IrTypeBasic* isBasic() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
protected:
///
const llvm::Type* basic2llvm(Type* t);
LLType* getComplexType(llvm::LLVMContext& ctx, LLType* type);
///
llvm::Type* basic2llvm(Type* t);
};
//////////////////////////////////////////////////////////////////////////////
@@ -98,11 +100,11 @@ public:
IrTypePointer* isPointer() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
protected:
///
const llvm::Type* pointer2llvm(Type* t);
llvm::Type* pointer2llvm(Type* t);
};
//////////////////////////////////////////////////////////////////////////////
@@ -118,11 +120,11 @@ public:
IrTypeSArray* isSArray() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
protected:
///
const llvm::Type* sarray2llvm(Type* t);
llvm::Type* sarray2llvm(Type* t);
/// Dimension.
uint64_t dim;
@@ -141,11 +143,11 @@ public:
IrTypeArray* isArray() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
protected:
///
const llvm::Type* array2llvm(Type* t);
llvm::Type* array2llvm(Type* t);
};
//////////////////////////////////////////////////////////////////////////////

View File

@@ -14,7 +14,7 @@
//////////////////////////////////////////////////////////////////////////////
extern size_t add_zeros(std::vector<const llvm::Type*>& defaultTypes, size_t diff);
extern size_t add_zeros(std::vector<llvm::Type*>& defaultTypes, size_t diff);
extern bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v2);
//////////////////////////////////////////////////////////////////////////////
@@ -22,9 +22,11 @@ extern bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v
IrTypeClass::IrTypeClass(ClassDeclaration* cd)
: IrTypeAggr(cd),
cd(cd),
tc((TypeClass*)cd->type),
vtbl_pa(llvm::OpaqueType::get(gIR->context()))
tc((TypeClass*)cd->type)
{
std::string vtbl_name(cd->toPrettyChars());
vtbl_name.append(".__vtbl");
vtbl_type = LLStructType::create(gIR->context(), vtbl_name);
vtbl_size = cd->vtbl.dim;
num_interface_vtbls = 0;
}
@@ -32,7 +34,7 @@ IrTypeClass::IrTypeClass(ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////
void IrTypeClass::addBaseClassData(
std::vector< const llvm::Type * > & defaultTypes,
std::vector<llvm::Type *> & defaultTypes,
ClassDeclaration * base,
size_t & offset,
size_t & field_index)
@@ -184,7 +186,7 @@ void IrTypeClass::addBaseClassData(
FuncDeclarations arr;
b->fillVtbl(cd, &arr, new_instances);
const llvm::Type* ivtbl_type = buildVtblType(first, &arr);
llvm::Type* ivtbl_type = llvm::StructType::get(gIR->context(), buildVtblType(first, &arr));
defaultTypes.push_back(llvm::PointerType::get(ivtbl_type, 0));
offset += PTRSIZE;
@@ -210,7 +212,7 @@ void IrTypeClass::addBaseClassData(
//////////////////////////////////////////////////////////////////////////////
const llvm::Type* IrTypeClass::buildType()
llvm::Type* IrTypeClass::buildType()
{
IF_LOG Logger::println("Building class type %s @ %s", cd->toPrettyChars(), cd->loc.toChars());
LOG_SCOPE;
@@ -219,11 +221,11 @@ const llvm::Type* IrTypeClass::buildType()
// find the fields that contribute to the default initializer.
// these will define the default type.
std::vector<const llvm::Type*> defaultTypes;
std::vector<llvm::Type*> defaultTypes;
defaultTypes.reserve(32);
// add vtbl
defaultTypes.push_back(llvm::PointerType::get(vtbl_pa.get(), 0));
defaultTypes.push_back(llvm::PointerType::get(vtbl_type, 0));
// interfaces are just a vtable
if (cd->isInterfaceDeclaration())
@@ -257,43 +259,27 @@ const llvm::Type* IrTypeClass::buildType()
if (global.errors)
fatal();
// build the llvm type
const llvm::Type* st = llvm::StructType::get(gIR->context(), defaultTypes, false);
// refine type
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(st);
// name type
Type::sir->getState()->module->addTypeName(cd->toPrettyChars(), pa.get());
// set struct body
isaStruct(type)->setBody(defaultTypes, false);
// VTBL
// build vtbl type
const llvm::Type* vtblty = buildVtblType(
ClassDeclaration::classinfo->type,
&cd->vtbl);
// set vtbl type body
vtbl_type->setBody(buildVtblType(ClassDeclaration::classinfo->type, &cd->vtbl));
// refine vtbl pa
llvm::cast<llvm::OpaqueType>(vtbl_pa.get())->refineAbstractTypeTo(vtblty);
// name vtbl type
std::string name(cd->toPrettyChars());
name.append(".__vtbl");
Type::sir->getState()->module->addTypeName(name, vtbl_pa.get());
IF_LOG Logger::cout() << "class type: " << *pa.get() << std::endl;
IF_LOG Logger::cout() << "class type: " << *type << std::endl;
return get();
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type* IrTypeClass::buildVtblType(Type* first, Array* vtbl_array)
std::vector<llvm::Type*> IrTypeClass::buildVtblType(Type* first, Array* vtbl_array)
{
IF_LOG Logger::println("Building vtbl type for class %s", cd->toPrettyChars());
LOG_SCOPE;
std::vector<const llvm::Type*> types;
std::vector<llvm::Type*> types;
types.reserve(vtbl_array->dim);
// first comes the classinfo
@@ -323,15 +309,14 @@ const llvm::Type* IrTypeClass::buildVtblType(Type* first, Array* vtbl_array)
types.push_back(DtoType(fd->type->pointerTo()));
}
// build the vtbl llvm type
return llvm::StructType::get(gIR->context(), types, false);
return types;
}
//////////////////////////////////////////////////////////////////////////////
const llvm::Type * IrTypeClass::get()
llvm::Type * IrTypeClass::get()
{
return llvm::PointerType::get(pa.get(), 0);
return llvm::PointerType::get(type, 0);
}
//////////////////////////////////////////////////////////////////////////////

View File

@@ -2,6 +2,7 @@
#define __LDC_IR_IRTYPECLASS_H__
#include "ir/irtypestruct.h"
#include <llvm/DerivedTypes.h>
///
class IrTypeClass : public IrTypeAggr
@@ -14,13 +15,13 @@ public:
virtual IrTypeClass* isClass() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
///
const llvm::Type* get();
llvm::Type* get();
/// Returns the vtable type for this class.
const llvm::Type* getVtbl() { return vtbl_pa.get(); }
llvm::Type* getVtbl() { return vtbl_type; }
/// Get index to interface implementation.
/// Returns the index of a specific interface implementation in this
@@ -40,8 +41,8 @@ protected:
///
TypeClass* tc;
/// Type holder for the vtable type.
llvm::PATypeHolder vtbl_pa;
/// Vtable type.
llvm::StructType *vtbl_type;
/// Number of pointers in vtable.
unsigned vtbl_size;
@@ -60,11 +61,11 @@ protected:
/// Builds a vtable type given the type of the first entry and an array
/// of all entries.
const llvm::Type* buildVtblType(Type* first, Array* vtbl_array);
std::vector<llvm::Type*> buildVtblType(Type* first, Array* vtbl_array);
///
void addBaseClassData(
std::vector<const llvm::Type*>& defaultTypes,
std::vector<llvm::Type*>& defaultTypes,
ClassDeclaration* base,
size_t& offset,
size_t& field_index);

View File

@@ -7,41 +7,47 @@
#include "ir/irtypefunction.h"
IrTypeFunction::IrTypeFunction(Type * dt)
: IrType(dt, llvm::OpaqueType::get(gIR->context()))
IrTypeFunction::IrTypeFunction(Type* dt)
: IrType(dt, func2llvm(dt))
{
irfty = NULL;
}
const llvm::Type * IrTypeFunction::buildType()
llvm::Type * IrTypeFunction::buildType()
{
const llvm::Type* T;
TypeFunction* tf = (TypeFunction*)dtype;
return type;
}
llvm::Type* IrTypeFunction::func2llvm(Type* dt)
{
llvm::Type* T;
TypeFunction* tf = (TypeFunction*)dt;
if (tf->funcdecl)
T = DtoFunctionType(tf->funcdecl);
else
T = DtoFunctionType(tf,NULL,NULL);
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(T);
return pa.get();
return T;
}
//////////////////////////////////////////////////////////////////////////////
IrTypeDelegate::IrTypeDelegate(Type * dt)
: IrType(dt, llvm::OpaqueType::get(gIR->context()))
: IrType(dt, delegate2llvm(dt))
{
}
const llvm::Type * IrTypeDelegate::buildType()
llvm::Type* IrTypeDelegate::buildType()
{
assert(dtype->ty == Tdelegate);
const LLType* i8ptr = getVoidPtrType();
const LLType* func = DtoFunctionType(dtype->nextOf(), NULL, Type::tvoid->pointerTo());
const LLType* funcptr = getPtrToType(func);
const LLStructType* dgtype = LLStructType::get(gIR->context(), i8ptr, funcptr, NULL);
gIR->module->addTypeName(dtype->toChars(), dgtype);
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(dgtype);
return pa.get();
return type;
}
llvm::Type* IrTypeDelegate::delegate2llvm(Type* dt)
{
assert(dt->ty == Tdelegate);
LLType* func = DtoFunctionType(dt->nextOf(), NULL, Type::tvoid->pointerTo());
llvm::SmallVector<LLType*, 2> types;
types.push_back(getVoidPtrType());
types.push_back(getPtrToType(func));
LLStructType* dgtype = LLStructType::get(gIR->context(), types);
return dgtype;
}

View File

@@ -16,11 +16,12 @@ public:
IrTypeFunction* isFunction() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
IrFuncTy* fty() { return irfty; }
protected:
llvm::Type* func2llvm(Type* dt);
///
IrFuncTy* irfty;
};
@@ -36,7 +37,9 @@ public:
IrTypeDelegate* isDelegate() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
protected:
llvm::Type* delegate2llvm(Type* dt);
};
#endif

View File

@@ -17,7 +17,7 @@
//////////////////////////////////////////////////////////////////////////////
IrTypeAggr::IrTypeAggr(AggregateDeclaration * ad)
: IrType(ad->type, llvm::OpaqueType::get(gIR->context())),
: IrType(ad->type, LLStructType::create(gIR->context(), ad->toPrettyChars())),
aggr(ad)
{
}
@@ -35,7 +35,7 @@ IrTypeStruct::IrTypeStruct(StructDeclaration * sd)
//////////////////////////////////////////////////////////////////////////////
size_t add_zeros(std::vector<const llvm::Type*>& defaultTypes, size_t diff)
size_t add_zeros(std::vector<llvm::Type*>& defaultTypes, size_t diff)
{
size_t n = defaultTypes.size();
while (diff)
@@ -75,7 +75,7 @@ bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v2)
// this is pretty much the exact same thing we need to do for fields in each
// base class of a class
const llvm::Type* IrTypeStruct::buildType()
llvm::Type* IrTypeStruct::buildType()
{
IF_LOG Logger::println("Building struct type %s @ %s",
sd->toPrettyChars(), sd->loc.toChars());
@@ -83,7 +83,7 @@ const llvm::Type* IrTypeStruct::buildType()
// if it's a forward declaration, all bets are off, stick with the opaque
if (sd->sizeok != 1)
return pa.get();
return type;
// mirror the sd->fields array but only fill in contributors
size_t n = sd->fields.dim;
@@ -166,7 +166,7 @@ const llvm::Type* IrTypeStruct::buildType()
}
// ok. now we can build a list of llvm types. and make sure zeros are inserted if necessary.
std::vector<const llvm::Type*> defaultTypes;
std::vector<LLType*> defaultTypes;
defaultTypes.reserve(16);
size_t offset = 0;
@@ -219,18 +219,12 @@ const llvm::Type* IrTypeStruct::buildType()
add_zeros(defaultTypes, sd->structsize - offset);
}
// build the llvm type
const llvm::Type* st = llvm::StructType::get(gIR->context(), defaultTypes, packed);
// set struct body
isaStruct(type)->setBody(defaultTypes, packed);
// refine type
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(st);
IF_LOG Logger::cout() << "final struct type: " << type << std::endl;
// name types
Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get());
IF_LOG Logger::cout() << "final struct type: " << *pa.get() << std::endl;
return pa.get();
return type;
}
//////////////////////////////////////////////////////////////////////////////

View File

@@ -53,7 +53,7 @@ public:
IrTypeStruct* isStruct() { return this; }
///
const llvm::Type* buildType();
llvm::Type* buildType();
protected:
/// StructDeclaration this type represents.

View File

@@ -18,9 +18,9 @@ IrVar::IrVar(VarDeclaration* var)
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v),
type(llvm::OpaqueType::get(gIR->context()))
IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v)
{
type = NULL;
constInit = NULL;
}

View File

@@ -17,7 +17,7 @@ struct IrGlobal : IrVar
{
IrGlobal(VarDeclaration* v);
llvm::PATypeHolder type;
llvm::Type *type;
llvm::Constant* constInit;
};