Add an option to change the way nested variables are handled.

Only one value is implemented, which is the old way.
This commit is contained in:
Frits van Bommel 2009-04-12 16:22:21 +02:00
parent b5af30636e
commit 8820024070

View file

@ -6,6 +6,42 @@
#include "gen/logger.h"
#include "gen/tollvm.h"
#include "llvm/Support/CommandLine.h"
namespace cl = llvm::cl;
/// What the context pointer for a nested function looks like
enum NestedCtxType {
/// Context is void*[] of pointers to variables.
/// Variables from higher levels are at the front.
NCArray,
/// Context is a struct containing variables belonging to the parent function.
/// If the parent function itself has a parent function, one of the members is
/// a pointer to its context. (linked-list style)
// FIXME: implement
// TODO: Functions without any variables accessed by nested functions, but
// with a parent whose variables are accessed, can use the parent's
// context.
NCStruct,
/// Context is an array of pointers to nested contexts. Each function with variables
/// accessed by nested functions puts them in a struct, and appends a pointer to that
/// struct to the array.
// FIXME: implement
NCHybrid
};
static cl::opt<NestedCtxType> nestedCtx("nested-ctx",
cl::desc("How to construct a nested function's context:"),
cl::ZeroOrMore,
cl::values(
clEnumValN(NCArray, "array", "Array of pointers to variables (including multi-level)"),
//clEnumValN(NCStruct, "struct", "Struct of variables (with multi-level via linked list)"),
//clEnumValN(NCHybrid, "hybrid", "Array of pointers to structs of variables"),
clEnumValEnd),
cl::init(NCArray));
/****************************************************************************************/
/*////////////////////////////////////////////////////////////////////////////////////////
// NESTED VARIABLE HELPERS
@ -13,6 +49,9 @@
DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
{
////////////////////////////////////
// Locate context value
Dsymbol* vdparent = vd->toParent2();
assert(vdparent);
@ -25,7 +64,7 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
return new DVarValue(astype, vd, val);
}
// get it from the nested context
// get the nested context
LLValue* ctx = 0;
if (irfunc->decl->isMember2())
{
@ -38,6 +77,11 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
assert(ctx);
assert(vd->ir.irLocal);
////////////////////////////////////
// Extract variable from nested context
if (nestedCtx == NCArray) {
LLValue* val = DtoBitCast(ctx, getPtrToType(getVoidPtrType()));
val = DtoGEPi1(val, vd->ir.irLocal->nestedIndex);
val = DtoLoad(val);
@ -45,9 +89,14 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars());
return new DVarValue(astype, vd, val);
}
else {
assert(0 && "Not implemented yet");
}
}
void DtoNestedInit(VarDeclaration* vd)
{
if (nestedCtx == NCArray) {
// alloca as usual if no value already
if (!vd->ir.irLocal->value)
vd->ir.irLocal->value = DtoAlloca(DtoType(vd->type), vd->toChars());
@ -61,6 +110,10 @@ void DtoNestedInit(VarDeclaration* vd)
DtoStore(val, gep);
}
else {
assert(0 && "Not implemented yet");
}
}
LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
{
@ -92,6 +145,7 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
}
void DtoCreateNestedContext(FuncDeclaration* fd) {
if (nestedCtx == NCArray) {
// construct nested variables array
if (!fd->nestedVars.empty())
{
@ -177,10 +231,11 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
// fixup nested result variable
#if DMDV2
if (fd->vresult && fd->vresult->nestedrefs.dim) {
if (fd->vresult && fd->vresult->nestedrefs.dim)
#else
if (fd->vresult && fd->vresult->nestedref) {
if (fd->vresult && fd->vresult->nestedref)
#endif
{
Logger::println("nested vresult value: %s", fd->vresult->toChars());
LLValue* gep = DtoGEPi(nestedVars, 0, fd->vresult->ir.irLocal->nestedIndex);
LLValue* val = DtoBitCast(fd->vresult->ir.irLocal->value, getVoidPtrType());
@ -188,3 +243,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
}
}
}
else {
assert(0 && "Not implemented yet");
}
}