diff --git a/gen/classes.cpp b/gen/classes.cpp index cf5a00a3db..b386a82789 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -52,9 +52,7 @@ void DtoResolveClass(ClassDeclaration* cd) DtoType(cd->type); // create IrAggr - assert(cd->ir.irAggr == NULL); - IrAggr* irAggr = new IrAggr(cd); - cd->ir.irAggr = irAggr; + IrAggr* irAggr = getIrAggr(cd, true); // make sure all fields really get their ir field for (VarDeclarations::iterator I = cd->fields.begin(), @@ -62,11 +60,11 @@ void DtoResolveClass(ClassDeclaration* cd) I != E; ++I) { VarDeclaration* vd = *I; - if (vd->ir.irField == NULL) { - new IrField(vd); - } else { + + if (!isIrFieldCreated(vd)) + getIrField(vd, true); + else IF_LOG Logger::println("class field already exists!!!"); - } } // emit the interfaceInfosZ symbol if necessary @@ -98,7 +96,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp) else if (newexp->allocator) { DtoResolveFunction(newexp->allocator); - DFuncValue dfn(newexp->allocator, newexp->allocator->ir.irFunc->func); + DFuncValue dfn(newexp->allocator, getIrFunc(newexp->allocator)->func); DValue* res = DtoCallFunction(newexp->loc, NULL, &dfn, newexp->newargs); mem = DtoBitCast(res->getRVal(), DtoType(tc), ".newclass_custom"); } @@ -106,7 +104,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp) else { llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_newclass"); - LLConstant* ci = DtoBitCast(tc->sym->ir.irAggr->getClassInfoSymbol(), DtoType(Type::typeinfoclass->type)); + LLConstant* ci = DtoBitCast(getIrAggr(tc->sym)->getClassInfoSymbol(), DtoType(Type::typeinfoclass->type)); mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction(); mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc"); } @@ -120,7 +118,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp) Logger::println("Resolving outer class"); LOG_SCOPE; DValue* thisval = newexp->thisexp->toElem(gIR); - size_t idx = tc->sym->vthis->ir.irField->index; + size_t idx = getIrField(tc->sym->vthis)->index; LLValue* src = thisval->getRVal(); LLValue* dst = DtoGEPi(mem,0,idx,"tmp"); IF_LOG Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; @@ -138,7 +136,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp) Logger::println("Calling constructor"); assert(newexp->arguments != NULL); DtoResolveFunction(newexp->member); - DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem); + DFuncValue dfn(newexp->member, getIrFunc(newexp->member)->func, mem); return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments); } @@ -154,7 +152,7 @@ void DtoInitClass(TypeClass* tc, LLValue* dst) // Set vtable field. Doing this seperately might be optimized better. LLValue* tmp = DtoGEPi(dst, 0, 0, "vtbl"); - LLValue* val = DtoBitCast(tc->sym->ir.irAggr->getVtblSymbol(), + LLValue* val = DtoBitCast(getIrAggr(tc->sym)->getVtblSymbol(), tmp->getType()->getContainedType(0)); DtoStore(val, tmp); @@ -176,7 +174,7 @@ void DtoInitClass(TypeClass* tc, LLValue* dst) LLValue* dstarr = DtoGEPi(dst, 0, firstDataIdx, "tmp"); // init symbols might not have valid types - LLValue* initsym = tc->sym->ir.irAggr->getInitSymbol(); + LLValue* initsym = getIrAggr(tc->sym)->getInitSymbol(); initsym = DtoBitCast(initsym, DtoType(tc)); LLValue* srcarr = DtoGEPi(initsym, 0, firstDataIdx, "tmp"); @@ -335,7 +333,7 @@ DValue* DtoDynamicCastObject(Loc& loc, DValue* val, Type* _to) TypeClass* to = static_cast(_to->toBasetype()); DtoResolveClass(to->sym); - LLValue* cinfo = to->sym->ir.irAggr->getClassInfoSymbol(); + LLValue* cinfo = getIrAggr(to->sym)->getClassInfoSymbol(); // unfortunately this is needed as the implementation of object differs somehow from the declaration // this could happen in user code as well :/ cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); @@ -396,7 +394,7 @@ DValue* DtoDynamicCastInterface(Loc& loc, DValue* val, Type* _to) // ClassInfo c TypeClass* to = static_cast(_to->toBasetype()); DtoResolveClass(to->sym); - LLValue* cinfo = to->sym->ir.irAggr->getClassInfoSymbol(); + LLValue* cinfo = getIrAggr(to->sym)->getClassInfoSymbol(); // unfortunately this is needed as the implementation of object differs somehow from the declaration // this could happen in user code as well :/ cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); @@ -423,7 +421,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) DtoResolveClass(cd); // vd must be a field - IrField* field = vd->ir.irField; + IrField* field = getIrField(vd); assert(field); // get the start pointer @@ -573,7 +571,7 @@ static LLConstant* build_class_dtor(ClassDeclaration* cd) return getNullPtr(getVoidPtrType()); DtoResolveFunction(dtor); - return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::getInt8Ty(gIR->context()))); + return llvm::ConstantExpr::getBitCast(getIrFunc(dtor)->func, getPtrToType(LLType::getInt8Ty(gIR->context()))); } static unsigned build_classinfo_flags(ClassDeclaration* cd) @@ -643,9 +641,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) assert(cd->type->ty == Tclass); TypeClass* cdty = static_cast(cd->type); - IrAggr* ir = cd->ir.irAggr; - assert(ir); - + IrAggr* ir = getIrAggr(cd); ClassDeclaration* cinfo = Type::typeinfoclass; if (cinfo->fields.dim != 12) diff --git a/gen/declarations.cpp b/gen/declarations.cpp index 9238699fb4..87e3fb3a88 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -79,8 +79,9 @@ public: DtoTypeInfoOf(decl->type); // Define __InterfaceZ. - llvm::GlobalVariable *interfaceZ = decl->ir.irAggr->getClassInfoSymbol(); - interfaceZ->setInitializer(decl->ir.irAggr->getClassInfoInit()); + IrAggr *ir = getIrAggr(decl); + llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol(); + interfaceZ->setInitializer(ir->getClassInfoInit()); interfaceZ->setLinkage(DtoExternalLinkage(decl)); } } @@ -112,8 +113,9 @@ public: } // Define the __initZ symbol. - llvm::GlobalVariable *initZ = ir.irAggr->getInitSymbol(); - initZ->setInitializer(ir.irAggr->getDefaultInit()); + IrAggr *ir = getIrAggr(decl); + llvm::GlobalVariable *initZ = ir->getInitSymbol(); + initZ->setInitializer(ir->getDefaultInit()); initZ->setLinkage(DtoExternalLinkage(decl)); // emit typeinfo @@ -133,9 +135,8 @@ public: IF_LOG Logger::println("ClassDeclaration::codegen: '%s'", decl->toPrettyChars()); LOG_SCOPE - IrDsymbol &ir = decl->ir; - if (ir.defined) return; - ir.defined = true; + if (decl->ir.defined) return; + decl->ir.defined = true; if (decl->type->ty == Terror) { error(decl->loc, "had semantic errors when compiling"); @@ -153,18 +154,19 @@ public: (*I)->accept(this); } + IrAggr *ir = getIrAggr(decl); llvm::GlobalValue::LinkageTypes const linkage = DtoExternalLinkage(decl); - llvm::GlobalVariable *initZ = ir.irAggr->getInitSymbol(); - initZ->setInitializer(ir.irAggr->getDefaultInit()); + llvm::GlobalVariable *initZ = ir->getInitSymbol(); + initZ->setInitializer(ir->getDefaultInit()); initZ->setLinkage(linkage); - llvm::GlobalVariable *vtbl = ir.irAggr->getVtblSymbol(); - vtbl->setInitializer(ir.irAggr->getVtblInit()); + llvm::GlobalVariable *vtbl = ir->getVtblSymbol(); + vtbl->setInitializer(ir->getVtblInit()); vtbl->setLinkage(linkage); - llvm::GlobalVariable *classZ = ir.irAggr->getClassInfoSymbol(); - classZ->setInitializer(ir.irAggr->getClassInfoInit()); + llvm::GlobalVariable *classZ = ir->getClassInfoSymbol(); + classZ->setInitializer(ir->getClassInfoInit()); classZ->setLinkage(linkage); // No need to do TypeInfo here, it is __classZ for classes in D2. @@ -227,8 +229,8 @@ public: "manifest constant being codegen'd!"); #endif - llvm::GlobalVariable *gvar = llvm::cast( - decl->ir.irGlobal->value); + IrGlobal *irGlobal = getIrGlobal(decl); + llvm::GlobalVariable *gvar = llvm::cast(irGlobal->value); assert(gvar && "DtoResolveVariable should have created value"); const llvm::GlobalValue::LinkageTypes llLinkage = DtoLinkage(decl); @@ -257,12 +259,12 @@ public: gvar->eraseFromParent(); gvar = newGvar; - decl->ir.irGlobal->value = newGvar; + irGlobal->value = newGvar; } // Now, set the initializer. - assert(!decl->ir.irGlobal->constInit); - decl->ir.irGlobal->constInit = initVal; + assert(!irGlobal->constInit); + irGlobal->constInit = initVal; gvar->setInitializer(initVal); gvar->setLinkage(llLinkage); diff --git a/gen/dibuilder.cpp b/gen/dibuilder.cpp index 91ae33e8e8..bf5056c4b7 100644 --- a/gen/dibuilder.cpp +++ b/gen/dibuilder.cpp @@ -1,6 +1,6 @@ //===-- gen/dibuilder.h - Debug information builder -------------*- C++ -*-===// // -// LDC – the LLVM D compiler +// LDC – the LLVM D compiler // // This file is distributed under the BSD-style LDC license. See the LICENSE // file for details. @@ -282,7 +282,7 @@ llvm::DIType ldc::DIBuilder::CreateCompositeType(Type *type) assert(sd); // Use the actual type associated with the declaration, ignoring any - // const/… wrappers. + // const/Â… wrappers. LLType *T = DtoType(sd->type); IrTypeAggr *ir = sd->type->irtype->isAggr(); assert(ir); @@ -605,7 +605,7 @@ llvm::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) fd->loc.linnum, // FIXME: scope line 0, // Flags false, // isOptimized - fd->ir.irFunc->func + getIrFunc(fd)->func ); } @@ -657,7 +657,7 @@ void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) Logger::println("D to dwarf funcstart"); LOG_SCOPE; - assert(static_cast(fd->ir.irFunc->diSubprogram) != 0); + assert(static_cast(getIrFunc(fd)->diSubprogram) != 0); EmitStopPoint(fd->loc.linnum); } @@ -669,7 +669,7 @@ void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) Logger::println("D to dwarf funcend"); LOG_SCOPE; - assert(static_cast(fd->ir.irFunc->diSubprogram) != 0); + assert(static_cast(getIrFunc(fd)->diSubprogram) != 0); } void ldc::DIBuilder::EmitBlockStart(Loc& loc) diff --git a/gen/dibuilder.h b/gen/dibuilder.h index f82e037fe4..29a899a7ab 100644 --- a/gen/dibuilder.h +++ b/gen/dibuilder.h @@ -1,6 +1,6 @@ //===-- gen/dibuilder.h - Debug information builder -------------*- C++ -*-===// // -// LDC – the LLVM D compiler +// LDC – the LLVM D compiler // // This file is distributed under the BSD-style LDC license. See the LICENSE // file for details. diff --git a/gen/functions.cpp b/gen/functions.cpp index e74e72e29b..8f6c3e9987 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -501,7 +501,7 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl) func = GET_INTRINSIC_DECL(vaend); assert(func); - fdecl->ir.irFunc->func = func; + getIrFunc(fdecl)->func = func; return func; } @@ -767,9 +767,8 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) Type* t = fdecl->type->toBasetype(); TypeFunction* f = static_cast(t); - if (!fdecl->ir.irFunc) { - fdecl->ir.irFunc = new IrFunction(fdecl); - } + // create IrFunction + IrFunction *irFunc = getIrFunc(fdecl, true); LLFunction* vafunc = 0; if (fdecl->isVaIntrinsic()) @@ -816,7 +815,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) IF_LOG Logger::cout() << "func = " << *func << std::endl; // add func to IRFunc - fdecl->ir.irFunc->func = func; + irFunc->func = func; // parameter attributes if (!fdecl->isIntrinsic()) { @@ -838,7 +837,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) if (fdecl->neverInline) { - fdecl->ir.irFunc->setNeverInline(); + irFunc->setNeverInline(); } if (fdecl->llvmInternal == LLVMglobal_crt_ctor || fdecl->llvmInternal == LLVMglobal_crt_dtor) @@ -855,13 +854,13 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) if (irFty.arg_sret) { iarg->setName(".sret_arg"); - fdecl->ir.irFunc->retArg = iarg; + irFunc->retArg = iarg; ++iarg; } if (irFty.arg_this) { iarg->setName(".this_arg"); - fdecl->ir.irFunc->thisArg = iarg; + irFunc->thisArg = iarg; VarDeclaration* v = fdecl->vthis; if (v) { @@ -869,25 +868,28 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) // later for codegen'ing the function, just as normal // parameters below, because it can be referred to in nested // context types. Will be given storage in DtoDefineFunction. - assert(!v->ir.irParam); - v->ir.irParam = new IrParameter(v, iarg, irFty.arg_this, true); + assert(!isIrParameterCreated(v)); + IrParameter *irParam = getIrParameter(v, true); + irParam->value = iarg; + irParam->arg = irFty.arg_this; + irParam->isVthis = true; } ++iarg; } else if (irFty.arg_nest) { iarg->setName(".nest_arg"); - fdecl->ir.irFunc->nestArg = iarg; - assert(fdecl->ir.irFunc->nestArg); + irFunc->nestArg = iarg; + assert(irFunc->nestArg); ++iarg; } if (irFty.arg_argptr) { iarg->setName("._arguments"); - fdecl->ir.irFunc->_arguments = iarg; + irFunc->_arguments = iarg; ++iarg; iarg->setName("._argptr"); - fdecl->ir.irFunc->_argptr = iarg; + irFunc->_argptr = iarg; ++iarg; } @@ -902,11 +904,14 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) VarDeclaration* argvd = argsym->isVarDeclaration(); assert(argvd); - assert(!argvd->ir.irLocal); + assert(!isIrLocalCreated(argvd)); std::string str(argvd->ident->toChars()); str.append("_arg"); iarg->setName(str); - argvd->ir.irParam = new IrParameter(argvd, iarg, irFty.args[paramIndex]); + + IrParameter *irParam = getIrParameter(argvd, true); + irParam->value = iarg; + irParam->arg = irFty.args[paramIndex]; k++; } @@ -1023,24 +1028,23 @@ void DtoDefineFunction(FuncDeclaration* fd) } IrFuncTy &irFty = fd->irFty; + IrFunction *irFunc = getIrFunc(fd); // debug info - fd->ir.irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd); + irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd); Type* t = fd->type->toBasetype(); TypeFunction* f = static_cast(t); // assert(f->irtype); - llvm::Function* func = fd->ir.irFunc->func; + llvm::Function* func = irFunc->func; // is there a body? if (fd->fbody == NULL) return; IF_LOG Logger::println("Doing function body for: %s", fd->toChars()); - assert(fd->ir.irFunc); - IrFunction* irfunction = fd->ir.irFunc; - gIR->functions.push_back(irfunction); + gIR->functions.push_back(irFunc); if (fd->isMain()) gIR->emitMain = true; @@ -1079,7 +1083,7 @@ void DtoDefineFunction(FuncDeclaration* fd) // create alloca point // this gets erased when the function is complete, so alignment etc does not matter at all llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb); - irfunction->allocapoint = allocaPoint; + irFunc->allocapoint = allocaPoint; // debug info - after all allocas, but before any llvm.dbg.declare etc gIR->DBuilder.EmitFuncStart(fd); @@ -1096,7 +1100,7 @@ void DtoDefineFunction(FuncDeclaration* fd) // give the 'this' argument storage and debug info if (irFty.arg_this) { - LLValue* thisvar = irfunction->thisArg; + LLValue* thisvar = irFunc->thisArg; assert(thisvar); LLValue* thismem = thisvar; @@ -1104,11 +1108,11 @@ void DtoDefineFunction(FuncDeclaration* fd) { thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align? DtoStore(thisvar, thismem); - irfunction->thisArg = thismem; + irFunc->thisArg = thismem; } - assert(fd->vthis->ir.irParam->value == thisvar); - fd->vthis->ir.irParam->value = thismem; + assert(getIrParameter(fd->vthis)->value == thisvar); + getIrParameter(fd->vthis)->value = thismem; gIR->DBuilder.EmitLocalVariable(thismem, fd->vthis); } @@ -1116,10 +1120,10 @@ void DtoDefineFunction(FuncDeclaration* fd) // give the 'nestArg' storage if (irFty.arg_nest) { - LLValue *nestArg = irfunction->nestArg; + LLValue *nestArg = irFunc->nestArg; LLValue *val = DtoRawAlloca(nestArg->getType(), 0, "nestedFrame"); DtoStore(nestArg, val); - irfunction->nestArg = val; + irFunc->nestArg = val; } // give arguments storage @@ -1134,7 +1138,7 @@ void DtoDefineFunction(FuncDeclaration* fd) VarDeclaration* vd = argsym->isVarDeclaration(); assert(vd); - IrParameter* irparam = vd->ir.irParam; + IrParameter* irparam = getIrParameter(vd); assert(irparam); bool refout = vd->storage_class & (STCref | STCout); @@ -1163,7 +1167,7 @@ void DtoDefineFunction(FuncDeclaration* fd) } FuncGen fg; - irfunction->gen = &fg; + irFunc->gen = &fg; DtoCreateNestedContext(fd); @@ -1178,19 +1182,19 @@ void DtoDefineFunction(FuncDeclaration* fd) if (f->linkage == LINKd && f->varargs == 1) { // _argptr - LLValue* argptrmem = DtoRawAlloca(fd->ir.irFunc->_argptr->getType(), 0, "_argptr_mem"); - new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); - fd->ir.irFunc->_argptr = argptrmem; + LLValue* argptrmem = DtoRawAlloca(irFunc->_argptr->getType(), 0, "_argptr_mem"); + new llvm::StoreInst(irFunc->_argptr, argptrmem, gIR->scopebb()); + irFunc->_argptr = argptrmem; // _arguments - LLValue* argumentsmem = DtoRawAlloca(fd->ir.irFunc->_arguments->getType(), 0, "_arguments_mem"); - new llvm::StoreInst(fd->ir.irFunc->_arguments, argumentsmem, gIR->scopebb()); - fd->ir.irFunc->_arguments = argumentsmem; + LLValue* argumentsmem = DtoRawAlloca(irFunc->_arguments->getType(), 0, "_arguments_mem"); + new llvm::StoreInst(irFunc->_arguments, argumentsmem, gIR->scopebb()); + irFunc->_arguments = argumentsmem; } // output function body Statement_toIR(fd->fbody, gIR); - irfunction->gen = 0; + irFunc->gen = 0; // TODO: clean up this mess diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index c56f9d440c..4d6566149a 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1032,7 +1032,7 @@ void DtoResolveVariable(VarDeclaration* vd) vd->ir.resolved = true; vd->ir.declared = true; - vd->ir.irGlobal = new IrGlobal(vd); + getIrGlobal(vd, true); IF_LOG { if (vd->parent) @@ -1066,7 +1066,7 @@ void DtoResolveVariable(VarDeclaration* vd) llvm::GlobalVariable* gvar = getOrCreateGlobal(vd->loc, *gIR->module, i1ToI8(DtoType(vd->type)), isLLConst, linkage, 0, llName, vd->isThreadlocal()); - vd->ir.irGlobal->value = gvar; + getIrGlobal(vd)->value = gvar; // Set the alignment (it is important not to use type->alignsize because // VarDeclarations can have an align() attribute independent of the type @@ -1101,7 +1101,7 @@ void DtoVarDeclaration(VarDeclaration* vd) // assert(vd->ir.irLocal && "irLocal is expected to be already set by DtoCreateNestedContext"); } - if(vd->ir.irLocal) + if (isIrLocalCreated(vd)) { // Nothing to do if it has already been allocated. } @@ -1114,11 +1114,12 @@ void DtoVarDeclaration(VarDeclaration* vd) */ else if (gIR->func()->retArg && gIR->func()->decl->nrvo_can && gIR->func()->decl->nrvo_var == vd) { assert(!isSpecialRefVar(vd) && "Can this happen?"); - vd->ir.irLocal = new IrLocal(vd, gIR->func()->retArg); + IrLocal *irLocal = getIrLocal(vd, true); + irLocal->value = gIR->func()->retArg; } // normal stack variable, allocate storage on the stack if it has not already been done else { - vd->ir.irLocal = new IrLocal(vd); + IrLocal *irLocal = getIrLocal(vd, true); Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type; @@ -1129,7 +1130,7 @@ void DtoVarDeclaration(VarDeclaration* vd) else allocainst = DtoAlloca(type, vd->toChars()); - vd->ir.irLocal->value = allocainst; + irLocal->value = allocainst; gIR->DBuilder.EmitLocalVariable(allocainst, vd); @@ -1157,12 +1158,12 @@ void DtoVarDeclaration(VarDeclaration* vd) if (isSpecialRefVar(vd)) { LLValue* const val = ce->toElem(gIR)->getLVal(); - DtoStore(val, vd->ir.irLocal->value); + DtoStore(val, irLocal->value); } else { DValue* fnval = ce->e1->toElem(gIR); - DtoCallFunction(ce->loc, ce->type, fnval, ce->arguments, vd->ir.irLocal->value); + DtoCallFunction(ce->loc, ce->type, fnval, ce->arguments, irLocal->value); } return; } @@ -1171,7 +1172,7 @@ void DtoVarDeclaration(VarDeclaration* vd) } } - IF_LOG Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n'; + IF_LOG Logger::cout() << "llvm value for decl: " << *getIrLocal(vd)->value << '\n'; if (vd->init) { @@ -1209,7 +1210,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration) { DtoVarDeclaration(vd); } - return new DVarValue(vd->type, vd, vd->ir.getIrValue()); + return new DVarValue(vd->type, vd, getIrValue(vd)); } // struct declaration else if (StructDeclaration* s = declaration->isStructDeclaration()) @@ -1289,8 +1290,10 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr) // we don't handle aliases either assert(!var->aliassym); + IrLocal *irLocal = isIrLocalCreated(var) ? getIrLocal(var) : 0; + // alloca if necessary - if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value)) + if (!addr && (!irLocal || !irLocal->value)) { addr = DtoAlloca(var->type, var->toChars()); // add debug info @@ -1300,22 +1303,22 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr) // nested variable? // A variable may not be really nested even if nextedrefs is not empty // in case it is referenced by a function inside __traits(compile) or typeof. - if (var->nestedrefs.dim && var->ir.irLocal) + if (var->nestedrefs.dim && isIrLocalCreated(var)) { - if(!var->ir.irLocal->value) + if (!irLocal->value) { assert(addr); - var->ir.irLocal->value = addr; + irLocal->value = addr; } else - assert(!addr || addr == var->ir.irLocal->value); + assert(!addr || addr == irLocal->value); } // normal local variable else { // if this already has storage, it must've been handled already - if (var->ir.irLocal && var->ir.irLocal->value) { - if (addr && addr != var->ir.irLocal->value) { + if (irLocal && irLocal->value) { + if (addr && addr != irLocal->value) { // This can happen, for example, in scope(exit) blocks which // are translated to IR multiple times. // That *should* only happen after the first one is completely done @@ -1323,21 +1326,22 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr) IF_LOG { Logger::println("Replacing LLVM address of %s", var->toChars()); LOG_SCOPE; - Logger::cout() << "Old val: " << *var->ir.irLocal->value << '\n'; + Logger::cout() << "Old val: " << *irLocal->value << '\n'; Logger::cout() << "New val: " << *addr << '\n'; } - var->ir.irLocal->value = addr; + irLocal->value = addr; } return addr; } - assert(!var->ir.isSet()); assert(addr); - var->ir.irLocal = new IrLocal(var, addr); + if (!irLocal) + irLocal = getIrLocal(var, true); + irLocal->value = addr; } // return the alloca - return var->ir.irLocal->value; + return irLocal->value; } /****************************************************************************************/ @@ -1473,9 +1477,8 @@ LLConstant* DtoTypeInfoOf(Type* type, bool base) TypeInfoDeclaration* tidecl = type->vtinfo; assert(tidecl); Declaration_codegen(tidecl); - assert(tidecl->ir.irGlobal != NULL); - assert(tidecl->ir.irGlobal->value != NULL); - LLConstant* c = isaConstant(tidecl->ir.irGlobal->value); + assert(getIrGlobal(tidecl)->value != NULL); + LLConstant* c = isaConstant(getIrGlobal(tidecl)->value); assert(c != NULL); if (base) return llvm::ConstantExpr::getBitCast(c, DtoType(Type::dtypeinfo->type)); @@ -1575,18 +1578,6 @@ bool hasUnalignedFields(Type* t) ////////////////////////////////////////////////////////////////////////////////////////// -IrModule * getIrModule(Module * M) -{ - if (M == NULL) - M = gIR->func()->decl->getModule(); - assert(M && "null module"); - if (!M->ir.irModule) - M->ir.irModule = new IrModule(M, M->srcfile->toChars()); - return M->ir.irModule; -} - -////////////////////////////////////////////////////////////////////////////////////////// - size_t realignOffset(size_t offset, Type* type) { size_t alignsize = type->alignsize(); @@ -1684,7 +1675,7 @@ void callPostblit(Loc& loc, Expression *exp, LLValue *val) fd->toParent()->error(loc, "is not copyable because it is annotated with @disable"); DtoResolveFunction(fd); Expressions args; - DFuncValue dfn(fd, fd->ir.irFunc->func, val); + DFuncValue dfn(fd, getIrFunc(fd)->func, val); DtoCallFunction(loc, Type::basic[Tvoid], &dfn, &args); } } @@ -1802,7 +1793,7 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl) { Logger::println("Id::dollar"); LLValue* val = 0; - if (vd->ir.isSet() && (val = vd->ir.getIrValue())) + if (isIrVarCreated(vd) && (val = getIrValue(vd))) { // It must be length of a range return new DVarValue(type, vd, val); @@ -1816,16 +1807,16 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl) { Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars()); DtoResolveClass(cid->cd); - return new DVarValue(type, vd, cid->cd->ir.irAggr->getClassInfoSymbol()); + return new DVarValue(type, vd, getIrAggr(cid->cd)->getClassInfoSymbol()); } // typeinfo else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) { Logger::println("TypeInfoDeclaration"); DtoResolveTypeInfo(tid); - assert(tid->ir.getIrValue()); + assert(getIrValue(tid)); LLType* vartype = DtoType(type); - LLValue* m = tid->ir.getIrValue(); + LLValue* m = getIrValue(tid); if (m->getType() != getPtrToType(vartype)) m = gIR->ir->CreateBitCast(m, vartype, "tmp"); return new DImValue(type, m); @@ -1853,16 +1844,16 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl) { Logger::println("lazy parameter"); assert(type->ty == Tdelegate); - return new DVarValue(type, vd->ir.getIrValue()); + return new DVarValue(type, getIrValue(vd)); } else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || - llvm::isa(vd->ir.getIrValue())) + llvm::isa(getIrValue(vd))) { - return new DVarValue(type, vd, vd->ir.getIrValue()); + return new DVarValue(type, vd, getIrValue(vd)); } - else if (llvm::isa(vd->ir.getIrValue())) + else if (llvm::isa(getIrValue(vd))) { - return new DImValue(type, vd->ir.getIrValue()); + return new DImValue(type, getIrValue(vd)); } else llvm_unreachable("Unexpected parameter value."); } @@ -1875,9 +1866,9 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl) if (isGlobal) DtoResolveVariable(vd); - assert(vd->ir.isSet() && "Variable not resolved."); + assert(isIrVarCreated(vd) && "Variable not resolved."); - llvm::Value* val = vd->ir.getIrValue(); + llvm::Value* val = getIrValue(vd); assert(val && "Variable value not set yet."); if (isGlobal) @@ -1910,8 +1901,7 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl) fatal(); } DtoResolveFunction(fdecl); - assert(fdecl->llvmInternal == LLVMva_arg || fdecl->ir.irFunc); - return new DFuncValue(fdecl, fdecl->ir.irFunc ? fdecl->ir.irFunc->func : 0); + return new DFuncValue(fdecl, fdecl->llvmInternal != LLVMva_arg ? getIrFunc(fdecl)->func : 0); } if (SymbolDeclaration* sdecl = decl->isSymbolDeclaration()) @@ -1924,7 +1914,7 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl) assert(ts->sym); DtoResolveStruct(ts->sym); - LLValue* initsym = ts->sym->ir.irAggr->getInitSymbol(); + LLValue* initsym = getIrAggr(ts->sym)->getInitSymbol(); initsym = DtoBitCast(initsym, DtoType(ts->pointerTo())); return new DVarValue(type, initsym); } @@ -1959,7 +1949,7 @@ llvm::Constant* DtoConstSymbolAddress(Loc& loc, Declaration* decl) } DtoResolveVariable(vd); - LLConstant* llc = llvm::dyn_cast(vd->ir.getIrValue()); + LLConstant* llc = llvm::dyn_cast(getIrValue(vd)); assert(llc); return llc; } @@ -1967,8 +1957,7 @@ llvm::Constant* DtoConstSymbolAddress(Loc& loc, Declaration* decl) else if (FuncDeclaration* fd = decl->isFuncDeclaration()) { DtoResolveFunction(fd); - IrFunction* irfunc = fd->ir.irFunc; - return irfunc->func; + return getIrFunc(fd)->func; } llvm_unreachable("Taking constant address not implemented."); diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index a8d3cfeea9..88d093b4e4 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -147,9 +147,6 @@ bool hasUnalignedFields(Type* t); /// DValue* DtoInlineAsmExpr(Loc& loc, FuncDeclaration* fd, Expressions* arguments); -/// Create the IrModule if necessary and returns it. -IrModule* getIrModule(Module* M); - /// Update an offset to make sure it follows both the D and LLVM alignments. /// Returns the offset rounded up to the closest safely aligned offset. size_t realignOffset(size_t offset, Type* type); diff --git a/gen/module.cpp b/gen/module.cpp index 86a24c32ff..6c576b50e4 100644 --- a/gen/module.cpp +++ b/gen/module.cpp @@ -186,7 +186,7 @@ static llvm::Function* build_module_function(const std::string &name, const std: return NULL; if (funcs.size() == 1) - return funcs.front()->ir.irFunc->func; + return getIrFunc(funcs.front())->func; } std::vector argsTy; @@ -207,7 +207,7 @@ static llvm::Function* build_module_function(const std::string &name, const std: // Call ctor's typedef std::list::const_iterator FuncIterator; for (FuncIterator itr = funcs.begin(), end = funcs.end(); itr != end; ++itr) { - llvm::Function* f = (*itr)->ir.irFunc->func; + llvm::Function* f = getIrFunc(*itr)->func; llvm::CallInst* call = builder.CreateCall(f,""); call->setCallingConv(gABI->callingConv(LINKd)); } @@ -215,8 +215,8 @@ static llvm::Function* build_module_function(const std::string &name, const std: // Increment vgate's typedef std::list::const_iterator GatesIterator; for (GatesIterator itr = gates.begin(), end = gates.end(); itr != end; ++itr) { - assert((*itr)->ir.irGlobal); - llvm::Value* val = (*itr)->ir.irGlobal->value; + assert(getIrGlobal(*itr)); + llvm::Value* val = getIrGlobal(*itr)->value; llvm::Value* rval = builder.CreateLoad(val, "vgate"); llvm::Value* res = builder.CreateAdd(rval, DtoConstUint(1), "vgate"); builder.CreateStore(res, val); @@ -781,7 +781,7 @@ void Module::genmoduleinfo() continue; } IF_LOG Logger::println("class: %s", cd->toPrettyChars()); - LLConstant *c = DtoBitCast(cd->ir.irAggr->getClassInfoSymbol(), classinfoTy); + LLConstant *c = DtoBitCast(getIrAggr(cd)->getClassInfoSymbol(), classinfoTy); classInits.push_back(c); } // has class array? diff --git a/gen/naked.cpp b/gen/naked.cpp index 46d9a798d8..7dc0ab3725 100644 --- a/gen/naked.cpp +++ b/gen/naked.cpp @@ -147,8 +147,7 @@ void DtoDefineNakedFunction(FuncDeclaration* fd) IF_LOG Logger::println("DtoDefineNakedFunction(%s)", fd->mangleExact()); LOG_SCOPE; - assert(fd->ir.irFunc); - gIR->functions.push_back(fd->ir.irFunc); + gIR->functions.push_back(getIrFunc(fd)); // we need to do special processing on the body, since we only want // to allow actual inline asm blocks to reach the final asm output diff --git a/gen/nested.cpp b/gen/nested.cpp index 02d6821f90..5d4c036dfa 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -26,7 +26,7 @@ namespace cl = llvm::cl; static void storeVariable(VarDeclaration *vd, LLValue *dst) { - LLValue *value = vd->ir.irLocal->value; + LLValue *value = getIrLocal(vd)->value; int ty = vd->type->ty; FuncDeclaration *fd = getParentFunc(vd, true); assert(fd && "No parent function for nested variable?"); @@ -69,7 +69,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref // is the nested variable in this scope? if (vdparent == irfunc->decl) { - LLValue* val = vd->ir.getIrValue(); + LLValue* val = getIrValue(vd); return new DVarValue(astype, vd, val); } @@ -89,7 +89,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref LLValue* val = irfunc->thisArg; if (cd->isClassDeclaration()) val = DtoLoad(val); - ctx = DtoLoad(DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis")); + ctx = DtoLoad(DtoGEPi(val, 0, getIrField(cd->vthis)->index, ".vthis")); } else { // Otherwise, this is a simple nested function, load from the context // argument. @@ -101,7 +101,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref assert(ctx); DtoCreateNestedContextType(vdparent->isFuncDeclaration()); - assert(vd->ir.irLocal); + assert(isIrLocalCreated(vd)); //////////////////////////////////// // Extract variable from nested context @@ -112,7 +112,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref Logger::cout() << "of type: " << *irfunc->frameType << '\n'; } - unsigned vardepth = vd->ir.irLocal->nestedDepth; + unsigned vardepth = getIrLocal(vd)->nestedDepth; unsigned funcdepth = irfunc->depth; IF_LOG { @@ -129,17 +129,17 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref } else { // Load frame pointer and index that... if (dwarfValue && global.params.symdebug) { - gIR->DBuilder.OpOffset(dwarfAddr, val, vd->ir.irLocal->nestedDepth); + gIR->DBuilder.OpOffset(dwarfAddr, val, vardepth); gIR->DBuilder.OpDeref(dwarfAddr); } IF_LOG Logger::println("Lower depth"); - val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth); + val = DtoGEPi(val, 0, vardepth); IF_LOG Logger::cout() << "Frame index: " << *val << '\n'; val = DtoAlignedLoad(val, (std::string(".frame.") + vdparent->toChars()).c_str()); IF_LOG Logger::cout() << "Frame: " << *val << '\n'; } - int idx = vd->ir.irLocal->nestedIndex; + int idx = getIrLocal(vd)->nestedIndex; assert(idx != -1 && "Nested context not yet resolved for variable."); if (dwarfValue && global.params.symdebug) @@ -150,7 +150,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref Logger::cout() << "Addr: " << *val << '\n'; Logger::cout() << "of type: " << *val->getType() << '\n'; } - if (byref || (vd->isParameter() && vd->ir.irParam->arg->byref)) { + if (byref || (vd->isParameter() && getIrParameter(vd)->arg->byref)) { val = DtoAlignedLoad(val); //dwarfOpDeref(dwarfAddr); IF_LOG { @@ -183,7 +183,7 @@ void DtoResolveNestedContext(Loc& loc, AggregateDeclaration *decl, LLValue *valu // our codegen order. DtoResolveDsymbol(decl); - size_t idx = decl->vthis->ir.irField->index; + size_t idx = getIrField(decl->vthis)->index; LLValue* gep = DtoGEPi(value,0,idx,".vthis"); DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep); } @@ -221,7 +221,7 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym) // function (but without any variables in the nested context). return val; } - val = DtoLoad(DtoGEPi(val, 0, ad->vthis->ir.irField->index, ".vthis")); + val = DtoLoad(DtoGEPi(val, 0, getIrField(ad->vthis)->index, ".vthis")); } else { @@ -242,7 +242,7 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym) // if this is for a function that doesn't access variables from // enclosing scopes, it doesn't matter what we pass. - if (symfd->ir.irFunc->depth == -1) + if (getIrFunc(symfd)->depth == -1) return llvm::UndefValue::get(getVoidPtrType()); // If sym is a nested function, and its parent context is different @@ -260,8 +260,8 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym) } IF_LOG Logger::println("Context is from %s", ctxfd->toChars()); - unsigned neededDepth = frameToPass->ir.irFunc->depth; - unsigned ctxDepth = ctxfd->ir.irFunc->depth; + unsigned neededDepth = getIrFunc(frameToPass)->depth; + unsigned ctxDepth = getIrFunc(ctxfd)->depth; IF_LOG { Logger::cout() << "Needed depth: " << neededDepth << '\n'; @@ -273,7 +273,7 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym) // fd needs the same context as we do, so all is well IF_LOG Logger::println("Calling sibling function or directly nested function"); } else { - val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType)); + val = DtoBitCast(val, LLPointerType::getUnqual(getIrFunc(ctxfd)->frameType)); val = DtoGEPi(val, 0, neededDepth); val = DtoAlignedLoad(val, (std::string(".frame.") + frameToPass->toChars()).c_str()); @@ -293,9 +293,9 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { DtoDeclareFunction(fd); - if (fd->ir.irFunc->nestedContextCreated) + if (getIrFunc(fd)->nestedContextCreated) return; - fd->ir.irFunc->nestedContextCreated = true; + getIrFunc(fd)->nestedContextCreated = true; // construct nested variables array if (fd->closureVars.dim > 0) @@ -316,12 +316,12 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { // Make sure the parent has already been analyzed. DtoCreateNestedContextType(parfd); - innerFrameType = parfd->ir.irFunc->frameType; + innerFrameType = getIrFunc(parfd)->frameType; if (innerFrameType) - depth = parfd->ir.irFunc->depth; + depth = getIrFunc(parfd)->depth; } } - fd->ir.irFunc->depth = ++depth; + getIrFunc(fd)->depth = ++depth; IF_LOG Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n'; @@ -352,15 +352,14 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { E = fd->closureVars.end(); I != E; ++I) { VarDeclaration* vd = *I; - if (!vd->ir.irLocal) - vd->ir.irLocal = new IrLocal(vd); + IrLocal *irLocal = getIrLocal(vd, true); + irLocal->nestedIndex = types.size(); + irLocal->nestedDepth = depth; - vd->ir.irLocal->nestedIndex = types.size(); - vd->ir.irLocal->nestedDepth = depth; if (vd->isParameter()) { // Parameters will have storage associated with them (to handle byref etc.), // so handle those cases specially by storing a pointer instead of a value. - const IrParameter* irparam = vd->ir.irParam; + const IrParameter* irparam = getIrParameter(vd); const bool refout = vd->storage_class & (STCref | STCout); const bool lazy = vd->storage_class & STClazy; const bool byref = irparam->arg->byref; @@ -389,12 +388,12 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { IF_LOG Logger::cout() << "frameType = " << *frameType << '\n'; // Store type in IrFunction - fd->ir.irFunc->frameType = frameType; + getIrFunc(fd)->frameType = frameType; } else if (FuncDeclaration* parFunc = getParentFunc(fd, true)) { // Propagate context arg properties if the context arg is passed on unmodified. DtoCreateNestedContextType(parFunc); - fd->ir.irFunc->frameType = parFunc->ir.irFunc->frameType; - fd->ir.irFunc->depth = parFunc->ir.irFunc->depth; + getIrFunc(fd)->frameType = getIrFunc(parFunc)->frameType; + getIrFunc(fd)->depth = getIrFunc(parFunc)->depth; } } @@ -408,7 +407,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { // construct nested variables array if (fd->closureVars.dim > 0) { - IrFunction* irfunction = fd->ir.irFunc; + IrFunction* irfunction = getIrFunc(fd); unsigned depth = irfunction->depth; LLStructType *frameType = irfunction->frameType; // Create frame for current function and append to frames list @@ -432,9 +431,9 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { assert(cd->vthis); Logger::println("Indexing to 'this'"); if (cd->isStructDeclaration()) - src = DtoExtractValue(thisval, cd->vthis->ir.irField->index, ".vthis"); + src = DtoExtractValue(thisval, getIrField(cd->vthis)->index, ".vthis"); else - src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis")); + src = DtoLoad(DtoGEPi(thisval, 0, getIrField(cd->vthis)->index, ".vthis")); } else { src = DtoLoad(src); } @@ -465,11 +464,12 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { vd->error("has scoped destruction, cannot build closure"); } - LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars()); + IrLocal *irLocal = getIrLocal(vd); + LLValue* gep = DtoGEPi(frame, 0, irLocal->nestedIndex, vd->toChars()); if (vd->isParameter()) { IF_LOG Logger::println("nested param: %s", vd->toChars()); LOG_SCOPE - IrParameter* parm = vd->ir.irParam; + IrParameter* parm = getIrParameter(vd); if (parm->arg->byref) { @@ -487,13 +487,13 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { } } else { IF_LOG Logger::println("nested var: %s", vd->toChars()); - assert(!vd->ir.irLocal->value); - vd->ir.irLocal->value = gep; + assert(!irLocal->value); + irLocal->value = gep; } if (global.params.symdebug) { LLSmallVector addr; - gIR->DBuilder.OpOffset(addr, frameType, vd->ir.irLocal->nestedIndex); + gIR->DBuilder.OpOffset(addr, frameType, irLocal->nestedIndex); gIR->DBuilder.EmitLocalVariable(frame, vd, addr); } } diff --git a/gen/rttibuilder.cpp b/gen/rttibuilder.cpp index 9b6b5a9e7b..1e95af798f 100644 --- a/gen/rttibuilder.cpp +++ b/gen/rttibuilder.cpp @@ -26,7 +26,7 @@ RTTIBuilder::RTTIBuilder(AggregateDeclaration* base_class) base = base_class; basetype = static_cast(base->type); - baseir = base->ir.irAggr; + baseir = getIrAggr(base); assert(baseir && "no IrStruct for TypeInfo base class"); if (base->isClassDeclaration()) { @@ -59,7 +59,7 @@ void RTTIBuilder::push_typeinfo(Type* t) void RTTIBuilder::push_classinfo(ClassDeclaration* cd) { - inits.push_back(cd->ir.irAggr->getClassInfoSymbol()); + inits.push_back(getIrAggr(cd)->getClassInfoSymbol()); } void RTTIBuilder::push_string(const char* str) @@ -137,7 +137,7 @@ void RTTIBuilder::push_funcptr(FuncDeclaration* fd, Type* castto) if (fd) { DtoResolveFunction(fd); - LLConstant* F = fd->ir.irFunc->func; + LLConstant* F = getIrFunc(fd)->func; if (castto) F = DtoBitCast(F, DtoType(castto)); inits.push_back(F); diff --git a/gen/statements.cpp b/gen/statements.cpp index fd41a4bcf4..0e933c308d 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -150,12 +150,12 @@ public: { // sanity check IrFunction* f = irs->func(); - assert(f->decl->ir.irFunc->retArg); + assert(getIrFunc(f->decl)->retArg); // FIXME: is there ever a case where a sret return needs to be rewritten for the ABI? // get return pointer - DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg); + DValue* rvar = new DVarValue(f->type->next, getIrFunc(f->decl)->retArg); DValue* e = stmt->exp->toElemDtor(irs); // store return value if (rvar->getLVal() != e->getRVal()) @@ -1205,7 +1205,7 @@ public: if (!stmt->value->isRef() && !stmt->value->isOut()) { // Create a local variable to serve as the value. DtoRawVarDeclaration(stmt->value); - valvar = stmt->value->ir.irLocal->value; + valvar = getIrLocal(stmt->value)->value; } // what to iterate @@ -1269,7 +1269,7 @@ public: DVarValue dst(stmt->value->type, valvar); DVarValue src(stmt->value->type, gep); DtoAssign(stmt->loc, &dst, &src); - stmt->value->ir.irLocal->value = valvar; + getIrLocal(stmt->value)->value = valvar; } else { // Use the GEP as the address of the value variable. DtoRawVarDeclaration(stmt->value, gep); diff --git a/gen/structs.cpp b/gen/structs.cpp index 8da6c1332c..6c4c55e368 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -53,8 +53,7 @@ void DtoResolveStruct(StructDeclaration* sd, Loc& callerLoc) } // create the IrAggr - IrAggr* iraggr = new IrAggr(sd); - sd->ir.irAggr = iraggr; + getIrAggr(sd, true); // Set up our field metadata. for (VarDeclarations::iterator I = sd->fields.begin(), @@ -62,8 +61,8 @@ void DtoResolveStruct(StructDeclaration* sd, Loc& callerLoc) I != E; ++I) { VarDeclaration *vd = *I; - assert(!vd->ir.irField); - (void)new IrField(vd); + assert(!isIrFieldCreated(vd)); + getIrField(vd, true); } } @@ -99,7 +98,7 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) DtoResolveStruct(sd); // vd must be a field - IrField* field = vd->ir.irField; + IrField* field = getIrField(vd); assert(field); // get the start pointer diff --git a/gen/toir.cpp b/gen/toir.cpp index 5a2feaedf7..5383f6f103 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -205,7 +205,7 @@ LLConstant* VarExp::toConstElem(IRState* p) assert(sdecltype->ty == Tstruct); TypeStruct* ts = static_cast(sdecltype); DtoResolveStruct(ts->sym); - return ts->sym->ir.irAggr->getDefaultInit(); + return getIrAggr(ts->sym)->getDefaultInit(); } if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration()) @@ -1238,7 +1238,7 @@ LLConstant* CastExp::toConstElem(IRState* p) VarDeclaration *vd = static_cast(e1)->var->isVarDeclaration(); assert(vd); DtoResolveVariable(vd); - LLConstant *value = vd->ir.irGlobal ? isaConstant(vd->ir.irGlobal->value) : 0; + LLConstant *value = isIrGlobalCreated(vd) ? isaConstant(getIrGlobal(vd)->value) : 0; if (!value) goto Lerr; Type *type = vd->type->toBasetype(); @@ -1405,7 +1405,7 @@ DValue* AddrExp::toElem(IRState* p) FuncDeclaration* fd = fv->func; assert(fd); DtoResolveFunction(fd); - return new DFuncValue(fd, fd->ir.irFunc->func); + return new DFuncValue(fd, getIrFunc(fd)->func); } else if (v->isIm()) { Logger::println("is immediate"); @@ -1456,7 +1456,7 @@ LLConstant* AddrExp::toConstElem(IRState* p) assert(vd); assert(vd->type->toBasetype()->ty == Tsarray); DtoResolveVariable(vd); - assert(vd->ir.irGlobal); + assert(isIrGlobalCreated(vd)); // get index LLConstant* index = iexp->e2->toConstElem(p); @@ -1464,7 +1464,7 @@ LLConstant* AddrExp::toConstElem(IRState* p) // gep LLConstant* idxs[2] = { DtoConstSize_t(0), index }; - LLConstant *val = isaConstant(vd->ir.irGlobal->value); + LLConstant *val = isaConstant(getIrGlobal(vd)->value); val = DtoBitCast(val, DtoType(vd->type->pointerTo())); LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(val, idxs, true); @@ -1681,7 +1681,7 @@ DValue* DotVarExp::toElem(IRState* p) } else { - funcval = fdecl->ir.irFunc->func; + funcval = getIrFunc(fdecl)->func; } assert(funcval); @@ -2170,7 +2170,7 @@ DValue* NewExp::toElem(IRState* p) { // custom allocator DtoResolveFunction(allocator); - DFuncValue dfn(allocator, allocator->ir.irFunc->func); + DFuncValue dfn(allocator, getIrFunc(allocator)->func); DValue* res = DtoCallFunction(loc, NULL, &dfn, newargs); mem = DtoBitCast(res->getRVal(), DtoType(ntype->pointerTo()), ".newstruct_custom"); } else @@ -2186,7 +2186,7 @@ DValue* NewExp::toElem(IRState* p) else { assert(ts->sym); DtoResolveStruct(ts->sym, loc); - DtoAggrCopy(mem, ts->sym->ir.irAggr->getInitSymbol()); + DtoAggrCopy(mem, getIrAggr(ts->sym)->getInitSymbol()); } if (ts->sym->isNested() && ts->sym->vthis) DtoResolveNestedContext(loc, ts->sym, mem); @@ -2197,7 +2197,7 @@ DValue* NewExp::toElem(IRState* p) Logger::println("Calling constructor"); assert(arguments != NULL); DtoResolveFunction(member); - DFuncValue dfn(member, member->ir.irFunc->func, mem); + DFuncValue dfn(member, getIrFunc(member)->func, mem); DtoCallFunction(loc, ts, &dfn, arguments); } return new DImValue(type, mem); @@ -2360,7 +2360,7 @@ DValue* AssertExp::toElem(IRState* p) { Logger::print("calling struct invariant"); DtoResolveFunction(invdecl); - DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal()); + DFuncValue invfunc(invdecl, getIrFunc(invdecl)->func, cond->getRVal()); DtoCallFunction(loc, NULL, &invfunc, NULL); } @@ -2601,7 +2601,7 @@ DValue* DelegateExp::toElem(IRState* p) } } - castfptr = func->ir.irFunc->func; + castfptr = getIrFunc(func)->func; } castfptr = DtoBitCast(castfptr, dgty->getContainedType(1)); @@ -2850,14 +2850,14 @@ DValue* FuncExp::toElem(IRState* p) // We need to actually codegen the function here, as literals are not added // to the module member list. Declaration_codegen(fd, p); - if (!fd->ir.irFunc) + if (!isIrFuncCreated(fd)) { // See DtoDefineFunction for reasons why codegen was suppressed. // Instead just declare the function. DtoDeclareFunction(fd); assert(!fd->isNested()); } - assert(fd->ir.irFunc->func); + assert(getIrFunc(fd)->func); if (fd->isNested()) { LLType* dgty = DtoType(type); @@ -2881,19 +2881,19 @@ DValue* FuncExp::toElem(IRState* p) cval = getNullPtr(getVoidPtrType()); } else { cval = ad->isClassDeclaration() ? DtoLoad(irfn->thisArg) : irfn->thisArg; - cval = DtoLoad(DtoGEPi(cval, 0,ad->vthis->ir.irField->index, ".vthis")); + cval = DtoLoad(DtoGEPi(cval, 0, getIrField(ad->vthis)->index, ".vthis")); } } else cval = getNullPtr(getVoidPtrType()); cval = DtoBitCast(cval, dgty->getContainedType(0)); - LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, dgty->getContainedType(1)); + LLValue* castfptr = DtoBitCast(getIrFunc(fd)->func, dgty->getContainedType(1)); return new DImValue(type, DtoAggrPair(cval, castfptr, ".func")); } else { - return new DFuncValue(type, fd, fd->ir.irFunc->func); + return new DFuncValue(type, fd, getIrFunc(fd)->func); } } @@ -2927,9 +2927,9 @@ LLConstant* FuncExp::toConstElem(IRState* p) // We need to actually codegen the function here, as literals are not added // to the module member list. Declaration_codegen(fd, p); - assert(fd->ir.irFunc->func); + assert(getIrFunc(fd)->func); - return fd->ir.irFunc->func; + return getIrFunc(fd)->func; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -3061,7 +3061,7 @@ DValue* StructLiteralExp::toElem(IRState* p) assert(ts->sym); DtoResolveStruct(ts->sym); - LLValue* initsym = ts->sym->ir.irAggr->getInitSymbol(); + LLValue* initsym = getIrAggr(ts->sym)->getInitSymbol(); initsym = DtoBitCast(initsym, DtoType(ts->pointerTo())); return new DVarValue(type, initsym); } @@ -3200,7 +3200,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) TypeStruct* ts = static_cast(sdecltype); DtoResolveStruct(ts->sym); - return ts->sym->ir.irAggr->getDefaultInit(); + return getIrAggr(ts->sym)->getDefaultInit(); } // make sure the struct is resolved @@ -3216,7 +3216,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) } } - return sd->ir.irAggr->createInitializerConstant(varInits); + return getIrAggr(sd)->createInitializerConstant(varInits); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -3285,7 +3285,7 @@ llvm::Constant* ClassReferenceExp::toConstElem(IRState *p) assert(i == nexprs); } - llvm::Constant* constValue = origClass->ir.irAggr->createInitializerConstant(varInits); + llvm::Constant* constValue = getIrAggr(origClass)->createInitializerConstant(varInits); if (constValue->getType() != value->globalVar->getType()->getContainedType(0)) { diff --git a/gen/typinf.cpp b/gen/typinf.cpp index a5236d0161..336b855b01 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -307,7 +307,7 @@ static void emitTypeMetadata(TypeInfoDeclaration *tid) if (!meta) { // Construct the fields MDNodeField* mdVals[TD_NumFields]; - mdVals[TD_TypeInfo] = llvm::cast(tid->ir.irGlobal->value); + mdVals[TD_TypeInfo] = llvm::cast(getIrGlobal(tid)->value); mdVals[TD_Type] = llvm::UndefValue::get(DtoType(tid->tinfo)); // Construct the metadata and insert it into the module. @@ -342,8 +342,7 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState* p) Logger::println("typeinfo mangle: %s", mangled.c_str()); } - IrGlobal* irg = new IrGlobal(decl); - decl->ir.irGlobal = irg; + IrGlobal* irg = getIrGlobal(decl, true); irg->value = gIR->module->getGlobalVariable(mangled); if (irg->value) { irg->type = irg->value->getType()->getContainedType(0); @@ -378,7 +377,7 @@ void TypeInfoDeclaration::llvmDefine() LOG_SCOPE; RTTIBuilder b(Type::dtypeinfo); - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -416,7 +415,7 @@ void TypeInfoTypedefDeclaration::llvmDefine() } // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -463,7 +462,7 @@ void TypeInfoEnumDeclaration::llvmDefine() } // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -477,7 +476,7 @@ void TypeInfoPointerDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tinfo->nextOf()); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -491,7 +490,7 @@ void TypeInfoArrayDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tinfo->nextOf()); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -513,7 +512,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine() b.push(DtoConstSize_t(static_cast(tc->dim->toUInteger()))); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -538,7 +537,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine() b.push_typeinfo(tc->getImpl()->type); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -554,7 +553,7 @@ void TypeInfoFunctionDeclaration::llvmDefine() // string deco b.push_string(tinfo->deco); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -573,7 +572,7 @@ void TypeInfoDelegateDeclaration::llvmDefine() // string deco b.push_string(tinfo->deco); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -591,7 +590,7 @@ void TypeInfoStructDeclaration::llvmDefine() // handle opaque structs if (!sd->members) { RTTIBuilder b(Type::typeinfostruct); - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); return; } @@ -603,7 +602,7 @@ void TypeInfoStructDeclaration::llvmDefine() } DtoResolveStruct(sd); - IrAggr* iraggr = sd->ir.irAggr; + IrAggr* iraggr = getIrAggr(sd); RTTIBuilder b(Type::typeinfostruct); @@ -692,7 +691,7 @@ void TypeInfoStructDeclaration::llvmDefine() b.push_size_as_vp(1); // has pointers // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -702,14 +701,13 @@ void TypeInfoClassDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) // For classes, the TypeInfo is in fact a ClassInfo instance and emitted // as a __ClassZ symbol. For interfaces, the __InterfaceZ symbol is // referenced as "info" member in a (normal) TypeInfo_Interface instance. - IrGlobal *irg = new IrGlobal(decl); - decl->ir.irGlobal = irg; + IrGlobal *irg = getIrGlobal(decl, true); assert(decl->tinfo->ty == Tclass); TypeClass *tc = static_cast(decl->tinfo); DtoResolveClass(tc->sym); - irg->value = tc->sym->ir.irAggr->getClassInfoSymbol(); + irg->value = getIrAggr(tc->sym)->getClassInfoSymbol(); irg->type = irg->value->getType()->getContainedType(0); if (!tc->sym->isInterfaceDeclaration()) @@ -742,7 +740,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine() b.push_classinfo(tc->sym); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -778,7 +776,7 @@ void TypeInfoTupleDeclaration::llvmDefine() b.push_array(arrC, dim, Type::dtypeinfo->type, NULL); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -792,7 +790,7 @@ void TypeInfoConstDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tinfo->mutableOf()->merge()); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -806,7 +804,7 @@ void TypeInfoInvariantDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tinfo->mutableOf()->merge()); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -820,7 +818,7 @@ void TypeInfoSharedDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tinfo->unSharedOf()->merge()); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -834,7 +832,7 @@ void TypeInfoWildDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tinfo->mutableOf()->merge()); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } /* ========================================================================= */ @@ -851,5 +849,5 @@ void TypeInfoVectorDeclaration::llvmDefine() // TypeInfo base b.push_typeinfo(tv->basetype); // finish - b.finalize(ir.irGlobal); + b.finalize(getIrGlobal(this)); } diff --git a/ir/iraggr.cpp b/ir/iraggr.cpp index 360a86c7bf..8eefe92c2e 100644 --- a/ir/iraggr.cpp +++ b/ir/iraggr.cpp @@ -18,6 +18,7 @@ #include "gen/logger.h" #include "gen/tollvm.h" #include "ir/iraggr.h" +#include "irdsymbol.h" #include "ir/irtypeclass.h" #include "ir/irtypestruct.h" #include @@ -376,3 +377,22 @@ void IrAggr::addFieldInitializers( } } } + +IrAggr *getIrAggr(AggregateDeclaration *decl, bool create) +{ + if (!isIrAggrCreated(decl) && create) + { + assert(decl->ir.irAggr == NULL); + decl->ir.irAggr = new IrAggr(decl); + decl->ir.m_type = IrDsymbol::AggrType; + } + assert(decl->ir.irAggr != NULL); + return decl->ir.irAggr; +} + +bool isIrAggrCreated(AggregateDeclaration *decl) +{ + int t = decl->ir.type(); + assert(t == IrDsymbol::AggrType || t == IrDsymbol::NotSet); + return t == IrDsymbol::AggrType; +} diff --git a/ir/iraggr.h b/ir/iraggr.h index e050eef837..0e05d4362c 100644 --- a/ir/iraggr.h +++ b/ir/iraggr.h @@ -150,4 +150,7 @@ private: ////////////////////////////////////////////////////////////////////////////// +IrAggr *getIrAggr(AggregateDeclaration *decl, bool create = false); +bool isIrAggrCreated(AggregateDeclaration *decl); + #endif diff --git a/ir/irclass.cpp b/ir/irclass.cpp index 35f5efdafc..a400ace662 100644 --- a/ir/irclass.cpp +++ b/ir/irclass.cpp @@ -185,8 +185,8 @@ LLConstant * IrAggr::getVtblInit() else { DtoResolveFunction(fd); - assert(fd->ir.irFunc && "invalid vtbl function"); - c = fd->ir.irFunc->func; + assert(isIrFuncCreated(fd) && "invalid vtbl function"); + c = getIrFunc(fd)->func; if (cd->isFuncHidden(fd)) { /* fd is hidden from the view of this class. * If fd overlaps with any function in the vtbl[], then @@ -321,9 +321,9 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance "null symbol in interface implementation vtable"); DtoResolveFunction(fd); - assert(fd->ir.irFunc && "invalid vtbl function"); + assert(isIrFuncCreated(fd) && "invalid vtbl function"); - LLFunction *fn = fd->ir.irFunc->func; + LLFunction *fn = getIrFunc(fd)->func; // If the base is a cpp interface, 'this' parameter is a pointer to // the interface not the underlying object as expected. Instead of @@ -445,7 +445,7 @@ LLConstant * IrAggr::getClassInfoInterfaces() IF_LOG Logger::println("Adding interface %s", it->base->toPrettyChars()); - IrAggr* irinter = it->base->ir.irAggr; + IrAggr* irinter = getIrAggr(it->base); assert(irinter && "interface has null IrStruct"); IrTypeClass* itc = stripModifiers(irinter->type)->irtype->isClass(); assert(itc && "null interface IrTypeClass"); diff --git a/ir/irdsymbol.cpp b/ir/irdsymbol.cpp index e27f86472d..b24ec4228c 100644 --- a/ir/irdsymbol.cpp +++ b/ir/irdsymbol.cpp @@ -22,7 +22,8 @@ void IrDsymbol::resetAll() (*it)->reset(); } -IrDsymbol::IrDsymbol() +IrDsymbol::IrDsymbol() : + m_type(NotSet) { list.push_back(this); reset(); @@ -31,12 +32,8 @@ IrDsymbol::IrDsymbol() IrDsymbol::IrDsymbol(const IrDsymbol& s) { list.push_back(this); - irModule = s.irModule; - irAggr = s.irAggr; - irFunc = s.irFunc; - irGlobal = s.irGlobal; - irLocal = s.irLocal; - irField = s.irField; + irData = s.irData; + m_type = s.m_type; resolved = s.resolved; declared = s.declared; initialized = s.initialized; @@ -58,24 +55,6 @@ IrDsymbol::~IrDsymbol() void IrDsymbol::reset() { - irModule = NULL; - irAggr = NULL; - irFunc = NULL; - irGlobal = NULL; - irLocal = NULL; - irField = NULL; + irData = NULL; resolved = declared = initialized = defined = false; } - -bool IrDsymbol::isSet() -{ - return irAggr || irFunc || irGlobal || irLocal || irField; -} - -IrVar* IrDsymbol::getIrVar() -{ - assert(irGlobal || irLocal || irField); - return irGlobal ? static_cast(irGlobal) : irLocal ? static_cast(irLocal) : static_cast(irField); -} - -llvm::Value*& IrDsymbol::getIrValue() { return getIrVar()->value; } diff --git a/ir/irdsymbol.h b/ir/irdsymbol.h index 632e17dad5..24b0fe4de5 100644 --- a/ir/irdsymbol.h +++ b/ir/irdsymbol.h @@ -25,6 +25,9 @@ struct IrParameter; struct IrField; struct IrVar; class Dsymbol; +class AggregateDeclaration; +class FuncDeclaration; +class VarDeclaration; class Module; namespace llvm { @@ -33,6 +36,18 @@ namespace llvm { struct IrDsymbol { + enum Type + { + NotSet, + ModuleType, + AggrType, + FuncType, + GlobalType, + LocalType, + ParamterType, + FieldType + }; + static std::vector list; static void resetAll(); @@ -44,24 +59,34 @@ struct IrDsymbol void reset(); - IrModule* irModule; - IrAggr* irAggr; - IrFunction* irFunc; - IrGlobal* irGlobal; - union { - IrLocal* irLocal; - IrParameter *irParam; - }; - IrField* irField; + Type type() const { return m_type; } + bool resolved; bool declared; bool initialized; bool defined; +private: + friend IrModule* getIrModule(Module *m); + friend IrAggr *getIrAggr(AggregateDeclaration *decl, bool create); + friend IrFunction *getIrFunc(FuncDeclaration *decl, bool create); + friend IrVar *getIrVar(VarDeclaration *decl); + friend IrGlobal *getIrGlobal(VarDeclaration *decl, bool create); + friend IrLocal *getIrLocal(VarDeclaration *decl, bool create); + friend IrParameter *getIrParameter(VarDeclaration *decl, bool create); + friend IrField *getIrField(VarDeclaration *decl, bool create); - IrVar* getIrVar(); - llvm::Value*& getIrValue(); - - bool isSet(); + Type m_type; + union { + void* irData; + IrModule* irModule; + IrAggr* irAggr; + IrFunction* irFunc; + IrVar* irVar; + IrGlobal* irGlobal; + IrLocal* irLocal; + IrParameter* irParam; + IrField* irField; + }; }; #endif diff --git a/ir/irfunction.cpp b/ir/irfunction.cpp index cc49a65e90..c16c7e3534 100644 --- a/ir/irfunction.cpp +++ b/ir/irfunction.cpp @@ -9,6 +9,7 @@ #include "gen/llvm.h" #include "gen/tollvm.h" +#include "ir/irdsymbol.h" #include "ir/irfunction.h" #include @@ -96,3 +97,22 @@ void IrFunction::setAlwaysInline() func->addFnAttr(llvm::Attribute::AlwaysInline); #endif } + +IrFunction *getIrFunc(FuncDeclaration *decl, bool create) +{ + if (!isIrFuncCreated(decl) && create) + { + assert(decl->ir.irFunc == NULL); + decl->ir.irFunc = new IrFunction(decl); + decl->ir.m_type = IrDsymbol::FuncType; + } + assert(decl->ir.irFunc != NULL); + return decl->ir.irFunc; +} + +bool isIrFuncCreated(FuncDeclaration *decl) +{ + int t = decl->ir.type(); + assert(t == IrDsymbol::FuncType || t == IrDsymbol::NotSet); + return t == IrDsymbol::FuncType; +} diff --git a/ir/irfunction.h b/ir/irfunction.h index 4b9ef9d70b..1a20d7bdfe 100644 --- a/ir/irfunction.h +++ b/ir/irfunction.h @@ -125,4 +125,7 @@ struct IrFunction std::stack diLexicalBlocks; }; +IrFunction *getIrFunc(FuncDeclaration *decl, bool create = false); +bool isIrFuncCreated(FuncDeclaration *decl); + #endif diff --git a/ir/irlandingpad.cpp b/ir/irlandingpad.cpp index de44b8cc39..60f894f578 100644 --- a/ir/irlandingpad.cpp +++ b/ir/irlandingpad.cpp @@ -56,17 +56,17 @@ void IRLandingPadCatchInfo::toIR() // use the same storage for all exceptions that are not accessed in // nested functions if (!catchStmt->var->nestedrefs.dim) { - assert(!catchStmt->var->ir.irLocal); - catchStmt->var->ir.irLocal = new IrLocal(catchStmt->var); + assert(!isIrLocalCreated(catchStmt->var)); + IrLocal *irLocal = getIrLocal(catchStmt->var, true); LLValue* catch_var = gIR->func()->gen->landingPadInfo.getExceptionStorage(); - catchStmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchStmt->var->type))); + irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchStmt->var->type))); } else { // this will alloca if we haven't already and take care of nested refs DtoDeclarationExp(catchStmt->var); // the exception will only be stored in catch_var. copy it over if necessary LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->gen->landingPadInfo.getExceptionStorage()), DtoType(catchStmt->var->type)); - DtoStore(exc, catchStmt->var->ir.irLocal->value); + DtoStore(exc, getIrLocal(catchStmt->var)->value); } } @@ -194,7 +194,7 @@ void IRLandingPad::constructLandingPad(IRLandingPadScope scope) // create next block llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend()); // get class info symbol - LLValue *classInfo = catchItr->catchType->ir.irAggr->getClassInfoSymbol(); + LLValue *classInfo = getIrAggr(catchItr->catchType)->getClassInfoSymbol(); // add that symbol as landing pad clause landingPad->addClause(llvm::cast(classInfo)); // call llvm.eh.typeid.for to get class info index in the exception table diff --git a/ir/irmodule.cpp b/ir/irmodule.cpp index eab29ff84c..bd514c979a 100644 --- a/ir/irmodule.cpp +++ b/ir/irmodule.cpp @@ -7,9 +7,11 @@ // //===----------------------------------------------------------------------===// +#include "module.h" #include "gen/llvm.h" #include "gen/irstate.h" #include "gen/tollvm.h" +#include "ir/irdsymbol.h" #include "ir/irmodule.h" IrModule::IrModule(Module* module, const char* srcfilename) @@ -24,3 +26,17 @@ IrModule::IrModule(Module* module, const char* srcfilename) IrModule::~IrModule() { } + +IrModule *getIrModule(Module *m) +{ + if (m == NULL) + m = gIR->func()->decl->getModule(); + assert(m && "null module"); + if (m->ir.m_type == IrDsymbol::NotSet) + { + m->ir.irModule = new IrModule(m, m->srcfile->toChars()); + m->ir.m_type = IrDsymbol::ModuleType; + } + assert(m->ir.m_type == IrDsymbol::ModuleType); + return m->ir.irModule; +} diff --git a/ir/irmodule.h b/ir/irmodule.h index 1991db387d..3e0fbc79a8 100644 --- a/ir/irmodule.h +++ b/ir/irmodule.h @@ -31,4 +31,6 @@ struct IrModule llvm::GlobalVariable* fileName; }; +IrModule *getIrModule(Module *m); + #endif diff --git a/ir/irvar.cpp b/ir/irvar.cpp index 98caaeed3d..cc3a039022 100644 --- a/ir/irvar.cpp +++ b/ir/irvar.cpp @@ -10,6 +10,7 @@ #include "gen/llvm.h" #include "declaration.h" #include "gen/irstate.h" +#include "ir/irdsymbol.h" #include "ir/irvar.h" ////////////////////////////////////////////////////////////////////////////// @@ -18,9 +19,6 @@ IrField::IrField(VarDeclaration* v) : IrVar(v) { - assert(V->ir.irField == NULL && "field for this variable already exists"); - V->ir.irField = this; - if (v->aggrIndex) { index = v->aggrIndex; @@ -46,3 +44,109 @@ llvm::Constant* IrField::getDefaultInit() ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// + +IrVar *getIrVar(VarDeclaration *decl) +{ + assert(isIrVarCreated(decl)); + assert(decl->ir.irVar != NULL); + return decl->ir.irVar; +} + +llvm::Value *getIrValue(VarDeclaration *decl) +{ + return getIrVar(decl)->value; +} + +bool isIrVarCreated(VarDeclaration *decl) +{ + int t = decl->ir.type(); + bool isIrVar = t == IrDsymbol::GlobalType || + t == IrDsymbol::LocalType || + t == IrDsymbol::ParamterType || + t == IrDsymbol::FieldType; + assert(isIrVar || t == IrDsymbol::NotSet); + return isIrVar; +} + +////////////////////////////////////////////////////////////////////////////// + +IrGlobal *getIrGlobal(VarDeclaration *decl, bool create) +{ + if (!isIrGlobalCreated(decl) && create) + { + assert(decl->ir.irGlobal == NULL); + decl->ir.irGlobal = new IrGlobal(decl); + decl->ir.m_type = IrDsymbol::GlobalType; + } + assert(decl->ir.irGlobal != NULL); + return decl->ir.irGlobal; +} + +bool isIrGlobalCreated(VarDeclaration *decl) +{ + int t = decl->ir.type(); + assert(t == IrDsymbol::GlobalType || t == IrDsymbol::NotSet); + return t == IrDsymbol::GlobalType; +} + +////////////////////////////////////////////////////////////////////////////// + +IrLocal *getIrLocal(VarDeclaration *decl, bool create) +{ + if (!isIrLocalCreated(decl) && create) + { + assert(decl->ir.irLocal == NULL); + decl->ir.irLocal = new IrLocal(decl); + decl->ir.m_type = IrDsymbol::LocalType; + } + assert(decl->ir.irLocal != NULL); + return decl->ir.irLocal; +} + +bool isIrLocalCreated(VarDeclaration *decl) +{ + int t = decl->ir.type(); + assert(t == IrDsymbol::LocalType || t == IrDsymbol::ParamterType || t == IrDsymbol::NotSet); + return t == IrDsymbol::LocalType || t == IrDsymbol::ParamterType; +} + +////////////////////////////////////////////////////////////////////////////// + +IrParameter *getIrParameter(VarDeclaration *decl, bool create) +{ + if (!isIrParameterCreated(decl) && create) + { + assert(decl->ir.irParam == NULL); + decl->ir.irParam = new IrParameter(decl); + decl->ir.m_type = IrDsymbol::ParamterType; + } + return decl->ir.irParam; +} + +bool isIrParameterCreated(VarDeclaration *decl) +{ + int t = decl->ir.type(); + assert(t == IrDsymbol::ParamterType || t == IrDsymbol::NotSet); + return t == IrDsymbol::ParamterType; +} + +////////////////////////////////////////////////////////////////////////////// + +IrField *getIrField(VarDeclaration *decl, bool create) +{ + if (!isIrFieldCreated(decl) && create) + { + assert(decl->ir.irField == NULL); + decl->ir.irField = new IrField(decl); + decl->ir.m_type = IrDsymbol::FieldType; + } + assert(decl->ir.irField != NULL); + return decl->ir.irField; +} + +bool isIrFieldCreated(VarDeclaration *decl) +{ + int t = decl->ir.type(); + assert(t == IrDsymbol::FieldType || t == IrDsymbol::NotSet); + return t == IrDsymbol::FieldType; +} diff --git a/ir/irvar.h b/ir/irvar.h index 256775d7f7..e25745d60a 100644 --- a/ir/irvar.h +++ b/ir/irvar.h @@ -91,4 +91,20 @@ protected: llvm::Constant* constInit; }; +IrVar *getIrVar(VarDeclaration *decl); +llvm::Value *getIrValue(VarDeclaration *decl); +bool isIrVarCreated(VarDeclaration *decl); + +IrGlobal *getIrGlobal(VarDeclaration *decl, bool create = false); +bool isIrGlobalCreated(VarDeclaration *decl); + +IrLocal *getIrLocal(VarDeclaration *decl, bool create = false); +bool isIrLocalCreated(VarDeclaration *decl); + +IrParameter *getIrParameter(VarDeclaration *decl, bool create = false); +bool isIrParameterCreated(VarDeclaration *decl); + +IrField *getIrField(VarDeclaration *decl, bool create = false); +bool isIrFieldCreated(VarDeclaration *decl); + #endif