# HG changeset patch # User lindquist # Date 1212997028 -7200 # Node ID a95056b3c9960e92144a17f1cde5e83878f21c89 # Parent 4d006f7b2ada1b4c63bbe670175c27dc4ab86d6b [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. diff -r 4d006f7b2ada -r a95056b3c996 gen/aa.cpp --- a/gen/aa.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/aa.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -7,6 +7,7 @@ #include "gen/aa.h" #include "gen/runtime.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/logger.h" #include "gen/irstate.h" #include "gen/dvalue.h" diff -r 4d006f7b2ada -r a95056b3c996 gen/arrays.cpp --- a/gen/arrays.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/arrays.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -8,6 +8,7 @@ #include "gen/irstate.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/arrays.h" #include "gen/runtime.h" #include "gen/logger.h" @@ -15,23 +16,23 @@ ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::StructType* DtoArrayType(Type* arrayTy) +const LLStructType* DtoArrayType(Type* arrayTy) { assert(arrayTy->next); const LLType* elemty = DtoType(arrayTy->next); - if (elemty == llvm::Type::VoidTy) - elemty = llvm::Type::Int8Ty; - return llvm::StructType::get(DtoSize_t(), getPtrToType(elemty), 0); + if (elemty == LLType::VoidTy) + elemty = LLType::Int8Ty; + 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) return isaArray(t->ir.type->get()); @@ -43,10 +44,10 @@ TypeSArray* tsa = (TypeSArray*)t; 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); - tsa->ir.type = new llvm::PATypeHolder(arrty); + tsa->ir.type = new LLPATypeHolder(arrty); return arrty; } @@ -57,14 +58,14 @@ Logger::println("DtoSetArrayToNull"); 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); - new llvm::StoreInst(zerolen, len, gIR->scopebb()); + DtoStore(zerolen, len); - LLValue* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb()); - const llvm::PointerType* pty = isaPointer(ptr->getType()->getContainedType(0)); + LLValue* ptr = DtoGEPi(v,0,1); + const LLPointerType* pty = isaPointer(ptr->getType()->getContainedType(0)); LLValue* nullptr = llvm::ConstantPointerNull::get(pty); - new llvm::StoreInst(nullptr, ptr, gIR->scopebb()); + DtoStore(nullptr, ptr); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -77,20 +78,20 @@ assert(gIR); if (dst->getType() == src->getType()) { - LLValue* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb()); - LLValue* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); - ptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); - new llvm::StoreInst(val, ptr, gIR->scopebb()); + LLValue* ptr = DtoGEPi(src,0,0); + LLValue* val = DtoLoad(ptr); + ptr = DtoGEPi(dst,0,0); + DtoStore(val, ptr); - ptr = DtoGEPi(src,0,1,"tmp",gIR->scopebb()); - val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); - ptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); - new llvm::StoreInst(val, ptr, gIR->scopebb()); + ptr = DtoGEPi(src,0,1); + val = DtoLoad(ptr); + ptr = DtoGEPi(dst,0,1); + DtoStore(val, ptr); } else { 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) { Logger::cout() << "invalid: " << *src << '\n'; @@ -98,13 +99,13 @@ } 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()); - 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); - new llvm::StoreInst(srcptr, dstptr, gIR->scopebb()); + DtoStore(srcptr, dstptr); } } @@ -115,19 +116,19 @@ Logger::println("DtoArrayInit"); LOG_SCOPE; - const llvm::PointerType* ptrty = isaPointer(l->getType()); + const LLPointerType* ptrty = isaPointer(l->getType()); const LLType* t = ptrty->getContainedType(0); - const llvm::ArrayType* arrty = isaArray(t); + const LLArrayType* arrty = isaArray(t); if (arrty) { - LLValue* ptr = DtoGEPi(l,0,0,"tmp",gIR->scopebb()); - LLValue* dim = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); + LLValue* ptr = DtoGEPi(l,0,0); + LLValue* dim = DtoConstSize_t(arrty->getNumElements()); DtoArrayInit(ptr, dim, r); } else if (isaStruct(t)) { - LLValue* dim = DtoLoad(DtoGEPi(l, 0,0, "tmp")); - LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1, "tmp")); + LLValue* dim = DtoLoad(DtoGEPi(l, 0,0)); + LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1)); DtoArrayInit(ptr, dim, r); } else @@ -140,7 +141,7 @@ 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 ne = arrty->getNumElements(); if (n) return n * ne; @@ -180,7 +181,7 @@ return; } else { - ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(llvm::Type::Int8Ty), "tmp"); + ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(LLType::Int8Ty), "tmp"); } } else { @@ -203,33 +204,33 @@ else if (isaPointer(t)) { 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) args[0] = DtoBitCast(args[0],dstty); - const LLType* valty = getPtrToType(llvm::Type::Int8Ty); + const LLType* valty = getPtrToType(LLType::Int8Ty); if (args[2]->getType() != valty) args[2] = DtoBitCast(args[2],valty); } - else if (t == llvm::Type::Int1Ty) { + else if (t == LLType::Int1Ty) { funcname = "_d_array_init_i1"; } - else if (t == llvm::Type::Int8Ty) { + else if (t == LLType::Int8Ty) { funcname = "_d_array_init_i8"; } - else if (t == llvm::Type::Int16Ty) { + else if (t == LLType::Int16Ty) { funcname = "_d_array_init_i16"; } - else if (t == llvm::Type::Int32Ty) { + else if (t == LLType::Int32Ty) { funcname = "_d_array_init_i32"; } - else if (t == llvm::Type::Int64Ty) { + else if (t == LLType::Int64Ty) { funcname = "_d_array_init_i64"; } - else if (t == llvm::Type::FloatTy) { + else if (t == LLType::FloatTy) { funcname = "_d_array_init_float"; } - else if (t == llvm::Type::DoubleTy) { + else if (t == LLType::DoubleTy) { funcname = "_d_array_init_double"; } else { @@ -237,7 +238,7 @@ assert(0); } - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname); + LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname); assert(fn); Logger::cout() << "calling array init function: " << *fn <<'\n'; llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); @@ -248,25 +249,9 @@ void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr) { - Logger::println("DtoSetArray"); - LOG_SCOPE; - - 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()); + Logger::println("SetArray"); + DtoStore(dim, DtoGEPi(arr,0,0)); + DtoStore(ptr, DtoGEPi(arr,0,1)); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -326,7 +311,7 @@ LLConstant* cc = idx->toConstElem(gIR); Logger::println("value gotten"); assert(cc != NULL); - llvm::ConstantInt* ci = llvm::dyn_cast(cc); + LLConstantInt* ci = llvm::dyn_cast(cc); assert(ci != NULL); uint64_t k = ci->getZExtValue(); if (i == k) @@ -356,15 +341,15 @@ } Logger::println("building constant array"); - const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim); - LLConstant* constarr = llvm::ConstantArray::get(arrty, inits); + const LLArrayType* arrty = LLArrayType::get(elemty,tdim); + LLConstant* constarr = LLConstantArray::get(arrty, inits); if (arrinittype->ty == Tsarray) return constarr; else 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* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); return DtoConstSlice(DtoConstSize_t(tdim),gep); @@ -390,7 +375,7 @@ } } 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)); llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false); @@ -401,14 +386,14 @@ sz = llvm::ConstantExpr::getMul(elemsz, nelems); } else if (isaStruct(t)) { - ret = DtoGEPi(e->ptr, 0, 1, "tmp", gIR->scopebb()); - ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb()); + ret = DtoGEPi(e->ptr, 0, 1); + ret = DtoLoad(ret); size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0)); llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false); - LLValue* len = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb()); - len = new llvm::LoadInst(len, "tmp", gIR->scopebb()); + LLValue* len = DtoGEPi(e->ptr, 0, 0); + len = DtoLoad(len); sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb()); } else { @@ -420,63 +405,32 @@ void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src) { Logger::println("ArrayCopySlices"); - const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); - - LLValue* sz1; - LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty); - - LLValue* sz2; - LLValue* srcarr = DtoBitCast(get_slice_ptr(src,sz2),arrty); - llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); - LLSmallVector llargs(4); - llargs[0] = dstarr; - llargs[1] = srcarr; - llargs[2] = sz1; - llargs[3] = DtoConstInt(0); + LLValue *sz1,*sz2; + LLValue* dstarr = get_slice_ptr(dst,sz1); + LLValue* srcarr = get_slice_ptr(src,sz2); - llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); + DtoMemCpy(dstarr, srcarr, sz1); } void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) { Logger::println("ArrayCopyToSlice"); - const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); LLValue* sz1; - LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty); - LLValue* srcarr = DtoBitCast(DtoArrayPtr(src),arrty); + LLValue* dstarr = get_slice_ptr(dst,sz1); + LLValue* srcarr = DtoArrayPtr(src); - llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); - LLSmallVector 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()); + DtoMemCpy(dstarr, srcarr, sz1); } ////////////////////////////////////////////////////////////////////////////////////////// void DtoStaticArrayCopy(LLValue* dst, LLValue* src) { - Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n'; - 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); - LLValue* dstarr = DtoBitCast(dst,arrty); - LLValue* srcarr = DtoBitCast(src,arrty); + Logger::println("StaticArrayCopy"); - llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); - LLSmallVector 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()); + size_t n = getABITypeSize(dst->getType()->getContainedType(0)); + DtoMemCpy(dst, src, DtoConstSize_t(n)); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -501,7 +455,7 @@ // get runtime function 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 LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem"); @@ -538,7 +492,7 @@ bool zeroInit = arrayType->toBasetype()->next->isZeroInit(); // 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 args; args.push_back(DtoTypeInfoOf(arrayType)); @@ -725,7 +679,7 @@ static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti) { Logger::println("comparing arrays"); - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); + LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); assert(fn); LLValue* lmem; @@ -888,7 +842,7 @@ args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, 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()); } @@ -898,12 +852,12 @@ llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; 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* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); - LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); - const llvm::PointerType* pty = isaPointer(lp->getType()); + LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp"); + const LLPointerType* pty = isaPointer(lp->getType()); LLValue* rp = llvm::ConstantPointerNull::get(pty); LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); @@ -913,12 +867,12 @@ else { assert(l->getType() == r->getType()); - LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); - LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp"); + LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp"); + LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0),"tmp"); LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); - LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); - LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp"); + LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp"); + LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1),"tmp"); LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); @@ -929,7 +883,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c) { - const llvm::ArrayType* at = isaArray(t); + const LLArrayType* at = isaArray(t); assert(at); if (isaArray(at->getElementType())) @@ -956,19 +910,19 @@ if (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) return DtoConstSize_t(arrTy->getNumElements()); 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) { assert(!v->isSlice()); LLValue* rv = v->getRVal(); 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()); } assert(0); @@ -987,16 +941,16 @@ if (s->len) return s->ptr; const LLType* t = s->ptr->getType()->getContainedType(0); 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) - return DtoGEPi(s->ptr, 0,0, "tmp"); + return DtoGEPi(s->ptr, 0,0); 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) { - return DtoGEPi(v->getRVal(), 0,0, "tmp"); + return DtoGEPi(v->getRVal(), 0,0); } assert(0); return 0; @@ -1028,13 +982,13 @@ else if (totype->ty == Tarray) { Logger::cout() << "to array" << '\n'; const LLType* ptrty = DtoType(totype->next); - if (ptrty == llvm::Type::VoidTy) - ptrty = llvm::Type::Int8Ty; + if (ptrty == LLType::VoidTy) + ptrty = LLType::Int8Ty; ptrty = getPtrToType(ptrty); const LLType* ety = DtoType(fromtype->next); - if (ety == llvm::Type::VoidTy) - ety = llvm::Type::Int8Ty; + if (ety == LLType::VoidTy) + ety = LLType::Int8Ty; if (DSliceValue* usl = u->isSlice()) { Logger::println("from slice"); @@ -1050,20 +1004,20 @@ if (fromtype->ty == Tsarray) { Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; 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 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); rval = DtoBitCast(uval, ptrty); } else { - LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); - rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb()); - rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb()); + LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); + LLValue* one = llvm::ConstantInt::get(LLType::Int32Ty, 1, false); + rval2 = DtoGEP(uval,zero,zero); + rval2 = DtoLoad(rval2); rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); - rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb()); - rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb()); + rval = DtoGEP(uval,zero,one); + rval = DtoLoad(rval); //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n'; rval = DtoBitCast(rval, ptrty); } diff -r 4d006f7b2ada -r a95056b3c996 gen/arrays.h --- a/gen/arrays.h Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/arrays.h Mon Jun 09 09:37:08 2008 +0200 @@ -9,7 +9,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* si); 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 DtoArrayCopyToSlice(DSliceValue* dst, DValue* src); @@ -35,7 +35,7 @@ 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* DtoArrayPtr(DValue* v); diff -r 4d006f7b2ada -r a95056b3c996 gen/binops.cpp --- a/gen/binops.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/binops.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -35,7 +35,7 @@ DValue* DtoBinDiv(DValue* lhs, DValue* rhs) { Type* t = lhs->getType(); - llvm::Value *l, *r; + LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); LLValue* res; @@ -53,7 +53,7 @@ DValue* DtoBinRem(DValue* lhs, DValue* rhs) { Type* t = lhs->getType(); - llvm::Value *l, *r; + LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); LLValue* res; diff -r 4d006f7b2ada -r a95056b3c996 gen/classes.cpp --- a/gen/classes.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/classes.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -8,6 +8,7 @@ #include "gen/irstate.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/arrays.h" #include "gen/logger.h" #include "gen/classes.h" @@ -199,7 +200,7 @@ fieldtypes.push_back(fieldtype); irstruct->defaultFields.push_back(fieldinit); 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); idx++; } @@ -218,7 +219,7 @@ fieldtypes.push_back(fieldtype); irstruct->defaultFields.push_back(fieldinit); 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); } } @@ -498,7 +499,7 @@ } // 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 size_t nfi = irstruct->defaultFields.size(); @@ -511,7 +512,7 @@ else { const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2)); assert(arrty); - std::vector vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); + std::vector vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false)); c = llvm::ConstantArray::get(arrty, vals); } fieldinits.push_back(c); @@ -628,7 +629,7 @@ infoInits.push_back(c); // vtbl - const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); + const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty)); c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); infoInits.push_back(c); @@ -706,7 +707,7 @@ infoInits.push_back(c); // vtbl - const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); + const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty)); c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); infoInits.push_back(c); @@ -865,23 +866,10 @@ assert(tc->sym->ir.irStruct->init); assert(dst->getType() == tc->sym->ir.irStruct->init->getType()); - const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); - LLValue* dstarr = DtoGEPi(dst,0,2,"tmp"); - dstarr = DtoBitCast(dstarr, arrty); - LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp"); - srcarr = DtoBitCast(srcarr, arrty); - llvm::Function* fn = LLVM_DeclareMemCpy32(); - std::vector 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()); + DtoMemCpy(dstarr, srcarr, DtoConstSize_t(n)); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1343,16 +1331,16 @@ std::vector paramTypes; 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) { - return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); + return llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)); } else if (cd->dtors.dim == 1) { DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; DtoForceDeclareDsymbol(d); 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"); @@ -1375,7 +1363,7 @@ } 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) @@ -1462,7 +1450,7 @@ inits.push_back(c); // byte[] init - const LLType* byteptrty = getPtrToType(llvm::Type::Int8Ty); + const LLType* byteptrty = getPtrToType(LLType::Int8Ty); if (cd->isInterfaceDeclaration() || cd->isAbstract()) { c = cinfo->ir.irStruct->constInit->getOperand(2); } diff -r 4d006f7b2ada -r a95056b3c996 gen/complex.cpp --- a/gen/complex.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/complex.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -5,6 +5,7 @@ #include "gen/complex.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/irstate.h" #include "gen/dvalue.h" @@ -307,3 +308,56 @@ LLValue* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb()); 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); +} \ No newline at end of file diff -r 4d006f7b2ada -r a95056b3c996 gen/complex.h --- a/gen/complex.h Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/complex.h Mon Jun 09 09:37:08 2008 +0200 @@ -26,4 +26,6 @@ LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs); +DValue* DtoCastComplex(DValue* val, Type* to); + #endif // LLVMDC_GEN_COMPLEX_H diff -r 4d006f7b2ada -r a95056b3c996 gen/functions.cpp --- a/gen/functions.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/functions.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -10,6 +10,7 @@ #include "gen/irstate.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/runtime.h" #include "gen/arrays.h" #include "gen/logger.h" @@ -49,7 +50,7 @@ if (ismain) { - rettype = llvm::Type::Int32Ty; + rettype = LLType::Int32Ty; actualRettype = rettype; if (Argument::dim(f->parameters) == 0) { @@ -63,7 +64,7 @@ Type* rtfin = DtoDType(rt); if (DtoIsReturnedInArg(rt)) { rettype = getPtrToType(DtoType(rt)); - actualRettype = llvm::Type::VoidTy; + actualRettype = LLType::VoidTy; f->llvmRetInPtr = retinptr = true; } else { @@ -92,7 +93,7 @@ types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType()))); const LLType* t1 = llvm::StructType::get(types); paramvec.push_back(getPtrToType(t1)); - paramvec.push_back(getPtrToType(llvm::Type::Int8Ty)); + paramvec.push_back(getPtrToType(LLType::Int8Ty)); } else if (arrayVararg) { @@ -172,7 +173,7 @@ TypeFunction* f = (TypeFunction*)fdecl->type; assert(f != 0); - const llvm::PointerType* i8pty = getPtrToType(llvm::Type::Int8Ty); + const llvm::PointerType* i8pty = getPtrToType(LLType::Int8Ty); std::vector args; if (fdecl->llvmInternal == LLVMva_start) { @@ -187,7 +188,7 @@ else 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); @@ -205,7 +206,7 @@ // unittest has null type, just build it manually /*if (fdecl->isUnitTestDeclaration()) { std::vector args; - return llvm::FunctionType::get(llvm::Type::VoidTy, args, false); + return llvm::FunctionType::get(LLType::VoidTy, args, false); }*/ // type has already been resolved @@ -228,7 +229,7 @@ } } else if (fdecl->isNested()) { - thisty = getPtrToType(llvm::Type::Int8Ty); + thisty = getPtrToType(LLType::Int8Ty); } const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); @@ -549,194 +550,195 @@ const llvm::FunctionType* functype = func->getFunctionType(); // only members of the current module or template instances maybe be defined - if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) - { - fd->ir.DModule = gIR->dmodule; + if (!(fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent))) + return; - // function definition - if (fd->fbody != 0) - { - 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()); + // set module owner + fd->ir.DModule = gIR->dmodule; - 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)); + // is there a body? + if (fd->fbody == NULL) + return; - // 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); - } + Logger::println("Doing function body for: %s", fd->toChars()); + assert(fd->ir.irFunc); + gIR->functions.push_back(fd->ir.irFunc); - // 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 (fd->isMain()) + gIR->emitMain = true; - 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"); + std::string entryname("entry_"); + entryname.append(fd->toPrettyChars()); - 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); + llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func); + llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func); - LLValue* parentNested = NULL; - if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { - if (!fd->isStatic()) // huh? - parentNested = fd2->ir.irFunc->nestedVar; - } + //assert(gIR->scopes.empty()); + gIR->scopes.push_back(IRScope(beginbb, endbb)); - // need result variable? (nested) - if (fd->vresult && fd->vresult->nestedref) { - Logger::println("nested vresult value: %s", fd->vresult->toChars()); - fd->nestedVars.insert(fd->vresult); - } + // create alloca point + llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb); + gIR->func()->allocapoint = allocaPoint; - // construct nested variables struct - if (!fd->nestedVars.empty() || parentNested) { - std::vector nestTypes; - int j = 0; - if (parentNested) { - nestTypes.push_back(parentNested->getType()); - j++; - } - for (std::set::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::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); + // 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); + } - // 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(); + // 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 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 (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) + continue; - // 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); - } + 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"); - gIR->functions.pop_back(); + 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 nestTypes; + int j = 0; + if (parentNested) { + nestTypes.push_back(parentNested->getType()); + j++; + } + for (std::set::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::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(); } ////////////////////////////////////////////////////////////////////////////////////////// diff -r 4d006f7b2ada -r a95056b3c996 gen/linker.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/linker.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -0,0 +1,25 @@ +#include "gen/llvm.h" +#include "llvm/Linker.h" + +#include "root.h" +#include "mars.h" + +typedef std::vector 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(); + } + } +} diff -r 4d006f7b2ada -r a95056b3c996 gen/linker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/linker.h Mon Jun 09 09:37:08 2008 +0200 @@ -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& MV); + +#endif // LLVMDC_GEN_LINKER_H diff -r 4d006f7b2ada -r a95056b3c996 gen/llvm.h --- a/gen/llvm.h Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/llvm.h Mon Jun 09 09:37:08 2008 +0200 @@ -18,10 +18,27 @@ #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::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::GlobalValue LLGlobalValue; +typedef llvm::GlobalVariable LLGlobalVariable; +typedef llvm::Function LLFunction; + typedef llvm::Constant LLConstant; +typedef llvm::ConstantStruct LLConstantStruct; +typedef llvm::ConstantArray LLConstantArray; +typedef llvm::ConstantInt LLConstantInt; + +typedef llvm::PATypeHolder LLPATypeHolder; #define LLSmallVector llvm::SmallVector diff -r 4d006f7b2ada -r a95056b3c996 gen/llvmhelpers.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/llvmhelpers.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -0,0 +1,1090 @@ +#include "gen/llvm.h" + +#include "mars.h" +#include "init.h" + +#include "gen/tollvm.h" +#include "gen/llvmhelpers.h" +#include "gen/irstate.h" +#include "gen/runtime.h" +#include "gen/logger.h" +#include "gen/arrays.h" +#include "gen/dvalue.h" +#include "gen/complex.h" +#include "gen/classes.h" +#include "gen/functions.h" +#include "gen/typeinf.h" + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// DYNAMIC MEMORY HELPERS +////////////////////////////////////////////////////////////////////////////////////////*/ + +LLValue* DtoNew(Type* newtype) +{ + // get runtime function + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT"); + // get type info + LLConstant* ti = DtoTypeInfoOf(newtype); + assert(isaPointer(ti)); + // call runtime allocator + LLValue* mem = gIR->ir->CreateCall(fn, ti, ".gc_mem"); + // cast + return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); +} + +void DtoDeleteMemory(LLValue* ptr) +{ + // get runtime function + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory"); + // build args + LLSmallVector arg; + arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp")); + // call + llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); +} + +void DtoDeleteClass(LLValue* inst) +{ + // get runtime function + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass"); + // build args + LLSmallVector arg; + arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); + // call + llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); +} + +void DtoDeleteInterface(LLValue* inst) +{ + // get runtime function + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface"); + // build args + LLSmallVector arg; + arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); + // call + llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); +} + +void DtoDeleteArray(DValue* arr) +{ + // get runtime function + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray"); + // build args + LLSmallVector arg; + arg.push_back(DtoArrayLen(arr)); + arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp")); + // call + llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// ASSERT HELPER +////////////////////////////////////////////////////////////////////////////////////////*/ + +void DtoAssert(Loc* loc, DValue* msg) +{ + std::vector args; + LLConstant* c; + + // func + const char* fname = msg ? "_d_assert_msg" : "_d_assert"; + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); + + // param attrs + llvm::PAListPtr palist; + int idx = 1; + + c = DtoConstString(loc->filename); + + // msg param + if (msg) + { + if (DSliceValue* s = msg->isSlice()) + { + llvm::AllocaInst* alloc = gIR->func()->msgArg; + if (!alloc) + { + alloc = new llvm::AllocaInst(c->getType(), ".assertmsg", gIR->topallocapoint()); + DtoSetArray(alloc, DtoArrayLen(s), DtoArrayPtr(s)); + gIR->func()->msgArg = alloc; + } + args.push_back(alloc); + } + else + { + args.push_back(msg->getRVal()); + } + palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal); + } + + // file param + llvm::AllocaInst* alloc = gIR->func()->srcfileArg; + if (!alloc) + { + alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint()); + gIR->func()->srcfileArg = alloc; + } + LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); + DtoStore(c->getOperand(0), ptr); + ptr = DtoGEPi(alloc, 0,1, "tmp"); + DtoStore(c->getOperand(1), ptr); + + args.push_back(alloc); + palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal); + + + // line param + c = DtoConstUint(loc->linnum); + args.push_back(c); + + // call + llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); + call->setParamAttrs(palist); +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// NESTED VARIABLE HELPERS +////////////////////////////////////////////////////////////////////////////////////////*/ + +static const LLType* get_next_frame_ptr_type(Dsymbol* sc) +{ + assert(sc->isFuncDeclaration() || sc->isClassDeclaration()); + Dsymbol* p = sc->toParent2(); + if (!p->isFuncDeclaration() && !p->isClassDeclaration()) + Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind()); + assert(p->isFuncDeclaration() || p->isClassDeclaration()); + if (FuncDeclaration* fd = p->isFuncDeclaration()) + { + LLValue* v = fd->ir.irFunc->nestedVar; + assert(v); + return v->getType(); + } + else if (ClassDeclaration* cd = p->isClassDeclaration()) + { + return DtoType(cd->type); + } + else + { + Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind()); + assert(0); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v) +{ + LOG_SCOPE; + if (sc == func) + { + return v; + } + else if (FuncDeclaration* fd = sc->isFuncDeclaration()) + { + Logger::println("scope is function: %s", fd->toChars()); + + if (fd->toParent2() == func) + { + if (!func->ir.irFunc->nestedVar) + return NULL; + return DtoBitCast(v, func->ir.irFunc->nestedVar->getType()); + } + + v = DtoBitCast(v, get_next_frame_ptr_type(fd)); + Logger::cout() << "v = " << *v << '\n'; + + if (fd->toParent2()->isFuncDeclaration()) + { + v = DtoGEPi(v, 0,0, "tmp"); + v = DtoLoad(v); + } + else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) + { + size_t idx = 2; + //idx += cd->ir.irStruct->interfaceVec.size(); + v = DtoGEPi(v,0,idx,"tmp"); + v = DtoLoad(v); + } + else + { + assert(0); + } + return get_frame_ptr_impl(func, fd->toParent2(), v); + } + else if (ClassDeclaration* cd = sc->isClassDeclaration()) + { + Logger::println("scope is class: %s", cd->toChars()); + /*size_t idx = 2; + idx += cd->llvmIrStruct->interfaces.size(); + v = DtoGEPi(v,0,idx,"tmp"); + Logger::cout() << "gep = " << *v << '\n'; + v = DtoLoad(v);*/ + return get_frame_ptr_impl(func, cd->toParent2(), v); + } + else + { + Logger::println("symbol: '%s'", sc->toPrettyChars()); + assert(0); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +static LLValue* get_frame_ptr(FuncDeclaration* func) +{ + Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); + LOG_SCOPE; + IrFunction* irfunc = gIR->func(); + + // in the right scope already + if (func == irfunc->decl) + return irfunc->decl->ir.irFunc->nestedVar; + + // use the 'this' pointer + LLValue* ptr = irfunc->decl->ir.irFunc->thisVar; + assert(ptr); + + // return the fully resolved frame pointer + ptr = get_frame_ptr_impl(func, irfunc->decl, ptr); + if (ptr) Logger::cout() << "Found context!" << *ptr; + else Logger::cout() << "NULL context!\n"; + + return ptr; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +LLValue* DtoNestedContext(FuncDeclaration* func) +{ + // resolve frame ptr + LLValue* ptr = get_frame_ptr(func); + Logger::cout() << "Nested context ptr = "; + if (ptr) Logger::cout() << *ptr; + else Logger::cout() << "NULL"; + Logger::cout() << '\n'; + return ptr; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +static void print_frame_worker(VarDeclaration* vd, Dsymbol* par) +{ + if (vd->toParent2() == par) + { + Logger::println("found: '%s' kind: '%s'", par->toChars(), par->kind()); + return; + } + + Logger::println("diving into: '%s' kind: '%s'", par->toChars(), par->kind()); + LOG_SCOPE; + print_frame_worker(vd, par->toParent2()); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par) +{ + Logger::println("Frame pointer list for nested var: '%s'", vd->toPrettyChars()); + LOG_SCOPE; + if (vd->toParent2() != par) + print_frame_worker(vd, par); + else + Logger::println("Found at level 0"); + Logger::println("Done"); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +LLValue* DtoNestedVariable(VarDeclaration* vd) +{ + // log the frame list + IrFunction* irfunc = gIR->func(); + if (Logger::enabled()) + print_nested_frame_list(vd, irfunc->decl); + + // resolve frame ptr + FuncDeclaration* func = vd->toParent2()->isFuncDeclaration(); + assert(func); + LLValue* ptr = DtoNestedContext(func); + assert(ptr && "nested var, but no context"); + + // we must cast here to be sure. nested classes just have a void* + ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType()); + + // index nested var and load (if necessary) + LLValue* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp"); + // references must be loaded, for normal variables this IS already the variable storage!!! + if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) + v = DtoLoad(v); + + // log and return + Logger::cout() << "Nested var ptr = " << *v << '\n'; + return v; +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// ASSIGNMENT HELPER (store this in that) +////////////////////////////////////////////////////////////////////////////////////////*/ + +void DtoAssign(DValue* lhs, DValue* rhs) +{ + Logger::cout() << "DtoAssign(...);\n"; + LOG_SCOPE; + + Type* t = DtoDType(lhs->getType()); + Type* t2 = DtoDType(rhs->getType()); + + if (t->ty == Tstruct) { + if (t2 != t) { + // TODO: fix this, use 'rhs' for something + DtoAggrZeroInit(lhs->getLVal()); + } + else if (!rhs->inPlace()) { + DtoAggrCopy(lhs->getLVal(), rhs->getRVal()); + } + } + else if (t->ty == Tarray) { + // lhs is slice + if (DSliceValue* s = lhs->isSlice()) { + if (DSliceValue* s2 = rhs->isSlice()) { + DtoArrayCopySlices(s, s2); + } + else if (t->next == t2) { + if (s->len) + DtoArrayInit(s->ptr, s->len, rhs->getRVal()); + else + DtoArrayInit(s->ptr, rhs->getRVal()); + } + else { + DtoArrayCopyToSlice(s, rhs); + } + } + // rhs is slice + else if (DSliceValue* s = rhs->isSlice()) { + assert(s->getType()->toBasetype() == lhs->getType()->toBasetype()); + DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s)); + } + // null + else if (rhs->isNull()) { + DtoSetArrayToNull(lhs->getLVal()); + } + // reference assignment + else { + DtoArrayAssign(lhs->getLVal(), rhs->getRVal()); + } + } + else if (t->ty == Tsarray) { + if (DtoType(lhs->getType()) == DtoType(rhs->getType())) { + DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); + } + else { + DtoArrayInit(lhs->getLVal(), rhs->getRVal()); + } + } + else if (t->ty == Tdelegate) { + if (rhs->isNull()) + DtoAggrZeroInit(lhs->getLVal()); + else if (!rhs->inPlace()) { + LLValue* l = lhs->getLVal(); + LLValue* r = rhs->getRVal(); + Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; + DtoAggrCopy(l, r); + } + } + else if (t->ty == Tclass) { + assert(t2->ty == Tclass); + // assignment to this in constructor special case + if (lhs->isThis()) { + LLValue* tmp = rhs->getRVal(); + FuncDeclaration* fdecl = gIR->func()->decl; + // respecify the this param + if (!llvm::isa(fdecl->ir.irFunc->thisVar)) + fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); + DtoStore(tmp, fdecl->ir.irFunc->thisVar); + } + // regular class ref -> class ref assignment + else { + DtoStore(rhs->getRVal(), lhs->getLVal()); + } + } + else if (t->iscomplex()) { + assert(!lhs->isComplex()); + + LLValue* dst; + if (DLRValue* lr = lhs->isLRValue()) { + dst = lr->getLVal(); + rhs = DtoCastComplex(rhs, lr->getLType()); + } + else { + dst = lhs->getRVal(); + } + + if (DComplexValue* cx = rhs->isComplex()) + DtoComplexSet(dst, cx->re, cx->im); + else + DtoComplexAssign(dst, rhs->getRVal()); + } + else { + LLValue* l = lhs->getLVal(); + LLValue* r = rhs->getRVal(); + Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; + const LLType* lit = l->getType()->getContainedType(0); + if (r->getType() != lit) { + // handle lvalue cast assignments + if (DLRValue* lr = lhs->isLRValue()) { + Logger::println("lvalue cast!"); + r = DtoCast(rhs, lr->getLType())->getRVal(); + } + else { + r = DtoCast(rhs, lhs->getType())->getRVal(); + } + Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; + assert(r->getType() == l->getType()->getContainedType(0)); + } + gIR->ir->CreateStore(r, l); + } +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// CASTING HELPERS +////////////////////////////////////////////////////////////////////////////////////////*/ + +DValue* DtoCastInt(DValue* val, Type* _to) +{ + const LLType* tolltype = DtoType(_to); + + Type* to = DtoDType(_to); + Type* from = DtoDType(val->getType()); + assert(from->isintegral()); + + size_t fromsz = from->size(); + size_t tosz = to->size(); + + LLValue* rval = val->getRVal(); + if (rval->getType() == tolltype) { + return new DImValue(_to, rval); + } + + if (to->isintegral()) { + if (fromsz < tosz) { + Logger::cout() << "cast to: " << *tolltype << '\n'; + if (from->isunsigned() || from->ty == Tbool) { + rval = new llvm::ZExtInst(rval, tolltype, "tmp", gIR->scopebb()); + } else { + rval = new llvm::SExtInst(rval, tolltype, "tmp", gIR->scopebb()); + } + } + else if (fromsz > tosz) { + rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb()); + } + else { + rval = DtoBitCast(rval, tolltype); + } + } + else if (to->isfloating()) { + if (from->isunsigned()) { + rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); + } + else { + rval = new llvm::SIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); + } + } + else if (to->ty == Tpointer) { + Logger::cout() << "cast pointer: " << *tolltype << '\n'; + rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp"); + } + else { + assert(0 && "bad int cast"); + } + + return new DImValue(_to, rval); +} + +DValue* DtoCastPtr(DValue* val, Type* to) +{ + const LLType* tolltype = DtoType(to); + + Type* totype = DtoDType(to); + Type* fromtype = DtoDType(val->getType()); + assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction); + + LLValue* rval; + + if (totype->ty == Tpointer || totype->ty == Tclass) { + LLValue* src = val->getRVal(); + Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n'; + rval = DtoBitCast(src, tolltype); + } + else if (totype->isintegral()) { + rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); + } + else { + Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); + assert(0); + } + + return new DImValue(to, rval); +} + +DValue* DtoCastFloat(DValue* val, Type* to) +{ + if (val->getType() == to) + return val; + + const LLType* tolltype = DtoType(to); + + Type* totype = DtoDType(to); + Type* fromtype = DtoDType(val->getType()); + assert(fromtype->isfloating()); + + size_t fromsz = fromtype->size(); + size_t tosz = totype->size(); + + LLValue* rval; + + if (totype->iscomplex()) { + assert(0); + //return new DImValue(to, DtoComplex(to, val)); + } + else if (totype->isfloating()) { + if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { + rval = val->getRVal(); + } + else if (fromsz < tosz) { + rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); + } + else if (fromsz > tosz) { + rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); + } + else { + assert(0 && "bad float cast"); + } + } + else if (totype->isintegral()) { + if (totype->isunsigned()) { + rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); + } + else { + rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); + } + } + else { + assert(0 && "bad float cast"); + } + + return new DImValue(to, rval); +} + +DValue* DtoCast(DValue* val, Type* to) +{ + Type* fromtype = DtoDType(val->getType()); + Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); + if (fromtype->isintegral()) { + return DtoCastInt(val, to); + } + else if (fromtype->iscomplex()) { + return DtoCastComplex(val, to); + } + else if (fromtype->isfloating()) { + return DtoCastFloat(val, to); + } + else if (fromtype->ty == Tclass) { + return DtoCastClass(val, to); + } + else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { + return DtoCastArray(val, to); + } + else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) { + return DtoCastPtr(val, to); + } + else { + assert(0); + } +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// TEMPLATE HELPERS +////////////////////////////////////////////////////////////////////////////////////////*/ + +bool DtoIsTemplateInstance(Dsymbol* s) +{ + if (!s) return false; + if (s->isTemplateInstance() && !s->isTemplateMixin()) + return true; + else if (s->parent) + return DtoIsTemplateInstance(s->parent); + return false; +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// LAZY STATIC INIT HELPER +////////////////////////////////////////////////////////////////////////////////////////*/ + +void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t) +{ + // create a flag to make sure initialization only happens once + llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage; + std::string gflagname(gvar->getName()); + gflagname.append("__initflag"); + llvm::GlobalVariable* gflag = new llvm::GlobalVariable(LLType::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module); + + // check flag and do init if not already done + llvm::BasicBlock* oldend = gIR->scopeend(); + llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend); + llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend); + LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); + gIR->ir->CreateCondBr(cond, initbb, endinitbb); + gIR->scope() = IRScope(initbb,endinitbb); + DValue* ie = DtoInitializer(init); + if (!ie->inPlace()) { + DValue* dst = new DVarValue(t, gvar, true); + DtoAssign(dst, ie); + } + gIR->ir->CreateStore(DtoConstBool(true), gflag); + gIR->ir->CreateBr(endinitbb); + gIR->scope() = IRScope(endinitbb,oldend); +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// PROCESSING QUEUE HELPERS +////////////////////////////////////////////////////////////////////////////////////////*/ + +void DtoResolveDsymbol(Dsymbol* dsym) +{ + if (StructDeclaration* sd = dsym->isStructDeclaration()) { + DtoResolveStruct(sd); + } + else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { + DtoResolveClass(cd); + } + else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { + DtoResolveFunction(fd); + } + else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { + DtoResolveTypeInfo(fd); + } + else { + error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); + assert(0 && "unsupported dsymbol for DtoResolveDsymbol"); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoDeclareDsymbol(Dsymbol* dsym) +{ + if (StructDeclaration* sd = dsym->isStructDeclaration()) { + DtoDeclareStruct(sd); + } + else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { + DtoDeclareClass(cd); + } + else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { + DtoDeclareFunction(fd); + } + else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { + DtoDeclareTypeInfo(fd); + } + else { + error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); + assert(0 && "unsupported dsymbol for DtoDeclareDsymbol"); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoConstInitDsymbol(Dsymbol* dsym) +{ + if (StructDeclaration* sd = dsym->isStructDeclaration()) { + DtoConstInitStruct(sd); + } + else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { + DtoConstInitClass(cd); + } + else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { + DtoConstInitTypeInfo(fd); + } + else if (VarDeclaration* vd = dsym->isVarDeclaration()) { + DtoConstInitGlobal(vd); + } + else { + error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); + assert(0 && "unsupported dsymbol for DtoConstInitDsymbol"); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoDefineDsymbol(Dsymbol* dsym) +{ + if (StructDeclaration* sd = dsym->isStructDeclaration()) { + DtoDefineStruct(sd); + } + else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { + DtoDefineClass(cd); + } + else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { + DtoDefineFunc(fd); + } + else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { + DtoDefineTypeInfo(fd); + } + else { + error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); + assert(0 && "unsupported dsymbol for DtoDefineDsymbol"); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoConstInitGlobal(VarDeclaration* vd) +{ + if (vd->ir.initialized) return; + vd->ir.initialized = gIR->dmodule; + + Logger::println("* DtoConstInitGlobal(%s)", vd->toChars()); + LOG_SCOPE; + + bool emitRTstaticInit = false; + + LLConstant* _init = 0; + if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) { + _init = DtoConstInitializer(vd->type, NULL); + emitRTstaticInit = true; + } + else { + _init = DtoConstInitializer(vd->type, vd->init); + } + + const LLType* _type = DtoType(vd->type); + Type* t = DtoDType(vd->type); + + //Logger::cout() << "initializer: " << *_init << '\n'; + if (_type != _init->getType()) { + Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; + // zero initalizer + if (_init->isNullValue()) + _init = llvm::Constant::getNullValue(_type); + // pointer to global constant (struct.init) + else if (llvm::isa(_init)) + { + assert(_init->getType()->getContainedType(0) == _type); + llvm::GlobalVariable* gv = llvm::cast(_init); + assert(t->ty == Tstruct); + TypeStruct* ts = (TypeStruct*)t; + assert(ts->sym->ir.irStruct->constInit); + _init = ts->sym->ir.irStruct->constInit; + } + // array single value init + else if (isaArray(_type)) + { + _init = DtoConstStaticArray(_type, _init); + } + else { + Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; + //assert(0); + } + } + + bool istempl = false; + if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) { + istempl = true; + } + + if (_init && _init->getType() != _type) + _type = _init->getType(); + llvm::cast(vd->ir.irGlobal->type.get())->refineAbstractTypeTo(_type); + _type = vd->ir.irGlobal->type.get(); + //_type->dump(); + assert(!_type->isAbstract()); + + llvm::GlobalVariable* gvar = llvm::cast(vd->ir.irGlobal->value); + if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) + { + gvar->setInitializer(_init); + } + + if (emitRTstaticInit) + DtoLazyStaticInit(istempl, gvar, vd->init, t); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoEmptyResolveList() +{ + //Logger::println("DtoEmptyResolveList()"); + Dsymbol* dsym; + while (!gIR->resolveList.empty()) { + dsym = gIR->resolveList.front(); + gIR->resolveList.pop_front(); + DtoResolveDsymbol(dsym); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoEmptyDeclareList() +{ + //Logger::println("DtoEmptyDeclareList()"); + Dsymbol* dsym; + while (!gIR->declareList.empty()) { + dsym = gIR->declareList.front(); + gIR->declareList.pop_front(); + DtoDeclareDsymbol(dsym); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoEmptyConstInitList() +{ + //Logger::println("DtoEmptyConstInitList()"); + Dsymbol* dsym; + while (!gIR->constInitList.empty()) { + dsym = gIR->constInitList.front(); + gIR->constInitList.pop_front(); + DtoConstInitDsymbol(dsym); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoEmptyDefineList() +{ + //Logger::println("DtoEmptyDefineList()"); + Dsymbol* dsym; + while (!gIR->defineList.empty()) { + dsym = gIR->defineList.front(); + gIR->defineList.pop_front(); + DtoDefineDsymbol(dsym); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +void DtoEmptyAllLists() +{ + for(;;) + { + Dsymbol* dsym; + if (!gIR->resolveList.empty()) { + dsym = gIR->resolveList.front(); + gIR->resolveList.pop_front(); + DtoResolveDsymbol(dsym); + } + else if (!gIR->declareList.empty()) { + dsym = gIR->declareList.front(); + gIR->declareList.pop_front(); + DtoDeclareDsymbol(dsym); + } + else if (!gIR->constInitList.empty()) { + dsym = gIR->constInitList.front(); + gIR->constInitList.pop_front(); + DtoConstInitDsymbol(dsym); + } + else if (!gIR->defineList.empty()) { + dsym = gIR->defineList.front(); + gIR->defineList.pop_front(); + DtoDefineDsymbol(dsym); + } + else { + break; + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoForceDeclareDsymbol(Dsymbol* dsym) +{ + if (dsym->ir.declared) return; + Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars()); + LOG_SCOPE; + DtoResolveDsymbol(dsym); + + DtoEmptyResolveList(); + + DtoDeclareDsymbol(dsym); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoForceConstInitDsymbol(Dsymbol* dsym) +{ + if (dsym->ir.initialized) return; + Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars()); + LOG_SCOPE; + DtoResolveDsymbol(dsym); + + DtoEmptyResolveList(); + DtoEmptyDeclareList(); + + DtoConstInitDsymbol(dsym); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoForceDefineDsymbol(Dsymbol* dsym) +{ + if (dsym->ir.defined) return; + Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars()); + LOG_SCOPE; + DtoResolveDsymbol(dsym); + + DtoEmptyResolveList(); + DtoEmptyDeclareList(); + DtoEmptyConstInitList(); + + DtoDefineDsymbol(dsym); +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// INITIALIZER HELPERS +////////////////////////////////////////////////////////////////////////////////////////*/ + +LLConstant* DtoConstInitializer(Type* type, Initializer* init) +{ + LLConstant* _init = 0; // may return zero + if (!init) + { + Logger::println("const default initializer for %s", type->toChars()); + _init = type->defaultInit()->toConstElem(gIR); + } + else if (ExpInitializer* ex = init->isExpInitializer()) + { + Logger::println("const expression initializer"); + _init = ex->exp->toConstElem(gIR); + } + else if (StructInitializer* si = init->isStructInitializer()) + { + Logger::println("const struct initializer"); + _init = DtoConstStructInitializer(si); + } + else if (ArrayInitializer* ai = init->isArrayInitializer()) + { + Logger::println("const array initializer"); + _init = DtoConstArrayInitializer(ai); + } + else if (init->isVoidInitializer()) + { + Logger::println("const void initializer"); + const LLType* ty = DtoType(type); + _init = llvm::Constant::getNullValue(ty); + } + else { + Logger::println("unsupported const initializer: %s", init->toChars()); + } + return _init; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +LLConstant* DtoConstFieldInitializer(Type* t, Initializer* init) +{ + Logger::println("DtoConstFieldInitializer"); + LOG_SCOPE; + + const LLType* _type = DtoType(t); + + LLConstant* _init = DtoConstInitializer(t, init); + assert(_init); + if (_type != _init->getType()) + { + Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; + if (t->ty == Tsarray) + { + const LLArrayType* arrty = isaArray(_type); + uint64_t n = arrty->getNumElements(); + std::vector vals(n,_init); + _init = llvm::ConstantArray::get(arrty, vals); + } + else if (t->ty == Tarray) + { + assert(isaStruct(_type)); + _init = llvm::ConstantAggregateZero::get(_type); + } + else if (t->ty == Tstruct) + { + const LLStructType* structty = isaStruct(_type); + TypeStruct* ts = (TypeStruct*)t; + assert(ts); + assert(ts->sym); + assert(ts->sym->ir.irStruct->constInit); + _init = ts->sym->ir.irStruct->constInit; + } + else if (t->ty == Tclass) + { + _init = llvm::Constant::getNullValue(_type); + } + else { + Logger::println("failed for type %s", t->toChars()); + assert(0); + } + } + + return _init; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +DValue* DtoInitializer(Initializer* init) +{ + if (ExpInitializer* ex = init->isExpInitializer()) + { + Logger::println("expression initializer"); + assert(ex->exp); + return ex->exp->toElem(gIR); + } + else if (init->isVoidInitializer()) + { + // do nothing + } + else { + Logger::println("unsupported initializer: %s", init->toChars()); + assert(0); + } + return 0; +} + + +////////////////////////////////////////////////////////////////////////////////////////// + +void DtoAnnotation(const char* str) +{ + std::string s("CODE: "); + s.append(str); + char* p = &s[0]; + while (*p) + { + if (*p == '"') + *p = '\''; + ++p; + } + // create a noop with the code as the result name! + gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str()); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +LLConstant* DtoTypeInfoOf(Type* type, bool base) +{ + const LLType* typeinfotype = DtoType(Type::typeinfo->type); + if (!type->vtinfo) + type->getTypeInfo(NULL); + TypeInfoDeclaration* tidecl = type->vtinfo; + DtoForceDeclareDsymbol(tidecl); + assert(tidecl->ir.irGlobal != NULL); + LLConstant* c = isaConstant(tidecl->ir.irGlobal->value); + assert(c != NULL); + if (base) + return llvm::ConstantExpr::getBitCast(c, typeinfotype); + return c; +} diff -r 4d006f7b2ada -r a95056b3c996 gen/llvmhelpers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/llvmhelpers.h Mon Jun 09 09:37:08 2008 +0200 @@ -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 diff -r 4d006f7b2ada -r a95056b3c996 gen/runtime.cpp --- a/gen/runtime.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/runtime.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -158,12 +158,12 @@ static const LLType* rt_dg1() { std::vector types; - types.push_back(rt_ptr(llvm::Type::Int8Ty)); - types.push_back(rt_ptr(llvm::Type::Int8Ty)); - const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false); + types.push_back(rt_ptr(LLType::Int8Ty)); + types.push_back(rt_ptr(LLType::Int8Ty)); + const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false); std::vector t; - t.push_back(rt_ptr(llvm::Type::Int8Ty)); + t.push_back(rt_ptr(LLType::Int8Ty)); t.push_back(rt_ptr(fty)); return rt_ptr(llvm::StructType::get(t)); } @@ -171,13 +171,13 @@ static const LLType* rt_dg2() { std::vector types; - types.push_back(rt_ptr(llvm::Type::Int8Ty)); - types.push_back(rt_ptr(llvm::Type::Int8Ty)); - types.push_back(rt_ptr(llvm::Type::Int8Ty)); - const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false); + types.push_back(rt_ptr(LLType::Int8Ty)); + types.push_back(rt_ptr(LLType::Int8Ty)); + types.push_back(rt_ptr(LLType::Int8Ty)); + const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false); std::vector t; - t.push_back(rt_ptr(llvm::Type::Int8Ty)); + t.push_back(rt_ptr(LLType::Int8Ty)); t.push_back(rt_ptr(fty)); return rt_ptr(llvm::StructType::get(t)); } @@ -186,14 +186,14 @@ { M = new llvm::Module("llvmdc internal runtime"); - const LLType* voidTy = llvm::Type::VoidTy; - const LLType* boolTy = llvm::Type::Int1Ty; - const LLType* byteTy = llvm::Type::Int8Ty; - const LLType* shortTy = llvm::Type::Int16Ty; - const LLType* intTy = llvm::Type::Int32Ty; - const LLType* longTy = llvm::Type::Int64Ty; - const LLType* floatTy = llvm::Type::FloatTy; - const LLType* doubleTy = llvm::Type::DoubleTy; + const LLType* voidTy = LLType::VoidTy; + const LLType* boolTy = LLType::Int1Ty; + const LLType* byteTy = LLType::Int8Ty; + const LLType* shortTy = LLType::Int16Ty; + const LLType* intTy = LLType::Int32Ty; + const LLType* longTy = LLType::Int64Ty; + const LLType* floatTy = LLType::FloatTy; + const LLType* doubleTy = LLType::DoubleTy; const LLType* sizeTy = DtoSize_t(); const LLType* voidPtrTy = rt_ptr(byteTy); const LLType* stringTy = rt_array(byteTy); diff -r 4d006f7b2ada -r a95056b3c996 gen/statements.cpp --- a/gen/statements.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/statements.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -20,6 +20,7 @@ #include "gen/irstate.h" #include "gen/logger.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/runtime.h" #include "gen/arrays.h" #include "gen/todebug.h" @@ -74,7 +75,7 @@ if (exp) { - if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { + if (p->topfunc()->getReturnType() == LLType::VoidTy) { IrFunction* f = p->func(); assert(f->type->llvmRetInPtr); assert(f->decl->ir.irFunc->retArg); @@ -128,7 +129,7 @@ } else { - assert(p->topfunc()->getReturnType() == llvm::Type::VoidTy); + assert(p->topfunc()->getReturnType() == LLType::VoidTy); emit_finallyblocks(p, enclosingtryfinally, NULL); if (gIR->func()->inVolatile) { @@ -187,7 +188,7 @@ llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endif", gIR->topfunc(), oldend); 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'; cond_val = DtoBoolean(cond_val); } @@ -892,10 +893,10 @@ else { Logger::println("foreach over dynamic array"); val = aggrval->getRVal(); - niters = DtoGEPi(val,0,0,"tmp",p->scopebb()); - niters = p->ir->CreateLoad(niters, "numiterations"); - val = DtoGEPi(val,0,1,"tmp",p->scopebb()); - val = p->ir->CreateLoad(val, "collection"); + niters = DtoGEPi(val,0,0); + niters = DtoLoad(niters, "numiterations"); + val = DtoGEPi(val,0,1); + val = DtoLoad(val, "collection"); } } else @@ -935,7 +936,7 @@ p->scope() = IRScope(condbb,bodybb); LLValue* done = 0; - LLValue* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb()); + LLValue* load = DtoLoad(keyvar); if (op == TOKforeach) { done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb()); } diff -r 4d006f7b2ada -r a95056b3c996 gen/structs.cpp --- a/gen/structs.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/structs.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -9,6 +9,7 @@ #include "gen/irstate.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/arrays.h" #include "gen/logger.h" #include "gen/structs.h" @@ -16,66 +17,6 @@ #include "ir/irstruct.h" ////////////////////////////////////////////////////////////////////////////////////////// - -const LLType* DtoStructType(Type* t) -{ - assert(0); - std::vector 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 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 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) { Logger::println("DtoConstStructInitializer: %s", si->toChars()); @@ -227,7 +168,7 @@ if (irstruct->offsets.empty()) { Logger::println("has no fields"); - fieldtypes.push_back(llvm::Type::Int8Ty); + fieldtypes.push_back(LLType::Int8Ty); structtype = llvm::StructType::get(fieldtypes); } else @@ -273,7 +214,7 @@ fieldtypes.push_back(fieldtype); irstruct->defaultFields.push_back(fieldinit); 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); idx++; } @@ -292,7 +233,7 @@ fieldtypes.push_back(fieldtype); irstruct->defaultFields.push_back(fieldinit); 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); } @@ -380,7 +321,7 @@ } else { const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); - std::vector vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); + std::vector vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false)); c = llvm::ConstantArray::get(arrty, vals); } fieldinits_ll.push_back(c); @@ -392,6 +333,7 @@ // always generate the constant initalizer if (!sd->zeroInit) { Logger::println("Not zero initialized"); + #if 0 //assert(tk == gIR->gIR->topstruct()().size()); #ifndef LLVMD_NO_LOGGER Logger::cout() << "struct type: " << *structtype << '\n'; @@ -403,6 +345,7 @@ } Logger::cout() << "Initializer printed" << '\n'; #endif + #endif sd->ir.irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll); } else { @@ -498,8 +441,8 @@ static void push_nulls(size_t nbytes, std::vector& out) { assert(nbytes > 0); - std::vector i(nbytes, llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); - out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(llvm::Type::Int8Ty, nbytes), i)); + std::vector i(nbytes, llvm::ConstantInt::get(LLType::Int8Ty, 0, false)); + out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(LLType::Int8Ty, nbytes), i)); } LLConstant* DUnion::getConst(std::vector& in) diff -r 4d006f7b2ada -r a95056b3c996 gen/structs.h --- a/gen/structs.h Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/structs.h Mon Jun 09 09:37:08 2008 +0200 @@ -3,11 +3,6 @@ struct StructInitializer; -const LLType* DtoStructType(Type* t); - -LLValue* DtoStructZeroInit(LLValue* v); -LLValue* DtoStructCopy(LLValue* dst, LLValue* src); - LLConstant* DtoConstStructInitializer(StructInitializer* si); /** diff -r 4d006f7b2ada -r a95056b3c996 gen/todebug.cpp --- a/gen/todebug.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/todebug.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -22,17 +22,15 @@ static const llvm::PointerType* dbgArrTy() { - std::vector t; - return ptrTy(llvm::StructType::get(t)); + return ptrTy(llvm::StructType::get(NULL,NULL)); } static LLConstant* dbgToArrTy(LLConstant* c) { - Logger::cout() << "casting: " << *c << '\n'; return llvm::ConstantExpr::getBitCast(c, dbgArrTy()); } -#define Ty(X) llvm::Type::X +#define Ty(X) LLType::X ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -48,7 +46,7 @@ uint ;; Tag of descriptors grouped by the anchor } */ - std::vector elems(2, Ty(Int32Ty)); + const llvm::StructType* t = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type")); /* @@ -154,7 +152,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) +LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) { std::vector vals; vals.push_back(llvm::ConstantExpr::getAdd( @@ -203,3 +201,111 @@ args.push_back(dbgToArrTy(DtoDwarfCompileUnit(fd->getModule()))); 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 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 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 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()); +} diff -r 4d006f7b2ada -r a95056b3c996 gen/todebug.h --- a/gen/todebug.h Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/todebug.h Mon Jun 09 09:37:08 2008 +0200 @@ -15,6 +15,13 @@ 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 diff -r 4d006f7b2ada -r a95056b3c996 gen/toir.cpp --- a/gen/toir.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/toir.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -24,6 +24,7 @@ #include "gen/irstate.h" #include "gen/logger.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/runtime.h" #include "gen/arrays.h" #include "gen/structs.h" @@ -33,6 +34,7 @@ #include "gen/dvalue.h" #include "gen/aa.h" #include "gen/functions.h" +#include "gen/todebug.h" ////////////////////////////////////////////////////////////////////////////////////////// @@ -75,6 +77,14 @@ assert(!vd->ir.irLocal); vd->ir.irLocal = new IrLocal(vd); 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'; @@ -315,7 +325,7 @@ LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false); return llvm::ConstantExpr::getIntToPtr(i, t); } - assert(llvm::isa(t)); + assert(llvm::isa(t)); LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); assert(c); Logger::cout() << "value = " << *c << '\n'; @@ -410,10 +420,10 @@ Type* cty = DtoDType(dtype->next); const LLType* ct = DtoType(cty); - if (ct == llvm::Type::VoidTy) - ct = llvm::Type::Int8Ty; + if (ct == LLType::VoidTy) + ct = LLType::Int8Ty; //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; if (cty->size() == 1) { @@ -446,7 +456,7 @@ Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; 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* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); @@ -471,7 +481,7 @@ assert(0); } 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); return new DVarValue(type, emem, true); } @@ -497,7 +507,7 @@ size_t endlen = nullterm ? len+1 : len; const LLType* ct = DtoType(cty); - const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen); + const LLArrayType* at = LLArrayType::get(ct,endlen); LLConstant* _init; if (cty->size() == 1) { @@ -536,7 +546,7 @@ llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; 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* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); @@ -880,8 +890,6 @@ Type* e1type = DtoDType(e1->type); 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; // hidden struct return parameter handling @@ -952,7 +960,7 @@ DValue* expv = exp->toElem(p); if (expv->getType()->toBasetype()->ty != 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 return new DImValue(type, alloc); } @@ -972,32 +980,32 @@ assert(funcval != 0); std::vector 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. // // normal function call - if (llvm::isa(funcval->getType())) { - llfnty = llvm::cast(funcval->getType()); + if (llvm::isa(funcval->getType())) { + llfnty = llvm::cast(funcval->getType()); } // pointer to something else if (isaPointer(funcval->getType())) { // 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** if (isaPointer(funcval->getType()->getContainedType(0))) { - funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); + funcval = DtoLoad(funcval); } // function pointer - if (llvm::isa(funcval->getType()->getContainedType(0))) { + if (llvm::isa(funcval->getType()->getContainedType(0))) { //Logger::cout() << "function pointer type:\n" << *funcval << '\n'; - llfnty = llvm::cast(funcval->getType()->getContainedType(0)); + llfnty = llvm::cast(funcval->getType()->getContainedType(0)); } // struct pointer - delegate else if (isaStruct(funcval->getType()->getContainedType(0))) { - funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb()); - funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); + funcval = DtoGEPi(funcval,0,1); + funcval = DtoLoad(funcval); const LLType* ty = funcval->getType()->getContainedType(0); - llfnty = llvm::cast(ty); + llfnty = llvm::cast(ty); } // unknown else { @@ -1011,7 +1019,7 @@ //Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; // argument handling - llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); + LLFunctionType::param_iterator argiter = llfnty->param_begin(); int j = 0; IRExp* topexp = p->topexp(); @@ -1069,8 +1077,8 @@ // delegate context arguments else if (delegateCall) { Logger::println("Delegate Call"); - LLValue* contextptr = DtoGEP(fn->getRVal(),zero,zero,"tmp",p->scopebb()); - llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); + LLValue* contextptr = DtoGEPi(fn->getRVal(),0,0); + llargs[j] = DtoLoad(contextptr); ++j; ++argiter; } @@ -1079,8 +1087,8 @@ Logger::println("Nested Call"); LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); if (!contextptr) - contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); - llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty)); + contextptr = llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)); + llargs[j] = DtoBitCast(contextptr, getPtrToType(LLType::Int8Ty)); ++j; ++argiter; } @@ -1094,7 +1102,7 @@ Argument* fnarg = Argument::getNth(tf->parameters, i); Expression* exp = (Expression*)arguments->data[i]; 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 @@ -1117,7 +1125,7 @@ Expression* argexp = (Expression*)arguments->data[i]; 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'; LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); @@ -1133,7 +1141,7 @@ // build type info array assert(Type::typeinfo->ir.irStruct->constInit); 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 = new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module); @@ -1162,7 +1170,7 @@ // specify arguments llargs[j] = typeinfoarrayparam;; j++; - llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); + llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(LLType::Int8Ty), "tmp"); j++; // pass non variadic args @@ -1228,7 +1236,7 @@ // void returns cannot not be named const char* varname = ""; - if (llfnty->getReturnType() != llvm::Type::VoidTy) + if (llfnty->getReturnType() != LLType::VoidTy) varname = "tmp"; //Logger::cout() << "Calling: " << *funcval << '\n'; @@ -1425,13 +1433,13 @@ assert(fdecl->vtblIndex > 0); assert(e1type->ty == Tclass); - LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - LLValue* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); + LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); + LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false); //Logger::cout() << "vthis: " << *vthis << '\n'; - funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb()); - funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); - funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); - funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); + funcval = DtoGEP(vthis, zero, zero); + funcval = DtoLoad(funcval); + funcval = DtoGEP(funcval, zero, vtblidx, toChars()); + funcval = DtoLoad(funcval); #if OPAQUE_VTBLS funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); Logger::cout() << "funcval casted: " << *funcval << '\n'; @@ -1465,10 +1473,10 @@ LLValue* v; v = p->func()->decl->ir.irFunc->thisVar; if (llvm::isa(v)) - v = new llvm::LoadInst(v, "tmp", p->scopebb()); + v = DtoLoad(v); const LLType* t = DtoType(type); if (v->getType() != t) - v = DtoBitCast(v, t, "tmp"); + v = DtoBitCast(v, t); return new DThisValue(vd, v); } @@ -1491,20 +1499,20 @@ DValue* r = e2->toElem(p); p->arrays.pop_back(); - LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); + LLValue* zero = DtoConstUint(0); + LLValue* one = DtoConstUint(1); LLValue* arrptr = 0; 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) { - arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb()); + arrptr = DtoGEP(l->getRVal(), zero, r->getRVal()); } else if (e1type->ty == Tarray) { - arrptr = DtoGEP(l->getRVal(),zero,one,"tmp",p->scopebb()); - arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb()); - arrptr = llvm::GetElementPtrInst::Create(arrptr,r->getRVal(),"tmp",p->scopebb()); + arrptr = DtoGEP(l->getRVal(),zero,one); + arrptr = DtoLoad(arrptr); + arrptr = DtoGEP1(arrptr,r->getRVal()); } else if (e1type->ty == Taarray) { return DtoAAIndex(type, l, r); @@ -1530,8 +1538,8 @@ LLValue* vmem = v->getRVal(); assert(vmem); - LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); + LLValue* zero = DtoConstUint(0); + LLValue* one = DtoConstUint(1); LLValue* emem = 0; LLValue* earg = 0; @@ -1552,32 +1560,32 @@ emem = v->getRVal(); } else if (e1type->ty == Tarray) { - LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); - emem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); + LLValue* tmp = DtoGEP(vmem,zero,one); + emem = DtoLoad(tmp); } else if (e1type->ty == Tsarray) { - emem = DtoGEP(vmem,zero,zero,"tmp",p->scopebb()); + emem = DtoGEP(vmem,zero,zero); } else assert(emem); llvm::ConstantInt* c = llvm::cast(cv->c); if (!(lwr_is_zero = c->isZero())) { - emem = llvm::GetElementPtrInst::Create(emem,cv->c,"tmp",p->scopebb()); + emem = DtoGEP1(emem,cv->c); } } else { if (e1type->ty == Tarray) { - LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); - tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); - emem = llvm::GetElementPtrInst::Create(tmp,lo->getRVal(),"tmp",p->scopebb()); + LLValue* tmp = DtoGEP(vmem,zero,one); + tmp = DtoLoad(tmp); + emem = DtoGEP1(tmp,lo->getRVal()); } 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) { - emem = llvm::GetElementPtrInst::Create(v->getRVal(),lo->getRVal(),"tmp",p->scopebb()); + emem = DtoGEP1(v->getRVal(),lo->getRVal()); } else { Logger::println("type = %s", e1type->toChars()); @@ -1915,11 +1923,11 @@ // init TypeStruct* ts = (TypeStruct*)ntype; if (ts->isZeroInit()) { - DtoStructZeroInit(mem); + DtoAggrZeroInit(mem); } else { assert(ts->sym); - DtoStructCopy(mem,ts->sym->ir.irStruct->init); + DtoAggrCopy(mem,ts->sym->ir.irStruct->init); } return new DImValue(type, mem, false); } @@ -2071,7 +2079,7 @@ 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); return new DImValue(type, b); @@ -2087,7 +2095,7 @@ // allocate a temporary for the final result. failed to come up with a better way :/ LLValue* resval = 0; 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); @@ -2096,7 +2104,7 @@ llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); LLValue* ubool = DtoBoolean(u->getRVal()); - new llvm::StoreInst(ubool,resval,p->scopebb()); + DtoStore(ubool,resval); llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); p->scope() = IRScope(andand, andandend); @@ -2104,12 +2112,12 @@ LLValue* vbool = DtoBoolean(v->getRVal()); 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()); p->scope() = IRScope(andandend, oldend); - resval = new llvm::LoadInst(resval,"tmp",p->scopebb()); + resval = DtoLoad(resval); return new DImValue(type, resval); } @@ -2123,7 +2131,7 @@ // allocate a temporary for the final result. failed to come up with a better way :/ LLValue* resval = 0; 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); @@ -2132,14 +2140,14 @@ llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); LLValue* ubool = DtoBoolean(u->getRVal()); - new llvm::StoreInst(ubool,resval,p->scopebb()); + DtoStore(ubool,resval); llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); p->scope() = IRScope(oror, ororend); DValue* v = e2->toElem(p); LLValue* vbool = DtoBoolean(v->getRVal()); - new llvm::StoreInst(vbool,resval,p->scopebb()); + DtoStore(vbool,resval); llvm::BranchInst::Create(ororend,p->scopebb()); p->scope() = IRScope(ororend, oldend); @@ -2173,7 +2181,7 @@ LLValue* uval = u->getRVal(); \ LLValue* vval = v->getRVal(); \ 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; \ } @@ -2205,7 +2213,7 @@ Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty); + const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); LLValue* lval; bool inplace = false; @@ -2245,11 +2253,11 @@ Logger::cout() << "context = " << *uval << '\n'; - LLValue* context = DtoGEPi(lval,0,0,"tmp"); + LLValue* context = DtoGEPi(lval,0,0); LLValue* castcontext = DtoBitCast(uval, int8ptrty); DtoStore(castcontext, context); - LLValue* fptr = DtoGEPi(lval,0,1,"tmp"); + LLValue* fptr = DtoGEPi(lval,0,1); Logger::println("func: '%s'", func->toPrettyChars()); @@ -2318,7 +2326,7 @@ if (v->isNull()) r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); 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; eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); @@ -2528,23 +2536,23 @@ temp = true; } - LLValue* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); - const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); + LLValue* context = DtoGEPi(lval,0,0); + const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; if (llvmNested == NULL) { LLValue* nullcontext = llvm::ConstantPointerNull::get(pty); - p->ir->CreateStore(nullcontext, context); + DtoStore(nullcontext, context); } else { - LLValue* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); - p->ir->CreateStore(nestedcontext, context); + LLValue* nestedcontext = DtoBitCast(llvmNested, pty); + DtoStore(nestedcontext, context); } LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); assert(fd->ir.irFunc->func); - LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func,fptr->getType()->getContainedType(0)); - new llvm::StoreInst(castfptr, fptr, p->scopebb()); + LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); + DtoStore(castfptr, fptr); if (temp) return new DVarValue(type, lval, true); @@ -2575,7 +2583,7 @@ Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; // llvm storage type - const LLType* llStoType = llvm::ArrayType::get(DtoType(elemType), len); + const LLType* llStoType = LLArrayType::get(DtoType(elemType), len); Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; // dst pointer @@ -2641,7 +2649,7 @@ const LLType* t = DtoType(type); Logger::cout() << "array literal has llvm type: " << *t << '\n'; assert(isaArray(t)); - const llvm::ArrayType* arrtype = isaArray(t); + const LLArrayType* arrtype = isaArray(t); assert(arrtype->getNumElements() == elements->dim); std::vector vals(elements->dim, NULL); @@ -2692,7 +2700,7 @@ if (!vx) continue; tys.push_back(DtoType(vx->type)); } - const llvm::StructType* t = llvm::StructType::get(tys); + const LLStructType* t = LLStructType::get(tys); if (t != llt) { if (getABITypeSize(t) != getABITypeSize(llt)) { Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n'; @@ -2711,7 +2719,7 @@ if (!vx) continue; 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); p->exps.push_back(IRExp(NULL,vx,darrptr)); @@ -2745,7 +2753,7 @@ assert(DtoDType(type)->ty == Tstruct); const LLType* t = DtoType(type); - const llvm::StructType* st = isaStruct(t); + const LLStructType* st = isaStruct(t); return llvm::ConstantStruct::get(st,vals); } diff -r 4d006f7b2ada -r a95056b3c996 gen/tollvm.cpp --- a/gen/tollvm.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/tollvm.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -18,6 +18,7 @@ #include "gen/classes.h" #include "gen/typeinf.h" #include "gen/complex.h" +#include "gen/llvmhelpers.h" bool DtoIsPassedByRef(Type* type) { @@ -52,18 +53,18 @@ case Tint8: case Tuns8: case Tchar: - return (const LLType*)llvm::Type::Int8Ty; + return (const LLType*)LLType::Int8Ty; case Tint16: case Tuns16: case Twchar: - return (const LLType*)llvm::Type::Int16Ty; + return (const LLType*)LLType::Int16Ty; case Tint32: case Tuns32: case Tdchar: - return (const LLType*)llvm::Type::Int32Ty; + return (const LLType*)LLType::Int32Ty; case Tint64: case Tuns64: - return (const LLType*)llvm::Type::Int64Ty; + return (const LLType*)LLType::Int64Ty; case Tbool: return (const LLType*)llvm::ConstantInt::getTrue()->getType(); @@ -71,13 +72,13 @@ // floats case Tfloat32: case Timaginary32: - return llvm::Type::FloatTy; + return LLType::FloatTy; case Tfloat64: case Timaginary64: - return llvm::Type::DoubleTy; + return LLType::DoubleTy; case Tfloat80: case Timaginary80: - return (global.params.useFP80) ? llvm::Type::X86_FP80Ty : llvm::Type::DoubleTy; + return (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy; // complex case Tcomplex32: @@ -89,7 +90,7 @@ case Tpointer: { assert(t->next); if (t->next->ty == Tvoid) - return (const LLType*)getPtrToType(llvm::Type::Int8Ty); + return (const LLType*)getPtrToType(LLType::Int8Ty); else return (const LLType*)getPtrToType(DtoType(t->next)); } @@ -102,25 +103,10 @@ // void case Tvoid: - return llvm::Type::VoidTy; + return LLType::VoidTy; // aggregates case Tstruct: { - if (!t->ir.type || *t->ir.type == NULL) { - // recursive or cyclic declaration - if (!gIR->structs.empty()) - { - IrStruct* found = 0; - for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) - { - if (t == (*i)->type) - { - return (*i)->recty.get(); - } - } - } - } - TypeStruct* ts = (TypeStruct*)t; assert(ts->sym); DtoResolveDsymbol(ts->sym); @@ -128,22 +114,6 @@ } case Tclass: { - /*if (!t].type || *gIR->irType[t->ir.type == NULL) { - // recursive or cyclic declaration - if (!gIR->structs.empty()) - { - IrStruct* found = 0; - for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) - { - if (t == (*i)->type) - { - return getPtrToType((*i)->recty.get()); - } - } - } - Logger::println("no type found"); - }*/ - TypeClass* tc = (TypeClass*)t; assert(tc->sym); DtoResolveDsymbol(tc->sym); @@ -186,10 +156,7 @@ case Taarray: { TypeAArray* taa = (TypeAArray*)t; - std::vector types; - types.push_back(DtoType(taa->key)); - types.push_back(DtoType(taa->next)); - return getPtrToType(llvm::StructType::get(types)); + return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0)); } default: @@ -201,112 +168,12 @@ ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::StructType* DtoDelegateType(Type* t) +const LLStructType* DtoDelegateType(Type* t) { - const LLType* i8ptr = getPtrToType(llvm::Type::Int8Ty); + const LLType* i8ptr = getVoidPtrType(); const LLType* func = DtoFunctionType(t->next, i8ptr); const LLType* funcptr = getPtrToType(func); - - std::vector types; - types.push_back(i8ptr); - types.push_back(funcptr); - return llvm::StructType::get(types); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -/* -static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false) -{ - assert(bits == 32 || bits == 64); - const LLType* int8ty = (const LLType*)llvm::Type::Int8Ty; - const LLType* int32ty = (const LLType*)llvm::Type::Int32Ty; - const LLType* int64ty = (const LLType*)llvm::Type::Int64Ty; - const LLType* int8ptrty = (const LLType*)getPtrToType(llvm::Type::Int8Ty); - const LLType* voidty = (const LLType*)llvm::Type::VoidTy; - - assert(gIR); - assert(gIR->module); - - // parameter types - std::vector pvec; - pvec.push_back(int8ptrty); - pvec.push_back(set?int8ty:int8ptrty); - pvec.push_back(bits==32?int32ty:int64ty); - pvec.push_back(int32ty); - llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false); - return llvm::cast(gIR->module->getOrInsertFunction(name, functype)); -} -*/ - -////////////////////////////////////////////////////////////////////////////////////////// - -// llvm.memset.i32 -llvm::Function* LLVM_DeclareMemSet32() -{ - return GET_INTRINSIC_DECL(memset_i32); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -llvm::Function* LLVM_DeclareMemSet64() -{ - return GET_INTRINSIC_DECL(memset_i64); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -// llvm.memcpy.i32 -llvm::Function* LLVM_DeclareMemCpy32() -{ - return GET_INTRINSIC_DECL(memcpy_i32); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -// llvm.memcpy.i64 -llvm::Function* LLVM_DeclareMemCpy64() -{ - return GET_INTRINSIC_DECL(memcpy_i64); -} - -void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) -{ - llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier); - assert(fn != NULL); - - LLSmallVector llargs; - llargs.push_back(DtoConstBool(ll)); - llargs.push_back(DtoConstBool(ls)); - llargs.push_back(DtoConstBool(sl)); - llargs.push_back(DtoConstBool(ss)); - llargs.push_back(DtoConstBool(device)); - - llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoDelegateToNull(LLValue* v) -{ - LLSmallVector args; - args.push_back(DtoBitCast(v, getVoidPtrType())); - args.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty)); - args.push_back(DtoConstInt(global.params.is64bit ? 16 : 8)); - args.push_back(DtoConstInt(0)); - gIR->ir->CreateCall(GET_INTRINSIC_DECL(memset_i32), args.begin(), args.end(), ""); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoDelegateCopy(LLValue* dst, LLValue* src) -{ - LLSmallVector args; - args.push_back(DtoBitCast(dst,getVoidPtrType())); - args.push_back(DtoBitCast(src,getVoidPtrType())); - args.push_back(DtoConstInt(global.params.is64bit ? 16 : 8)); - args.push_back(DtoConstInt(0)); - gIR->ir->CreateCall(GET_INTRINSIC_DECL(memcpy_i32), args.begin(), args.end(), ""); + return LLStructType::get(i8ptr, funcptr, 0); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -318,20 +185,20 @@ llvm::Value *b1, *b2; if (rhs == NULL) { - LLValue* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); + LLValue* l = DtoLoad(DtoGEPi(lhs,0,0)); LLValue* r = llvm::Constant::getNullValue(l->getType()); b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); - l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); + l = DtoLoad(DtoGEPi(lhs,0,1)); r = llvm::Constant::getNullValue(l->getType()); b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); } else { - LLValue* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); - LLValue* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); + LLValue* l = DtoLoad(DtoGEPi(lhs,0,0)); + LLValue* r = DtoLoad(DtoGEPi(rhs,0,0)); b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); - l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); - r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); + l = DtoLoad(DtoGEPi(lhs,0,1)); + r = DtoLoad(DtoGEPi(rhs,0,1)); b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); } LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); @@ -342,7 +209,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) +LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) { // global variable if (VarDeclaration* vd = sym->isVarDeclaration()) @@ -384,11 +251,6 @@ // default to external linkage return llvm::GlobalValue::ExternalLinkage; - -// llvm linkage types -/* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage, - InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage, - GhostLinkage */ } llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym) @@ -437,8 +299,8 @@ { // val is integer assert(valTy->isInteger()); - const llvm::IntegerType* pt = llvm::cast(ptrTy); - const llvm::IntegerType* vt = llvm::cast(valTy); + const LLIntegerType* pt = llvm::cast(ptrTy); + const LLIntegerType* vt = llvm::cast(valTy); if (pt->getBitWidth() < vt->getBitWidth()) { return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb()); } @@ -461,7 +323,7 @@ const LLType* t = val->getType(); if (t->isInteger()) { - if (t == llvm::Type::Int1Ty) + if (t == LLType::Int1Ty) return val; else { LLValue* zero = llvm::ConstantInt::get(t, 0, false); @@ -484,116 +346,18 @@ const LLType* DtoSize_t() { - if (global.params.is64bit) - return llvm::Type::Int64Ty; - else - return llvm::Type::Int32Ty; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -LLConstant* DtoConstInitializer(Type* type, Initializer* init) -{ - LLConstant* _init = 0; // may return zero - if (!init) - { - Logger::println("const default initializer for %s", type->toChars()); - _init = type->defaultInit()->toConstElem(gIR); - } - else if (ExpInitializer* ex = init->isExpInitializer()) - { - Logger::println("const expression initializer"); - _init = ex->exp->toConstElem(gIR); - } - else if (StructInitializer* si = init->isStructInitializer()) - { - Logger::println("const struct initializer"); - _init = DtoConstStructInitializer(si); - } - else if (ArrayInitializer* ai = init->isArrayInitializer()) - { - Logger::println("const array initializer"); - _init = DtoConstArrayInitializer(ai); - } - else if (init->isVoidInitializer()) - { - Logger::println("const void initializer"); - const LLType* ty = DtoType(type); - _init = llvm::Constant::getNullValue(ty); - } - else { - Logger::println("unsupported const initializer: %s", init->toChars()); - } - return _init; + // the type of size_t does not change once set + static const LLType* t = NULL; + if (t == NULL) + t = (global.params.is64bit) ? LLType::Int64Ty : LLType::Int32Ty; + return t; } ////////////////////////////////////////////////////////////////////////////////////////// -LLConstant* DtoConstFieldInitializer(Type* t, Initializer* init) +LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var, llvm::BasicBlock* bb) { - Logger::println("DtoConstFieldInitializer"); - LOG_SCOPE; - - const LLType* _type = DtoType(t); - - LLConstant* _init = DtoConstInitializer(t, init); - assert(_init); - if (_type != _init->getType()) - { - Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; - if (t->ty == Tsarray) - { - const llvm::ArrayType* arrty = isaArray(_type); - uint64_t n = arrty->getNumElements(); - std::vector vals(n,_init); - _init = llvm::ConstantArray::get(arrty, vals); - } - else if (t->ty == Tarray) - { - assert(isaStruct(_type)); - _init = llvm::ConstantAggregateZero::get(_type); - } - else if (t->ty == Tstruct) - { - const llvm::StructType* structty = isaStruct(_type); - TypeStruct* ts = (TypeStruct*)t; - assert(ts); - assert(ts->sym); - assert(ts->sym->ir.irStruct->constInit); - _init = ts->sym->ir.irStruct->constInit; - } - else if (t->ty == Tclass) - { - _init = llvm::Constant::getNullValue(_type); - } - else { - Logger::println("failed for type %s", t->toChars()); - assert(0); - } - } - - return _init; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -DValue* DtoInitializer(Initializer* init) -{ - if (ExpInitializer* ex = init->isExpInitializer()) - { - Logger::println("expression initializer"); - assert(ex->exp); - return ex->exp->toElem(gIR); - } - else if (init->isVoidInitializer()) - { - // do nothing - } - else { - Logger::println("unsupported initializer: %s", init->toChars()); - assert(0); - } - return 0; + return llvm::GetElementPtrInst::Create(ptr, i0, var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -603,7 +367,7 @@ LLSmallVector v(2); v[0] = i0; v[1] = i1; - return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); + return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -617,14 +381,14 @@ for (DStructIndexVector::const_iterator i=src.begin(); i!=src.end(); ++i) dst[j++] = DtoConstUint(*i); - return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); + return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoGEPi(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb) +LLValue* DtoGEPi1(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb) { - return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); + return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(i), var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -634,634 +398,71 @@ LLSmallVector v(2); v[0] = DtoConstUint(i0); v[1] = DtoConstUint(i1); - return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -LLValue* DtoNew(Type* newtype) -{ - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT"); - // get type info - LLConstant* ti = DtoTypeInfoOf(newtype); - assert(isaPointer(ti)); - // call runtime allocator - LLValue* mem = gIR->ir->CreateCall(fn, ti, ".gc_mem"); - // cast - return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); -} - -void DtoDeleteMemory(LLValue* ptr) -{ - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory"); - // build args - LLSmallVector arg; - arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp")); - // call - llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); -} - -void DtoDeleteClass(LLValue* inst) -{ - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass"); - // build args - LLSmallVector arg; - arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); - // call - llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); -} - -void DtoDeleteInterface(LLValue* inst) -{ - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface"); - // build args - LLSmallVector arg; - arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); - // call - llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); -} - -void DtoDeleteArray(DValue* arr) -{ - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray"); - // build args - LLSmallVector arg; - arg.push_back(DtoArrayLen(arr)); - arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp")); - // call - llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoAssert(Loc* loc, DValue* msg) -{ - std::vector args; - LLConstant* c; - - // func - const char* fname = msg ? "_d_assert_msg" : "_d_assert"; - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); - - // param attrs - llvm::PAListPtr palist; - int idx = 1; - - c = DtoConstString(loc->filename); - - // msg param - if (msg) - { - if (DSliceValue* s = msg->isSlice()) - { - llvm::AllocaInst* alloc = gIR->func()->msgArg; - if (!alloc) - { - alloc = new llvm::AllocaInst(c->getType(), ".assertmsg", gIR->topallocapoint()); - DtoSetArray(alloc, DtoArrayLen(s), DtoArrayPtr(s)); - gIR->func()->msgArg = alloc; - } - args.push_back(alloc); - } - else - { - args.push_back(msg->getRVal()); - } - palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal); - } - - // file param - llvm::AllocaInst* alloc = gIR->func()->srcfileArg; - if (!alloc) - { - alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint()); - gIR->func()->srcfileArg = alloc; - } - LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); - DtoStore(c->getOperand(0), ptr); - ptr = DtoGEPi(alloc, 0,1, "tmp"); - DtoStore(c->getOperand(1), ptr); - - args.push_back(alloc); - palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal); - - - // line param - c = DtoConstUint(loc->linnum); - args.push_back(c); - - // call - llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); - call->setParamAttrs(palist); + return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// -static const LLType* get_next_frame_ptr_type(Dsymbol* sc) -{ - assert(sc->isFuncDeclaration() || sc->isClassDeclaration()); - Dsymbol* p = sc->toParent2(); - if (!p->isFuncDeclaration() && !p->isClassDeclaration()) - Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind()); - assert(p->isFuncDeclaration() || p->isClassDeclaration()); - if (FuncDeclaration* fd = p->isFuncDeclaration()) - { - LLValue* v = fd->ir.irFunc->nestedVar; - assert(v); - return v->getType(); - } - else if (ClassDeclaration* cd = p->isClassDeclaration()) - { - return DtoType(cd->type); - } - else - { - Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind()); - assert(0); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v) -{ - LOG_SCOPE; - if (sc == func) - { - return v; - } - else if (FuncDeclaration* fd = sc->isFuncDeclaration()) - { - Logger::println("scope is function: %s", fd->toChars()); - - if (fd->toParent2() == func) - { - if (!func->ir.irFunc->nestedVar) - return NULL; - return DtoBitCast(v, func->ir.irFunc->nestedVar->getType()); - } - - v = DtoBitCast(v, get_next_frame_ptr_type(fd)); - Logger::cout() << "v = " << *v << '\n'; - - if (fd->toParent2()->isFuncDeclaration()) - { - v = DtoGEPi(v, 0,0, "tmp"); - v = DtoLoad(v); - } - else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) - { - size_t idx = 2; - //idx += cd->ir.irStruct->interfaceVec.size(); - v = DtoGEPi(v,0,idx,"tmp"); - v = DtoLoad(v); - } - else - { - assert(0); - } - return get_frame_ptr_impl(func, fd->toParent2(), v); - } - else if (ClassDeclaration* cd = sc->isClassDeclaration()) - { - Logger::println("scope is class: %s", cd->toChars()); - /*size_t idx = 2; - idx += cd->llvmIrStruct->interfaces.size(); - v = DtoGEPi(v,0,idx,"tmp"); - Logger::cout() << "gep = " << *v << '\n'; - v = DtoLoad(v);*/ - return get_frame_ptr_impl(func, cd->toParent2(), v); - } - else - { - Logger::println("symbol: '%s'", sc->toPrettyChars()); - assert(0); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static LLValue* get_frame_ptr(FuncDeclaration* func) +void DtoMemSetZero(LLValue* dst, LLValue* nbytes) { - Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); - LOG_SCOPE; - IrFunction* irfunc = gIR->func(); - - // in the right scope already - if (func == irfunc->decl) - return irfunc->decl->ir.irFunc->nestedVar; - - // use the 'this' pointer - LLValue* ptr = irfunc->decl->ir.irFunc->thisVar; - assert(ptr); - - // return the fully resolved frame pointer - ptr = get_frame_ptr_impl(func, irfunc->decl, ptr); - if (ptr) Logger::cout() << "Found context!" << *ptr; - else Logger::cout() << "NULL context!\n"; - - return ptr; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -LLValue* DtoNestedContext(FuncDeclaration* func) -{ - // resolve frame ptr - LLValue* ptr = get_frame_ptr(func); - Logger::cout() << "Nested context ptr = "; - if (ptr) Logger::cout() << *ptr; - else Logger::cout() << "NULL"; - Logger::cout() << '\n'; - return ptr; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static void print_frame_worker(VarDeclaration* vd, Dsymbol* par) -{ - if (vd->toParent2() == par) - { - Logger::println("found: '%s' kind: '%s'", par->toChars(), par->kind()); - return; - } + dst = DtoBitCast(dst,getVoidPtrType()); - Logger::println("diving into: '%s' kind: '%s'", par->toChars(), par->kind()); - LOG_SCOPE; - print_frame_worker(vd, par->toParent2()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par) -{ - Logger::println("Frame pointer list for nested var: '%s'", vd->toPrettyChars()); - LOG_SCOPE; - if (vd->toParent2() != par) - print_frame_worker(vd, par); + llvm::Function* fn; + if (global.params.is64bit) + fn = GET_INTRINSIC_DECL(memset_i64); else - Logger::println("Found at level 0"); - Logger::println("Done"); -} - -////////////////////////////////////////////////////////////////////////////////////////// + fn = GET_INTRINSIC_DECL(memset_i32); -LLValue* DtoNestedVariable(VarDeclaration* vd) -{ - // log the frame list - IrFunction* irfunc = gIR->func(); - if (Logger::enabled()) - print_nested_frame_list(vd, irfunc->decl); - - // resolve frame ptr - FuncDeclaration* func = vd->toParent2()->isFuncDeclaration(); - assert(func); - LLValue* ptr = DtoNestedContext(func); - assert(ptr && "nested var, but no context"); - - // we must cast here to be sure. nested classes just have a void* - ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType()); - - // index nested var and load (if necessary) - LLValue* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp"); - // references must be loaded, for normal variables this IS already the variable storage!!! - if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) - v = DtoLoad(v); - - // log and return - Logger::cout() << "Nested var ptr = " << *v << '\n'; - return v; + gIR->ir->CreateCall4(fn, dst, DtoConstUbyte(0), nbytes, DtoConstUint(0), ""); } ////////////////////////////////////////////////////////////////////////////////////////// -void DtoAssign(DValue* lhs, DValue* rhs) +void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes) { - Logger::cout() << "DtoAssign(...);\n"; - LOG_SCOPE; - - Type* t = DtoDType(lhs->getType()); - Type* t2 = DtoDType(rhs->getType()); + dst = DtoBitCast(dst,getVoidPtrType()); + src = DtoBitCast(src,getVoidPtrType()); - if (t->ty == Tstruct) { - if (t2 != t) { - // TODO: fix this, use 'rhs' for something - DtoStructZeroInit(lhs->getLVal()); - } - else if (!rhs->inPlace()) { - DtoStructCopy(lhs->getLVal(),rhs->getRVal()); - } - } - else if (t->ty == Tarray) { - // lhs is slice - if (DSliceValue* s = lhs->isSlice()) { - if (DSliceValue* s2 = rhs->isSlice()) { - DtoArrayCopySlices(s, s2); - } - else if (t->next == t2) { - if (s->len) - DtoArrayInit(s->ptr, s->len, rhs->getRVal()); - else - DtoArrayInit(s->ptr, rhs->getRVal()); - } - else { - DtoArrayCopyToSlice(s, rhs); - } - } - // rhs is slice - else if (DSliceValue* s = rhs->isSlice()) { - assert(s->getType()->toBasetype() == lhs->getType()->toBasetype()); - DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s)); - } - // null - else if (rhs->isNull()) { - DtoSetArrayToNull(lhs->getLVal()); - } - // reference assignment - else { - DtoArrayAssign(lhs->getLVal(), rhs->getRVal()); - } - } - else if (t->ty == Tsarray) { - if (DtoType(lhs->getType()) == DtoType(rhs->getType())) { - DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); - } - else { - DtoArrayInit(lhs->getLVal(), rhs->getRVal()); - } - } - else if (t->ty == Tdelegate) { - if (rhs->isNull()) - DtoDelegateToNull(lhs->getLVal()); - else if (!rhs->inPlace()) { - LLValue* l = lhs->getLVal(); - LLValue* r = rhs->getRVal(); - Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; - DtoDelegateCopy(l, r); - } - } - else if (t->ty == Tclass) { - assert(t2->ty == Tclass); - // assignment to this in constructor special case - if (lhs->isThis()) { - LLValue* tmp = rhs->getRVal(); - FuncDeclaration* fdecl = gIR->func()->decl; - // respecify the this param - if (!llvm::isa(fdecl->ir.irFunc->thisVar)) - fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); - DtoStore(tmp, fdecl->ir.irFunc->thisVar); - } - // regular class ref -> class ref assignment - else { - DtoStore(rhs->getRVal(), lhs->getLVal()); - } - } - else if (t->iscomplex()) { - assert(!lhs->isComplex()); + llvm::Function* fn; + if (global.params.is64bit) + fn = GET_INTRINSIC_DECL(memcpy_i64); + else + fn = GET_INTRINSIC_DECL(memcpy_i32); - LLValue* dst; - if (DLRValue* lr = lhs->isLRValue()) { - dst = lr->getLVal(); - rhs = DtoCastComplex(rhs, lr->getLType()); - } - else { - dst = lhs->getRVal(); - } + gIR->ir->CreateCall4(fn, dst, src, nbytes, DtoConstUint(0), ""); +} + +////////////////////////////////////////////////////////////////////////////////////////// - if (DComplexValue* cx = rhs->isComplex()) - DtoComplexSet(dst, cx->re, cx->im); - else - DtoComplexAssign(dst, rhs->getRVal()); - } - else { - LLValue* l = lhs->getLVal(); - LLValue* r = rhs->getRVal(); - Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; - const LLType* lit = l->getType()->getContainedType(0); - if (r->getType() != lit) { - // handle lvalue cast assignments - if (DLRValue* lr = lhs->isLRValue()) { - Logger::println("lvalue cast!"); - r = DtoCast(rhs, lr->getLType())->getRVal(); - } - else { - r = DtoCast(rhs, lhs->getType())->getRVal(); - } - Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; - assert(r->getType() == l->getType()->getContainedType(0)); - } - gIR->ir->CreateStore(r, l); - } +void DtoAggrZeroInit(LLValue* v) +{ + uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0)); + DtoMemSetZero(v, DtoConstSize_t(n)); } ////////////////////////////////////////////////////////////////////////////////////////// -DValue* DtoCastInt(DValue* val, Type* _to) + +void DtoAggrCopy(LLValue* dst, LLValue* src) { - const LLType* tolltype = DtoType(_to); - - Type* to = DtoDType(_to); - Type* from = DtoDType(val->getType()); - assert(from->isintegral()); - - size_t fromsz = from->size(); - size_t tosz = to->size(); - - LLValue* rval = val->getRVal(); - if (rval->getType() == tolltype) { - return new DImValue(_to, rval); - } - - if (to->isintegral()) { - if (fromsz < tosz) { - Logger::cout() << "cast to: " << *tolltype << '\n'; - if (from->isunsigned() || from->ty == Tbool) { - rval = new llvm::ZExtInst(rval, tolltype, "tmp", gIR->scopebb()); - } else { - rval = new llvm::SExtInst(rval, tolltype, "tmp", gIR->scopebb()); - } - } - else if (fromsz > tosz) { - rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb()); - } - else { - rval = DtoBitCast(rval, tolltype); - } - } - else if (to->isfloating()) { - if (from->isunsigned()) { - rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); - } - else { - rval = new llvm::SIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); - } - } - else if (to->ty == Tpointer) { - Logger::cout() << "cast pointer: " << *tolltype << '\n'; - rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp"); - } - else { - assert(0 && "bad int cast"); - } - - return new DImValue(_to, rval); -} - -DValue* DtoCastPtr(DValue* val, Type* to) -{ - const LLType* tolltype = DtoType(to); - - Type* totype = DtoDType(to); - Type* fromtype = DtoDType(val->getType()); - assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction); - - LLValue* rval; - - if (totype->ty == Tpointer || totype->ty == Tclass) { - LLValue* src = val->getRVal(); - Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n'; - rval = DtoBitCast(src, tolltype); - } - else if (totype->isintegral()) { - rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); - } - else { - Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); - assert(0); - } - - return new DImValue(to, rval); + uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0)); + DtoMemCpy(dst, src, DtoConstSize_t(n)); } -DValue* DtoCastFloat(DValue* val, Type* to) -{ - if (val->getType() == to) - return val; - - const LLType* tolltype = DtoType(to); - - Type* totype = DtoDType(to); - Type* fromtype = DtoDType(val->getType()); - assert(fromtype->isfloating()); - - size_t fromsz = fromtype->size(); - size_t tosz = totype->size(); - - LLValue* rval; +////////////////////////////////////////////////////////////////////////////////////////// - if (totype->iscomplex()) { - assert(0); - //return new DImValue(to, DtoComplex(to, val)); - } - else if (totype->isfloating()) { - if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { - rval = val->getRVal(); - } - else if (fromsz < tosz) { - rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); - } - else if (fromsz > tosz) { - rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); - } - else { - assert(0 && "bad float cast"); - } - } - else if (totype->isintegral()) { - if (totype->isunsigned()) { - rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); - } - else { - rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); - } - } - else { - assert(0 && "bad float cast"); - } - - return new DImValue(to, rval); -} - -DValue* DtoCastComplex(DValue* val, Type* _to) +void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) { - 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); + llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier); + assert(fn != NULL); - 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); + LLSmallVector llargs; + llargs.push_back(DtoConstBool(ll)); + llargs.push_back(DtoConstBool(ls)); + llargs.push_back(DtoConstBool(sl)); + llargs.push_back(DtoConstBool(ss)); + llargs.push_back(DtoConstBool(device)); - // 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); -} - -DValue* DtoCast(DValue* val, Type* to) -{ - Type* fromtype = DtoDType(val->getType()); - Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); - if (fromtype->isintegral()) { - return DtoCastInt(val, to); - } - else if (fromtype->iscomplex()) { - return DtoCastComplex(val, to); - } - else if (fromtype->isfloating()) { - return DtoCastFloat(val, to); - } - else if (fromtype->ty == Tclass) { - return DtoCastClass(val, to); - } - else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { - return DtoCastArray(val, to); - } - else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) { - return DtoCastPtr(val, to); - } - else { - assert(0); - } + llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1272,15 +473,19 @@ } llvm::ConstantInt* DtoConstUint(unsigned i) { - return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); + return llvm::ConstantInt::get(LLType::Int32Ty, i, false); } llvm::ConstantInt* DtoConstInt(int i) { - return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, true); + return llvm::ConstantInt::get(LLType::Int32Ty, i, true); } LLConstant* DtoConstBool(bool b) { - return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false); + return llvm::ConstantInt::get(LLType::Int1Ty, b, false); +} +llvm::ConstantInt* DtoConstUbyte(unsigned char i) +{ + return llvm::ConstantInt::get(LLType::Int8Ty, i, false); } llvm::ConstantFP* DtoConstFP(Type* t, long double value) @@ -1292,7 +497,6 @@ return llvm::ConstantFP::get(llvm::APFloat(double(value))); } - ////////////////////////////////////////////////////////////////////////////////////////// LLConstant* DtoConstString(const char* str) @@ -1320,61 +524,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -void DtoMemSetZero(LLValue* dst, LLValue* nbytes) -{ - const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); - llvm::Value *dstarr; - if (dst->getType() == arrty) - { - dstarr = dst; - } - else - { - dstarr = DtoBitCast(dst,arrty); - } - - llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemSet64() : LLVM_DeclareMemSet32(); - std::vector llargs; - llargs.resize(4); - llargs[0] = dstarr; - llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); - llargs[2] = nbytes; - llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - - llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes) -{ - const LLType* arrty = getVoidPtrType(); - - LLValue* dstarr; - if (dst->getType() == arrty) - dstarr = dst; - else - dstarr = DtoBitCast(dst, arrty, "tmp"); - - LLValue* srcarr; - if (src->getType() == arrty) - srcarr = src; - else - srcarr = DtoBitCast(src, arrty, "tmp"); - - llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); - std::vector llargs; - llargs.resize(4); - llargs[0] = dstarr; - llargs[1] = srcarr; - llargs[2] = nbytes; - llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - - llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - LLValue* DtoLoad(LLValue* src, const char* name) { LLValue* ld = gIR->ir->CreateLoad(src, name ? name : "tmp"); @@ -1407,34 +556,34 @@ ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::PointerType* isaPointer(LLValue* v) +const LLPointerType* isaPointer(LLValue* v) { - return llvm::dyn_cast(v->getType()); + return llvm::dyn_cast(v->getType()); } -const llvm::PointerType* isaPointer(const LLType* t) +const LLPointerType* isaPointer(const LLType* t) { - return llvm::dyn_cast(t); + return llvm::dyn_cast(t); } -const llvm::ArrayType* isaArray(LLValue* v) +const LLArrayType* isaArray(LLValue* v) { - return llvm::dyn_cast(v->getType()); + return llvm::dyn_cast(v->getType()); } -const llvm::ArrayType* isaArray(const LLType* t) +const LLArrayType* isaArray(const LLType* t) { - return llvm::dyn_cast(t); + return llvm::dyn_cast(t); } -const llvm::StructType* isaStruct(LLValue* v) +const LLStructType* isaStruct(LLValue* v) { - return llvm::dyn_cast(v->getType()); + return llvm::dyn_cast(v->getType()); } -const llvm::StructType* isaStruct(const LLType* t) +const LLStructType* isaStruct(const LLType* t) { - return llvm::dyn_cast(t); + return llvm::dyn_cast(t); } LLConstant* isaConstant(LLValue* v) @@ -1459,19 +608,19 @@ ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::PointerType* getPtrToType(const LLType* t) +const LLPointerType* getPtrToType(const LLType* t) { - return llvm::PointerType::get(t, 0); + return LLPointerType::get(t, 0); } -const llvm::PointerType* getVoidPtrType() +const LLPointerType* getVoidPtrType() { - return getPtrToType(llvm::Type::Int8Ty); + return getPtrToType(LLType::Int8Ty); } llvm::ConstantPointerNull* getNullPtr(const LLType* t) { - const llvm::PointerType* pt = llvm::cast(t); + const LLPointerType* pt = llvm::cast(t); return llvm::ConstantPointerNull::get(pt); } @@ -1492,355 +641,19 @@ return gTargetData->getABITypeSize(t); } -////////////////////////////////////////////////////////////////////////////////////////// - -bool DtoIsTemplateInstance(Dsymbol* s) -{ - if (!s) return false; - if (s->isTemplateInstance() && !s->isTemplateMixin()) - return true; - else if (s->parent) - return DtoIsTemplateInstance(s->parent); - return false; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t) +unsigned char getABITypeAlign(const LLType* t) { - // create a flag to make sure initialization only happens once - llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage; - std::string gflagname(gvar->getName()); - gflagname.append("__initflag"); - llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module); - - // check flag and do init if not already done - llvm::BasicBlock* oldend = gIR->scopeend(); - llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend); - llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend); - LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); - gIR->ir->CreateCondBr(cond, initbb, endinitbb); - gIR->scope() = IRScope(initbb,endinitbb); - DValue* ie = DtoInitializer(init); - if (!ie->inPlace()) { - DValue* dst = new DVarValue(t, gvar, true); - DtoAssign(dst, ie); - } - gIR->ir->CreateStore(DtoConstBool(true), gflag); - gIR->ir->CreateBr(endinitbb); - gIR->scope() = IRScope(endinitbb,oldend); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoResolveDsymbol(Dsymbol* dsym) -{ - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoResolveStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoResolveClass(cd); - } - else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { - DtoResolveFunction(fd); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoResolveTypeInfo(fd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoResolveDsymbol"); - } + return gTargetData->getABITypeAlignment(t); } -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoDeclareDsymbol(Dsymbol* dsym) -{ - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoDeclareStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoDeclareClass(cd); - } - else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { - DtoDeclareFunction(fd); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoDeclareTypeInfo(fd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoDeclareDsymbol"); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoConstInitDsymbol(Dsymbol* dsym) +unsigned char getPrefTypeAlign(const LLType* t) { - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoConstInitStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoConstInitClass(cd); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoConstInitTypeInfo(fd); - } - else if (VarDeclaration* vd = dsym->isVarDeclaration()) { - DtoConstInitGlobal(vd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoConstInitDsymbol"); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoDefineDsymbol(Dsymbol* dsym) -{ - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoDefineStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoDefineClass(cd); - } - else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { - DtoDefineFunc(fd); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoDefineTypeInfo(fd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoDefineDsymbol"); - } + return gTargetData->getPrefTypeAlignment(t); } ////////////////////////////////////////////////////////////////////////////////////////// -void DtoConstInitGlobal(VarDeclaration* vd) -{ - if (vd->ir.initialized) return; - vd->ir.initialized = gIR->dmodule; - - Logger::println("* DtoConstInitGlobal(%s)", vd->toChars()); - LOG_SCOPE; - - bool emitRTstaticInit = false; - - LLConstant* _init = 0; - if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) { - _init = DtoConstInitializer(vd->type, NULL); - emitRTstaticInit = true; - } - else { - _init = DtoConstInitializer(vd->type, vd->init); - } - - const LLType* _type = DtoType(vd->type); - Type* t = DtoDType(vd->type); - - //Logger::cout() << "initializer: " << *_init << '\n'; - if (_type != _init->getType()) { - Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; - // zero initalizer - if (_init->isNullValue()) - _init = llvm::Constant::getNullValue(_type); - // pointer to global constant (struct.init) - else if (llvm::isa(_init)) - { - assert(_init->getType()->getContainedType(0) == _type); - llvm::GlobalVariable* gv = llvm::cast(_init); - assert(t->ty == Tstruct); - TypeStruct* ts = (TypeStruct*)t; - assert(ts->sym->ir.irStruct->constInit); - _init = ts->sym->ir.irStruct->constInit; - } - // array single value init - else if (isaArray(_type)) - { - _init = DtoConstStaticArray(_type, _init); - } - else { - Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; - //assert(0); - } - } - - bool istempl = false; - if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) { - istempl = true; - } - - if (_init && _init->getType() != _type) - _type = _init->getType(); - llvm::cast(vd->ir.irGlobal->type.get())->refineAbstractTypeTo(_type); - _type = vd->ir.irGlobal->type.get(); - //_type->dump(); - assert(!_type->isAbstract()); - - llvm::GlobalVariable* gvar = llvm::cast(vd->ir.irGlobal->value); - if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) - { - gvar->setInitializer(_init); - } - - if (emitRTstaticInit) - DtoLazyStaticInit(istempl, gvar, vd->init, t); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoEmptyResolveList() -{ - //Logger::println("DtoEmptyResolveList()"); - Dsymbol* dsym; - while (!gIR->resolveList.empty()) { - dsym = gIR->resolveList.front(); - gIR->resolveList.pop_front(); - DtoResolveDsymbol(dsym); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoEmptyDeclareList() -{ - //Logger::println("DtoEmptyDeclareList()"); - Dsymbol* dsym; - while (!gIR->declareList.empty()) { - dsym = gIR->declareList.front(); - gIR->declareList.pop_front(); - DtoDeclareDsymbol(dsym); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoEmptyConstInitList() -{ - //Logger::println("DtoEmptyConstInitList()"); - Dsymbol* dsym; - while (!gIR->constInitList.empty()) { - dsym = gIR->constInitList.front(); - gIR->constInitList.pop_front(); - DtoConstInitDsymbol(dsym); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoEmptyDefineList() -{ - //Logger::println("DtoEmptyDefineList()"); - Dsymbol* dsym; - while (!gIR->defineList.empty()) { - dsym = gIR->defineList.front(); - gIR->defineList.pop_front(); - DtoDefineDsymbol(dsym); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -void DtoEmptyAllLists() -{ - for(;;) - { - Dsymbol* dsym; - if (!gIR->resolveList.empty()) { - dsym = gIR->resolveList.front(); - gIR->resolveList.pop_front(); - DtoResolveDsymbol(dsym); - } - else if (!gIR->declareList.empty()) { - dsym = gIR->declareList.front(); - gIR->declareList.pop_front(); - DtoDeclareDsymbol(dsym); - } - else if (!gIR->constInitList.empty()) { - dsym = gIR->constInitList.front(); - gIR->constInitList.pop_front(); - DtoConstInitDsymbol(dsym); - } - else if (!gIR->defineList.empty()) { - dsym = gIR->defineList.front(); - gIR->defineList.pop_front(); - DtoDefineDsymbol(dsym); - } - else { - break; - } - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoForceDeclareDsymbol(Dsymbol* dsym) -{ - if (dsym->ir.declared) return; - Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars()); - LOG_SCOPE; - DtoResolveDsymbol(dsym); - - DtoEmptyResolveList(); - - DtoDeclareDsymbol(dsym); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoForceConstInitDsymbol(Dsymbol* dsym) -{ - if (dsym->ir.initialized) return; - Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars()); - LOG_SCOPE; - DtoResolveDsymbol(dsym); - - DtoEmptyResolveList(); - DtoEmptyDeclareList(); - - DtoConstInitDsymbol(dsym); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoForceDefineDsymbol(Dsymbol* dsym) -{ - if (dsym->ir.defined) return; - Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars()); - LOG_SCOPE; - DtoResolveDsymbol(dsym); - - DtoEmptyResolveList(); - DtoEmptyDeclareList(); - DtoEmptyConstInitList(); - - DtoDefineDsymbol(dsym); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoAnnotation(const char* str) -{ - std::string s("CODE: "); - s.append(str); - char* p = &s[0]; - while (*p) - { - if (*p == '"') - *p = '\''; - ++p; - } - // create a noop with the code as the result name! - gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -const llvm::StructType* DtoInterfaceInfoType() +const LLStructType* DtoInterfaceInfoType() { if (gIR->interfaceInfoType) return gIR->interfaceInfoType; @@ -1854,34 +667,17 @@ // void*[] vtbl std::vector vtbltypes; vtbltypes.push_back(DtoSize_t()); - const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); + const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty)); vtbltypes.push_back(byteptrptrty); - types.push_back(llvm::StructType::get(vtbltypes)); + types.push_back(LLStructType::get(vtbltypes)); // int offset - types.push_back(llvm::Type::Int32Ty); + types.push_back(LLType::Int32Ty); // create type - gIR->interfaceInfoType = llvm::StructType::get(types); + gIR->interfaceInfoType = LLStructType::get(types); return gIR->interfaceInfoType; } -////////////////////////////////////////////////////////////////////////////////////////// - -LLConstant* DtoTypeInfoOf(Type* type, bool base) -{ - const LLType* typeinfotype = DtoType(Type::typeinfo->type); - if (!type->vtinfo) - type->getTypeInfo(NULL); - TypeInfoDeclaration* tidecl = type->vtinfo; - DtoForceDeclareDsymbol(tidecl); - assert(tidecl->ir.irGlobal != NULL); - LLConstant* c = isaConstant(tidecl->ir.irGlobal->value); - assert(c != NULL); - if (base) - return llvm::ConstantExpr::getBitCast(c, typeinfotype); - return c; -} - @@ -1891,5 +687,3 @@ - - diff -r 4d006f7b2ada -r a95056b3c996 gen/tollvm.h --- a/gen/tollvm.h Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/tollvm.h Mon Jun 09 09:37:08 2008 +0200 @@ -19,15 +19,13 @@ Type* DtoDType(Type* t); // delegate helpers -const llvm::StructType* DtoDelegateType(Type* t); -void DtoDelegateToNull(LLValue* v); -void DtoDelegateCopy(LLValue* dst, LLValue* src); +const LLStructType* DtoDelegateType(Type* t); LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs); // return linkage type for symbol using the current ir state for context -llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym); -llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym); -llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym); +LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym); +LLGlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym); +LLGlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym); // convert DMD calling conv to LLVM unsigned DtoCallingConv(LINK l); @@ -40,122 +38,94 @@ // some types const LLType* DtoSize_t(); -const llvm::StructType* 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(); +const LLStructType* DtoInterfaceInfoType(); // getelementptr helpers -LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb=NULL); -LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb=NULL); -LLValue* DtoGEPi(LLValue* ptr, unsigned i0, const char* var, llvm::BasicBlock* bb=NULL); -LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var, 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); +LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL); +LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var=NULL, llvm::BasicBlock* bb=NULL); +LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var=NULL, 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); // to constant helpers -llvm::ConstantInt* DtoConstSize_t(size_t); -llvm::ConstantInt* DtoConstUint(unsigned i); -llvm::ConstantInt* DtoConstInt(int i); +LLConstantInt* DtoConstSize_t(size_t); +LLConstantInt* DtoConstUint(unsigned i); +LLConstantInt* DtoConstInt(int i); +LLConstantInt* DtoConstUbyte(unsigned char i); llvm::ConstantFP* DtoConstFP(Type* t, long double value); LLConstant* DtoConstString(const char*); LLConstant* DtoConstStringPtr(const char* str, const char* section = 0); 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 -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); LLValue* DtoLoad(LLValue* src, const char* name=0); void DtoStore(LLValue* src, LLValue* dst); LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0); // llvm::dyn_cast wrappers -const llvm::PointerType* isaPointer(LLValue* v); -const llvm::PointerType* isaPointer(const LLType* t); -const llvm::ArrayType* isaArray(LLValue* v); -const llvm::ArrayType* isaArray(const LLType* t); -const llvm::StructType* isaStruct(LLValue* v); -const llvm::StructType* isaStruct(const LLType* t); +const LLPointerType* isaPointer(LLValue* v); +const LLPointerType* isaPointer(const LLType* t); +const LLArrayType* isaArray(LLValue* v); +const LLArrayType* isaArray(const LLType* t); +const LLStructType* isaStruct(LLValue* v); +const LLStructType* isaStruct(const LLType* t); LLConstant* isaConstant(LLValue* v); -llvm::ConstantInt* isaConstantInt(LLValue* v); +LLConstantInt* isaConstantInt(LLValue* v); llvm::Argument* isaArgument(LLValue* v); -llvm::GlobalVariable* isaGlobalVar(LLValue* v); +LLGlobalVariable* isaGlobalVar(LLValue* v); // llvm::T::get(...) wrappers -const llvm::PointerType* getPtrToType(const LLType* t); -const llvm::PointerType* getVoidPtrType(); +const LLPointerType* getPtrToType(const LLType* t); +const LLPointerType* getVoidPtrType(); llvm::ConstantPointerNull* getNullPtr(const LLType* t); // type sizes size_t getTypeBitSize(const LLType* t); size_t getTypeStoreSize(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); + +/** + * Generates a call to llvm.memcpy.i32 (or i64 depending on architecture). + * @param dst Destination memory. + * @param src Source memory. + * @param nbytes Number of bytes to copy. + */ +void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes); -// casts -DValue* DtoCastInt(DValue* val, Type* to); -DValue* DtoCastPtr(DValue* val, Type* to); -DValue* DtoCastFloat(DValue* val, Type* to); -DValue* DtoCastComplex(DValue* val, Type* to); -DValue* DtoCast(DValue* val, Type* to); +/** + * The same as DtoMemSetZero but figures out the size itself by "dereferencing" the v pointer once. + * @param v Destination memory. + */ +void DtoAggrZeroInit(LLValue* v); -// 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); +/** + * 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" diff -r 4d006f7b2ada -r a95056b3c996 gen/toobj.cpp --- a/gen/toobj.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/toobj.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -35,6 +35,7 @@ #include "gen/irstate.h" #include "gen/logger.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/arrays.h" #include "gen/structs.h" #include "gen/classes.h" @@ -203,7 +204,7 @@ name.append("6__ctorZ"); std::vector 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); llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); fn->setCallingConv(llvm::CallingConv::Fast); @@ -237,7 +238,7 @@ name.append("6__dtorZ"); std::vector 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); llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); fn->setCallingConv(llvm::CallingConv::Fast); @@ -271,7 +272,7 @@ name.append("10__unittestZ"); std::vector 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); llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); fn->setCallingConv(llvm::CallingConv::Fast); @@ -325,7 +326,7 @@ initVec.push_back(c); // monitor - c = getNullPtr(getPtrToType(llvm::Type::Int8Ty)); + c = getNullPtr(getPtrToType(LLType::Int8Ty)); initVec.push_back(c); // name @@ -463,9 +464,9 @@ gvar->setInitializer(constMI); // 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 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); std::string appendName("_d_moduleinfo_array"); llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module); diff -r 4d006f7b2ada -r a95056b3c996 gen/typinf.cpp --- a/gen/typinf.cpp Mon Jun 09 03:02:14 2008 +0200 +++ b/gen/typinf.cpp Mon Jun 09 09:37:08 2008 +0200 @@ -35,6 +35,7 @@ #include "gen/logger.h" #include "gen/runtime.h" #include "gen/tollvm.h" +#include "gen/llvmhelpers.h" #include "gen/arrays.h" #include "gen/structs.h" #include "gen/classes.h" @@ -279,7 +280,7 @@ LLValue* found = gIR->module->getNamedGlobal(mangled); 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); assert(g); /*if (!tid->ir.irGlobal) @@ -353,7 +354,7 @@ ClassDeclaration* base = Type::typeinfotypedef; DtoResolveClass(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // create the symbol this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -367,7 +368,7 @@ ClassDeclaration* base = Type::typeinfotypedef; 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'; // vtbl @@ -375,14 +376,14 @@ sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(getNullPtr(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty))); assert(tinfo->ty == Ttypedef); TypeTypedef *tc = (TypeTypedef *)tinfo; TypedefDeclaration *sd = tc->sym; // 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)); Logger::println("generating base typeinfo"); //sd->basetype = sd->basetype->merge(); @@ -403,7 +404,7 @@ assert(sinits.back()->getType() == stype->getElementType(3)); // 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 { sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt))); @@ -439,7 +440,7 @@ ClassDeclaration* base = Type::typeinfoenum; DtoResolveClass(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // create the symbol this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -453,21 +454,21 @@ ClassDeclaration* base = Type::typeinfoenum; DtoForceConstInitDsymbol(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // vtbl std::vector sinits; sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); assert(tinfo->ty == Tenum); TypeEnum *tc = (TypeEnum *)tinfo; EnumDeclaration *sd = tc->sym; // 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)); Logger::println("generating base typeinfo"); //sd->basetype = sd->basetype->merge(); @@ -487,7 +488,7 @@ assert(sinits.back()->getType() == stype->getElementType(3)); // 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 { sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); @@ -521,7 +522,7 @@ ClassDeclaration* base = cd; DtoResolveClass(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // create the symbol tid->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module); @@ -532,14 +533,14 @@ ClassDeclaration* base = cd; DtoForceConstInitDsymbol(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // vtbl std::vector sinits; sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // TypeInfo base Logger::println("generating base typeinfo"); @@ -626,7 +627,7 @@ DtoResolveClass(base); // 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 this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -642,7 +643,7 @@ DtoForceConstInitDsymbol(base); // 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 std::vector sinits; @@ -650,7 +651,7 @@ sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // value typeinfo assert(tinfo->ty == Tsarray); @@ -689,7 +690,7 @@ DtoResolveClass(base); // 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 this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -705,7 +706,7 @@ DtoForceConstInitDsymbol(base); // 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 std::vector sinits; @@ -713,7 +714,7 @@ sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // get type assert(tinfo->ty == Taarray); @@ -822,7 +823,7 @@ ClassDeclaration* base = Type::typeinfostruct; DtoResolveClass(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // create the symbol this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -841,14 +842,14 @@ ClassDeclaration* base = Type::typeinfostruct; DtoForceConstInitDsymbol(base); - const llvm::StructType* stype = isaStruct(base->type->ir.type->get()); + const LLStructType* stype = isaStruct(base->type->ir.type->get()); // vtbl std::vector sinits; sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // char[] name char *name = sd->toPrettyChars(); @@ -857,7 +858,7 @@ assert(sinits.back()->getType() == stype->getElementType(2)); // void[] init - const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty); + const LLPointerType* initpt = getPtrToType(LLType::Int8Ty); #if 0 // the implementation of TypeInfo_Struct uses this to determine size. :/ if (sd->zeroInit) // 0 initializer, or the same as the base type @@ -918,7 +919,7 @@ #endif //Logger::println("************** B"); - const llvm::PointerType* ptty = isaPointer(stype->getElementType(4)); + const LLPointerType* ptty = isaPointer(stype->getElementType(4)); assert(ptty); s = search_function(sd, Id::tohash); @@ -1025,7 +1026,7 @@ DtoResolveClass(base); // 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 this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -1042,7 +1043,7 @@ DtoForceConstInitDsymbol(base); // 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 std::vector sinits; @@ -1050,7 +1051,7 @@ sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // get classinfo assert(tinfo->ty == Tclass); @@ -1082,7 +1083,7 @@ DtoResolveClass(base); // 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 this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -1099,7 +1100,7 @@ DtoForceConstInitDsymbol(base); // 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 std::vector sinits; @@ -1107,7 +1108,7 @@ sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // get classinfo assert(tinfo->ty == Tclass); @@ -1138,7 +1139,7 @@ DtoResolveClass(base); // 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 this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); @@ -1155,7 +1156,7 @@ DtoForceConstInitDsymbol(base); // 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 std::vector sinits; @@ -1163,7 +1164,7 @@ sinits.push_back(base->ir.irStruct->vtbl); // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); + sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // create elements array assert(tinfo->ty == Ttuple); @@ -1187,7 +1188,7 @@ } // 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); // build the slice diff -r 4d006f7b2ada -r a95056b3c996 ir/irstruct.h --- a/ir/irstruct.h Mon Jun 09 03:02:14 2008 +0200 +++ b/ir/irstruct.h Mon Jun 09 09:37:08 2008 +0200 @@ -44,10 +44,10 @@ struct Offset { VarDeclaration* var; - const llvm::Type* type; + const LLType* type; llvm::Constant* init; - Offset(VarDeclaration* v, const llvm::Type* ty) + Offset(VarDeclaration* v, const LLType* ty) : var(v), type(ty), init(NULL) {} }; diff -r 4d006f7b2ada -r a95056b3c996 llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Mon Jun 09 03:02:14 2008 +0200 +++ b/llvmdc.kdevelop.filelist Mon Jun 09 09:37:08 2008 +0200 @@ -116,6 +116,8 @@ gen/enums.h gen/functions.cpp gen/functions.h +gen/intrinsics.cpp +gen/intrinsics.h gen/irstate.cpp gen/irstate.h gen/linker.h @@ -762,6 +764,7 @@ tangotests/c.d tangotests/classes1.d tangotests/constructors.d +tangotests/debug1.d tangotests/e.d tangotests/f.d tangotests/files1.d