Make IrDsymbol to be a typesafe union to reduce memory usage

This commit is contained in:
Alexey Prokhin 2014-09-12 00:17:18 +04:00
parent 5b15095c81
commit 18f33b1815
27 changed files with 465 additions and 293 deletions

View file

@ -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,12 +60,12 @@ 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
if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0)
@ -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<TypeClass*>(_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<TypeClass*>(_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<TypeClass*>(cd->type);
IrAggr* ir = cd->ir.irAggr;
assert(ir);
IrAggr* ir = getIrAggr(cd);
ClassDeclaration* cinfo = Type::typeinfoclass;
if (cinfo->fields.dim != 12)

View file

@ -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 <name>__classZ for classes in D2.
@ -227,8 +229,8 @@ public:
"manifest constant being codegen'd!");
#endif
llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(
decl->ir.irGlobal->value);
IrGlobal *irGlobal = getIrGlobal(decl);
llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(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);

View file

@ -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<llvm::MDNode *>(fd->ir.irFunc->diSubprogram) != 0);
assert(static_cast<llvm::MDNode *>(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<llvm::MDNode *>(fd->ir.irFunc->diSubprogram) != 0);
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
}
void ldc::DIBuilder::EmitBlockStart(Loc& loc)

View file

@ -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.

View file

@ -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<TypeFunction*>(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<TypeFunction*>(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

View file

@ -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<llvm::AllocaInst>(vd->ir.getIrValue()))
llvm::isa<llvm::AllocaInst>(getIrValue(vd)))
{
return new DVarValue(type, vd, vd->ir.getIrValue());
return new DVarValue(type, vd, getIrValue(vd));
}
else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue()))
else if (llvm::isa<llvm::Argument>(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<LLConstant>(vd->ir.getIrValue());
LLConstant* llc = llvm::dyn_cast<LLConstant>(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.");

View file

@ -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);

View file

@ -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<LLType*> argsTy;
@ -207,7 +207,7 @@ static llvm::Function* build_module_function(const std::string &name, const std:
// Call ctor's
typedef std::list<FuncDeclaration*>::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<VarDeclaration*>::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?

View file

@ -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

View file

@ -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<LLValue*, 2> addr;
gIR->DBuilder.OpOffset(addr, frameType, vd->ir.irLocal->nestedIndex);
gIR->DBuilder.OpOffset(addr, frameType, irLocal->nestedIndex);
gIR->DBuilder.EmitLocalVariable(frame, vd, addr);
}
}

View file

@ -26,7 +26,7 @@ RTTIBuilder::RTTIBuilder(AggregateDeclaration* base_class)
base = base_class;
basetype = static_cast<TypeClass*>(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);

View file

@ -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);

View file

@ -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

View file

@ -205,7 +205,7 @@ LLConstant* VarExp::toConstElem(IRState* p)
assert(sdecltype->ty == Tstruct);
TypeStruct* ts = static_cast<TypeStruct*>(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<VarExp*>(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<TypeStruct*>(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))
{

View file

@ -307,7 +307,7 @@ static void emitTypeMetadata(TypeInfoDeclaration *tid)
if (!meta) {
// Construct the fields
MDNodeField* mdVals[TD_NumFields];
mdVals[TD_TypeInfo] = llvm::cast<MDNodeField>(tid->ir.irGlobal->value);
mdVals[TD_TypeInfo] = llvm::cast<MDNodeField>(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<size_t>(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<TypeClass *>(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));
}

View file

@ -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 <algorithm>
@ -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;
}

View file

@ -150,4 +150,7 @@ private:
//////////////////////////////////////////////////////////////////////////////
IrAggr *getIrAggr(AggregateDeclaration *decl, bool create = false);
bool isIrAggrCreated(AggregateDeclaration *decl);
#endif

View file

@ -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");

View file

@ -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<IrVar*>(irGlobal) : irLocal ? static_cast<IrVar*>(irLocal) : static_cast<IrVar*>(irField);
}
llvm::Value*& IrDsymbol::getIrValue() { return getIrVar()->value; }

View file

@ -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<IrDsymbol*> 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

View file

@ -9,6 +9,7 @@
#include "gen/llvm.h"
#include "gen/tollvm.h"
#include "ir/irdsymbol.h"
#include "ir/irfunction.h"
#include <sstream>
@ -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;
}

View file

@ -125,4 +125,7 @@ struct IrFunction
std::stack<llvm::DILexicalBlock> diLexicalBlocks;
};
IrFunction *getIrFunc(FuncDeclaration *decl, bool create = false);
bool isIrFuncCreated(FuncDeclaration *decl);
#endif

View file

@ -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<llvm::Constant>(classInfo));
// call llvm.eh.typeid.for to get class info index in the exception table

View file

@ -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;
}

View file

@ -31,4 +31,6 @@ struct IrModule
llvm::GlobalVariable* fileName;
};
IrModule *getIrModule(Module *m);
#endif

View file

@ -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;
}

View file

@ -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