mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
[svn r261] Fixed debug info for integer and floating local variables, can now be inspected in GDB.
Did a lot of smaller cleans up here and there. Replaced more llvm::Foo with LLFoo for common stuff. Split up tollvm.cpp.
This commit is contained in:
parent
e23169d5d8
commit
8b83eda2a2
26 changed files with 2033 additions and 1995 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "gen/aa.h"
|
#include "gen/aa.h"
|
||||||
#include "gen/runtime.h"
|
#include "gen/runtime.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/dvalue.h"
|
#include "gen/dvalue.h"
|
||||||
|
|
246
gen/arrays.cpp
246
gen/arrays.cpp
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/runtime.h"
|
#include "gen/runtime.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
|
@ -15,23 +16,23 @@
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const llvm::StructType* DtoArrayType(Type* arrayTy)
|
const LLStructType* DtoArrayType(Type* arrayTy)
|
||||||
{
|
{
|
||||||
assert(arrayTy->next);
|
assert(arrayTy->next);
|
||||||
const LLType* elemty = DtoType(arrayTy->next);
|
const LLType* elemty = DtoType(arrayTy->next);
|
||||||
if (elemty == llvm::Type::VoidTy)
|
if (elemty == LLType::VoidTy)
|
||||||
elemty = llvm::Type::Int8Ty;
|
elemty = LLType::Int8Ty;
|
||||||
return llvm::StructType::get(DtoSize_t(), getPtrToType(elemty), 0);
|
return LLStructType::get(DtoSize_t(), getPtrToType(elemty), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::StructType* DtoArrayType(const LLType* t)
|
const LLStructType* DtoArrayType(const LLType* t)
|
||||||
{
|
{
|
||||||
return llvm::StructType::get(DtoSize_t(), getPtrToType(t), 0);
|
return LLStructType::get(DtoSize_t(), getPtrToType(t), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const llvm::ArrayType* DtoStaticArrayType(Type* t)
|
const LLArrayType* DtoStaticArrayType(Type* t)
|
||||||
{
|
{
|
||||||
if (t->ir.type)
|
if (t->ir.type)
|
||||||
return isaArray(t->ir.type->get());
|
return isaArray(t->ir.type->get());
|
||||||
|
@ -43,10 +44,10 @@ const llvm::ArrayType* DtoStaticArrayType(Type* t)
|
||||||
|
|
||||||
TypeSArray* tsa = (TypeSArray*)t;
|
TypeSArray* tsa = (TypeSArray*)t;
|
||||||
assert(tsa->dim->type->isintegral());
|
assert(tsa->dim->type->isintegral());
|
||||||
const llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
|
const LLArrayType* arrty = LLArrayType::get(at,tsa->dim->toUInteger());
|
||||||
|
|
||||||
assert(!tsa->ir.type);
|
assert(!tsa->ir.type);
|
||||||
tsa->ir.type = new llvm::PATypeHolder(arrty);
|
tsa->ir.type = new LLPATypeHolder(arrty);
|
||||||
return arrty;
|
return arrty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +58,14 @@ void DtoSetArrayToNull(LLValue* v)
|
||||||
Logger::println("DtoSetArrayToNull");
|
Logger::println("DtoSetArrayToNull");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
LLValue* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb());
|
LLValue* len = DtoGEPi(v,0,0);
|
||||||
LLValue* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false);
|
LLValue* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false);
|
||||||
new llvm::StoreInst(zerolen, len, gIR->scopebb());
|
DtoStore(zerolen, len);
|
||||||
|
|
||||||
LLValue* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb());
|
LLValue* ptr = DtoGEPi(v,0,1);
|
||||||
const llvm::PointerType* pty = isaPointer(ptr->getType()->getContainedType(0));
|
const LLPointerType* pty = isaPointer(ptr->getType()->getContainedType(0));
|
||||||
LLValue* nullptr = llvm::ConstantPointerNull::get(pty);
|
LLValue* nullptr = llvm::ConstantPointerNull::get(pty);
|
||||||
new llvm::StoreInst(nullptr, ptr, gIR->scopebb());
|
DtoStore(nullptr, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -77,20 +78,20 @@ void DtoArrayAssign(LLValue* dst, LLValue* src)
|
||||||
assert(gIR);
|
assert(gIR);
|
||||||
if (dst->getType() == src->getType())
|
if (dst->getType() == src->getType())
|
||||||
{
|
{
|
||||||
LLValue* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb());
|
LLValue* ptr = DtoGEPi(src,0,0);
|
||||||
LLValue* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
|
LLValue* val = DtoLoad(ptr);
|
||||||
ptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
ptr = DtoGEPi(dst,0,0);
|
||||||
new llvm::StoreInst(val, ptr, gIR->scopebb());
|
DtoStore(val, ptr);
|
||||||
|
|
||||||
ptr = DtoGEPi(src,0,1,"tmp",gIR->scopebb());
|
ptr = DtoGEPi(src,0,1);
|
||||||
val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
|
val = DtoLoad(ptr);
|
||||||
ptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
|
ptr = DtoGEPi(dst,0,1);
|
||||||
new llvm::StoreInst(val, ptr, gIR->scopebb());
|
DtoStore(val, ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger::cout() << "array assignment type dont match: " << *dst->getType() << "\n\n" << *src->getType() << '\n';
|
Logger::cout() << "array assignment type dont match: " << *dst->getType() << "\n\n" << *src->getType() << '\n';
|
||||||
const llvm::ArrayType* arrty = isaArray(src->getType()->getContainedType(0));
|
const LLArrayType* arrty = isaArray(src->getType()->getContainedType(0));
|
||||||
if (!arrty)
|
if (!arrty)
|
||||||
{
|
{
|
||||||
Logger::cout() << "invalid: " << *src << '\n';
|
Logger::cout() << "invalid: " << *src << '\n';
|
||||||
|
@ -98,13 +99,13 @@ void DtoArrayAssign(LLValue* dst, LLValue* src)
|
||||||
}
|
}
|
||||||
const LLType* dstty = getPtrToType(arrty->getElementType());
|
const LLType* dstty = getPtrToType(arrty->getElementType());
|
||||||
|
|
||||||
LLValue* dstlen = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
LLValue* dstlen = DtoGEPi(dst,0,0);
|
||||||
LLValue* srclen = DtoConstSize_t(arrty->getNumElements());
|
LLValue* srclen = DtoConstSize_t(arrty->getNumElements());
|
||||||
new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
|
DtoStore(srclen, dstlen);
|
||||||
|
|
||||||
LLValue* dstptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
|
LLValue* dstptr = DtoGEPi(dst,0,1);
|
||||||
LLValue* srcptr = DtoBitCast(src, dstty);
|
LLValue* srcptr = DtoBitCast(src, dstty);
|
||||||
new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
|
DtoStore(srcptr, dstptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,19 +116,19 @@ void DtoArrayInit(LLValue* l, LLValue* r)
|
||||||
Logger::println("DtoArrayInit");
|
Logger::println("DtoArrayInit");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
const llvm::PointerType* ptrty = isaPointer(l->getType());
|
const LLPointerType* ptrty = isaPointer(l->getType());
|
||||||
const LLType* t = ptrty->getContainedType(0);
|
const LLType* t = ptrty->getContainedType(0);
|
||||||
const llvm::ArrayType* arrty = isaArray(t);
|
const LLArrayType* arrty = isaArray(t);
|
||||||
if (arrty)
|
if (arrty)
|
||||||
{
|
{
|
||||||
LLValue* ptr = DtoGEPi(l,0,0,"tmp",gIR->scopebb());
|
LLValue* ptr = DtoGEPi(l,0,0);
|
||||||
LLValue* dim = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
|
LLValue* dim = DtoConstSize_t(arrty->getNumElements());
|
||||||
DtoArrayInit(ptr, dim, r);
|
DtoArrayInit(ptr, dim, r);
|
||||||
}
|
}
|
||||||
else if (isaStruct(t))
|
else if (isaStruct(t))
|
||||||
{
|
{
|
||||||
LLValue* dim = DtoLoad(DtoGEPi(l, 0,0, "tmp"));
|
LLValue* dim = DtoLoad(DtoGEPi(l, 0,0));
|
||||||
LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1, "tmp"));
|
LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1));
|
||||||
DtoArrayInit(ptr, dim, r);
|
DtoArrayInit(ptr, dim, r);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -140,7 +141,7 @@ typedef const LLType* constLLVMTypeP;
|
||||||
|
|
||||||
static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
|
static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
|
||||||
{
|
{
|
||||||
if (const llvm::ArrayType* arrty = isaArray(pt)) {
|
if (const LLArrayType* arrty = isaArray(pt)) {
|
||||||
size_t n = checkRectArrayInit(arrty->getElementType(), finalty);
|
size_t n = checkRectArrayInit(arrty->getElementType(), finalty);
|
||||||
size_t ne = arrty->getNumElements();
|
size_t ne = arrty->getNumElements();
|
||||||
if (n) return n * ne;
|
if (n) return n * ne;
|
||||||
|
@ -180,7 +181,7 @@ void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(llvm::Type::Int8Ty), "tmp");
|
ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(LLType::Int8Ty), "tmp");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -203,33 +204,33 @@ void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val)
|
||||||
else if (isaPointer(t)) {
|
else if (isaPointer(t)) {
|
||||||
funcname = "_d_array_init_pointer";
|
funcname = "_d_array_init_pointer";
|
||||||
|
|
||||||
const LLType* dstty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
const LLType* dstty = getPtrToType(getPtrToType(LLType::Int8Ty));
|
||||||
if (args[0]->getType() != dstty)
|
if (args[0]->getType() != dstty)
|
||||||
args[0] = DtoBitCast(args[0],dstty);
|
args[0] = DtoBitCast(args[0],dstty);
|
||||||
|
|
||||||
const LLType* valty = getPtrToType(llvm::Type::Int8Ty);
|
const LLType* valty = getPtrToType(LLType::Int8Ty);
|
||||||
if (args[2]->getType() != valty)
|
if (args[2]->getType() != valty)
|
||||||
args[2] = DtoBitCast(args[2],valty);
|
args[2] = DtoBitCast(args[2],valty);
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::Int1Ty) {
|
else if (t == LLType::Int1Ty) {
|
||||||
funcname = "_d_array_init_i1";
|
funcname = "_d_array_init_i1";
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::Int8Ty) {
|
else if (t == LLType::Int8Ty) {
|
||||||
funcname = "_d_array_init_i8";
|
funcname = "_d_array_init_i8";
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::Int16Ty) {
|
else if (t == LLType::Int16Ty) {
|
||||||
funcname = "_d_array_init_i16";
|
funcname = "_d_array_init_i16";
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::Int32Ty) {
|
else if (t == LLType::Int32Ty) {
|
||||||
funcname = "_d_array_init_i32";
|
funcname = "_d_array_init_i32";
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::Int64Ty) {
|
else if (t == LLType::Int64Ty) {
|
||||||
funcname = "_d_array_init_i64";
|
funcname = "_d_array_init_i64";
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::FloatTy) {
|
else if (t == LLType::FloatTy) {
|
||||||
funcname = "_d_array_init_float";
|
funcname = "_d_array_init_float";
|
||||||
}
|
}
|
||||||
else if (t == llvm::Type::DoubleTy) {
|
else if (t == LLType::DoubleTy) {
|
||||||
funcname = "_d_array_init_double";
|
funcname = "_d_array_init_double";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -237,7 +238,7 @@ void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
|
||||||
assert(fn);
|
assert(fn);
|
||||||
Logger::cout() << "calling array init function: " << *fn <<'\n';
|
Logger::cout() << "calling array init function: " << *fn <<'\n';
|
||||||
llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
|
llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
|
||||||
|
@ -248,25 +249,9 @@ void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val)
|
||||||
|
|
||||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
||||||
{
|
{
|
||||||
Logger::println("DtoSetArray");
|
Logger::println("SetArray");
|
||||||
LOG_SCOPE;
|
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||||
|
DtoStore(ptr, DtoGEPi(arr,0,1));
|
||||||
Logger::cout() << "arr = " << *arr << '\n';
|
|
||||||
Logger::cout() << "dim = " << *dim << '\n';
|
|
||||||
Logger::cout() << "ptr = " << *ptr << '\n';
|
|
||||||
|
|
||||||
const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0));
|
|
||||||
|
|
||||||
LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
||||||
LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
|
||||||
|
|
||||||
LLValue* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb());
|
|
||||||
Logger::cout() << "arrdim = " << *arrdim << '\n';
|
|
||||||
new llvm::StoreInst(dim, arrdim, gIR->scopebb());
|
|
||||||
|
|
||||||
LLValue* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb());
|
|
||||||
Logger::cout() << "arrptr = " << *arrptr << '\n';
|
|
||||||
new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -326,7 +311,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
|
||||||
LLConstant* cc = idx->toConstElem(gIR);
|
LLConstant* cc = idx->toConstElem(gIR);
|
||||||
Logger::println("value gotten");
|
Logger::println("value gotten");
|
||||||
assert(cc != NULL);
|
assert(cc != NULL);
|
||||||
llvm::ConstantInt* ci = llvm::dyn_cast<llvm::ConstantInt>(cc);
|
LLConstantInt* ci = llvm::dyn_cast<LLConstantInt>(cc);
|
||||||
assert(ci != NULL);
|
assert(ci != NULL);
|
||||||
uint64_t k = ci->getZExtValue();
|
uint64_t k = ci->getZExtValue();
|
||||||
if (i == k)
|
if (i == k)
|
||||||
|
@ -356,15 +341,15 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::println("building constant array");
|
Logger::println("building constant array");
|
||||||
const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim);
|
const LLArrayType* arrty = LLArrayType::get(elemty,tdim);
|
||||||
LLConstant* constarr = llvm::ConstantArray::get(arrty, inits);
|
LLConstant* constarr = LLConstantArray::get(arrty, inits);
|
||||||
|
|
||||||
if (arrinittype->ty == Tsarray)
|
if (arrinittype->ty == Tsarray)
|
||||||
return constarr;
|
return constarr;
|
||||||
else
|
else
|
||||||
assert(arrinittype->ty == Tarray);
|
assert(arrinittype->ty == Tarray);
|
||||||
|
|
||||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrty,true,llvm::GlobalValue::InternalLinkage,constarr,"constarray",gIR->module);
|
LLGlobalVariable* gvar = new LLGlobalVariable(arrty,true,LLGlobalValue::InternalLinkage,constarr,"constarray",gIR->module);
|
||||||
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
|
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
|
||||||
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
||||||
return DtoConstSlice(DtoConstSize_t(tdim),gep);
|
return DtoConstSlice(DtoConstSize_t(tdim),gep);
|
||||||
|
@ -390,7 +375,7 @@ static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isaArray(t)) {
|
else if (isaArray(t)) {
|
||||||
ret = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb());
|
ret = DtoGEPi(e->ptr, 0, 0);
|
||||||
|
|
||||||
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
||||||
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
||||||
|
@ -401,14 +386,14 @@ static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz)
|
||||||
sz = llvm::ConstantExpr::getMul(elemsz, nelems);
|
sz = llvm::ConstantExpr::getMul(elemsz, nelems);
|
||||||
}
|
}
|
||||||
else if (isaStruct(t)) {
|
else if (isaStruct(t)) {
|
||||||
ret = DtoGEPi(e->ptr, 0, 1, "tmp", gIR->scopebb());
|
ret = DtoGEPi(e->ptr, 0, 1);
|
||||||
ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb());
|
ret = DtoLoad(ret);
|
||||||
|
|
||||||
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
||||||
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
||||||
|
|
||||||
LLValue* len = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb());
|
LLValue* len = DtoGEPi(e->ptr, 0, 0);
|
||||||
len = new llvm::LoadInst(len, "tmp", gIR->scopebb());
|
len = DtoLoad(len);
|
||||||
sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb());
|
sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -420,63 +405,32 @@ static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz)
|
||||||
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src)
|
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src)
|
||||||
{
|
{
|
||||||
Logger::println("ArrayCopySlices");
|
Logger::println("ArrayCopySlices");
|
||||||
const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
|
|
||||||
|
|
||||||
LLValue* sz1;
|
LLValue *sz1,*sz2;
|
||||||
LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty);
|
LLValue* dstarr = get_slice_ptr(dst,sz1);
|
||||||
|
LLValue* srcarr = get_slice_ptr(src,sz2);
|
||||||
|
|
||||||
LLValue* sz2;
|
DtoMemCpy(dstarr, srcarr, sz1);
|
||||||
LLValue* srcarr = DtoBitCast(get_slice_ptr(src,sz2),arrty);
|
|
||||||
|
|
||||||
llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
|
|
||||||
LLSmallVector<LLValue*, 4> llargs(4);
|
|
||||||
llargs[0] = dstarr;
|
|
||||||
llargs[1] = srcarr;
|
|
||||||
llargs[2] = sz1;
|
|
||||||
llargs[3] = DtoConstInt(0);
|
|
||||||
|
|
||||||
llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
|
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
|
||||||
{
|
{
|
||||||
Logger::println("ArrayCopyToSlice");
|
Logger::println("ArrayCopyToSlice");
|
||||||
const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
|
|
||||||
|
|
||||||
LLValue* sz1;
|
LLValue* sz1;
|
||||||
LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty);
|
LLValue* dstarr = get_slice_ptr(dst,sz1);
|
||||||
LLValue* srcarr = DtoBitCast(DtoArrayPtr(src),arrty);
|
LLValue* srcarr = DtoArrayPtr(src);
|
||||||
|
|
||||||
llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
|
DtoMemCpy(dstarr, srcarr, sz1);
|
||||||
LLSmallVector<LLValue*, 4> llargs(4);
|
|
||||||
llargs[0] = dstarr;
|
|
||||||
llargs[1] = srcarr;
|
|
||||||
llargs[2] = sz1;
|
|
||||||
llargs[3] = DtoConstInt(0);
|
|
||||||
|
|
||||||
llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void DtoStaticArrayCopy(LLValue* dst, LLValue* src)
|
void DtoStaticArrayCopy(LLValue* dst, LLValue* src)
|
||||||
{
|
{
|
||||||
Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n';
|
Logger::println("StaticArrayCopy");
|
||||||
assert(dst->getType() == src->getType());
|
|
||||||
size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0));
|
|
||||||
LLValue* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false);
|
|
||||||
|
|
||||||
const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
|
size_t n = getABITypeSize(dst->getType()->getContainedType(0));
|
||||||
LLValue* dstarr = DtoBitCast(dst,arrty);
|
DtoMemCpy(dst, src, DtoConstSize_t(n));
|
||||||
LLValue* srcarr = DtoBitCast(src,arrty);
|
|
||||||
|
|
||||||
llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
|
|
||||||
LLSmallVector<LLValue*,4> llargs(4);
|
|
||||||
llargs[0] = dstarr;
|
|
||||||
llargs[1] = srcarr;
|
|
||||||
llargs[2] = n;
|
|
||||||
llargs[3] = DtoConstInt(0);
|
|
||||||
|
|
||||||
llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -501,7 +455,7 @@ DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
|
||||||
|
|
||||||
// get runtime function
|
// get runtime function
|
||||||
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
|
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
|
||||||
|
|
||||||
// call allocator
|
// call allocator
|
||||||
LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem");
|
LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem");
|
||||||
|
@ -538,7 +492,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||||
bool zeroInit = arrayType->toBasetype()->next->isZeroInit();
|
bool zeroInit = arrayType->toBasetype()->next->isZeroInit();
|
||||||
|
|
||||||
// call runtime
|
// call runtime
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
|
||||||
|
|
||||||
LLSmallVector<LLValue*,4> args;
|
LLSmallVector<LLValue*,4> args;
|
||||||
args.push_back(DtoTypeInfoOf(arrayType));
|
args.push_back(DtoTypeInfoOf(arrayType));
|
||||||
|
@ -725,7 +679,7 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
|
||||||
static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
|
static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
|
||||||
{
|
{
|
||||||
Logger::println("comparing arrays");
|
Logger::println("comparing arrays");
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func);
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, func);
|
||||||
assert(fn);
|
assert(fn);
|
||||||
|
|
||||||
LLValue* lmem;
|
LLValue* lmem;
|
||||||
|
@ -888,7 +842,7 @@ LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* ne
|
||||||
args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false));
|
args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false));
|
||||||
args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
|
args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
|
||||||
|
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
|
||||||
return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
|
return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,12 +852,12 @@ LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r)
|
||||||
llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
||||||
|
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp");
|
LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
|
||||||
LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0);
|
LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0);
|
||||||
LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
||||||
|
|
||||||
LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp");
|
LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
|
||||||
const llvm::PointerType* pty = isaPointer(lp->getType());
|
const LLPointerType* pty = isaPointer(lp->getType());
|
||||||
LLValue* rp = llvm::ConstantPointerNull::get(pty);
|
LLValue* rp = llvm::ConstantPointerNull::get(pty);
|
||||||
LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
|
LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
|
||||||
|
|
||||||
|
@ -913,12 +867,12 @@ LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r)
|
||||||
else {
|
else {
|
||||||
assert(l->getType() == r->getType());
|
assert(l->getType() == r->getType());
|
||||||
|
|
||||||
LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp");
|
LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
|
||||||
LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp");
|
LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0),"tmp");
|
||||||
LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
||||||
|
|
||||||
LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp");
|
LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
|
||||||
LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp");
|
LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1),"tmp");
|
||||||
LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
|
LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
|
||||||
|
|
||||||
LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
|
LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
|
||||||
|
@ -929,7 +883,7 @@ LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r)
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c)
|
LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c)
|
||||||
{
|
{
|
||||||
const llvm::ArrayType* at = isaArray(t);
|
const LLArrayType* at = isaArray(t);
|
||||||
assert(at);
|
assert(at);
|
||||||
|
|
||||||
if (isaArray(at->getElementType()))
|
if (isaArray(at->getElementType()))
|
||||||
|
@ -956,19 +910,19 @@ LLValue* DtoArrayLen(DValue* v)
|
||||||
if (s->len) {
|
if (s->len) {
|
||||||
return s->len;
|
return s->len;
|
||||||
}
|
}
|
||||||
const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
|
const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
|
||||||
if (arrTy)
|
if (arrTy)
|
||||||
return DtoConstSize_t(arrTy->getNumElements());
|
return DtoConstSize_t(arrTy->getNumElements());
|
||||||
else
|
else
|
||||||
return DtoLoad(DtoGEPi(s->ptr, 0,0, "tmp"));
|
return DtoLoad(DtoGEPi(s->ptr, 0,0));
|
||||||
}
|
}
|
||||||
return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp"));
|
return DtoLoad(DtoGEPi(v->getRVal(), 0,0));
|
||||||
}
|
}
|
||||||
else if (t->ty == Tsarray) {
|
else if (t->ty == Tsarray) {
|
||||||
assert(!v->isSlice());
|
assert(!v->isSlice());
|
||||||
LLValue* rv = v->getRVal();
|
LLValue* rv = v->getRVal();
|
||||||
Logger::cout() << "casting: " << *rv << '\n';
|
Logger::cout() << "casting: " << *rv << '\n';
|
||||||
const llvm::ArrayType* t = isaArray(rv->getType()->getContainedType(0));
|
const LLArrayType* t = isaArray(rv->getType()->getContainedType(0));
|
||||||
return DtoConstSize_t(t->getNumElements());
|
return DtoConstSize_t(t->getNumElements());
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -987,16 +941,16 @@ LLValue* DtoArrayPtr(DValue* v)
|
||||||
if (s->len) return s->ptr;
|
if (s->len) return s->ptr;
|
||||||
const LLType* t = s->ptr->getType()->getContainedType(0);
|
const LLType* t = s->ptr->getType()->getContainedType(0);
|
||||||
Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
|
Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
|
||||||
const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
|
const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
|
||||||
if (arrTy)
|
if (arrTy)
|
||||||
return DtoGEPi(s->ptr, 0,0, "tmp");
|
return DtoGEPi(s->ptr, 0,0);
|
||||||
else
|
else
|
||||||
return DtoLoad(DtoGEPi(s->ptr, 0,1, "tmp"));
|
return DtoLoad(DtoGEPi(s->ptr, 0,1));
|
||||||
}
|
}
|
||||||
return DtoLoad(DtoGEPi(v->getRVal(), 0,1, "tmp"));
|
return DtoLoad(DtoGEPi(v->getRVal(), 0,1));
|
||||||
}
|
}
|
||||||
else if (t->ty == Tsarray) {
|
else if (t->ty == Tsarray) {
|
||||||
return DtoGEPi(v->getRVal(), 0,0, "tmp");
|
return DtoGEPi(v->getRVal(), 0,0);
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1028,13 +982,13 @@ DValue* DtoCastArray(DValue* u, Type* to)
|
||||||
else if (totype->ty == Tarray) {
|
else if (totype->ty == Tarray) {
|
||||||
Logger::cout() << "to array" << '\n';
|
Logger::cout() << "to array" << '\n';
|
||||||
const LLType* ptrty = DtoType(totype->next);
|
const LLType* ptrty = DtoType(totype->next);
|
||||||
if (ptrty == llvm::Type::VoidTy)
|
if (ptrty == LLType::VoidTy)
|
||||||
ptrty = llvm::Type::Int8Ty;
|
ptrty = LLType::Int8Ty;
|
||||||
ptrty = getPtrToType(ptrty);
|
ptrty = getPtrToType(ptrty);
|
||||||
|
|
||||||
const LLType* ety = DtoType(fromtype->next);
|
const LLType* ety = DtoType(fromtype->next);
|
||||||
if (ety == llvm::Type::VoidTy)
|
if (ety == LLType::VoidTy)
|
||||||
ety = llvm::Type::Int8Ty;
|
ety = LLType::Int8Ty;
|
||||||
|
|
||||||
if (DSliceValue* usl = u->isSlice()) {
|
if (DSliceValue* usl = u->isSlice()) {
|
||||||
Logger::println("from slice");
|
Logger::println("from slice");
|
||||||
|
@ -1050,20 +1004,20 @@ DValue* DtoCastArray(DValue* u, Type* to)
|
||||||
if (fromtype->ty == Tsarray) {
|
if (fromtype->ty == Tsarray) {
|
||||||
Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
|
Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
|
||||||
assert(isaPointer(uval->getType()));
|
assert(isaPointer(uval->getType()));
|
||||||
const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
|
const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
|
||||||
rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
|
rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
|
||||||
rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
|
rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
|
||||||
rval = DtoBitCast(uval, ptrty);
|
rval = DtoBitCast(uval, ptrty);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||||
LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
LLValue* one = llvm::ConstantInt::get(LLType::Int32Ty, 1, false);
|
||||||
rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb());
|
rval2 = DtoGEP(uval,zero,zero);
|
||||||
rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb());
|
rval2 = DtoLoad(rval2);
|
||||||
rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
|
rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
|
||||||
|
|
||||||
rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb());
|
rval = DtoGEP(uval,zero,one);
|
||||||
rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb());
|
rval = DtoLoad(rval);
|
||||||
//Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
|
//Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
|
||||||
rval = DtoBitCast(rval, ptrty);
|
rval = DtoBitCast(rval, ptrty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ const llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy);
|
||||||
|
|
||||||
LLConstant* DtoConstArrayInitializer(ArrayInitializer* si);
|
LLConstant* DtoConstArrayInitializer(ArrayInitializer* si);
|
||||||
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr);
|
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr);
|
||||||
LLConstant* DtoConstStaticArray(const llvm::Type* t, LLConstant* c);
|
LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c);
|
||||||
|
|
||||||
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src);
|
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src);
|
||||||
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
|
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
|
||||||
|
@ -35,7 +35,7 @@ LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r);
|
||||||
|
|
||||||
LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r);
|
LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r);
|
||||||
|
|
||||||
LLValue* DtoArrayCastLength(LLValue* len, const llvm::Type* elemty, const llvm::Type* newelemty);
|
LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty);
|
||||||
|
|
||||||
LLValue* DtoArrayLen(DValue* v);
|
LLValue* DtoArrayLen(DValue* v);
|
||||||
LLValue* DtoArrayPtr(DValue* v);
|
LLValue* DtoArrayPtr(DValue* v);
|
||||||
|
|
|
@ -35,7 +35,7 @@ DValue* DtoBinMul(DValue* lhs, DValue* rhs)
|
||||||
DValue* DtoBinDiv(DValue* lhs, DValue* rhs)
|
DValue* DtoBinDiv(DValue* lhs, DValue* rhs)
|
||||||
{
|
{
|
||||||
Type* t = lhs->getType();
|
Type* t = lhs->getType();
|
||||||
llvm::Value *l, *r;
|
LLValue *l, *r;
|
||||||
l = lhs->getRVal();
|
l = lhs->getRVal();
|
||||||
r = rhs->getRVal();
|
r = rhs->getRVal();
|
||||||
LLValue* res;
|
LLValue* res;
|
||||||
|
@ -53,7 +53,7 @@ DValue* DtoBinDiv(DValue* lhs, DValue* rhs)
|
||||||
DValue* DtoBinRem(DValue* lhs, DValue* rhs)
|
DValue* DtoBinRem(DValue* lhs, DValue* rhs)
|
||||||
{
|
{
|
||||||
Type* t = lhs->getType();
|
Type* t = lhs->getType();
|
||||||
llvm::Value *l, *r;
|
LLValue *l, *r;
|
||||||
l = lhs->getRVal();
|
l = lhs->getRVal();
|
||||||
r = rhs->getRVal();
|
r = rhs->getRVal();
|
||||||
LLValue* res;
|
LLValue* res;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/classes.h"
|
#include "gen/classes.h"
|
||||||
|
@ -199,7 +200,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
fieldtypes.push_back(fieldtype);
|
fieldtypes.push_back(fieldtype);
|
||||||
irstruct->defaultFields.push_back(fieldinit);
|
irstruct->defaultFields.push_back(fieldinit);
|
||||||
if (fieldpad) {
|
if (fieldpad) {
|
||||||
fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
|
fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
|
||||||
irstruct->defaultFields.push_back(NULL);
|
irstruct->defaultFields.push_back(NULL);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +219,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
fieldtypes.push_back(fieldtype);
|
fieldtypes.push_back(fieldtype);
|
||||||
irstruct->defaultFields.push_back(fieldinit);
|
irstruct->defaultFields.push_back(fieldinit);
|
||||||
if (fieldpad) {
|
if (fieldpad) {
|
||||||
fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
|
fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
|
||||||
irstruct->defaultFields.push_back(NULL);
|
irstruct->defaultFields.push_back(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,7 +499,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// then comes monitor
|
// then comes monitor
|
||||||
fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// go through the field inits and build the default initializer
|
// go through the field inits and build the default initializer
|
||||||
size_t nfi = irstruct->defaultFields.size();
|
size_t nfi = irstruct->defaultFields.size();
|
||||||
|
@ -511,7 +512,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
else {
|
else {
|
||||||
const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2));
|
const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2));
|
||||||
assert(arrty);
|
assert(arrty);
|
||||||
std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
|
std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
|
||||||
c = llvm::ConstantArray::get(arrty, vals);
|
c = llvm::ConstantArray::get(arrty, vals);
|
||||||
}
|
}
|
||||||
fieldinits.push_back(c);
|
fieldinits.push_back(c);
|
||||||
|
@ -628,7 +629,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
infoInits.push_back(c);
|
infoInits.push_back(c);
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
|
||||||
c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
|
c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
|
||||||
c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
|
c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
|
||||||
infoInits.push_back(c);
|
infoInits.push_back(c);
|
||||||
|
@ -706,7 +707,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
infoInits.push_back(c);
|
infoInits.push_back(c);
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
|
||||||
c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
|
c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
|
||||||
infoInits.push_back(c);
|
infoInits.push_back(c);
|
||||||
|
|
||||||
|
@ -865,23 +866,10 @@ void DtoInitClass(TypeClass* tc, LLValue* dst)
|
||||||
assert(tc->sym->ir.irStruct->init);
|
assert(tc->sym->ir.irStruct->init);
|
||||||
assert(dst->getType() == tc->sym->ir.irStruct->init->getType());
|
assert(dst->getType() == tc->sym->ir.irStruct->init->getType());
|
||||||
|
|
||||||
const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
|
|
||||||
|
|
||||||
LLValue* dstarr = DtoGEPi(dst,0,2,"tmp");
|
LLValue* dstarr = DtoGEPi(dst,0,2,"tmp");
|
||||||
dstarr = DtoBitCast(dstarr, arrty);
|
|
||||||
|
|
||||||
LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp");
|
LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp");
|
||||||
srcarr = DtoBitCast(srcarr, arrty);
|
|
||||||
|
|
||||||
llvm::Function* fn = LLVM_DeclareMemCpy32();
|
DtoMemCpy(dstarr, srcarr, DtoConstSize_t(n));
|
||||||
std::vector<LLValue*> llargs;
|
|
||||||
llargs.resize(4);
|
|
||||||
llargs[0] = dstarr;
|
|
||||||
llargs[1] = srcarr;
|
|
||||||
llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
||||||
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
||||||
|
|
||||||
llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1343,16 +1331,16 @@ static LLConstant* build_class_dtor(ClassDeclaration* cd)
|
||||||
std::vector<const LLType*> paramTypes;
|
std::vector<const LLType*> paramTypes;
|
||||||
paramTypes.push_back(getPtrToType(cd->type->ir.type->get()));
|
paramTypes.push_back(getPtrToType(cd->type->ir.type->get()));
|
||||||
|
|
||||||
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false);
|
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy, paramTypes, false);
|
||||||
|
|
||||||
if (cd->dtors.dim == 0) {
|
if (cd->dtors.dim == 0) {
|
||||||
return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
|
return llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty));
|
||||||
}
|
}
|
||||||
else if (cd->dtors.dim == 1) {
|
else if (cd->dtors.dim == 1) {
|
||||||
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
|
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
|
||||||
DtoForceDeclareDsymbol(d);
|
DtoForceDeclareDsymbol(d);
|
||||||
assert(d->ir.irFunc->func);
|
assert(d->ir.irFunc->func);
|
||||||
return llvm::ConstantExpr::getBitCast(isaConstant(d->ir.irFunc->func), getPtrToType(llvm::Type::Int8Ty));
|
return llvm::ConstantExpr::getBitCast(isaConstant(d->ir.irFunc->func), getPtrToType(LLType::Int8Ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string gname("_D");
|
std::string gname("_D");
|
||||||
|
@ -1375,7 +1363,7 @@ static LLConstant* build_class_dtor(ClassDeclaration* cd)
|
||||||
}
|
}
|
||||||
builder.CreateRetVoid();
|
builder.CreateRetVoid();
|
||||||
|
|
||||||
return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty));
|
return llvm::ConstantExpr::getBitCast(func, getPtrToType(LLType::Int8Ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint build_classinfo_flags(ClassDeclaration* cd)
|
static uint build_classinfo_flags(ClassDeclaration* cd)
|
||||||
|
@ -1462,7 +1450,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
|
||||||
inits.push_back(c);
|
inits.push_back(c);
|
||||||
|
|
||||||
// byte[] init
|
// byte[] init
|
||||||
const LLType* byteptrty = getPtrToType(llvm::Type::Int8Ty);
|
const LLType* byteptrty = getPtrToType(LLType::Int8Ty);
|
||||||
if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
|
if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
|
||||||
c = cinfo->ir.irStruct->constInit->getOperand(2);
|
c = cinfo->ir.irStruct->constInit->getOperand(2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "gen/complex.h"
|
#include "gen/complex.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/dvalue.h"
|
#include "gen/dvalue.h"
|
||||||
|
|
||||||
|
@ -307,3 +308,56 @@ LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
|
||||||
LLValue* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb());
|
LLValue* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb());
|
||||||
return gIR->ir->CreateAnd(b1,b2,"tmp");
|
return gIR->ir->CreateAnd(b1,b2,"tmp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DValue* DtoCastComplex(DValue* val, Type* _to)
|
||||||
|
{
|
||||||
|
Type* to = DtoDType(_to);
|
||||||
|
Type* vty = val->getType();
|
||||||
|
if (to->iscomplex()) {
|
||||||
|
if (vty->size() == to->size())
|
||||||
|
return val;
|
||||||
|
|
||||||
|
llvm::Value *re, *im;
|
||||||
|
DtoGetComplexParts(val, re, im);
|
||||||
|
const LLType* toty = DtoComplexBaseType(to);
|
||||||
|
|
||||||
|
if (to->size() < vty->size()) {
|
||||||
|
re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
|
||||||
|
im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
|
||||||
|
}
|
||||||
|
else if (to->size() > vty->size()) {
|
||||||
|
re = gIR->ir->CreateFPExt(re, toty, "tmp");
|
||||||
|
im = gIR->ir->CreateFPExt(im, toty, "tmp");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val->isComplex())
|
||||||
|
return new DComplexValue(_to, re, im);
|
||||||
|
|
||||||
|
// unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions.
|
||||||
|
// so we need to give it storage, or fix the system that handles this stuff (DLRValue)
|
||||||
|
LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint());
|
||||||
|
DtoComplexSet(mem, re, im);
|
||||||
|
return new DLRValue(val->getType(), val->getRVal(), _to, mem);
|
||||||
|
}
|
||||||
|
else if (to->isimaginary()) {
|
||||||
|
if (val->isComplex())
|
||||||
|
return new DImValue(to, val->isComplex()->im);
|
||||||
|
LLValue* v = val->getRVal();
|
||||||
|
DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp")));
|
||||||
|
return DtoCastFloat(im, to);
|
||||||
|
}
|
||||||
|
else if (to->isfloating()) {
|
||||||
|
if (val->isComplex())
|
||||||
|
return new DImValue(to, val->isComplex()->re);
|
||||||
|
LLValue* v = val->getRVal();
|
||||||
|
DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp")));
|
||||||
|
return DtoCastFloat(re, to);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
assert(0);
|
||||||
|
}
|
|
@ -26,4 +26,6 @@ DValue* DtoComplexNeg(Type* type, DValue* val);
|
||||||
|
|
||||||
LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs);
|
LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs);
|
||||||
|
|
||||||
|
DValue* DtoCastComplex(DValue* val, Type* to);
|
||||||
|
|
||||||
#endif // LLVMDC_GEN_COMPLEX_H
|
#endif // LLVMDC_GEN_COMPLEX_H
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/runtime.h"
|
#include "gen/runtime.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
|
@ -49,7 +50,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
|
||||||
|
|
||||||
if (ismain)
|
if (ismain)
|
||||||
{
|
{
|
||||||
rettype = llvm::Type::Int32Ty;
|
rettype = LLType::Int32Ty;
|
||||||
actualRettype = rettype;
|
actualRettype = rettype;
|
||||||
if (Argument::dim(f->parameters) == 0)
|
if (Argument::dim(f->parameters) == 0)
|
||||||
{
|
{
|
||||||
|
@ -63,7 +64,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
|
||||||
Type* rtfin = DtoDType(rt);
|
Type* rtfin = DtoDType(rt);
|
||||||
if (DtoIsReturnedInArg(rt)) {
|
if (DtoIsReturnedInArg(rt)) {
|
||||||
rettype = getPtrToType(DtoType(rt));
|
rettype = getPtrToType(DtoType(rt));
|
||||||
actualRettype = llvm::Type::VoidTy;
|
actualRettype = LLType::VoidTy;
|
||||||
f->llvmRetInPtr = retinptr = true;
|
f->llvmRetInPtr = retinptr = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -92,7 +93,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
|
||||||
types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType())));
|
types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType())));
|
||||||
const LLType* t1 = llvm::StructType::get(types);
|
const LLType* t1 = llvm::StructType::get(types);
|
||||||
paramvec.push_back(getPtrToType(t1));
|
paramvec.push_back(getPtrToType(t1));
|
||||||
paramvec.push_back(getPtrToType(llvm::Type::Int8Ty));
|
paramvec.push_back(getPtrToType(LLType::Int8Ty));
|
||||||
}
|
}
|
||||||
else if (arrayVararg)
|
else if (arrayVararg)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +173,7 @@ static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
|
||||||
TypeFunction* f = (TypeFunction*)fdecl->type;
|
TypeFunction* f = (TypeFunction*)fdecl->type;
|
||||||
assert(f != 0);
|
assert(f != 0);
|
||||||
|
|
||||||
const llvm::PointerType* i8pty = getPtrToType(llvm::Type::Int8Ty);
|
const llvm::PointerType* i8pty = getPtrToType(LLType::Int8Ty);
|
||||||
std::vector<const LLType*> args;
|
std::vector<const LLType*> args;
|
||||||
|
|
||||||
if (fdecl->llvmInternal == LLVMva_start) {
|
if (fdecl->llvmInternal == LLVMva_start) {
|
||||||
|
@ -187,7 +188,7 @@ static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
|
||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
|
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::VoidTy, args, false);
|
||||||
|
|
||||||
f->ir.type = new llvm::PATypeHolder(fty);
|
f->ir.type = new llvm::PATypeHolder(fty);
|
||||||
|
|
||||||
|
@ -205,7 +206,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
|
||||||
// unittest has null type, just build it manually
|
// unittest has null type, just build it manually
|
||||||
/*if (fdecl->isUnitTestDeclaration()) {
|
/*if (fdecl->isUnitTestDeclaration()) {
|
||||||
std::vector<const LLType*> args;
|
std::vector<const LLType*> args;
|
||||||
return llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
|
return llvm::FunctionType::get(LLType::VoidTy, args, false);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// type has already been resolved
|
// type has already been resolved
|
||||||
|
@ -228,7 +229,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fdecl->isNested()) {
|
else if (fdecl->isNested()) {
|
||||||
thisty = getPtrToType(llvm::Type::Int8Ty);
|
thisty = getPtrToType(LLType::Int8Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain());
|
const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain());
|
||||||
|
@ -549,194 +550,195 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||||
const llvm::FunctionType* functype = func->getFunctionType();
|
const llvm::FunctionType* functype = func->getFunctionType();
|
||||||
|
|
||||||
// only members of the current module or template instances maybe be defined
|
// only members of the current module or template instances maybe be defined
|
||||||
if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent))
|
if (!(fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// set module owner
|
||||||
|
fd->ir.DModule = gIR->dmodule;
|
||||||
|
|
||||||
|
// is there a body?
|
||||||
|
if (fd->fbody == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Logger::println("Doing function body for: %s", fd->toChars());
|
||||||
|
assert(fd->ir.irFunc);
|
||||||
|
gIR->functions.push_back(fd->ir.irFunc);
|
||||||
|
|
||||||
|
if (fd->isMain())
|
||||||
|
gIR->emitMain = true;
|
||||||
|
|
||||||
|
std::string entryname("entry_");
|
||||||
|
entryname.append(fd->toPrettyChars());
|
||||||
|
|
||||||
|
llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func);
|
||||||
|
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func);
|
||||||
|
|
||||||
|
//assert(gIR->scopes.empty());
|
||||||
|
gIR->scopes.push_back(IRScope(beginbb, endbb));
|
||||||
|
|
||||||
|
// create alloca point
|
||||||
|
llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb);
|
||||||
|
gIR->func()->allocapoint = allocaPoint;
|
||||||
|
|
||||||
|
// need result variable? (not nested)
|
||||||
|
if (fd->vresult && !fd->vresult->nestedref) {
|
||||||
|
Logger::println("non-nested vresult value");
|
||||||
|
fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
|
||||||
|
fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// give arguments storage
|
||||||
|
if (fd->parameters)
|
||||||
{
|
{
|
||||||
fd->ir.DModule = gIR->dmodule;
|
size_t n = fd->parameters->dim;
|
||||||
|
for (int i=0; i < n; ++i)
|
||||||
// function definition
|
|
||||||
if (fd->fbody != 0)
|
|
||||||
{
|
{
|
||||||
Logger::println("Doing function body for: %s", fd->toChars());
|
Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
|
||||||
assert(fd->ir.irFunc);
|
VarDeclaration* vd = argsym->isVarDeclaration();
|
||||||
gIR->functions.push_back(fd->ir.irFunc);
|
assert(vd);
|
||||||
|
|
||||||
if (fd->isMain())
|
if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
|
||||||
gIR->emitMain = true;
|
continue;
|
||||||
|
|
||||||
std::string entryname("entry_");
|
LLValue* a = vd->ir.irLocal->value;
|
||||||
entryname.append(fd->toPrettyChars());
|
assert(a);
|
||||||
|
std::string s(a->getName());
|
||||||
|
Logger::println("giving argument '%s' storage", s.c_str());
|
||||||
|
s.append("_storage");
|
||||||
|
|
||||||
llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func);
|
LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
|
||||||
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func);
|
gIR->ir->CreateStore(a,v);
|
||||||
|
vd->ir.irLocal->value = v;
|
||||||
//assert(gIR->scopes.empty());
|
|
||||||
gIR->scopes.push_back(IRScope(beginbb, endbb));
|
|
||||||
|
|
||||||
// create alloca point
|
|
||||||
llvm::Instruction* allocaPoint = new llvm::AllocaInst(llvm::Type::Int32Ty, "alloca point", beginbb);
|
|
||||||
gIR->func()->allocapoint = allocaPoint;
|
|
||||||
|
|
||||||
// need result variable? (not nested)
|
|
||||||
if (fd->vresult && !fd->vresult->nestedref) {
|
|
||||||
Logger::println("non-nested vresult value");
|
|
||||||
fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
|
|
||||||
fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// give arguments storage
|
|
||||||
if (fd->parameters)
|
|
||||||
{
|
|
||||||
size_t n = fd->parameters->dim;
|
|
||||||
for (int i=0; i < n; ++i)
|
|
||||||
{
|
|
||||||
Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
|
|
||||||
VarDeclaration* vd = argsym->isVarDeclaration();
|
|
||||||
assert(vd);
|
|
||||||
|
|
||||||
if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LLValue* a = vd->ir.irLocal->value;
|
|
||||||
assert(a);
|
|
||||||
std::string s(a->getName());
|
|
||||||
Logger::println("giving argument '%s' storage", s.c_str());
|
|
||||||
s.append("_storage");
|
|
||||||
|
|
||||||
LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
|
|
||||||
gIR->ir->CreateStore(a,v);
|
|
||||||
vd->ir.irLocal->value = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// debug info
|
|
||||||
if (global.params.symdebug) DtoDwarfFuncStart(fd);
|
|
||||||
|
|
||||||
LLValue* parentNested = NULL;
|
|
||||||
if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
|
|
||||||
if (!fd->isStatic()) // huh?
|
|
||||||
parentNested = fd2->ir.irFunc->nestedVar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need result variable? (nested)
|
|
||||||
if (fd->vresult && fd->vresult->nestedref) {
|
|
||||||
Logger::println("nested vresult value: %s", fd->vresult->toChars());
|
|
||||||
fd->nestedVars.insert(fd->vresult);
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct nested variables struct
|
|
||||||
if (!fd->nestedVars.empty() || parentNested) {
|
|
||||||
std::vector<const LLType*> nestTypes;
|
|
||||||
int j = 0;
|
|
||||||
if (parentNested) {
|
|
||||||
nestTypes.push_back(parentNested->getType());
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
|
||||||
VarDeclaration* vd = *i;
|
|
||||||
Logger::println("referenced nested variable %s", vd->toChars());
|
|
||||||
if (!vd->ir.irLocal)
|
|
||||||
vd->ir.irLocal = new IrLocal(vd);
|
|
||||||
vd->ir.irLocal->nestedIndex = j++;
|
|
||||||
if (vd->isParameter()) {
|
|
||||||
if (!vd->ir.irLocal->value) {
|
|
||||||
assert(vd == fd->vthis);
|
|
||||||
vd->ir.irLocal->value = fd->ir.irFunc->thisVar;
|
|
||||||
}
|
|
||||||
assert(vd->ir.irLocal->value);
|
|
||||||
nestTypes.push_back(vd->ir.irLocal->value->getType());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nestTypes.push_back(DtoType(vd->type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
|
|
||||||
Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
|
|
||||||
fd->ir.irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
|
|
||||||
if (parentNested) {
|
|
||||||
assert(fd->ir.irFunc->thisVar);
|
|
||||||
LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp");
|
|
||||||
gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp"));
|
|
||||||
}
|
|
||||||
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
|
||||||
VarDeclaration* vd = *i;
|
|
||||||
if (vd->isParameter()) {
|
|
||||||
assert(vd->ir.irLocal);
|
|
||||||
gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp"));
|
|
||||||
vd->ir.irLocal->value = fd->ir.irFunc->nestedVar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy _argptr to a memory location
|
|
||||||
if (f->linkage == LINKd && f->varargs == 1)
|
|
||||||
{
|
|
||||||
LLValue* argptrmem = new llvm::AllocaInst(fd->ir.irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
|
|
||||||
new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
|
|
||||||
fd->ir.irFunc->_argptr = argptrmem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// output function body
|
|
||||||
fd->fbody->toIR(gIR);
|
|
||||||
|
|
||||||
// llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
|
|
||||||
// in automatically, so we do it here.
|
|
||||||
if (!fd->isMain()) {
|
|
||||||
if (!gIR->scopereturned()) {
|
|
||||||
// pass the previous block into this block
|
|
||||||
if (global.params.symdebug) DtoDwarfFuncEnd(fd);
|
|
||||||
if (func->getReturnType() == llvm::Type::VoidTy) {
|
|
||||||
llvm::ReturnInst::Create(gIR->scopebb());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// erase alloca point
|
|
||||||
allocaPoint->eraseFromParent();
|
|
||||||
allocaPoint = 0;
|
|
||||||
gIR->func()->allocapoint = 0;
|
|
||||||
|
|
||||||
gIR->scopes.pop_back();
|
|
||||||
|
|
||||||
// get rid of the endentry block, it's never used
|
|
||||||
assert(!func->getBasicBlockList().empty());
|
|
||||||
func->getBasicBlockList().pop_back();
|
|
||||||
|
|
||||||
// if the last block is empty now, it must be unreachable or it's a bug somewhere else
|
|
||||||
// would be nice to figure out how to assert that this is correct
|
|
||||||
llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
|
|
||||||
if (lastbb->empty()) {
|
|
||||||
if (lastbb->getNumUses() == 0)
|
|
||||||
lastbb->eraseFromParent();
|
|
||||||
else {
|
|
||||||
new llvm::UnreachableInst(lastbb);
|
|
||||||
/*if (func->getReturnType() == llvm::Type::VoidTy) {
|
|
||||||
llvm::ReturnInst::Create(lastbb);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the last block is not terminated we return a null value or void
|
|
||||||
// for some unknown reason this is needed when a void main() has a inline asm block ...
|
|
||||||
// this should be harmless for well formed code!
|
|
||||||
lastbb = &func->getBasicBlockList().back();
|
|
||||||
if (!lastbb->getTerminator())
|
|
||||||
{
|
|
||||||
Logger::println("adding missing return statement");
|
|
||||||
if (func->getReturnType() == llvm::Type::VoidTy)
|
|
||||||
llvm::ReturnInst::Create(lastbb);
|
|
||||||
else
|
|
||||||
llvm::ReturnInst::Create(llvm::Constant::getNullValue(func->getReturnType()), lastbb);
|
|
||||||
}
|
|
||||||
|
|
||||||
gIR->functions.pop_back();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debug info
|
||||||
|
if (global.params.symdebug) DtoDwarfFuncStart(fd);
|
||||||
|
|
||||||
|
LLValue* parentNested = NULL;
|
||||||
|
if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
|
||||||
|
if (!fd->isStatic()) // huh?
|
||||||
|
parentNested = fd2->ir.irFunc->nestedVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need result variable? (nested)
|
||||||
|
if (fd->vresult && fd->vresult->nestedref) {
|
||||||
|
Logger::println("nested vresult value: %s", fd->vresult->toChars());
|
||||||
|
fd->nestedVars.insert(fd->vresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct nested variables struct
|
||||||
|
if (!fd->nestedVars.empty() || parentNested) {
|
||||||
|
std::vector<const LLType*> nestTypes;
|
||||||
|
int j = 0;
|
||||||
|
if (parentNested) {
|
||||||
|
nestTypes.push_back(parentNested->getType());
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
||||||
|
VarDeclaration* vd = *i;
|
||||||
|
Logger::println("referenced nested variable %s", vd->toChars());
|
||||||
|
if (!vd->ir.irLocal)
|
||||||
|
vd->ir.irLocal = new IrLocal(vd);
|
||||||
|
vd->ir.irLocal->nestedIndex = j++;
|
||||||
|
if (vd->isParameter()) {
|
||||||
|
if (!vd->ir.irLocal->value) {
|
||||||
|
assert(vd == fd->vthis);
|
||||||
|
vd->ir.irLocal->value = fd->ir.irFunc->thisVar;
|
||||||
|
}
|
||||||
|
assert(vd->ir.irLocal->value);
|
||||||
|
nestTypes.push_back(vd->ir.irLocal->value->getType());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nestTypes.push_back(DtoType(vd->type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
|
||||||
|
Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
|
||||||
|
fd->ir.irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
|
||||||
|
if (parentNested) {
|
||||||
|
assert(fd->ir.irFunc->thisVar);
|
||||||
|
LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp");
|
||||||
|
gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp"));
|
||||||
|
}
|
||||||
|
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
||||||
|
VarDeclaration* vd = *i;
|
||||||
|
if (vd->isParameter()) {
|
||||||
|
assert(vd->ir.irLocal);
|
||||||
|
gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp"));
|
||||||
|
vd->ir.irLocal->value = fd->ir.irFunc->nestedVar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy _argptr to a memory location
|
||||||
|
if (f->linkage == LINKd && f->varargs == 1)
|
||||||
|
{
|
||||||
|
LLValue* argptrmem = new llvm::AllocaInst(fd->ir.irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
|
||||||
|
new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
|
||||||
|
fd->ir.irFunc->_argptr = argptrmem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// output function body
|
||||||
|
fd->fbody->toIR(gIR);
|
||||||
|
|
||||||
|
// llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
|
||||||
|
// in automatically, so we do it here.
|
||||||
|
if (!fd->isMain()) {
|
||||||
|
if (!gIR->scopereturned()) {
|
||||||
|
// pass the previous block into this block
|
||||||
|
if (global.params.symdebug) DtoDwarfFuncEnd(fd);
|
||||||
|
if (func->getReturnType() == LLType::VoidTy) {
|
||||||
|
llvm::ReturnInst::Create(gIR->scopebb());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// erase alloca point
|
||||||
|
allocaPoint->eraseFromParent();
|
||||||
|
allocaPoint = 0;
|
||||||
|
gIR->func()->allocapoint = 0;
|
||||||
|
|
||||||
|
gIR->scopes.pop_back();
|
||||||
|
|
||||||
|
// get rid of the endentry block, it's never used
|
||||||
|
assert(!func->getBasicBlockList().empty());
|
||||||
|
func->getBasicBlockList().pop_back();
|
||||||
|
|
||||||
|
// if the last block is empty now, it must be unreachable or it's a bug somewhere else
|
||||||
|
// would be nice to figure out how to assert that this is correct
|
||||||
|
llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
|
||||||
|
if (lastbb->empty()) {
|
||||||
|
if (lastbb->getNumUses() == 0)
|
||||||
|
lastbb->eraseFromParent();
|
||||||
|
else {
|
||||||
|
new llvm::UnreachableInst(lastbb);
|
||||||
|
/*if (func->getReturnType() == LLType::VoidTy) {
|
||||||
|
llvm::ReturnInst::Create(lastbb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the last block is not terminated we return a null value or void
|
||||||
|
// for some unknown reason this is needed when a void main() has a inline asm block ...
|
||||||
|
// this should be harmless for well formed code!
|
||||||
|
lastbb = &func->getBasicBlockList().back();
|
||||||
|
if (!lastbb->getTerminator())
|
||||||
|
{
|
||||||
|
Logger::println("adding missing return statement");
|
||||||
|
if (func->getReturnType() == LLType::VoidTy)
|
||||||
|
llvm::ReturnInst::Create(lastbb);
|
||||||
|
else
|
||||||
|
llvm::ReturnInst::Create(llvm::Constant::getNullValue(func->getReturnType()), lastbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
gIR->functions.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
25
gen/linker.cpp
Normal file
25
gen/linker.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include "gen/llvm.h"
|
||||||
|
#include "llvm/Linker.h"
|
||||||
|
|
||||||
|
#include "root.h"
|
||||||
|
#include "mars.h"
|
||||||
|
|
||||||
|
typedef std::vector<llvm::Module*> Module_vector;
|
||||||
|
|
||||||
|
void linkModules(llvm::Module* dst, const Module_vector& MV)
|
||||||
|
{
|
||||||
|
if (MV.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
llvm::Linker linker("llvmdc", dst);
|
||||||
|
|
||||||
|
std::string err;
|
||||||
|
for (Module_vector::const_iterator i=MV.begin(); i!=MV.end(); ++i)
|
||||||
|
{
|
||||||
|
if (!linker.LinkInModule(*i, &err))
|
||||||
|
{
|
||||||
|
error("%s", err.c_str());
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
gen/linker.h
Normal file
11
gen/linker.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef LLVMDC_GEN_LINKER_H
|
||||||
|
#define LLVMDC_GEN_LINKER_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links the modules given in MV in to dst.
|
||||||
|
* @param dst Destination module.
|
||||||
|
* @param MV Vector of modules to link in to destination.
|
||||||
|
*/
|
||||||
|
void linkModules(llvm::Module* dst, const std::vector<llvm::Module*>& MV);
|
||||||
|
|
||||||
|
#endif // LLVMDC_GEN_LINKER_H
|
19
gen/llvm.h
19
gen/llvm.h
|
@ -18,10 +18,27 @@ using llvm::IRBuilder;
|
||||||
|
|
||||||
#define GET_INTRINSIC_DECL(_X) (llvm::Intrinsic::getDeclaration(gIR->module, llvm::Intrinsic:: _X ))
|
#define GET_INTRINSIC_DECL(_X) (llvm::Intrinsic::getDeclaration(gIR->module, llvm::Intrinsic:: _X ))
|
||||||
|
|
||||||
// shortcuts for the _very_ common llvm types
|
// shortcuts for the common llvm types
|
||||||
|
|
||||||
typedef llvm::Type LLType;
|
typedef llvm::Type LLType;
|
||||||
|
typedef llvm::FunctionType LLFunctionType;
|
||||||
|
typedef llvm::PointerType LLPointerType;
|
||||||
|
typedef llvm::StructType LLStructType;
|
||||||
|
typedef llvm::ArrayType LLArrayType;
|
||||||
|
typedef llvm::IntegerType LLIntegerType;
|
||||||
|
typedef llvm::OpaqueType LLOpaqueType;
|
||||||
|
|
||||||
typedef llvm::Value LLValue;
|
typedef llvm::Value LLValue;
|
||||||
|
typedef llvm::GlobalValue LLGlobalValue;
|
||||||
|
typedef llvm::GlobalVariable LLGlobalVariable;
|
||||||
|
typedef llvm::Function LLFunction;
|
||||||
|
|
||||||
typedef llvm::Constant LLConstant;
|
typedef llvm::Constant LLConstant;
|
||||||
|
typedef llvm::ConstantStruct LLConstantStruct;
|
||||||
|
typedef llvm::ConstantArray LLConstantArray;
|
||||||
|
typedef llvm::ConstantInt LLConstantInt;
|
||||||
|
|
||||||
|
typedef llvm::PATypeHolder LLPATypeHolder;
|
||||||
|
|
||||||
#define LLSmallVector llvm::SmallVector
|
#define LLSmallVector llvm::SmallVector
|
||||||
|
|
||||||
|
|
1090
gen/llvmhelpers.cpp
Normal file
1090
gen/llvmhelpers.cpp
Normal file
File diff suppressed because it is too large
Load diff
65
gen/llvmhelpers.h
Normal file
65
gen/llvmhelpers.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#ifndef LLVMDC_GEN_LLVMHELPERS_H
|
||||||
|
#define LLVMDC_GEN_LLVMHELPERS_H
|
||||||
|
|
||||||
|
// dynamic memory helpers
|
||||||
|
LLValue* DtoNew(Type* newtype);
|
||||||
|
void DtoDeleteMemory(LLValue* ptr);
|
||||||
|
void DtoDeleteClass(LLValue* inst);
|
||||||
|
void DtoDeleteInterface(LLValue* inst);
|
||||||
|
void DtoDeleteArray(DValue* arr);
|
||||||
|
|
||||||
|
// assertion generator
|
||||||
|
void DtoAssert(Loc* loc, DValue* msg);
|
||||||
|
|
||||||
|
// nested variable/class helpers
|
||||||
|
LLValue* DtoNestedContext(FuncDeclaration* func);
|
||||||
|
LLValue* DtoNestedVariable(VarDeclaration* vd);
|
||||||
|
|
||||||
|
// basic operations
|
||||||
|
void DtoAssign(DValue* lhs, DValue* rhs);
|
||||||
|
|
||||||
|
// casts
|
||||||
|
DValue* DtoCastInt(DValue* val, Type* to);
|
||||||
|
DValue* DtoCastPtr(DValue* val, Type* to);
|
||||||
|
DValue* DtoCastFloat(DValue* val, Type* to);
|
||||||
|
DValue* DtoCast(DValue* val, Type* to);
|
||||||
|
|
||||||
|
// is template instance check
|
||||||
|
bool DtoIsTemplateInstance(Dsymbol* s);
|
||||||
|
|
||||||
|
// generates lazy static initialization code for a global variable
|
||||||
|
void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t);
|
||||||
|
|
||||||
|
// these are all basically drivers for the codegeneration called by the main loop
|
||||||
|
void DtoResolveDsymbol(Dsymbol* dsym);
|
||||||
|
void DtoDeclareDsymbol(Dsymbol* dsym);
|
||||||
|
void DtoDefineDsymbol(Dsymbol* dsym);
|
||||||
|
void DtoConstInitDsymbol(Dsymbol* dsym);
|
||||||
|
void DtoConstInitGlobal(VarDeclaration* vd);
|
||||||
|
void DtoEmptyResolveList();
|
||||||
|
void DtoEmptyDeclareList();
|
||||||
|
void DtoEmptyConstInitList();
|
||||||
|
void DtoEmptyAllLists();
|
||||||
|
void DtoForceDeclareDsymbol(Dsymbol* dsym);
|
||||||
|
void DtoForceConstInitDsymbol(Dsymbol* dsym);
|
||||||
|
void DtoForceDefineDsymbol(Dsymbol* dsym);
|
||||||
|
|
||||||
|
// initializer helpers
|
||||||
|
LLConstant* DtoConstInitializer(Type* type, Initializer* init);
|
||||||
|
LLConstant* DtoConstFieldInitializer(Type* type, Initializer* init);
|
||||||
|
DValue* DtoInitializer(Initializer* init);
|
||||||
|
|
||||||
|
// annotation generator
|
||||||
|
void DtoAnnotation(const char* str);
|
||||||
|
|
||||||
|
// getting typeinfo of type, base=true casts to object.TypeInfo
|
||||||
|
LLConstant* DtoTypeInfoOf(Type* ty, bool base=true);
|
||||||
|
|
||||||
|
// binary operations
|
||||||
|
DValue* DtoBinAdd(DValue* lhs, DValue* rhs);
|
||||||
|
DValue* DtoBinSub(DValue* lhs, DValue* rhs);
|
||||||
|
DValue* DtoBinMul(DValue* lhs, DValue* rhs);
|
||||||
|
DValue* DtoBinDiv(DValue* lhs, DValue* rhs);
|
||||||
|
DValue* DtoBinRem(DValue* lhs, DValue* rhs);
|
||||||
|
|
||||||
|
#endif
|
|
@ -158,12 +158,12 @@ static const LLType* rt_array2(const LLType* elemty)
|
||||||
static const LLType* rt_dg1()
|
static const LLType* rt_dg1()
|
||||||
{
|
{
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(rt_ptr(llvm::Type::Int8Ty));
|
types.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
types.push_back(rt_ptr(llvm::Type::Int8Ty));
|
types.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false);
|
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false);
|
||||||
|
|
||||||
std::vector<const LLType*> t;
|
std::vector<const LLType*> t;
|
||||||
t.push_back(rt_ptr(llvm::Type::Int8Ty));
|
t.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
t.push_back(rt_ptr(fty));
|
t.push_back(rt_ptr(fty));
|
||||||
return rt_ptr(llvm::StructType::get(t));
|
return rt_ptr(llvm::StructType::get(t));
|
||||||
}
|
}
|
||||||
|
@ -171,13 +171,13 @@ static const LLType* rt_dg1()
|
||||||
static const LLType* rt_dg2()
|
static const LLType* rt_dg2()
|
||||||
{
|
{
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(rt_ptr(llvm::Type::Int8Ty));
|
types.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
types.push_back(rt_ptr(llvm::Type::Int8Ty));
|
types.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
types.push_back(rt_ptr(llvm::Type::Int8Ty));
|
types.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false);
|
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false);
|
||||||
|
|
||||||
std::vector<const LLType*> t;
|
std::vector<const LLType*> t;
|
||||||
t.push_back(rt_ptr(llvm::Type::Int8Ty));
|
t.push_back(rt_ptr(LLType::Int8Ty));
|
||||||
t.push_back(rt_ptr(fty));
|
t.push_back(rt_ptr(fty));
|
||||||
return rt_ptr(llvm::StructType::get(t));
|
return rt_ptr(llvm::StructType::get(t));
|
||||||
}
|
}
|
||||||
|
@ -186,14 +186,14 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
{
|
{
|
||||||
M = new llvm::Module("llvmdc internal runtime");
|
M = new llvm::Module("llvmdc internal runtime");
|
||||||
|
|
||||||
const LLType* voidTy = llvm::Type::VoidTy;
|
const LLType* voidTy = LLType::VoidTy;
|
||||||
const LLType* boolTy = llvm::Type::Int1Ty;
|
const LLType* boolTy = LLType::Int1Ty;
|
||||||
const LLType* byteTy = llvm::Type::Int8Ty;
|
const LLType* byteTy = LLType::Int8Ty;
|
||||||
const LLType* shortTy = llvm::Type::Int16Ty;
|
const LLType* shortTy = LLType::Int16Ty;
|
||||||
const LLType* intTy = llvm::Type::Int32Ty;
|
const LLType* intTy = LLType::Int32Ty;
|
||||||
const LLType* longTy = llvm::Type::Int64Ty;
|
const LLType* longTy = LLType::Int64Ty;
|
||||||
const LLType* floatTy = llvm::Type::FloatTy;
|
const LLType* floatTy = LLType::FloatTy;
|
||||||
const LLType* doubleTy = llvm::Type::DoubleTy;
|
const LLType* doubleTy = LLType::DoubleTy;
|
||||||
const LLType* sizeTy = DtoSize_t();
|
const LLType* sizeTy = DtoSize_t();
|
||||||
const LLType* voidPtrTy = rt_ptr(byteTy);
|
const LLType* voidPtrTy = rt_ptr(byteTy);
|
||||||
const LLType* stringTy = rt_array(byteTy);
|
const LLType* stringTy = rt_array(byteTy);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/runtime.h"
|
#include "gen/runtime.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/todebug.h"
|
#include "gen/todebug.h"
|
||||||
|
@ -74,7 +75,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||||
|
|
||||||
if (exp)
|
if (exp)
|
||||||
{
|
{
|
||||||
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
|
if (p->topfunc()->getReturnType() == LLType::VoidTy) {
|
||||||
IrFunction* f = p->func();
|
IrFunction* f = p->func();
|
||||||
assert(f->type->llvmRetInPtr);
|
assert(f->type->llvmRetInPtr);
|
||||||
assert(f->decl->ir.irFunc->retArg);
|
assert(f->decl->ir.irFunc->retArg);
|
||||||
|
@ -128,7 +129,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(p->topfunc()->getReturnType() == llvm::Type::VoidTy);
|
assert(p->topfunc()->getReturnType() == LLType::VoidTy);
|
||||||
emit_finallyblocks(p, enclosingtryfinally, NULL);
|
emit_finallyblocks(p, enclosingtryfinally, NULL);
|
||||||
|
|
||||||
if (gIR->func()->inVolatile) {
|
if (gIR->func()->inVolatile) {
|
||||||
|
@ -187,7 +188,7 @@ void IfStatement::toIR(IRState* p)
|
||||||
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endif", gIR->topfunc(), oldend);
|
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endif", gIR->topfunc(), oldend);
|
||||||
llvm::BasicBlock* elsebb = elsebody ? llvm::BasicBlock::Create("else", gIR->topfunc(), endbb) : endbb;
|
llvm::BasicBlock* elsebb = elsebody ? llvm::BasicBlock::Create("else", gIR->topfunc(), endbb) : endbb;
|
||||||
|
|
||||||
if (cond_val->getType() != llvm::Type::Int1Ty) {
|
if (cond_val->getType() != LLType::Int1Ty) {
|
||||||
Logger::cout() << "if conditional: " << *cond_val << '\n';
|
Logger::cout() << "if conditional: " << *cond_val << '\n';
|
||||||
cond_val = DtoBoolean(cond_val);
|
cond_val = DtoBoolean(cond_val);
|
||||||
}
|
}
|
||||||
|
@ -892,10 +893,10 @@ void ForeachStatement::toIR(IRState* p)
|
||||||
else {
|
else {
|
||||||
Logger::println("foreach over dynamic array");
|
Logger::println("foreach over dynamic array");
|
||||||
val = aggrval->getRVal();
|
val = aggrval->getRVal();
|
||||||
niters = DtoGEPi(val,0,0,"tmp",p->scopebb());
|
niters = DtoGEPi(val,0,0);
|
||||||
niters = p->ir->CreateLoad(niters, "numiterations");
|
niters = DtoLoad(niters, "numiterations");
|
||||||
val = DtoGEPi(val,0,1,"tmp",p->scopebb());
|
val = DtoGEPi(val,0,1);
|
||||||
val = p->ir->CreateLoad(val, "collection");
|
val = DtoLoad(val, "collection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -935,7 +936,7 @@ void ForeachStatement::toIR(IRState* p)
|
||||||
p->scope() = IRScope(condbb,bodybb);
|
p->scope() = IRScope(condbb,bodybb);
|
||||||
|
|
||||||
LLValue* done = 0;
|
LLValue* done = 0;
|
||||||
LLValue* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb());
|
LLValue* load = DtoLoad(keyvar);
|
||||||
if (op == TOKforeach) {
|
if (op == TOKforeach) {
|
||||||
done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb());
|
done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,72 +9,13 @@
|
||||||
|
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/structs.h"
|
#include "gen/structs.h"
|
||||||
|
|
||||||
#include "ir/irstruct.h"
|
#include "ir/irstruct.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const LLType* DtoStructType(Type* t)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
std::vector<const LLType*> types;
|
|
||||||
return llvm::StructType::get(types);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
LLValue* DtoStructZeroInit(LLValue* v)
|
|
||||||
{
|
|
||||||
assert(gIR);
|
|
||||||
uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0));
|
|
||||||
//LLType* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
|
|
||||||
const LLType* sarrty = getPtrToType(llvm::Type::Int8Ty);
|
|
||||||
|
|
||||||
LLValue* sarr = DtoBitCast(v, sarrty);
|
|
||||||
|
|
||||||
llvm::Function* fn = LLVM_DeclareMemSet32();
|
|
||||||
assert(fn);
|
|
||||||
std::vector<LLValue*> llargs;
|
|
||||||
llargs.resize(4);
|
|
||||||
llargs[0] = sarr;
|
|
||||||
llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
|
|
||||||
llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
||||||
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
||||||
|
|
||||||
LLValue* ret = llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
LLValue* DtoStructCopy(LLValue* dst, LLValue* src)
|
|
||||||
{
|
|
||||||
Logger::cout() << "dst = " << *dst << " src = " << *src << '\n';
|
|
||||||
assert(dst->getType() == src->getType());
|
|
||||||
assert(gIR);
|
|
||||||
|
|
||||||
uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0));
|
|
||||||
//LLType* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
|
|
||||||
const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
|
|
||||||
|
|
||||||
LLValue* dstarr = DtoBitCast(dst,arrty);
|
|
||||||
LLValue* srcarr = DtoBitCast(src,arrty);
|
|
||||||
|
|
||||||
llvm::Function* fn = LLVM_DeclareMemCpy32();
|
|
||||||
std::vector<LLValue*> llargs;
|
|
||||||
llargs.resize(4);
|
|
||||||
llargs[0] = dstarr;
|
|
||||||
llargs[1] = srcarr;
|
|
||||||
llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
||||||
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
||||||
|
|
||||||
return llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
LLConstant* DtoConstStructInitializer(StructInitializer* si)
|
LLConstant* DtoConstStructInitializer(StructInitializer* si)
|
||||||
{
|
{
|
||||||
|
@ -227,7 +168,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||||
if (irstruct->offsets.empty())
|
if (irstruct->offsets.empty())
|
||||||
{
|
{
|
||||||
Logger::println("has no fields");
|
Logger::println("has no fields");
|
||||||
fieldtypes.push_back(llvm::Type::Int8Ty);
|
fieldtypes.push_back(LLType::Int8Ty);
|
||||||
structtype = llvm::StructType::get(fieldtypes);
|
structtype = llvm::StructType::get(fieldtypes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -273,7 +214,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||||
fieldtypes.push_back(fieldtype);
|
fieldtypes.push_back(fieldtype);
|
||||||
irstruct->defaultFields.push_back(fieldinit);
|
irstruct->defaultFields.push_back(fieldinit);
|
||||||
if (fieldpad) {
|
if (fieldpad) {
|
||||||
fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
|
fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
|
||||||
irstruct->defaultFields.push_back(NULL);
|
irstruct->defaultFields.push_back(NULL);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
@ -292,7 +233,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||||
fieldtypes.push_back(fieldtype);
|
fieldtypes.push_back(fieldtype);
|
||||||
irstruct->defaultFields.push_back(fieldinit);
|
irstruct->defaultFields.push_back(fieldinit);
|
||||||
if (fieldpad) {
|
if (fieldpad) {
|
||||||
fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
|
fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
|
||||||
irstruct->defaultFields.push_back(NULL);
|
irstruct->defaultFields.push_back(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +321,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i));
|
const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i));
|
||||||
std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
|
std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
|
||||||
c = llvm::ConstantArray::get(arrty, vals);
|
c = llvm::ConstantArray::get(arrty, vals);
|
||||||
}
|
}
|
||||||
fieldinits_ll.push_back(c);
|
fieldinits_ll.push_back(c);
|
||||||
|
@ -392,6 +333,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
||||||
// always generate the constant initalizer
|
// always generate the constant initalizer
|
||||||
if (!sd->zeroInit) {
|
if (!sd->zeroInit) {
|
||||||
Logger::println("Not zero initialized");
|
Logger::println("Not zero initialized");
|
||||||
|
#if 0
|
||||||
//assert(tk == gIR->gIR->topstruct()().size());
|
//assert(tk == gIR->gIR->topstruct()().size());
|
||||||
#ifndef LLVMD_NO_LOGGER
|
#ifndef LLVMD_NO_LOGGER
|
||||||
Logger::cout() << "struct type: " << *structtype << '\n';
|
Logger::cout() << "struct type: " << *structtype << '\n';
|
||||||
|
@ -403,6 +345,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
||||||
}
|
}
|
||||||
Logger::cout() << "Initializer printed" << '\n';
|
Logger::cout() << "Initializer printed" << '\n';
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
sd->ir.irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
|
sd->ir.irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -498,8 +441,8 @@ DUnion::DUnion()
|
||||||
static void push_nulls(size_t nbytes, std::vector<LLConstant*>& out)
|
static void push_nulls(size_t nbytes, std::vector<LLConstant*>& out)
|
||||||
{
|
{
|
||||||
assert(nbytes > 0);
|
assert(nbytes > 0);
|
||||||
std::vector<LLConstant*> i(nbytes, llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
|
std::vector<LLConstant*> i(nbytes, llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
|
||||||
out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(llvm::Type::Int8Ty, nbytes), i));
|
out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(LLType::Int8Ty, nbytes), i));
|
||||||
}
|
}
|
||||||
|
|
||||||
LLConstant* DUnion::getConst(std::vector<DUnionIdx>& in)
|
LLConstant* DUnion::getConst(std::vector<DUnionIdx>& in)
|
||||||
|
|
|
@ -3,11 +3,6 @@
|
||||||
|
|
||||||
struct StructInitializer;
|
struct StructInitializer;
|
||||||
|
|
||||||
const LLType* DtoStructType(Type* t);
|
|
||||||
|
|
||||||
LLValue* DtoStructZeroInit(LLValue* v);
|
|
||||||
LLValue* DtoStructCopy(LLValue* dst, LLValue* src);
|
|
||||||
|
|
||||||
LLConstant* DtoConstStructInitializer(StructInitializer* si);
|
LLConstant* DtoConstStructInitializer(StructInitializer* si);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
118
gen/todebug.cpp
118
gen/todebug.cpp
|
@ -22,17 +22,15 @@ static const llvm::PointerType* ptrTy(const LLType* t)
|
||||||
|
|
||||||
static const llvm::PointerType* dbgArrTy()
|
static const llvm::PointerType* dbgArrTy()
|
||||||
{
|
{
|
||||||
std::vector<const LLType*> t;
|
return ptrTy(llvm::StructType::get(NULL,NULL));
|
||||||
return ptrTy(llvm::StructType::get(t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLConstant* dbgToArrTy(LLConstant* c)
|
static LLConstant* dbgToArrTy(LLConstant* c)
|
||||||
{
|
{
|
||||||
Logger::cout() << "casting: " << *c << '\n';
|
|
||||||
return llvm::ConstantExpr::getBitCast(c, dbgArrTy());
|
return llvm::ConstantExpr::getBitCast(c, dbgArrTy());
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Ty(X) llvm::Type::X
|
#define Ty(X) LLType::X
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -48,7 +46,7 @@ const llvm::StructType* GetDwarfAnchorType()
|
||||||
uint ;; Tag of descriptors grouped by the anchor
|
uint ;; Tag of descriptors grouped by the anchor
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::vector<const LLType*> elems(2, Ty(Int32Ty));
|
|
||||||
const llvm::StructType* t = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type"));
|
const llvm::StructType* t = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -154,7 +152,7 @@ llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
|
LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
|
||||||
{
|
{
|
||||||
std::vector<LLConstant*> vals;
|
std::vector<LLConstant*> vals;
|
||||||
vals.push_back(llvm::ConstantExpr::getAdd(
|
vals.push_back(llvm::ConstantExpr::getAdd(
|
||||||
|
@ -203,3 +201,111 @@ void DtoDwarfStopPoint(unsigned ln)
|
||||||
args.push_back(dbgToArrTy(DtoDwarfCompileUnit(fd->getModule())));
|
args.push_back(dbgToArrTy(DtoDwarfCompileUnit(fd->getModule())));
|
||||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
|
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const llvm::StructType* GetDwarfBasicTypeType() {
|
||||||
|
return isaStruct(gIR->module->getTypeByName("llvm.dbg.basictype.type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit)
|
||||||
|
{
|
||||||
|
const LLType* T = DtoType(type);
|
||||||
|
|
||||||
|
std::vector<LLConstant*> vals;
|
||||||
|
// tag
|
||||||
|
vals.push_back(llvm::ConstantExpr::getAdd(
|
||||||
|
DtoConstUint(DW_TAG_base_type),
|
||||||
|
DtoConstUint(llvm::LLVMDebugVersion)));
|
||||||
|
// context
|
||||||
|
vals.push_back(dbgToArrTy(compileUnit));
|
||||||
|
// name
|
||||||
|
vals.push_back(DtoConstStringPtr(type->toChars(), "llvm.metadata"));
|
||||||
|
// compile unit where defined
|
||||||
|
vals.push_back(getNullPtr(dbgArrTy()));
|
||||||
|
// line number where defined
|
||||||
|
vals.push_back(DtoConstInt(0));
|
||||||
|
// size in bits
|
||||||
|
vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
|
||||||
|
// alignment in bits
|
||||||
|
vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
|
||||||
|
// offset in bits
|
||||||
|
vals.push_back(LLConstantInt::get(LLType::Int64Ty, 0, false));
|
||||||
|
// FIXME: dont know what this is
|
||||||
|
vals.push_back(DtoConstUint(0));
|
||||||
|
// dwarf type
|
||||||
|
unsigned id;
|
||||||
|
if (type->isintegral())
|
||||||
|
{
|
||||||
|
if (type->isunsigned())
|
||||||
|
id = llvm::dwarf::DW_ATE_unsigned;
|
||||||
|
else
|
||||||
|
id = llvm::dwarf::DW_ATE_signed;
|
||||||
|
}
|
||||||
|
else if (type->isfloating())
|
||||||
|
{
|
||||||
|
id = llvm::dwarf::DW_ATE_float;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(0 && "unsupported basictype for debug info");
|
||||||
|
}
|
||||||
|
vals.push_back(DtoConstUint(id));
|
||||||
|
|
||||||
|
LLConstant* c = llvm::ConstantStruct::get(GetDwarfBasicTypeType(), vals);
|
||||||
|
LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.basictype", gIR->module);
|
||||||
|
gv->setSection("llvm.metadata");
|
||||||
|
return gv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const llvm::StructType* GetDwarfVariableType() {
|
||||||
|
return isaStruct(gIR->module->getTypeByName("llvm.dbg.variable.type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr)
|
||||||
|
{
|
||||||
|
unsigned tag;
|
||||||
|
if (vd->isParameter())
|
||||||
|
tag = DW_TAG_arg_variable;
|
||||||
|
else if (vd->isCodeseg())
|
||||||
|
assert(0 && "a static variable");
|
||||||
|
else
|
||||||
|
tag = DW_TAG_auto_variable;
|
||||||
|
|
||||||
|
std::vector<LLConstant*> vals;
|
||||||
|
// tag
|
||||||
|
vals.push_back(llvm::ConstantExpr::getAdd(
|
||||||
|
DtoConstUint(tag),
|
||||||
|
DtoConstUint(llvm::LLVMDebugVersion)));
|
||||||
|
// context
|
||||||
|
vals.push_back(dbgToArrTy(gIR->func()->dwarfSubProg));
|
||||||
|
// name
|
||||||
|
vals.push_back(DtoConstStringPtr(vd->toChars(), "llvm.metadata"));
|
||||||
|
// compile unit where defined
|
||||||
|
vals.push_back(dbgToArrTy(DtoDwarfCompileUnit(vd->getModule())));
|
||||||
|
// line number where defined
|
||||||
|
vals.push_back(DtoConstUint(vd->loc.linnum));
|
||||||
|
// type descriptor
|
||||||
|
vals.push_back(dbgToArrTy(typeDescr));
|
||||||
|
|
||||||
|
LLConstant* c = llvm::ConstantStruct::get(GetDwarfVariableType(), vals);
|
||||||
|
LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.variable", gIR->module);
|
||||||
|
gv->setSection("llvm.metadata");
|
||||||
|
return gv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr)
|
||||||
|
{
|
||||||
|
LLSmallVector<LLValue*,2> args;
|
||||||
|
args.push_back(DtoBitCast(var, dbgArrTy()));
|
||||||
|
args.push_back(dbgToArrTy(varDescr));
|
||||||
|
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end());
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,13 @@ void DtoDwarfFuncEnd(FuncDeclaration* fd);
|
||||||
|
|
||||||
void DtoDwarfStopPoint(unsigned ln);
|
void DtoDwarfStopPoint(unsigned ln);
|
||||||
|
|
||||||
|
const llvm::StructType* GetDwarfBasicTypeType();
|
||||||
|
LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit);
|
||||||
|
|
||||||
|
const llvm::StructType* GetDwarfVariableType();
|
||||||
|
LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr);
|
||||||
|
void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr);
|
||||||
|
|
||||||
#endif // LLVMDC_GEN_TODEBUG_H
|
#endif // LLVMDC_GEN_TODEBUG_H
|
||||||
|
|
||||||
|
|
||||||
|
|
174
gen/toir.cpp
174
gen/toir.cpp
|
@ -24,6 +24,7 @@
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/runtime.h"
|
#include "gen/runtime.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/structs.h"
|
#include "gen/structs.h"
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
#include "gen/dvalue.h"
|
#include "gen/dvalue.h"
|
||||||
#include "gen/aa.h"
|
#include "gen/aa.h"
|
||||||
#include "gen/functions.h"
|
#include "gen/functions.h"
|
||||||
|
#include "gen/todebug.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -75,6 +77,14 @@ DValue* DeclarationExp::toElem(IRState* p)
|
||||||
assert(!vd->ir.irLocal);
|
assert(!vd->ir.irLocal);
|
||||||
vd->ir.irLocal = new IrLocal(vd);
|
vd->ir.irLocal = new IrLocal(vd);
|
||||||
vd->ir.irLocal->value = allocainst;
|
vd->ir.irLocal->value = allocainst;
|
||||||
|
|
||||||
|
if (global.params.symdebug && (vd->type->isintegral() || vd->type->isfloating()))
|
||||||
|
{
|
||||||
|
LLGlobalVariable* cu = DtoDwarfCompileUnit(vd->getModule());
|
||||||
|
LLGlobalVariable* bt = DtoDwarfBasicType(vd->type, cu);
|
||||||
|
LLGlobalVariable* vdesc = DtoDwarfVariable(vd, bt);
|
||||||
|
DtoDwarfDeclare(allocainst, vdesc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
|
Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
|
||||||
|
@ -315,7 +325,7 @@ LLConstant* IntegerExp::toConstElem(IRState* p)
|
||||||
LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false);
|
LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false);
|
||||||
return llvm::ConstantExpr::getIntToPtr(i, t);
|
return llvm::ConstantExpr::getIntToPtr(i, t);
|
||||||
}
|
}
|
||||||
assert(llvm::isa<llvm::IntegerType>(t));
|
assert(llvm::isa<LLIntegerType>(t));
|
||||||
LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned());
|
LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned());
|
||||||
assert(c);
|
assert(c);
|
||||||
Logger::cout() << "value = " << *c << '\n';
|
Logger::cout() << "value = " << *c << '\n';
|
||||||
|
@ -410,10 +420,10 @@ DValue* StringExp::toElem(IRState* p)
|
||||||
Type* cty = DtoDType(dtype->next);
|
Type* cty = DtoDType(dtype->next);
|
||||||
|
|
||||||
const LLType* ct = DtoType(cty);
|
const LLType* ct = DtoType(cty);
|
||||||
if (ct == llvm::Type::VoidTy)
|
if (ct == LLType::VoidTy)
|
||||||
ct = llvm::Type::Int8Ty;
|
ct = LLType::Int8Ty;
|
||||||
//printf("ct = %s\n", type->next->toChars());
|
//printf("ct = %s\n", type->next->toChars());
|
||||||
const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1);
|
const LLArrayType* at = LLArrayType::get(ct,len+1);
|
||||||
|
|
||||||
LLConstant* _init;
|
LLConstant* _init;
|
||||||
if (cty->size() == 1) {
|
if (cty->size() == 1) {
|
||||||
|
@ -446,7 +456,7 @@ DValue* StringExp::toElem(IRState* p)
|
||||||
Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
|
Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
|
||||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module);
|
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module);
|
||||||
|
|
||||||
llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||||
LLConstant* idxs[2] = { zero, zero };
|
LLConstant* idxs[2] = { zero, zero };
|
||||||
LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
||||||
|
|
||||||
|
@ -471,7 +481,7 @@ DValue* StringExp::toElem(IRState* p)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
else if (dtype->ty == Tsarray) {
|
else if (dtype->ty == Tsarray) {
|
||||||
const LLType* dstType = getPtrToType(llvm::ArrayType::get(ct, len));
|
const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
|
||||||
LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
|
LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
|
||||||
return new DVarValue(type, emem, true);
|
return new DVarValue(type, emem, true);
|
||||||
}
|
}
|
||||||
|
@ -497,7 +507,7 @@ LLConstant* StringExp::toConstElem(IRState* p)
|
||||||
size_t endlen = nullterm ? len+1 : len;
|
size_t endlen = nullterm ? len+1 : len;
|
||||||
|
|
||||||
const LLType* ct = DtoType(cty);
|
const LLType* ct = DtoType(cty);
|
||||||
const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen);
|
const LLArrayType* at = LLArrayType::get(ct,endlen);
|
||||||
|
|
||||||
LLConstant* _init;
|
LLConstant* _init;
|
||||||
if (cty->size() == 1) {
|
if (cty->size() == 1) {
|
||||||
|
@ -536,7 +546,7 @@ LLConstant* StringExp::toConstElem(IRState* p)
|
||||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
|
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
|
||||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module);
|
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module);
|
||||||
|
|
||||||
llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||||
LLConstant* idxs[2] = { zero, zero };
|
LLConstant* idxs[2] = { zero, zero };
|
||||||
LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
||||||
|
|
||||||
|
@ -880,8 +890,6 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
Type* e1type = DtoDType(e1->type);
|
Type* e1type = DtoDType(e1->type);
|
||||||
|
|
||||||
bool delegateCall = false;
|
bool delegateCall = false;
|
||||||
LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false);
|
|
||||||
LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false);
|
|
||||||
LINK dlink = LINKd;
|
LINK dlink = LINKd;
|
||||||
|
|
||||||
// hidden struct return parameter handling
|
// hidden struct return parameter handling
|
||||||
|
@ -952,7 +960,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
DValue* expv = exp->toElem(p);
|
DValue* expv = exp->toElem(p);
|
||||||
if (expv->getType()->toBasetype()->ty != Tint32)
|
if (expv->getType()->toBasetype()->ty != Tint32)
|
||||||
expv = DtoCast(expv, Type::tint32);
|
expv = DtoCast(expv, Type::tint32);
|
||||||
LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
|
LLValue* alloc = new llvm::AllocaInst(LLType::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
|
||||||
// done
|
// done
|
||||||
return new DImValue(type, alloc);
|
return new DImValue(type, alloc);
|
||||||
}
|
}
|
||||||
|
@ -972,32 +980,32 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
assert(funcval != 0);
|
assert(funcval != 0);
|
||||||
std::vector<LLValue*> llargs(n, 0);
|
std::vector<LLValue*> llargs(n, 0);
|
||||||
|
|
||||||
const llvm::FunctionType* llfnty = 0;
|
const LLFunctionType* llfnty = 0;
|
||||||
|
|
||||||
// TODO: review the stuff below, using the llvm type to choose seem like a bad idea. the D type should be used.
|
// TODO: review the stuff below, using the llvm type to choose seem like a bad idea. the D type should be used.
|
||||||
//
|
//
|
||||||
// normal function call
|
// normal function call
|
||||||
if (llvm::isa<llvm::FunctionType>(funcval->getType())) {
|
if (llvm::isa<LLFunctionType>(funcval->getType())) {
|
||||||
llfnty = llvm::cast<llvm::FunctionType>(funcval->getType());
|
llfnty = llvm::cast<LLFunctionType>(funcval->getType());
|
||||||
}
|
}
|
||||||
// pointer to something
|
// pointer to something
|
||||||
else if (isaPointer(funcval->getType())) {
|
else if (isaPointer(funcval->getType())) {
|
||||||
// pointer to function pointer - I think this not really supposed to happen, but does :/
|
// pointer to function pointer - I think this not really supposed to happen, but does :/
|
||||||
// seems like sometimes we get a func* other times a func**
|
// seems like sometimes we get a func* other times a func**
|
||||||
if (isaPointer(funcval->getType()->getContainedType(0))) {
|
if (isaPointer(funcval->getType()->getContainedType(0))) {
|
||||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
funcval = DtoLoad(funcval);
|
||||||
}
|
}
|
||||||
// function pointer
|
// function pointer
|
||||||
if (llvm::isa<llvm::FunctionType>(funcval->getType()->getContainedType(0))) {
|
if (llvm::isa<LLFunctionType>(funcval->getType()->getContainedType(0))) {
|
||||||
//Logger::cout() << "function pointer type:\n" << *funcval << '\n';
|
//Logger::cout() << "function pointer type:\n" << *funcval << '\n';
|
||||||
llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()->getContainedType(0));
|
llfnty = llvm::cast<LLFunctionType>(funcval->getType()->getContainedType(0));
|
||||||
}
|
}
|
||||||
// struct pointer - delegate
|
// struct pointer - delegate
|
||||||
else if (isaStruct(funcval->getType()->getContainedType(0))) {
|
else if (isaStruct(funcval->getType()->getContainedType(0))) {
|
||||||
funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb());
|
funcval = DtoGEPi(funcval,0,1);
|
||||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
funcval = DtoLoad(funcval);
|
||||||
const LLType* ty = funcval->getType()->getContainedType(0);
|
const LLType* ty = funcval->getType()->getContainedType(0);
|
||||||
llfnty = llvm::cast<llvm::FunctionType>(ty);
|
llfnty = llvm::cast<LLFunctionType>(ty);
|
||||||
}
|
}
|
||||||
// unknown
|
// unknown
|
||||||
else {
|
else {
|
||||||
|
@ -1011,7 +1019,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
//Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
|
//Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
|
||||||
|
|
||||||
// argument handling
|
// argument handling
|
||||||
llvm::FunctionType::param_iterator argiter = llfnty->param_begin();
|
LLFunctionType::param_iterator argiter = llfnty->param_begin();
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
IRExp* topexp = p->topexp();
|
IRExp* topexp = p->topexp();
|
||||||
|
@ -1069,8 +1077,8 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
// delegate context arguments
|
// delegate context arguments
|
||||||
else if (delegateCall) {
|
else if (delegateCall) {
|
||||||
Logger::println("Delegate Call");
|
Logger::println("Delegate Call");
|
||||||
LLValue* contextptr = DtoGEP(fn->getRVal(),zero,zero,"tmp",p->scopebb());
|
LLValue* contextptr = DtoGEPi(fn->getRVal(),0,0);
|
||||||
llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb());
|
llargs[j] = DtoLoad(contextptr);
|
||||||
++j;
|
++j;
|
||||||
++argiter;
|
++argiter;
|
||||||
}
|
}
|
||||||
|
@ -1079,8 +1087,8 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
Logger::println("Nested Call");
|
Logger::println("Nested Call");
|
||||||
LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration());
|
LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration());
|
||||||
if (!contextptr)
|
if (!contextptr)
|
||||||
contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
|
contextptr = llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty));
|
||||||
llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty));
|
llargs[j] = DtoBitCast(contextptr, getPtrToType(LLType::Int8Ty));
|
||||||
++j;
|
++j;
|
||||||
++argiter;
|
++argiter;
|
||||||
}
|
}
|
||||||
|
@ -1094,7 +1102,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
Argument* fnarg = Argument::getNth(tf->parameters, i);
|
Argument* fnarg = Argument::getNth(tf->parameters, i);
|
||||||
Expression* exp = (Expression*)arguments->data[i];
|
Expression* exp = (Expression*)arguments->data[i];
|
||||||
DValue* expelem = exp->toElem(p);
|
DValue* expelem = exp->toElem(p);
|
||||||
llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty));
|
llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(LLType::Int8Ty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// d variadic function
|
// d variadic function
|
||||||
|
@ -1117,7 +1125,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
Expression* argexp = (Expression*)arguments->data[i];
|
Expression* argexp = (Expression*)arguments->data[i];
|
||||||
vtypes.push_back(DtoType(argexp->type));
|
vtypes.push_back(DtoType(argexp->type));
|
||||||
}
|
}
|
||||||
const llvm::StructType* vtype = llvm::StructType::get(vtypes);
|
const LLStructType* vtype = LLStructType::get(vtypes);
|
||||||
Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
|
Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
|
||||||
LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
|
LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
|
||||||
|
|
||||||
|
@ -1133,7 +1141,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
// build type info array
|
// build type info array
|
||||||
assert(Type::typeinfo->ir.irStruct->constInit);
|
assert(Type::typeinfo->ir.irStruct->constInit);
|
||||||
const LLType* typeinfotype = DtoType(Type::typeinfo->type);
|
const LLType* typeinfotype = DtoType(Type::typeinfo->type);
|
||||||
const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
|
const LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements());
|
||||||
|
|
||||||
llvm::GlobalVariable* typeinfomem =
|
llvm::GlobalVariable* typeinfomem =
|
||||||
new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module);
|
new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module);
|
||||||
|
@ -1162,7 +1170,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
// specify arguments
|
// specify arguments
|
||||||
llargs[j] = typeinfoarrayparam;;
|
llargs[j] = typeinfoarrayparam;;
|
||||||
j++;
|
j++;
|
||||||
llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
|
llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(LLType::Int8Ty), "tmp");
|
||||||
j++;
|
j++;
|
||||||
|
|
||||||
// pass non variadic args
|
// pass non variadic args
|
||||||
|
@ -1228,7 +1236,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
|
|
||||||
// void returns cannot not be named
|
// void returns cannot not be named
|
||||||
const char* varname = "";
|
const char* varname = "";
|
||||||
if (llfnty->getReturnType() != llvm::Type::VoidTy)
|
if (llfnty->getReturnType() != LLType::VoidTy)
|
||||||
varname = "tmp";
|
varname = "tmp";
|
||||||
|
|
||||||
//Logger::cout() << "Calling: " << *funcval << '\n';
|
//Logger::cout() << "Calling: " << *funcval << '\n';
|
||||||
|
@ -1425,13 +1433,13 @@ DValue* DotVarExp::toElem(IRState* p)
|
||||||
assert(fdecl->vtblIndex > 0);
|
assert(fdecl->vtblIndex > 0);
|
||||||
assert(e1type->ty == Tclass);
|
assert(e1type->ty == Tclass);
|
||||||
|
|
||||||
LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||||
LLValue* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false);
|
LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false);
|
||||||
//Logger::cout() << "vthis: " << *vthis << '\n';
|
//Logger::cout() << "vthis: " << *vthis << '\n';
|
||||||
funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb());
|
funcval = DtoGEP(vthis, zero, zero);
|
||||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
funcval = DtoLoad(funcval);
|
||||||
funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb());
|
funcval = DtoGEP(funcval, zero, vtblidx, toChars());
|
||||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
funcval = DtoLoad(funcval);
|
||||||
#if OPAQUE_VTBLS
|
#if OPAQUE_VTBLS
|
||||||
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
|
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
|
||||||
Logger::cout() << "funcval casted: " << *funcval << '\n';
|
Logger::cout() << "funcval casted: " << *funcval << '\n';
|
||||||
|
@ -1465,10 +1473,10 @@ DValue* ThisExp::toElem(IRState* p)
|
||||||
LLValue* v;
|
LLValue* v;
|
||||||
v = p->func()->decl->ir.irFunc->thisVar;
|
v = p->func()->decl->ir.irFunc->thisVar;
|
||||||
if (llvm::isa<llvm::AllocaInst>(v))
|
if (llvm::isa<llvm::AllocaInst>(v))
|
||||||
v = new llvm::LoadInst(v, "tmp", p->scopebb());
|
v = DtoLoad(v);
|
||||||
const LLType* t = DtoType(type);
|
const LLType* t = DtoType(type);
|
||||||
if (v->getType() != t)
|
if (v->getType() != t)
|
||||||
v = DtoBitCast(v, t, "tmp");
|
v = DtoBitCast(v, t);
|
||||||
return new DThisValue(vd, v);
|
return new DThisValue(vd, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,20 +1499,20 @@ DValue* IndexExp::toElem(IRState* p)
|
||||||
DValue* r = e2->toElem(p);
|
DValue* r = e2->toElem(p);
|
||||||
p->arrays.pop_back();
|
p->arrays.pop_back();
|
||||||
|
|
||||||
LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
LLValue* zero = DtoConstUint(0);
|
||||||
LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
LLValue* one = DtoConstUint(1);
|
||||||
|
|
||||||
LLValue* arrptr = 0;
|
LLValue* arrptr = 0;
|
||||||
if (e1type->ty == Tpointer) {
|
if (e1type->ty == Tpointer) {
|
||||||
arrptr = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb());
|
arrptr = DtoGEP1(l->getRVal(),r->getRVal());
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Tsarray) {
|
else if (e1type->ty == Tsarray) {
|
||||||
arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb());
|
arrptr = DtoGEP(l->getRVal(), zero, r->getRVal());
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Tarray) {
|
else if (e1type->ty == Tarray) {
|
||||||
arrptr = DtoGEP(l->getRVal(),zero,one,"tmp",p->scopebb());
|
arrptr = DtoGEP(l->getRVal(),zero,one);
|
||||||
arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb());
|
arrptr = DtoLoad(arrptr);
|
||||||
arrptr = llvm::GetElementPtrInst::Create(arrptr,r->getRVal(),"tmp",p->scopebb());
|
arrptr = DtoGEP1(arrptr,r->getRVal());
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Taarray) {
|
else if (e1type->ty == Taarray) {
|
||||||
return DtoAAIndex(type, l, r);
|
return DtoAAIndex(type, l, r);
|
||||||
|
@ -1530,8 +1538,8 @@ DValue* SliceExp::toElem(IRState* p)
|
||||||
LLValue* vmem = v->getRVal();
|
LLValue* vmem = v->getRVal();
|
||||||
assert(vmem);
|
assert(vmem);
|
||||||
|
|
||||||
LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
LLValue* zero = DtoConstUint(0);
|
||||||
LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
LLValue* one = DtoConstUint(1);
|
||||||
|
|
||||||
LLValue* emem = 0;
|
LLValue* emem = 0;
|
||||||
LLValue* earg = 0;
|
LLValue* earg = 0;
|
||||||
|
@ -1552,32 +1560,32 @@ DValue* SliceExp::toElem(IRState* p)
|
||||||
emem = v->getRVal();
|
emem = v->getRVal();
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Tarray) {
|
else if (e1type->ty == Tarray) {
|
||||||
LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb());
|
LLValue* tmp = DtoGEP(vmem,zero,one);
|
||||||
emem = new llvm::LoadInst(tmp,"tmp",p->scopebb());
|
emem = DtoLoad(tmp);
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Tsarray) {
|
else if (e1type->ty == Tsarray) {
|
||||||
emem = DtoGEP(vmem,zero,zero,"tmp",p->scopebb());
|
emem = DtoGEP(vmem,zero,zero);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(emem);
|
assert(emem);
|
||||||
|
|
||||||
llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(cv->c);
|
llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(cv->c);
|
||||||
if (!(lwr_is_zero = c->isZero())) {
|
if (!(lwr_is_zero = c->isZero())) {
|
||||||
emem = llvm::GetElementPtrInst::Create(emem,cv->c,"tmp",p->scopebb());
|
emem = DtoGEP1(emem,cv->c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (e1type->ty == Tarray) {
|
if (e1type->ty == Tarray) {
|
||||||
LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb());
|
LLValue* tmp = DtoGEP(vmem,zero,one);
|
||||||
tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb());
|
tmp = DtoLoad(tmp);
|
||||||
emem = llvm::GetElementPtrInst::Create(tmp,lo->getRVal(),"tmp",p->scopebb());
|
emem = DtoGEP1(tmp,lo->getRVal());
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Tsarray) {
|
else if (e1type->ty == Tsarray) {
|
||||||
emem = DtoGEP(vmem,zero,lo->getRVal(),"tmp",p->scopebb());
|
emem = DtoGEP(vmem,zero,lo->getRVal());
|
||||||
}
|
}
|
||||||
else if (e1type->ty == Tpointer) {
|
else if (e1type->ty == Tpointer) {
|
||||||
emem = llvm::GetElementPtrInst::Create(v->getRVal(),lo->getRVal(),"tmp",p->scopebb());
|
emem = DtoGEP1(v->getRVal(),lo->getRVal());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Logger::println("type = %s", e1type->toChars());
|
Logger::println("type = %s", e1type->toChars());
|
||||||
|
@ -1915,11 +1923,11 @@ DValue* NewExp::toElem(IRState* p)
|
||||||
// init
|
// init
|
||||||
TypeStruct* ts = (TypeStruct*)ntype;
|
TypeStruct* ts = (TypeStruct*)ntype;
|
||||||
if (ts->isZeroInit()) {
|
if (ts->isZeroInit()) {
|
||||||
DtoStructZeroInit(mem);
|
DtoAggrZeroInit(mem);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(ts->sym);
|
assert(ts->sym);
|
||||||
DtoStructCopy(mem,ts->sym->ir.irStruct->init);
|
DtoAggrCopy(mem,ts->sym->ir.irStruct->init);
|
||||||
}
|
}
|
||||||
return new DImValue(type, mem, false);
|
return new DImValue(type, mem, false);
|
||||||
}
|
}
|
||||||
|
@ -2071,7 +2079,7 @@ DValue* NotExp::toElem(IRState* p)
|
||||||
|
|
||||||
LLValue* b = DtoBoolean(u->getRVal());
|
LLValue* b = DtoBoolean(u->getRVal());
|
||||||
|
|
||||||
LLConstant* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true);
|
LLConstant* zero = llvm::ConstantInt::get(LLType::Int1Ty, 0, true);
|
||||||
b = p->ir->CreateICmpEQ(b,zero);
|
b = p->ir->CreateICmpEQ(b,zero);
|
||||||
|
|
||||||
return new DImValue(type, b);
|
return new DImValue(type, b);
|
||||||
|
@ -2087,7 +2095,7 @@ DValue* AndAndExp::toElem(IRState* p)
|
||||||
// allocate a temporary for the final result. failed to come up with a better way :/
|
// allocate a temporary for the final result. failed to come up with a better way :/
|
||||||
LLValue* resval = 0;
|
LLValue* resval = 0;
|
||||||
llvm::BasicBlock* entryblock = &p->topfunc()->front();
|
llvm::BasicBlock* entryblock = &p->topfunc()->front();
|
||||||
resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"andandtmp",p->topallocapoint());
|
resval = new llvm::AllocaInst(LLType::Int1Ty,"andandtmp",p->topallocapoint());
|
||||||
|
|
||||||
DValue* u = e1->toElem(p);
|
DValue* u = e1->toElem(p);
|
||||||
|
|
||||||
|
@ -2096,7 +2104,7 @@ DValue* AndAndExp::toElem(IRState* p)
|
||||||
llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend);
|
llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend);
|
||||||
|
|
||||||
LLValue* ubool = DtoBoolean(u->getRVal());
|
LLValue* ubool = DtoBoolean(u->getRVal());
|
||||||
new llvm::StoreInst(ubool,resval,p->scopebb());
|
DtoStore(ubool,resval);
|
||||||
llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb());
|
llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb());
|
||||||
|
|
||||||
p->scope() = IRScope(andand, andandend);
|
p->scope() = IRScope(andand, andandend);
|
||||||
|
@ -2104,12 +2112,12 @@ DValue* AndAndExp::toElem(IRState* p)
|
||||||
|
|
||||||
LLValue* vbool = DtoBoolean(v->getRVal());
|
LLValue* vbool = DtoBoolean(v->getRVal());
|
||||||
LLValue* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb());
|
LLValue* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb());
|
||||||
new llvm::StoreInst(uandvbool,resval,p->scopebb());
|
DtoStore(uandvbool,resval);
|
||||||
llvm::BranchInst::Create(andandend,p->scopebb());
|
llvm::BranchInst::Create(andandend,p->scopebb());
|
||||||
|
|
||||||
p->scope() = IRScope(andandend, oldend);
|
p->scope() = IRScope(andandend, oldend);
|
||||||
|
|
||||||
resval = new llvm::LoadInst(resval,"tmp",p->scopebb());
|
resval = DtoLoad(resval);
|
||||||
return new DImValue(type, resval);
|
return new DImValue(type, resval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2123,7 +2131,7 @@ DValue* OrOrExp::toElem(IRState* p)
|
||||||
// allocate a temporary for the final result. failed to come up with a better way :/
|
// allocate a temporary for the final result. failed to come up with a better way :/
|
||||||
LLValue* resval = 0;
|
LLValue* resval = 0;
|
||||||
llvm::BasicBlock* entryblock = &p->topfunc()->front();
|
llvm::BasicBlock* entryblock = &p->topfunc()->front();
|
||||||
resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"orortmp",p->topallocapoint());
|
resval = new llvm::AllocaInst(LLType::Int1Ty,"orortmp",p->topallocapoint());
|
||||||
|
|
||||||
DValue* u = e1->toElem(p);
|
DValue* u = e1->toElem(p);
|
||||||
|
|
||||||
|
@ -2132,14 +2140,14 @@ DValue* OrOrExp::toElem(IRState* p)
|
||||||
llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend);
|
llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend);
|
||||||
|
|
||||||
LLValue* ubool = DtoBoolean(u->getRVal());
|
LLValue* ubool = DtoBoolean(u->getRVal());
|
||||||
new llvm::StoreInst(ubool,resval,p->scopebb());
|
DtoStore(ubool,resval);
|
||||||
llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
|
llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
|
||||||
|
|
||||||
p->scope() = IRScope(oror, ororend);
|
p->scope() = IRScope(oror, ororend);
|
||||||
DValue* v = e2->toElem(p);
|
DValue* v = e2->toElem(p);
|
||||||
|
|
||||||
LLValue* vbool = DtoBoolean(v->getRVal());
|
LLValue* vbool = DtoBoolean(v->getRVal());
|
||||||
new llvm::StoreInst(vbool,resval,p->scopebb());
|
DtoStore(vbool,resval);
|
||||||
llvm::BranchInst::Create(ororend,p->scopebb());
|
llvm::BranchInst::Create(ororend,p->scopebb());
|
||||||
|
|
||||||
p->scope() = IRScope(ororend, oldend);
|
p->scope() = IRScope(ororend, oldend);
|
||||||
|
@ -2173,7 +2181,7 @@ DValue* X##AssignExp::toElem(IRState* p) \
|
||||||
LLValue* uval = u->getRVal(); \
|
LLValue* uval = u->getRVal(); \
|
||||||
LLValue* vval = v->getRVal(); \
|
LLValue* vval = v->getRVal(); \
|
||||||
LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \
|
LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \
|
||||||
new llvm::StoreInst(DtoPointedType(u->getLVal(), tmp), u->getLVal(), p->scopebb()); \
|
DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \
|
||||||
return u; \
|
return u; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2205,7 +2213,7 @@ DValue* DelegateExp::toElem(IRState* p)
|
||||||
Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars());
|
Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty);
|
const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty);
|
||||||
|
|
||||||
LLValue* lval;
|
LLValue* lval;
|
||||||
bool inplace = false;
|
bool inplace = false;
|
||||||
|
@ -2245,11 +2253,11 @@ DValue* DelegateExp::toElem(IRState* p)
|
||||||
|
|
||||||
Logger::cout() << "context = " << *uval << '\n';
|
Logger::cout() << "context = " << *uval << '\n';
|
||||||
|
|
||||||
LLValue* context = DtoGEPi(lval,0,0,"tmp");
|
LLValue* context = DtoGEPi(lval,0,0);
|
||||||
LLValue* castcontext = DtoBitCast(uval, int8ptrty);
|
LLValue* castcontext = DtoBitCast(uval, int8ptrty);
|
||||||
DtoStore(castcontext, context);
|
DtoStore(castcontext, context);
|
||||||
|
|
||||||
LLValue* fptr = DtoGEPi(lval,0,1,"tmp");
|
LLValue* fptr = DtoGEPi(lval,0,1);
|
||||||
|
|
||||||
Logger::println("func: '%s'", func->toPrettyChars());
|
Logger::println("func: '%s'", func->toPrettyChars());
|
||||||
|
|
||||||
|
@ -2318,7 +2326,7 @@ DValue* IdentityExp::toElem(IRState* p)
|
||||||
if (v->isNull())
|
if (v->isNull())
|
||||||
r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
|
r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
|
||||||
else
|
else
|
||||||
r = DtoBitCast(r, l->getType(), "tmp");
|
r = DtoBitCast(r, l->getType());
|
||||||
}
|
}
|
||||||
llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
||||||
eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb());
|
eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb());
|
||||||
|
@ -2528,23 +2536,23 @@ DValue* FuncExp::toElem(IRState* p)
|
||||||
temp = true;
|
temp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
|
LLValue* context = DtoGEPi(lval,0,0);
|
||||||
const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
|
const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0));
|
||||||
LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar;
|
LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar;
|
||||||
if (llvmNested == NULL) {
|
if (llvmNested == NULL) {
|
||||||
LLValue* nullcontext = llvm::ConstantPointerNull::get(pty);
|
LLValue* nullcontext = llvm::ConstantPointerNull::get(pty);
|
||||||
p->ir->CreateStore(nullcontext, context);
|
DtoStore(nullcontext, context);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LLValue* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp");
|
LLValue* nestedcontext = DtoBitCast(llvmNested, pty);
|
||||||
p->ir->CreateStore(nestedcontext, context);
|
DtoStore(nestedcontext, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
|
LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
|
||||||
|
|
||||||
assert(fd->ir.irFunc->func);
|
assert(fd->ir.irFunc->func);
|
||||||
LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func,fptr->getType()->getContainedType(0));
|
LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0));
|
||||||
new llvm::StoreInst(castfptr, fptr, p->scopebb());
|
DtoStore(castfptr, fptr);
|
||||||
|
|
||||||
if (temp)
|
if (temp)
|
||||||
return new DVarValue(type, lval, true);
|
return new DVarValue(type, lval, true);
|
||||||
|
@ -2575,7 +2583,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||||
Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
|
Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
|
||||||
|
|
||||||
// llvm storage type
|
// llvm storage type
|
||||||
const LLType* llStoType = llvm::ArrayType::get(DtoType(elemType), len);
|
const LLType* llStoType = LLArrayType::get(DtoType(elemType), len);
|
||||||
Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
|
Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
|
||||||
|
|
||||||
// dst pointer
|
// dst pointer
|
||||||
|
@ -2641,7 +2649,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
|
||||||
const LLType* t = DtoType(type);
|
const LLType* t = DtoType(type);
|
||||||
Logger::cout() << "array literal has llvm type: " << *t << '\n';
|
Logger::cout() << "array literal has llvm type: " << *t << '\n';
|
||||||
assert(isaArray(t));
|
assert(isaArray(t));
|
||||||
const llvm::ArrayType* arrtype = isaArray(t);
|
const LLArrayType* arrtype = isaArray(t);
|
||||||
|
|
||||||
assert(arrtype->getNumElements() == elements->dim);
|
assert(arrtype->getNumElements() == elements->dim);
|
||||||
std::vector<LLConstant*> vals(elements->dim, NULL);
|
std::vector<LLConstant*> vals(elements->dim, NULL);
|
||||||
|
@ -2692,7 +2700,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
||||||
if (!vx) continue;
|
if (!vx) continue;
|
||||||
tys.push_back(DtoType(vx->type));
|
tys.push_back(DtoType(vx->type));
|
||||||
}
|
}
|
||||||
const llvm::StructType* t = llvm::StructType::get(tys);
|
const LLStructType* t = LLStructType::get(tys);
|
||||||
if (t != llt) {
|
if (t != llt) {
|
||||||
if (getABITypeSize(t) != getABITypeSize(llt)) {
|
if (getABITypeSize(t) != getABITypeSize(llt)) {
|
||||||
Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';
|
Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';
|
||||||
|
@ -2711,7 +2719,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
||||||
if (!vx) continue;
|
if (!vx) continue;
|
||||||
|
|
||||||
Logger::cout() << "getting index " << j << " of " << *sptr << '\n';
|
Logger::cout() << "getting index " << j << " of " << *sptr << '\n';
|
||||||
LLValue* arrptr = DtoGEPi(sptr,0,j,"tmp",p->scopebb());
|
LLValue* arrptr = DtoGEPi(sptr,0,j);
|
||||||
DValue* darrptr = new DVarValue(vx->type, arrptr, true);
|
DValue* darrptr = new DVarValue(vx->type, arrptr, true);
|
||||||
|
|
||||||
p->exps.push_back(IRExp(NULL,vx,darrptr));
|
p->exps.push_back(IRExp(NULL,vx,darrptr));
|
||||||
|
@ -2745,7 +2753,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
||||||
|
|
||||||
assert(DtoDType(type)->ty == Tstruct);
|
assert(DtoDType(type)->ty == Tstruct);
|
||||||
const LLType* t = DtoType(type);
|
const LLType* t = DtoType(type);
|
||||||
const llvm::StructType* st = isaStruct(t);
|
const LLStructType* st = isaStruct(t);
|
||||||
return llvm::ConstantStruct::get(st,vals);
|
return llvm::ConstantStruct::get(st,vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1416
gen/tollvm.cpp
1416
gen/tollvm.cpp
File diff suppressed because it is too large
Load diff
154
gen/tollvm.h
154
gen/tollvm.h
|
@ -19,15 +19,13 @@ bool DtoIsReturnedInArg(Type* type);
|
||||||
Type* DtoDType(Type* t);
|
Type* DtoDType(Type* t);
|
||||||
|
|
||||||
// delegate helpers
|
// delegate helpers
|
||||||
const llvm::StructType* DtoDelegateType(Type* t);
|
const LLStructType* DtoDelegateType(Type* t);
|
||||||
void DtoDelegateToNull(LLValue* v);
|
|
||||||
void DtoDelegateCopy(LLValue* dst, LLValue* src);
|
|
||||||
LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs);
|
LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs);
|
||||||
|
|
||||||
// return linkage type for symbol using the current ir state for context
|
// return linkage type for symbol using the current ir state for context
|
||||||
llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
|
LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
|
||||||
llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym);
|
LLGlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym);
|
||||||
llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym);
|
LLGlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym);
|
||||||
|
|
||||||
// convert DMD calling conv to LLVM
|
// convert DMD calling conv to LLVM
|
||||||
unsigned DtoCallingConv(LINK l);
|
unsigned DtoCallingConv(LINK l);
|
||||||
|
@ -40,122 +38,94 @@ LLValue* DtoBoolean(LLValue* val);
|
||||||
|
|
||||||
// some types
|
// some types
|
||||||
const LLType* DtoSize_t();
|
const LLType* DtoSize_t();
|
||||||
const llvm::StructType* DtoInterfaceInfoType();
|
const LLStructType* DtoInterfaceInfoType();
|
||||||
|
|
||||||
// getting typeinfo of type, base=true casts to object.TypeInfo
|
|
||||||
LLConstant* DtoTypeInfoOf(Type* ty, bool base=true);
|
|
||||||
|
|
||||||
// initializer helpers
|
|
||||||
LLConstant* DtoConstInitializer(Type* type, Initializer* init);
|
|
||||||
LLConstant* DtoConstFieldInitializer(Type* type, Initializer* init);
|
|
||||||
DValue* DtoInitializer(Initializer* init);
|
|
||||||
|
|
||||||
// declaration of memset/cpy intrinsics
|
|
||||||
llvm::Function* LLVM_DeclareMemSet32();
|
|
||||||
llvm::Function* LLVM_DeclareMemSet64();
|
|
||||||
llvm::Function* LLVM_DeclareMemCpy32();
|
|
||||||
llvm::Function* LLVM_DeclareMemCpy64();
|
|
||||||
|
|
||||||
// getelementptr helpers
|
// getelementptr helpers
|
||||||
LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb=NULL);
|
LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
||||||
LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb=NULL);
|
LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
||||||
LLValue* DtoGEPi(LLValue* ptr, unsigned i0, const char* var, llvm::BasicBlock* bb=NULL);
|
LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
||||||
LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var, llvm::BasicBlock* bb=NULL);
|
LLValue* DtoGEPi1(LLValue* ptr, unsigned i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
||||||
|
LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
||||||
// dynamic memory helpers
|
|
||||||
LLValue* DtoNew(Type* newtype);
|
|
||||||
void DtoDeleteMemory(LLValue* ptr);
|
|
||||||
void DtoDeleteClass(LLValue* inst);
|
|
||||||
void DtoDeleteInterface(LLValue* inst);
|
|
||||||
void DtoDeleteArray(DValue* arr);
|
|
||||||
|
|
||||||
// assertion generator
|
|
||||||
void DtoAssert(Loc* loc, DValue* msg);
|
|
||||||
|
|
||||||
// nested variable/class helpers
|
|
||||||
LLValue* DtoNestedContext(FuncDeclaration* func);
|
|
||||||
LLValue* DtoNestedVariable(VarDeclaration* vd);
|
|
||||||
|
|
||||||
// annotation generator
|
|
||||||
void DtoAnnotation(const char* str);
|
|
||||||
|
|
||||||
// to constant helpers
|
// to constant helpers
|
||||||
llvm::ConstantInt* DtoConstSize_t(size_t);
|
LLConstantInt* DtoConstSize_t(size_t);
|
||||||
llvm::ConstantInt* DtoConstUint(unsigned i);
|
LLConstantInt* DtoConstUint(unsigned i);
|
||||||
llvm::ConstantInt* DtoConstInt(int i);
|
LLConstantInt* DtoConstInt(int i);
|
||||||
|
LLConstantInt* DtoConstUbyte(unsigned char i);
|
||||||
llvm::ConstantFP* DtoConstFP(Type* t, long double value);
|
llvm::ConstantFP* DtoConstFP(Type* t, long double value);
|
||||||
|
|
||||||
LLConstant* DtoConstString(const char*);
|
LLConstant* DtoConstString(const char*);
|
||||||
LLConstant* DtoConstStringPtr(const char* str, const char* section = 0);
|
LLConstant* DtoConstStringPtr(const char* str, const char* section = 0);
|
||||||
LLConstant* DtoConstBool(bool);
|
LLConstant* DtoConstBool(bool);
|
||||||
|
|
||||||
// is template instance check
|
|
||||||
bool DtoIsTemplateInstance(Dsymbol* s);
|
|
||||||
|
|
||||||
// generates lazy static initialization code for a global variable
|
|
||||||
void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t);
|
|
||||||
|
|
||||||
// these are all basically drivers for the codegeneration called by the main loop
|
|
||||||
void DtoResolveDsymbol(Dsymbol* dsym);
|
|
||||||
void DtoDeclareDsymbol(Dsymbol* dsym);
|
|
||||||
void DtoDefineDsymbol(Dsymbol* dsym);
|
|
||||||
void DtoConstInitDsymbol(Dsymbol* dsym);
|
|
||||||
void DtoConstInitGlobal(VarDeclaration* vd);
|
|
||||||
void DtoEmptyResolveList();
|
|
||||||
void DtoEmptyDeclareList();
|
|
||||||
void DtoEmptyConstInitList();
|
|
||||||
void DtoEmptyAllLists();
|
|
||||||
void DtoForceDeclareDsymbol(Dsymbol* dsym);
|
|
||||||
void DtoForceConstInitDsymbol(Dsymbol* dsym);
|
|
||||||
void DtoForceDefineDsymbol(Dsymbol* dsym);
|
|
||||||
|
|
||||||
// llvm wrappers
|
// llvm wrappers
|
||||||
void DtoMemSetZero(LLValue* dst, LLValue* nbytes);
|
|
||||||
void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes);
|
|
||||||
void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device=false);
|
|
||||||
bool DtoCanLoad(LLValue* ptr);
|
bool DtoCanLoad(LLValue* ptr);
|
||||||
LLValue* DtoLoad(LLValue* src, const char* name=0);
|
LLValue* DtoLoad(LLValue* src, const char* name=0);
|
||||||
void DtoStore(LLValue* src, LLValue* dst);
|
void DtoStore(LLValue* src, LLValue* dst);
|
||||||
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
|
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
|
||||||
|
|
||||||
// llvm::dyn_cast wrappers
|
// llvm::dyn_cast wrappers
|
||||||
const llvm::PointerType* isaPointer(LLValue* v);
|
const LLPointerType* isaPointer(LLValue* v);
|
||||||
const llvm::PointerType* isaPointer(const LLType* t);
|
const LLPointerType* isaPointer(const LLType* t);
|
||||||
const llvm::ArrayType* isaArray(LLValue* v);
|
const LLArrayType* isaArray(LLValue* v);
|
||||||
const llvm::ArrayType* isaArray(const LLType* t);
|
const LLArrayType* isaArray(const LLType* t);
|
||||||
const llvm::StructType* isaStruct(LLValue* v);
|
const LLStructType* isaStruct(LLValue* v);
|
||||||
const llvm::StructType* isaStruct(const LLType* t);
|
const LLStructType* isaStruct(const LLType* t);
|
||||||
LLConstant* isaConstant(LLValue* v);
|
LLConstant* isaConstant(LLValue* v);
|
||||||
llvm::ConstantInt* isaConstantInt(LLValue* v);
|
LLConstantInt* isaConstantInt(LLValue* v);
|
||||||
llvm::Argument* isaArgument(LLValue* v);
|
llvm::Argument* isaArgument(LLValue* v);
|
||||||
llvm::GlobalVariable* isaGlobalVar(LLValue* v);
|
LLGlobalVariable* isaGlobalVar(LLValue* v);
|
||||||
|
|
||||||
// llvm::T::get(...) wrappers
|
// llvm::T::get(...) wrappers
|
||||||
const llvm::PointerType* getPtrToType(const LLType* t);
|
const LLPointerType* getPtrToType(const LLType* t);
|
||||||
const llvm::PointerType* getVoidPtrType();
|
const LLPointerType* getVoidPtrType();
|
||||||
llvm::ConstantPointerNull* getNullPtr(const LLType* t);
|
llvm::ConstantPointerNull* getNullPtr(const LLType* t);
|
||||||
|
|
||||||
// type sizes
|
// type sizes
|
||||||
size_t getTypeBitSize(const LLType* t);
|
size_t getTypeBitSize(const LLType* t);
|
||||||
size_t getTypeStoreSize(const LLType* t);
|
size_t getTypeStoreSize(const LLType* t);
|
||||||
size_t getABITypeSize(const LLType* t);
|
size_t getABITypeSize(const LLType* t);
|
||||||
|
// type alignments
|
||||||
|
unsigned char getABITypeAlign(const LLType* t);
|
||||||
|
unsigned char getPrefTypeAlign(const LLType* t);
|
||||||
|
|
||||||
// basic operations
|
/**
|
||||||
void DtoAssign(DValue* lhs, DValue* rhs);
|
* Generates a call to llvm.memset.i32 (or i64 depending on architecture).
|
||||||
|
* @param dst Destination memory.
|
||||||
|
* @param nbytes Number of bytes to overwrite.
|
||||||
|
*/
|
||||||
|
void DtoMemSetZero(LLValue* dst, LLValue* nbytes);
|
||||||
|
|
||||||
// casts
|
/**
|
||||||
DValue* DtoCastInt(DValue* val, Type* to);
|
* Generates a call to llvm.memcpy.i32 (or i64 depending on architecture).
|
||||||
DValue* DtoCastPtr(DValue* val, Type* to);
|
* @param dst Destination memory.
|
||||||
DValue* DtoCastFloat(DValue* val, Type* to);
|
* @param src Source memory.
|
||||||
DValue* DtoCastComplex(DValue* val, Type* to);
|
* @param nbytes Number of bytes to copy.
|
||||||
DValue* DtoCast(DValue* val, Type* to);
|
*/
|
||||||
|
void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes);
|
||||||
|
|
||||||
// binary operations
|
/**
|
||||||
DValue* DtoBinAdd(DValue* lhs, DValue* rhs);
|
* The same as DtoMemSetZero but figures out the size itself by "dereferencing" the v pointer once.
|
||||||
DValue* DtoBinSub(DValue* lhs, DValue* rhs);
|
* @param v Destination memory.
|
||||||
DValue* DtoBinMul(DValue* lhs, DValue* rhs);
|
*/
|
||||||
DValue* DtoBinDiv(DValue* lhs, DValue* rhs);
|
void DtoAggrZeroInit(LLValue* v);
|
||||||
DValue* DtoBinRem(DValue* lhs, DValue* rhs);
|
|
||||||
|
/**
|
||||||
|
* The same as DtoMemCpy but figures out the size itself by "dereferencing" dst the pointer once.
|
||||||
|
* @param dst Destination memory.
|
||||||
|
* @param src Source memory.
|
||||||
|
*/
|
||||||
|
void DtoAggrCopy(LLValue* dst, LLValue* src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a call to llvm.memory.barrier
|
||||||
|
* @param ll load-load
|
||||||
|
* @param ls load-store
|
||||||
|
* @param sl store-load
|
||||||
|
* @param ss store-store
|
||||||
|
* @param device special device flag
|
||||||
|
*/
|
||||||
|
void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device=false);
|
||||||
|
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/structs.h"
|
#include "gen/structs.h"
|
||||||
#include "gen/classes.h"
|
#include "gen/classes.h"
|
||||||
|
@ -203,7 +204,7 @@ static llvm::Function* build_module_ctor()
|
||||||
name.append("6__ctorZ");
|
name.append("6__ctorZ");
|
||||||
|
|
||||||
std::vector<const LLType*> argsTy;
|
std::vector<const LLType*> argsTy;
|
||||||
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
|
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy,argsTy,false);
|
||||||
assert(gIR->module->getFunction(name) == NULL);
|
assert(gIR->module->getFunction(name) == NULL);
|
||||||
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
|
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
|
||||||
fn->setCallingConv(llvm::CallingConv::Fast);
|
fn->setCallingConv(llvm::CallingConv::Fast);
|
||||||
|
@ -237,7 +238,7 @@ static llvm::Function* build_module_dtor()
|
||||||
name.append("6__dtorZ");
|
name.append("6__dtorZ");
|
||||||
|
|
||||||
std::vector<const LLType*> argsTy;
|
std::vector<const LLType*> argsTy;
|
||||||
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
|
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy,argsTy,false);
|
||||||
assert(gIR->module->getFunction(name) == NULL);
|
assert(gIR->module->getFunction(name) == NULL);
|
||||||
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
|
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
|
||||||
fn->setCallingConv(llvm::CallingConv::Fast);
|
fn->setCallingConv(llvm::CallingConv::Fast);
|
||||||
|
@ -271,7 +272,7 @@ static llvm::Function* build_module_unittest()
|
||||||
name.append("10__unittestZ");
|
name.append("10__unittestZ");
|
||||||
|
|
||||||
std::vector<const LLType*> argsTy;
|
std::vector<const LLType*> argsTy;
|
||||||
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
|
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy,argsTy,false);
|
||||||
assert(gIR->module->getFunction(name) == NULL);
|
assert(gIR->module->getFunction(name) == NULL);
|
||||||
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
|
llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
|
||||||
fn->setCallingConv(llvm::CallingConv::Fast);
|
fn->setCallingConv(llvm::CallingConv::Fast);
|
||||||
|
@ -325,7 +326,7 @@ void Module::genmoduleinfo()
|
||||||
initVec.push_back(c);
|
initVec.push_back(c);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
c = getNullPtr(getPtrToType(llvm::Type::Int8Ty));
|
c = getNullPtr(getPtrToType(LLType::Int8Ty));
|
||||||
initVec.push_back(c);
|
initVec.push_back(c);
|
||||||
|
|
||||||
// name
|
// name
|
||||||
|
@ -463,9 +464,9 @@ void Module::genmoduleinfo()
|
||||||
gvar->setInitializer(constMI);
|
gvar->setInitializer(constMI);
|
||||||
|
|
||||||
// declare the appending array
|
// declare the appending array
|
||||||
const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(llvm::Type::Int8Ty), 1);
|
const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(LLType::Int8Ty), 1);
|
||||||
std::vector<LLConstant*> appendInits;
|
std::vector<LLConstant*> appendInits;
|
||||||
appendInits.push_back(llvm::ConstantExpr::getBitCast(gvar, getPtrToType(llvm::Type::Int8Ty)));
|
appendInits.push_back(llvm::ConstantExpr::getBitCast(gvar, getPtrToType(LLType::Int8Ty)));
|
||||||
LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits);
|
LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits);
|
||||||
std::string appendName("_d_moduleinfo_array");
|
std::string appendName("_d_moduleinfo_array");
|
||||||
llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module);
|
llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/runtime.h"
|
#include "gen/runtime.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/structs.h"
|
#include "gen/structs.h"
|
||||||
#include "gen/classes.h"
|
#include "gen/classes.h"
|
||||||
|
@ -279,7 +280,7 @@ void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
|
||||||
LLValue* found = gIR->module->getNamedGlobal(mangled);
|
LLValue* found = gIR->module->getNamedGlobal(mangled);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
const LLType* t = llvm::OpaqueType::get();
|
const LLType* t = LLOpaqueType::get();
|
||||||
llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
|
llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
|
||||||
assert(g);
|
assert(g);
|
||||||
/*if (!tid->ir.irGlobal)
|
/*if (!tid->ir.irGlobal)
|
||||||
|
@ -353,7 +354,7 @@ void TypeInfoTypedefDeclaration::llvmDeclare()
|
||||||
ClassDeclaration* base = Type::typeinfotypedef;
|
ClassDeclaration* base = Type::typeinfotypedef;
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -367,7 +368,7 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||||
ClassDeclaration* base = Type::typeinfotypedef;
|
ClassDeclaration* base = Type::typeinfotypedef;
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
Logger::cout() << "got stype: " << *stype << '\n';
|
Logger::cout() << "got stype: " << *stype << '\n';
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
|
@ -375,14 +376,14 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(getNullPtr(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
assert(tinfo->ty == Ttypedef);
|
assert(tinfo->ty == Ttypedef);
|
||||||
TypeTypedef *tc = (TypeTypedef *)tinfo;
|
TypeTypedef *tc = (TypeTypedef *)tinfo;
|
||||||
TypedefDeclaration *sd = tc->sym;
|
TypedefDeclaration *sd = tc->sym;
|
||||||
|
|
||||||
// TypeInfo base
|
// TypeInfo base
|
||||||
//const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType());
|
//const LLPointerType* basept = isaPointer(initZ->getOperand(1)->getType());
|
||||||
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
|
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
|
||||||
Logger::println("generating base typeinfo");
|
Logger::println("generating base typeinfo");
|
||||||
//sd->basetype = sd->basetype->merge();
|
//sd->basetype = sd->basetype->merge();
|
||||||
|
@ -403,7 +404,7 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||||
assert(sinits.back()->getType() == stype->getElementType(3));
|
assert(sinits.back()->getType() == stype->getElementType(3));
|
||||||
|
|
||||||
// void[] init
|
// void[] init
|
||||||
const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
|
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
||||||
if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
|
if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
|
||||||
{
|
{
|
||||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt)));
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt)));
|
||||||
|
@ -439,7 +440,7 @@ void TypeInfoEnumDeclaration::llvmDeclare()
|
||||||
ClassDeclaration* base = Type::typeinfoenum;
|
ClassDeclaration* base = Type::typeinfoenum;
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -453,21 +454,21 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||||
ClassDeclaration* base = Type::typeinfoenum;
|
ClassDeclaration* base = Type::typeinfoenum;
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
assert(tinfo->ty == Tenum);
|
assert(tinfo->ty == Tenum);
|
||||||
TypeEnum *tc = (TypeEnum *)tinfo;
|
TypeEnum *tc = (TypeEnum *)tinfo;
|
||||||
EnumDeclaration *sd = tc->sym;
|
EnumDeclaration *sd = tc->sym;
|
||||||
|
|
||||||
// TypeInfo base
|
// TypeInfo base
|
||||||
//const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType());
|
//const LLPointerType* basept = isaPointer(initZ->getOperand(1)->getType());
|
||||||
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
|
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
|
||||||
Logger::println("generating base typeinfo");
|
Logger::println("generating base typeinfo");
|
||||||
//sd->basetype = sd->basetype->merge();
|
//sd->basetype = sd->basetype->merge();
|
||||||
|
@ -487,7 +488,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||||
assert(sinits.back()->getType() == stype->getElementType(3));
|
assert(sinits.back()->getType() == stype->getElementType(3));
|
||||||
|
|
||||||
// void[] init
|
// void[] init
|
||||||
const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
|
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
||||||
if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
|
if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
|
||||||
{
|
{
|
||||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
|
||||||
|
@ -521,7 +522,7 @@ static LLConstant* LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, ClassDe
|
||||||
ClassDeclaration* base = cd;
|
ClassDeclaration* base = cd;
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
tid->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
tid->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
||||||
|
@ -532,14 +533,14 @@ static LLConstant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaratio
|
||||||
ClassDeclaration* base = cd;
|
ClassDeclaration* base = cd;
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// TypeInfo base
|
// TypeInfo base
|
||||||
Logger::println("generating base typeinfo");
|
Logger::println("generating base typeinfo");
|
||||||
|
@ -626,7 +627,7 @@ void TypeInfoStaticArrayDeclaration::llvmDeclare()
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -642,7 +643,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// initializer vector
|
// initializer vector
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
|
@ -650,7 +651,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// value typeinfo
|
// value typeinfo
|
||||||
assert(tinfo->ty == Tsarray);
|
assert(tinfo->ty == Tsarray);
|
||||||
|
@ -689,7 +690,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -705,7 +706,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// initializer vector
|
// initializer vector
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
|
@ -713,7 +714,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// get type
|
// get type
|
||||||
assert(tinfo->ty == Taarray);
|
assert(tinfo->ty == Taarray);
|
||||||
|
@ -822,7 +823,7 @@ void TypeInfoStructDeclaration::llvmDeclare()
|
||||||
ClassDeclaration* base = Type::typeinfostruct;
|
ClassDeclaration* base = Type::typeinfostruct;
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -841,14 +842,14 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||||
ClassDeclaration* base = Type::typeinfostruct;
|
ClassDeclaration* base = Type::typeinfostruct;
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// char[] name
|
// char[] name
|
||||||
char *name = sd->toPrettyChars();
|
char *name = sd->toPrettyChars();
|
||||||
|
@ -857,7 +858,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||||
assert(sinits.back()->getType() == stype->getElementType(2));
|
assert(sinits.back()->getType() == stype->getElementType(2));
|
||||||
|
|
||||||
// void[] init
|
// void[] init
|
||||||
const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
|
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
||||||
#if 0
|
#if 0
|
||||||
// the implementation of TypeInfo_Struct uses this to determine size. :/
|
// the implementation of TypeInfo_Struct uses this to determine size. :/
|
||||||
if (sd->zeroInit) // 0 initializer, or the same as the base type
|
if (sd->zeroInit) // 0 initializer, or the same as the base type
|
||||||
|
@ -918,7 +919,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Logger::println("************** B");
|
//Logger::println("************** B");
|
||||||
const llvm::PointerType* ptty = isaPointer(stype->getElementType(4));
|
const LLPointerType* ptty = isaPointer(stype->getElementType(4));
|
||||||
assert(ptty);
|
assert(ptty);
|
||||||
|
|
||||||
s = search_function(sd, Id::tohash);
|
s = search_function(sd, Id::tohash);
|
||||||
|
@ -1025,7 +1026,7 @@ void TypeInfoClassDeclaration::llvmDeclare()
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -1042,7 +1043,7 @@ void TypeInfoClassDeclaration::llvmDefine()
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// initializer vector
|
// initializer vector
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
|
@ -1050,7 +1051,7 @@ void TypeInfoClassDeclaration::llvmDefine()
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// get classinfo
|
// get classinfo
|
||||||
assert(tinfo->ty == Tclass);
|
assert(tinfo->ty == Tclass);
|
||||||
|
@ -1082,7 +1083,7 @@ void TypeInfoInterfaceDeclaration::llvmDeclare()
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -1099,7 +1100,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// initializer vector
|
// initializer vector
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
|
@ -1107,7 +1108,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// get classinfo
|
// get classinfo
|
||||||
assert(tinfo->ty == Tclass);
|
assert(tinfo->ty == Tclass);
|
||||||
|
@ -1138,7 +1139,7 @@ void TypeInfoTupleDeclaration::llvmDeclare()
|
||||||
DtoResolveClass(base);
|
DtoResolveClass(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// create the symbol
|
// create the symbol
|
||||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||||
|
@ -1155,7 +1156,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||||
DtoForceConstInitDsymbol(base);
|
DtoForceConstInitDsymbol(base);
|
||||||
|
|
||||||
// get type of typeinfo class
|
// get type of typeinfo class
|
||||||
const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
|
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||||
|
|
||||||
// initializer vector
|
// initializer vector
|
||||||
std::vector<LLConstant*> sinits;
|
std::vector<LLConstant*> sinits;
|
||||||
|
@ -1163,7 +1164,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||||
sinits.push_back(base->ir.irStruct->vtbl);
|
sinits.push_back(base->ir.irStruct->vtbl);
|
||||||
|
|
||||||
// monitor
|
// monitor
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||||
|
|
||||||
// create elements array
|
// create elements array
|
||||||
assert(tinfo->ty == Ttuple);
|
assert(tinfo->ty == Ttuple);
|
||||||
|
@ -1187,7 +1188,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||||
}
|
}
|
||||||
|
|
||||||
// build array type
|
// build array type
|
||||||
const llvm::ArrayType* arrTy = llvm::ArrayType::get(tiTy, dim);
|
const LLArrayType* arrTy = LLArrayType::get(tiTy, dim);
|
||||||
LLConstant* arrC = llvm::ConstantArray::get(arrTy, arrInits);
|
LLConstant* arrC = llvm::ConstantArray::get(arrTy, arrInits);
|
||||||
|
|
||||||
// build the slice
|
// build the slice
|
||||||
|
|
|
@ -44,10 +44,10 @@ struct IrStruct : IrBase
|
||||||
struct Offset
|
struct Offset
|
||||||
{
|
{
|
||||||
VarDeclaration* var;
|
VarDeclaration* var;
|
||||||
const llvm::Type* type;
|
const LLType* type;
|
||||||
llvm::Constant* init;
|
llvm::Constant* init;
|
||||||
|
|
||||||
Offset(VarDeclaration* v, const llvm::Type* ty)
|
Offset(VarDeclaration* v, const LLType* ty)
|
||||||
: var(v), type(ty), init(NULL) {}
|
: var(v), type(ty), init(NULL) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,8 @@ gen/dwarftypes.cpp
|
||||||
gen/enums.h
|
gen/enums.h
|
||||||
gen/functions.cpp
|
gen/functions.cpp
|
||||||
gen/functions.h
|
gen/functions.h
|
||||||
|
gen/intrinsics.cpp
|
||||||
|
gen/intrinsics.h
|
||||||
gen/irstate.cpp
|
gen/irstate.cpp
|
||||||
gen/irstate.h
|
gen/irstate.h
|
||||||
gen/linker.h
|
gen/linker.h
|
||||||
|
@ -762,6 +764,7 @@ tangotests/byval1.d
|
||||||
tangotests/c.d
|
tangotests/c.d
|
||||||
tangotests/classes1.d
|
tangotests/classes1.d
|
||||||
tangotests/constructors.d
|
tangotests/constructors.d
|
||||||
|
tangotests/debug1.d
|
||||||
tangotests/e.d
|
tangotests/e.d
|
||||||
tangotests/f.d
|
tangotests/f.d
|
||||||
tangotests/files1.d
|
tangotests/files1.d
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue