diff --git a/dmd2/module.c b/dmd2/module.c index c087b3c581..dc42b01cf3 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -45,6 +45,9 @@ #endif #if IN_LLVM +#include "llvm/Type.h" +#include "llvm/LLVMContext.h" +#include "llvm/DerivedTypes.h" #include "llvm/Support/CommandLine.h" #include @@ -211,6 +214,8 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen #if IN_LLVM // LDC llvmForceLogging = false; + moduleInfoVar = NULL; + moduleInfoType = new llvm::PATypeHolder(llvm::OpaqueType::get(llvm::getGlobalContext())); this->doDocComment = doDocComment; this->doHdrGen = doHdrGen; #endif @@ -408,6 +413,9 @@ void Module::deleteObjFile() Module::~Module() { +#if IN_LLVM + delete moduleInfoType; +#endif } const char *Module::kind() diff --git a/dmd2/module.h b/dmd2/module.h index 21ebd01d35..9b1b20eadc 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -34,6 +34,8 @@ typedef DValue elem; namespace llvm { class LLVMContext; class Module; + class GlobalVariable; + class PATypeHolder; } #else @@ -202,8 +204,11 @@ struct Module : Package void buildTargetFiles(bool singleObj); File* buildFilePath(const char* forcename, const char* path, const char* ext); Module *isModule() { return this; } + llvm::GlobalVariable* moduleInfoSymbol(); bool llvmForceLogging; + llvm::GlobalVariable* moduleInfoVar; + llvm::PATypeHolder* moduleInfoType; // array ops emitted in this module already StringTable arrayfuncs; diff --git a/gen/aa.cpp b/gen/aa.cpp index 384547dfb2..d4f3f6e86f 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -80,9 +80,16 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) std::vector args; +#if DMDV2 + // module param + LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol(); + const LLType *moduleInfoType = DtoType(Module::moduleinfo->type); + args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType))); +#else // file param IrModule* irmod = getIrModule(NULL); args.push_back(DtoLoad(irmod->fileName)); +#endif // line param LLConstant* c = DtoConstUint(loc.linnum); diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 54a3c1137e..9d9449be37 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -1327,9 +1327,15 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice) std::vector args; + Module* funcmodule = gIR->func()->decl->getModule(); +#if DMDV2 + // module param + LLValue *moduleInfoSymbol = funcmodule->moduleInfoSymbol(); + const LLType *moduleInfoType = DtoType(Module::moduleinfo->type); + args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType))); +#else // file param // we might be generating for an imported template function - Module* funcmodule = gIR->func()->decl->getModule(); const char* cur_file = funcmodule->srcfile->name->toChars(); if (loc.filename && strcmp(loc.filename, cur_file) != 0) { @@ -1340,6 +1346,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice) IrModule* irmod = getIrModule(funcmodule); args.push_back(DtoLoad(irmod->fileName)); } +#endif // line param LLConstant* c = DtoConstUint(loc.linnum); diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 25d11ea090..163c81e4cd 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -11,11 +11,13 @@ #include "dsymbol.h" #include "mtype.h" #include "aggregate.h" +#include "module.h" #include "gen/runtime.h" #include "gen/logger.h" #include "gen/tollvm.h" #include "gen/irstate.h" +#include "ir/irtype.h" using namespace llvm::Attribute; @@ -234,19 +236,34 @@ static void LLVM_D_BuildRuntimeModule() ///////////////////////////////////////////////////////////////////////////////////// // void _d_assert( char[] file, uint line ) - // void _d_array_bounds( char[] file, uint line ) - // void _d_switch_error( char[] file, uint line ) { llvm::StringRef fname("_d_assert"); - llvm::StringRef fname2("_d_array_bounds"); - llvm::StringRef fname3("_d_switch_error"); std::vector types; types.push_back(stringTy); types.push_back(intTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // D1: + // void _d_array_bounds( char[] file, uint line ) + // void _d_switch_error( char[] file, uint line ) + // D2: + // void _d_array_bounds(ModuleInfo* m, uint line) + // void _d_switch_error(ModuleInfo* m, uint line) + { + llvm::StringRef fname("_d_array_bounds"); + llvm::StringRef fname2("_d_switch_error"); + std::vector types; +#if DMDV2 + types.push_back(getPtrToType(DtoType(Module::moduleinfo->type))); +#else + types.push_back(stringTy); +#endif + types.push_back(intTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M); } // void _d_assert_msg( char[] msg, char[] file, uint line ) diff --git a/gen/statements.cpp b/gen/statements.cpp index 52d4ec1c47..e648c3257d 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -1555,9 +1555,16 @@ void SwitchErrorStatement::toIR(IRState* p) std::vector args; +#if DMDV2 + // module param + LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol(); + const LLType *moduleInfoType = DtoType(Module::moduleinfo->type); + args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType))); +#else // file param IrModule* irmod = getIrModule(NULL); args.push_back(DtoLoad(irmod->fileName)); +#endif // line param LLConstant* c = DtoConstUint(loc.linnum); diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 80971bbaa8..1a19a73458 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/CodeGen/MachineCodeEmitter.h" +#include "llvm/LLVMContext.h" #include "mars.h" #include "module.h" @@ -535,6 +536,31 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) return ctor; } +llvm::GlobalVariable* Module::moduleInfoSymbol() +{ + // create name + std::string MIname("_D"); + MIname.append(mangle()); + MIname.append("8__ModuleZ"); + + if (gIR->dmodule != this) { + const LLType* moduleinfoTy = DtoType(moduleinfo->type); + LLGlobalVariable *var = gIR->module->getGlobalVariable(MIname); + if (!var) + var = new llvm::GlobalVariable(*gIR->module, moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); + return var; + } + + if (moduleInfoVar) + return moduleInfoVar; + + // declare global + // flags will be modified at runtime so can't make it constant + moduleInfoVar = new llvm::GlobalVariable(*gIR->module, moduleInfoType->get(), false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); + + return moduleInfoVar; +} + // Put out instance of ModuleInfo for this Module void Module::genmoduleinfo() @@ -592,7 +618,6 @@ void Module::genmoduleinfo() b.push_string(toPrettyChars()); // importedModules[] - int aimports_dim = aimports.dim; std::vector importInits; LLConstant* c = 0; for (size_t i = 0; i < aimports.dim; i++) @@ -742,23 +767,13 @@ void Module::genmoduleinfo() assert(0); }*/ - // create initializer + // create and set initializer LLConstant* constMI = b.get_constant(); - - // create name - std::string MIname("_D"); - MIname.append(mangle()); - MIname.append("8__ModuleZ"); - - // declare global - // flags will be modified at runtime so can't make it constant - - // it makes no sense that the our own module info already exists! - assert(!gIR->module->getGlobalVariable(MIname)); - llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module, constMI->getType(), false, llvm::GlobalValue::ExternalLinkage, constMI, MIname); + llvm::cast(moduleInfoType->get())->refineAbstractTypeTo(constMI->getType()); + moduleInfoSymbol()->setInitializer(constMI); // build the modulereference and ctor for registering it - LLFunction* mictor = build_module_reference_and_ctor(gvar); + LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol()); // register this ctor in the magic llvm.global_ctors appending array const LLFunctionType* magicfty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false);