mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 14:40:40 +03:00
Make IrDsymbol to be a typesafe union to reduce memory usage
This commit is contained in:
parent
5b15095c81
commit
18f33b1815
27 changed files with 465 additions and 293 deletions
|
@ -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.");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue