# HG changeset patch # User lindquist # Date 1214009333 -7200 # Node ID 70c370e97944c8ced91f73725649b639d06de6a4 # Parent 9bb48fb57a7d08d7197a3197bf5619191c8563d0 [svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed. Removed the LLVM stacktrace code from mars.c. Moved the LLVM based default target detection code from mars.c to llvmhelpers.cpp. diff -r 9bb48fb57a7d -r 70c370e97944 dmd/mars.c --- a/dmd/mars.c Sat Jun 21 00:54:55 2008 +0200 +++ b/dmd/mars.c Sat Jun 21 02:48:53 2008 +0200 @@ -7,9 +7,6 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. -#include "llvm/Target/TargetMachineRegistry.h" -#include "llvm/System/Signals.h" - #include #include #include @@ -42,6 +39,9 @@ void getenv_setargv(const char *envvar, int *pargc, char** *pargv); +// llvmdc +void findDefaultTarget(); + Global global; Global::Global() @@ -225,8 +225,6 @@ int main(int argc, char *argv[]) { - llvm::sys::PrintStackTraceOnErrorSignal(); - int i; Array files; char *p; @@ -690,21 +688,7 @@ bool allowForceEndianness = false; if (global.params.llvmArch == 0) { - std::string err_str; - const llvm::TargetMachineRegistry::entry* e = llvm::TargetMachineRegistry::getClosestTargetForJIT(err_str); - if (e == 0) { - error("Failed to find a default target machine: %s", err_str.c_str()); - fatal(); - } - else { - global.params.llvmArch = const_cast(e->Name); - if (global.params.verbose || very_verbose) - printf("Default target found: %s\n", global.params.llvmArch); - if (very_verbose) { - int X = sizeof(va_list); - printf("valist.sizeof = %d\n", X); - } - } + findDefaultTarget(); } bool is_x86 = false; @@ -717,7 +701,6 @@ tt_arch = "i686"; data_layout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-f80:32:32-v64:64:64-v128:128:128-a0:0:64"; is_x86 = true; - } else if (strcmp(global.params.llvmArch,"x86-64")==0) { VersionCondition::addPredefinedGlobalIdent("X86_64"); diff -r 9bb48fb57a7d -r 70c370e97944 gen/classes.cpp --- a/gen/classes.cpp Sat Jun 21 00:54:55 2008 +0200 +++ b/gen/classes.cpp Sat Jun 21 02:48:53 2008 +0200 @@ -794,6 +794,20 @@ { mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); } + // custom allocator + else if (newexp->allocator) + { + DtoForceDeclareDsymbol(newexp->allocator); + assert(newexp->newargs); + assert(newexp->newargs->dim == 1); + + llvm::Function* fn = newexp->allocator->ir.irFunc->func; + assert(fn); + DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR); + mem = gIR->ir->CreateCall(fn, arg->getRVal(), "newclass_custom_alloc"); + mem = DtoBitCast(mem, DtoType(tc), "newclass_custom"); + } + // default allocator else { llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); @@ -1446,26 +1460,30 @@ DtoForceConstInitDsymbol(cinfo); assert(cinfo->ir.irStruct->constInit); + // def init constant + LLConstant* defc = cinfo->ir.irStruct->constInit; + assert(defc); + LLConstant* c; // own vtable - c = cinfo->ir.irStruct->constInit->getOperand(0); + c = defc->getOperand(0); assert(c); inits.push_back(c); // monitor - c = cinfo->ir.irStruct->constInit->getOperand(1); + c = defc->getOperand(1); inits.push_back(c); // byte[] init const LLType* byteptrty = getPtrToType(LLType::Int8Ty); if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->ir.irStruct->constInit->getOperand(2); + c = defc->getOperand(2); } else { c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); - assert(!cd->ir.irStruct->constInit->getType()->isAbstract()); - size_t initsz = getABITypeSize(cd->ir.irStruct->constInit->getType()); + assert(!defc->getType()->isAbstract()); + size_t initsz = getABITypeSize(defc->getType()); c = DtoConstSlice(DtoConstSize_t(initsz), c); } inits.push_back(c); @@ -1484,7 +1502,7 @@ // vtbl array if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->ir.irStruct->constInit->getOperand(4); + c = defc->getOperand(4); } else { const LLType* byteptrptrty = getPtrToType(byteptrty); @@ -1503,10 +1521,10 @@ // interfaces array IrStruct* irstruct = cd->ir.irStruct; if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { - c = cinfo->ir.irStruct->constInit->getOperand(5); + c = defc->getOperand(5); } else { - const LLType* t = cinfo->ir.irStruct->constInit->getOperand(5)->getType()->getContainedType(1); + const LLType* t = defc->getOperand(5)->getType()->getContainedType(1); c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); size_t iisz = irstruct->interfaceInfosTy->getNumElements(); c = DtoConstSlice(DtoConstSize_t(iisz), c); @@ -1522,13 +1540,13 @@ } else { // null - c = cinfo->ir.irStruct->constInit->getOperand(6); + c = defc->getOperand(6); inits.push_back(c); } // destructor if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->ir.irStruct->constInit->getOperand(7); + c = defc->getOperand(7); } else { c = build_class_dtor(cd); @@ -1537,12 +1555,12 @@ // invariant // TODO - c = cinfo->ir.irStruct->constInit->getOperand(8); + c = defc->getOperand(8); inits.push_back(c); // uint flags if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->ir.irStruct->constInit->getOperand(9); + c = defc->getOperand(9); } else { uint flags = build_classinfo_flags(cd); @@ -1550,17 +1568,23 @@ } inits.push_back(c); - // allocator - // TODO - c = cinfo->ir.irStruct->constInit->getOperand(10); + // deallocator + if (cd->aggDelete) { + DtoForceDeclareDsymbol(cd->aggDelete); + c = cd->aggDelete->ir.irFunc->func; + c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(10)->getType()); + } + else { + c = defc->getOperand(10); + } inits.push_back(c); // offset typeinfo if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->ir.irStruct->constInit->getOperand(11); + c = defc->getOperand(11); } else { - c = build_offti_array(cd, cinfo->ir.irStruct->constInit->getOperand(11)); + c = build_offti_array(cd, defc->getOperand(11)); } inits.push_back(c); @@ -1568,11 +1592,11 @@ if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { DtoForceDeclareDsymbol(cd->defaultCtor); c = isaConstant(cd->defaultCtor->ir.irFunc->func); - const LLType* toTy = cinfo->ir.irStruct->constInit->getOperand(12)->getType(); + const LLType* toTy = defc->getOperand(12)->getType(); c = llvm::ConstantExpr::getBitCast(c, toTy); } else { - c = cinfo->ir.irStruct->constInit->getOperand(12); + c = defc->getOperand(12); } inits.push_back(c); @@ -1583,7 +1607,7 @@ }*/ // build the initializer - const llvm::StructType* st = isaStruct(cinfo->ir.irStruct->constInit->getType()); + const llvm::StructType* st = isaStruct(defc->getType()); LLConstant* finalinit = llvm::ConstantStruct::get(st, inits); //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; diff -r 9bb48fb57a7d -r 70c370e97944 gen/linker.h --- a/gen/linker.h Sat Jun 21 00:54:55 2008 +0200 +++ b/gen/linker.h Sat Jun 21 02:48:53 2008 +0200 @@ -1,6 +1,13 @@ #ifndef LLVMDC_GEN_LINKER_H #define LLVMDC_GEN_LINKER_H +#include + +namespace llvm +{ + class Module; +} + /** * Links the modules given in MV in to dst. * @param dst Destination module. diff -r 9bb48fb57a7d -r 70c370e97944 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Sat Jun 21 00:54:55 2008 +0200 +++ b/gen/llvmhelpers.cpp Sat Jun 21 02:48:53 2008 +0200 @@ -1,4 +1,5 @@ #include "gen/llvm.h" +#include "llvm/Target/TargetMachineRegistry.h" #include "mars.h" #include "init.h" @@ -1096,3 +1097,18 @@ return llvm::ConstantExpr::getBitCast(c, typeinfotype); return c; } + +void findDefaultTarget() +{ + std::string err_str; + const llvm::TargetMachineRegistry::entry* e = llvm::TargetMachineRegistry::getClosestTargetForJIT(err_str); + if (e == 0) + { + error("Failed to find a default target machine: %s", err_str.c_str()); + fatal(); + } + else + { + global.params.llvmArch = const_cast(e->Name); + } +} diff -r 9bb48fb57a7d -r 70c370e97944 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Sat Jun 21 00:54:55 2008 +0200 +++ b/gen/llvmhelpers.h Sat Jun 21 02:48:53 2008 +0200 @@ -62,4 +62,7 @@ DValue* DtoBinDiv(DValue* lhs, DValue* rhs); DValue* DtoBinRem(DValue* lhs, DValue* rhs); +// target stuff +void findDefaultTarget(); + #endif diff -r 9bb48fb57a7d -r 70c370e97944 gen/toir.cpp --- a/gen/toir.cpp Sat Jun 21 00:54:55 2008 +0200 +++ b/gen/toir.cpp Sat Jun 21 02:48:53 2008 +0200 @@ -1885,10 +1885,7 @@ Logger::print("NewExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - assert(!newargs && "arguments to new not yet supported"); assert(newtype); - assert(!allocator && "custom allocators not yet supported"); - Type* ntype = DtoDType(newtype); // new class