mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Merge remote-tracking branch 'upstream/llvm3.0'
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -114,6 +114,9 @@ StructInitializer::StructInitializer(Loc loc)
|
||||
: Initializer(loc)
|
||||
{
|
||||
ad = NULL;
|
||||
#if IN_LLVM
|
||||
ltype = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
Initializer *StructInitializer::syntaxCopy()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
20
dmd2/func.c
20
dmd2/func.c
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -114,6 +114,9 @@ StructInitializer::StructInitializer(Loc loc)
|
||||
: Initializer(loc)
|
||||
{
|
||||
ad = NULL;
|
||||
#if IN_LLVM
|
||||
ltype = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
Initializer *StructInitializer::syntaxCopy()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -106,6 +106,7 @@ enum BE
|
||||
struct Statement : Object
|
||||
{
|
||||
Loc loc;
|
||||
virtual ~Statement() {}
|
||||
|
||||
Statement(Loc loc);
|
||||
virtual Statement *syntaxCopy();
|
||||
|
||||
2
druntime
2
druntime
Submodule druntime updated: 406e772aa3...54cd2ffd40
20
gen/aa.cpp
20
gen/aa.cpp
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
175
gen/arrays.cpp
175
gen/arrays.cpp
@@ -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();
|
||||
|
||||
11
gen/arrays.h
11
gen/arrays.h
@@ -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);
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ ConfigFile::ConfigFile()
|
||||
|
||||
ConfigFile::~ConfigFile()
|
||||
{
|
||||
delete cfg;
|
||||
// delete cfg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "declaration.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -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&) { }
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
25
gen/main.cpp
25
gen/main.cpp
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
351
gen/runtime.cpp
351
gen/runtime.cpp
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -48,6 +48,8 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd);
|
||||
*/
|
||||
llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
|
||||
|
||||
void DtoDwarfModuleEnd();
|
||||
|
||||
|
||||
#endif // DISABLE_DEBUG_INFO
|
||||
|
||||
|
||||
149
gen/toir.cpp
149
gen/toir.cpp
@@ -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];
|
||||
|
||||
167
gen/tollvm.cpp
167
gen/tollvm.cpp
@@ -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;
|
||||
|
||||
60
gen/tollvm.h
60
gen/tollvm.h
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
150
gen/toobj.cpp
150
gen/toobj.cpp
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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* <ype = 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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
103
ir/irtype.cpp
103
ir/irtype.cpp
@@ -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;
|
||||
}
|
||||
|
||||
30
ir/irtype.h
30
ir/irtype.h
@@ -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);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
IrTypeStruct* isStruct() { return this; }
|
||||
|
||||
///
|
||||
const llvm::Type* buildType();
|
||||
llvm::Type* buildType();
|
||||
|
||||
protected:
|
||||
/// StructDeclaration this type represents.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ struct IrGlobal : IrVar
|
||||
{
|
||||
IrGlobal(VarDeclaration* v);
|
||||
|
||||
llvm::PATypeHolder type;
|
||||
llvm::Type *type;
|
||||
llvm::Constant* constInit;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user