diff --git a/dmd/mars.c b/dmd/mars.c index 1eceec9a..08e7391a 100644 --- a/dmd/mars.c +++ b/dmd/mars.c @@ -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 @@ Usage:\n\ int main(int argc, char *argv[]) { - llvm::sys::PrintStackTraceOnErrorSignal(); - int i; Array files; char *p; @@ -690,21 +688,7 @@ int main(int argc, char *argv[]) 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 @@ int main(int argc, char *argv[]) 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 --git a/gen/classes.cpp b/gen/classes.cpp index cdd08d7d..9137e01e 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -794,6 +794,20 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) { 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) // 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) // 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) } 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) // 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) } 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) 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 @@ void DtoDefineClassInfo(ClassDeclaration* cd) }*/ // 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 --git a/gen/linker.h b/gen/linker.h index 2426f406..6b619b94 100644 --- a/gen/linker.h +++ b/gen/linker.h @@ -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 --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 2363c178..0f3a39a6 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1,4 +1,5 @@ #include "gen/llvm.h" +#include "llvm/Target/TargetMachineRegistry.h" #include "mars.h" #include "init.h" @@ -1096,3 +1097,18 @@ LLConstant* DtoTypeInfoOf(Type* type, bool base) 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 --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 57b544d1..604e1d1e 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -62,4 +62,7 @@ DValue* DtoBinMul(DValue* lhs, DValue* rhs); DValue* DtoBinDiv(DValue* lhs, DValue* rhs); DValue* DtoBinRem(DValue* lhs, DValue* rhs); +// target stuff +void findDefaultTarget(); + #endif diff --git a/gen/toir.cpp b/gen/toir.cpp index 8ee60dec..2b6ca491 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1885,10 +1885,7 @@ DValue* NewExp::toElem(IRState* p) 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