annotate gen/nested.cpp @ 1212:df2227fdc860

For the outermost function needing a context frame, use the address of that frame as the nest argument instead of the address of a single-element list containing only that frame address. This saves some stack space and reduces memory accesses.
author Frits van Bommel <fvbommel wxs.nl>
date Mon, 13 Apr 2009 04:09:08 +0200
parents 3d4581761b4c
children 9430d4959ab4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
1 #include "gen/nested.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
2
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
3 #include "gen/dvalue.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
4 #include "gen/irstate.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
5 #include "gen/llvmhelpers.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
6 #include "gen/logger.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
7 #include "gen/tollvm.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
8
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
9 #include "llvm/Support/CommandLine.h"
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
10 namespace cl = llvm::cl;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
11
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
12 /// What the context pointer for a nested function looks like
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
13 enum NestedCtxType {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
14 /// Context is void*[] of pointers to variables.
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
15 /// Variables from higher levels are at the front.
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
16 NCArray,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
17
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
18 /// Context is a struct containing variables belonging to the parent function.
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
19 /// If the parent function itself has a parent function, one of the members is
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
20 /// a pointer to its context. (linked-list style)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
21 // FIXME: implement
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
22 // TODO: Functions without any variables accessed by nested functions, but
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
23 // with a parent whose variables are accessed, can use the parent's
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
24 // context.
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
25 // NOTE: This is what DMD seems to do.
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
26 NCStruct,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
27
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
28 /// Context is a list of pointers to structs. Each function with variables
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
29 /// accessed by nested functions puts them in a struct, and appends a
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
30 /// pointer to that struct to it's local copy of the list.
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
31 /// As an additional optimization, if the list has length one it's not
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
32 /// generated; the only element is used directly instead.
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
33 NCHybrid
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
34 };
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
35
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
36 static cl::opt<NestedCtxType> nestedCtx("nested-ctx",
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
37 cl::desc("How to construct a nested function's context:"),
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
38 cl::ZeroOrMore,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
39 cl::values(
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
40 clEnumValN(NCArray, "array", "Array of pointers to variables (including multi-level)"),
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
41 //clEnumValN(NCStruct, "struct", "Struct of variables (with multi-level via linked list)"),
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
42 clEnumValN(NCHybrid, "hybrid", "List of pointers to structs of variables, one per level."),
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
43 clEnumValEnd),
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
44 cl::init(NCHybrid));
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
45
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
46
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
47 /****************************************************************************************/
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
48 /*////////////////////////////////////////////////////////////////////////////////////////
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
49 // NESTED VARIABLE HELPERS
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
50 ////////////////////////////////////////////////////////////////////////////////////////*/
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
51
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
52 static FuncDeclaration* getParentFunc(Dsymbol* sym) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
53 Dsymbol* parent = sym->parent;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
54 assert(parent);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
55 while (parent && !parent->isFuncDeclaration())
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
56 parent = parent->parent;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
57
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
58 return (parent ? parent->isFuncDeclaration() : NULL);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
59 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
60
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
61 DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
62 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
63 Logger::println("DtoNestedVariable for %s @ %s", vd->toChars(), loc.toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
64 LOG_SCOPE;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
65
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
66 ////////////////////////////////////
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
67 // Locate context value
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
68
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
69 Dsymbol* vdparent = vd->toParent2();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
70 assert(vdparent);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
71
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
72 IrFunction* irfunc = gIR->func();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
73
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
74 // is the nested variable in this scope?
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
75 if (vdparent == irfunc->decl)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
76 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
77 LLValue* val = vd->ir.getIrValue();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
78 return new DVarValue(astype, vd, val);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
79 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
80
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
81 // get the nested context
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
82 LLValue* ctx = 0;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
83 if (irfunc->decl->isMember2())
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
84 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
85 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
86 LLValue* val = DtoLoad(irfunc->thisArg);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
87 ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
88 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
89 else
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
90 ctx = irfunc->nestArg;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
91 assert(ctx);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
92
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
93 assert(vd->ir.irLocal);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
94
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
95 ////////////////////////////////////
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
96 // Extract variable from nested context
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
97
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
98 if (nestedCtx == NCArray) {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
99 LLValue* val = DtoBitCast(ctx, getPtrToType(getVoidPtrType()));
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
100 val = DtoGEPi1(val, vd->ir.irLocal->nestedIndex);
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
101 val = DtoAlignedLoad(val);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
102 assert(vd->ir.irLocal->value);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
103 val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
104 return new DVarValue(astype, vd, val);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
105 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
106 else if (nestedCtx == NCHybrid) {
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
107 FuncDeclaration* parentfunc = getParentFunc(irfunc->decl);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
108 assert(parentfunc && "No parent function for nested function?");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
109 Logger::println("Parent function: %s", parentfunc->toChars());
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
110
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
111 LLValue* val = DtoBitCast(ctx, LLPointerType::getUnqual(parentfunc->ir.irFunc->framesType));
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
112 Logger::cout() << "Context: " << *val << '\n';
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
113
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
114 if (!parentfunc->ir.irFunc->elidedCtxList) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
115 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
116 val = DtoAlignedLoad(val, (std::string(".frame.") + vdparent->toChars()).c_str());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
117 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
118 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
119 if (vd->ir.irLocal->byref)
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
120 val = DtoAlignedLoad(val);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
121 return new DVarValue(astype, vd, val);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
122 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
123 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
124 assert(0 && "Not implemented yet");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
125 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
126 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
127
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
128 void DtoNestedInit(VarDeclaration* vd)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
129 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
130 Logger::println("DtoNestedInit for %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
131 LOG_SCOPE
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
132
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
133 IrFunction* irfunc = gIR->func()->decl->ir.irFunc;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
134 LLValue* nestedVar = irfunc->nestedVar;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
135
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
136 if (nestedCtx == NCArray) {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
137 // alloca as usual if no value already
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
138 if (!vd->ir.irLocal->value)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
139 vd->ir.irLocal->value = DtoAlloca(DtoType(vd->type), vd->toChars());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
140
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
141 // store the address into the nested vars array
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
142 assert(vd->ir.irLocal->nestedIndex >= 0);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
143 LLValue* gep = DtoGEPi(nestedVar, 0, vd->ir.irLocal->nestedIndex);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
144
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
145 assert(isaPointer(vd->ir.irLocal->value));
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
146 LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
147
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
148 DtoAlignedStore(val, gep);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
149 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
150 else if (nestedCtx == NCHybrid) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
151 assert(vd->ir.irLocal->value && "Nested variable without storage?");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
152 if (!vd->isParameter() && (vd->isRef() || vd->isOut())) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
153 Logger::println("Initializing non-parameter byref value");
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
154 LLValue* frame;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
155 if (!irfunc->elidedCtxList) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
156 LLValue* framep = DtoGEPi(nestedVar, 0, vd->ir.irLocal->nestedDepth);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
157
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
158 FuncDeclaration *parentfunc = getParentFunc(vd);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
159 assert(parentfunc && "No parent function for nested variable?");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
160 frame = DtoAlignedLoad(framep, (std::string(".frame.") + parentfunc->toChars()).c_str());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
161 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
162 frame = nestedVar;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
163 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
164 LLValue* slot = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex);
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
165 DtoAlignedStore(vd->ir.irLocal->value, slot);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
166 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
167 // Already initialized in DtoCreateNestedContext
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
168 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
169 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
170 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
171 assert(0 && "Not implemented yet");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
172 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
173 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
174
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
175 LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
176 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
177 Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
178 LOG_SCOPE;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
179
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
180 IrFunction* irfunc = gIR->func();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
181
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
182 // if this func has its own vars that are accessed by nested funcs
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
183 // use its own context
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
184 if (irfunc->nestedVar)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
185 return irfunc->nestedVar;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
186 // otherwise, it may have gotten a context from the caller
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
187 else if (irfunc->nestArg)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
188 return irfunc->nestArg;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
189 // or just have a this argument
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
190 else if (irfunc->thisArg)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
191 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
192 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
193 if (!cd || !cd->vthis)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
194 return getNullPtr(getVoidPtrType());
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
195 LLValue* val = DtoLoad(irfunc->thisArg);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
196 return DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
197 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
198 else
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
199 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
200 return getNullPtr(getVoidPtrType());
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
201 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
202 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
203
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
204 void DtoCreateNestedContext(FuncDeclaration* fd) {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
205 Logger::println("DtoCreateNestedContext for %s", fd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
206 LOG_SCOPE
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
207
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
208 if (nestedCtx == NCArray) {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
209 // construct nested variables array
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
210 if (!fd->nestedVars.empty())
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
211 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
212 Logger::println("has nested frame");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
213 // start with adding all enclosing parent frames until a static parent is reached
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
214 int nparelems = 0;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
215 if (!fd->isStatic())
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
216 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
217 Dsymbol* par = fd->toParent2();
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
218 while (par)
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
219 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
220 if (FuncDeclaration* parfd = par->isFuncDeclaration())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
221 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
222 nparelems += parfd->nestedVars.size();
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
223 // stop at first static
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
224 if (parfd->isStatic())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
225 break;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
226 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
227 else if (ClassDeclaration* parcd = par->isClassDeclaration())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
228 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
229 // nothing needed
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
230 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
231 else
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
232 {
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
233 break;
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
234 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
235
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
236 par = par->toParent2();
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
237 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
238 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
239 int nelems = fd->nestedVars.size() + nparelems;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
240
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
241 // make array type for nested vars
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
242 const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
243
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
244 // alloca it
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
245 LLValue* nestedVars = DtoAlloca(nestedVarsTy, ".nested_vars");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
246
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
247 IrFunction* irfunction = fd->ir.irFunc;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
248
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
249 // copy parent frame into beginning
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
250 if (nparelems)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
251 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
252 LLValue* src = irfunction->nestArg;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
253 if (!src)
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
254 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
255 assert(irfunction->thisArg);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
256 assert(fd->isMember2());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
257 LLValue* thisval = DtoLoad(irfunction->thisArg);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
258 ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
259 assert(cd);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
260 assert(cd->vthis);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
261 src = DtoLoad(DtoGEPi(thisval, 0,cd->vthis->ir.irField->index, ".vthis"));
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
262 }
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
263 DtoMemCpy(nestedVars, src, DtoConstSize_t(nparelems*PTRSIZE),
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
264 getABITypeAlign(getVoidPtrType()));
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
265 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
266
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
267 // store in IrFunction
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
268 irfunction->nestedVar = nestedVars;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
269
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
270 // go through all nested vars and assign indices
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
271 int idx = nparelems;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
272 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
273 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
274 VarDeclaration* vd = *i;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
275 if (!vd->ir.irLocal)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
276 vd->ir.irLocal = new IrLocal(vd);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
277
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
278 if (vd->isParameter())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
279 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
280 Logger::println("nested param: %s", vd->toChars());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
281 LLValue* gep = DtoGEPi(nestedVars, 0, idx);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
282 LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
283 DtoAlignedStore(val, gep);
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
284 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
285 else
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
286 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
287 Logger::println("nested var: %s", vd->toChars());
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
288 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
289
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
290 vd->ir.irLocal->nestedIndex = idx++;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
291 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
292 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
293 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
294 else if (nestedCtx == NCHybrid) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
295 // construct nested variables array
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
296 if (!fd->nestedVars.empty())
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
297 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
298 Logger::println("has nested frame");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
299 // start with adding all enclosing parent frames until a static parent is reached
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
300 typedef std::vector<const LLType*> TypeVec;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
301 TypeVec frametypes;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
302 if (!fd->isStatic()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
303 Dsymbol* par = fd->toParent2();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
304 while (par) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
305 if (FuncDeclaration* parfd = par->isFuncDeclaration()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
306 // skip functions without nested parameters
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
307 if (!parfd->nestedVars.empty()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
308 const LLStructType* parft = parfd->ir.irFunc->framesType;
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
309 if (parfd->ir.irFunc->elidedCtxList) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
310 // This is the outermost function with a nested context.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
311 // Its context is not a list of frames, but just the frame itself.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
312 frametypes.push_back(LLPointerType::getUnqual(parft));
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
313 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
314 // Copy the types of parent function frames.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
315 frametypes.insert(frametypes.begin(), parft->element_begin(), parft->element_end());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
316 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
317 break; // That's all the info needed.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
318 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
319 } else if (ClassDeclaration* parcd = par->isClassDeclaration()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
320 // skip
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
321 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
322 break;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
323 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
324 par = par->toParent2();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
325 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
326 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
327 unsigned depth = frametypes.size();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
328
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
329 if (Logger::enabled()) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
330 Logger::println("Frame types: ");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
331 LOG_SCOPE;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
332 for (TypeVec::iterator i=frametypes.begin(); i!=frametypes.end(); ++i)
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
333 Logger::cout() << **i << '\n';
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
334 }
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
335
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
336 // Construct a struct for the direct nested variables of this function, and update their indices to match.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
337 // TODO: optimize ordering for minimal space usage?
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
338 TypeVec types;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
339 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
340 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
341 VarDeclaration* vd = *i;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
342 if (!vd->ir.irLocal)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
343 vd->ir.irLocal = new IrLocal(vd);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
344
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
345 vd->ir.irLocal->nestedDepth = depth;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
346 vd->ir.irLocal->nestedIndex = types.size();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
347 if (vd->isParameter()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
348 // Parameters already have storage associated with them (to handle byref etc.),
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
349 // so handle specially for now by storing a pointer instead of a value.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
350 assert(vd->ir.irLocal->value);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
351 // FIXME: don't do this for normal parameters?
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
352 types.push_back(vd->ir.irLocal->value->getType());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
353 } else if (vd->isRef() || vd->isOut()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
354 // Foreach variables can also be by reference, for instance.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
355 types.push_back(DtoType(vd->type->pointerTo()));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
356 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
357 types.push_back(DtoType(vd->type));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
358 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
359 if (Logger::enabled()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
360 Logger::println("Nested var: %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
361 Logger::cout() << "of type: " << *types.back() << '\n';
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
362 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
363 }
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
364
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
365 // Append current frame type to frame type list
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
366 const LLStructType* frameType = LLStructType::get(types);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
367 const LLStructType* nestedVarsTy = NULL;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
368 if (!frametypes.empty()) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
369 assert(depth > 0);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
370 frametypes.push_back(LLPointerType::getUnqual(frameType));
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
371
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
372 // make struct type for nested frame list
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
373 nestedVarsTy = LLStructType::get(frametypes);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
374 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
375 assert(depth == 0);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
376 // For the outer function, just use the frame as the context
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
377 // instead of alloca'ing a single-element framelist and passing
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
378 // a pointer to that.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
379 nestedVarsTy = frameType;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
380 fd->ir.irFunc->elidedCtxList = true;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
381 }
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
382
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
383 Logger::cout() << "nestedVarsTy = " << *nestedVarsTy << '\n';
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
384
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
385 // Store type in IrFunction
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
386 IrFunction* irfunction = fd->ir.irFunc;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
387 irfunction->framesType = nestedVarsTy;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
388
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
389 LLValue* nestedVars = NULL;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
390
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
391 // Create frame for current function and append to frames list
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
392 // FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
393 LLValue* frame = DtoAlloca(frameType, ".frame");
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
394
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
395 // copy parent frames into beginning
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
396 if (depth != 0)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
397 {
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
398 // alloca frame list first
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
399 nestedVars = DtoAlloca(nestedVarsTy, ".frame_list");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
400
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
401 LLValue* src = irfunction->nestArg;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
402 if (!src)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
403 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
404 assert(irfunction->thisArg);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
405 assert(fd->isMember2());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
406 LLValue* thisval = DtoLoad(irfunction->thisArg);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
407 ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
408 assert(cd);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
409 assert(cd->vthis);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
410 Logger::println("Indexing to 'this'");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
411 src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis"));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
412 }
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
413 if (depth == 1) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
414 // Just copy nestArg into framelist; the outer frame is not a list of pointers
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
415 // but a direct pointer.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
416 src = DtoBitCast(src, frametypes[0]);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
417 LLValue* gep = DtoGEPi(nestedVars, 0, 0);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
418 DtoAlignedStore(src, gep);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
419 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
420 src = DtoBitCast(src, getVoidPtrType());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
421 LLValue* dst = DtoBitCast(nestedVars, getVoidPtrType());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
422 DtoMemCpy(dst, src, DtoConstSize_t(depth * PTRSIZE),
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
423 getABITypeAlign(getVoidPtrType()));
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
424 }
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
425 // store current frame in list
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
426 DtoAlignedStore(frame, DtoGEPi(nestedVars, 0, depth));
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
427 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
428 // Use frame as context directly
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
429 nestedVars = frame;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
430 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
431
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
432 // store context in IrFunction
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
433 irfunction->nestedVar = nestedVars;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
434
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
435 // go through all nested vars and assign addresses where possible.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
436 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
437 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
438 VarDeclaration* vd = *i;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
439
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
440 LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
441 if (vd->isParameter()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
442 Logger::println("nested param: %s", vd->toChars());
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
443 DtoAlignedStore(vd->ir.irLocal->value, gep);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
444 vd->ir.irLocal->byref = true;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
445 } else if (vd->isRef() || vd->isOut()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
446 // This slot is initialized in DtoNestedInit, to handle things like byref foreach variables
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
447 // which move around in memory.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
448 vd->ir.irLocal->byref = true;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
449 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
450 Logger::println("nested var: %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
451 if (vd->ir.irLocal->value)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
452 Logger::cout() << "Pre-existing value: " << *vd->ir.irLocal->value << '\n';
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
453 assert(!vd->ir.irLocal->value);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
454 vd->ir.irLocal->value = gep;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
455 vd->ir.irLocal->byref = false;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
456 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
457 }
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
458 } else if (FuncDeclaration* parFunc = getParentFunc(fd)) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
459 // Propagate context arg properties if the context arg is passed on unmodified.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
460 fd->ir.irFunc->framesType = parFunc->ir.irFunc->framesType;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
461 fd->ir.irFunc->elidedCtxList = parFunc->ir.irFunc->elidedCtxList;
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
462 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
463 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
464 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
465 assert(0 && "Not implemented yet");
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
466 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
467 }