annotate gen/nested.cpp @ 1638:0de4525a9ed6

Apply workaround for #395 by klickverbot.
author Christian Kamm <kamm incasoftware de>
date Mon, 08 Mar 2010 20:06:08 +0100
parents 755abafbf25d
children
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"
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
8 #include "gen/functions.h"
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
9
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
10 #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
11 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
12
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
13 /// 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
14 enum NestedCtxType {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
15 /// 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
16 /// 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
17 NCArray,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
18
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
19 /// 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
20 /// 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
21 /// 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
22 // FIXME: implement
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
23 // 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
24 // 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
25 // context.
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
26 // 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
27 NCStruct,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
28
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
29 /// Context is a list of pointers to structs of variables, followed by the
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
30 /// variables of the inner-most function with variables accessed by nested
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
31 /// functions. The initial pointers point to similar structs for enclosing
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
32 /// functions.
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
33 /// Only functions whose variables are accessed by nested functions create
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
34 /// new frames, others just pass on what got passed in.
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
35 NCHybrid
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
36 };
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
37
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
38 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
39 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
40 cl::ZeroOrMore,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
41 cl::values(
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
42 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
43 //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
44 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
45 clEnumValEnd),
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
46 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
47
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
48
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
49 /****************************************************************************************/
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 // 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
52 ////////////////////////////////////////////////////////////////////////////////////////*/
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
53
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
54 static FuncDeclaration* getParentFunc(Dsymbol* sym, bool stopOnStatic) {
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
55 if (!sym)
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
56 return NULL;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
57 Dsymbol* parent = sym->parent;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
58 assert(parent);
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
59 while (parent && !parent->isFuncDeclaration()) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
60 if (stopOnStatic) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
61 Declaration* decl = sym->isDeclaration();
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
62 if (decl && decl->isStatic())
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
63 return NULL;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
64 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
65 parent = parent->parent;
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
66 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
67
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
68 return (parent ? parent->isFuncDeclaration() : NULL);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
69 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
70
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
71 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
72 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
73 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
74 LOG_SCOPE;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
75
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
76 ////////////////////////////////////
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
77 // 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
78
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
79 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
80 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
81
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 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
83
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 // 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
85 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
86 {
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 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
88 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
89 }
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
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
91 // 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
92 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
93 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
94 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
95 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
96 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
97 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
98 }
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
99 else if (irfunc->nestedVar)
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
100 ctx = irfunc->nestedVar;
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
101 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
102 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
103 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
104
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
105 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
106
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
107 ////////////////////////////////////
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
108 // 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
109
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
110 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
111 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
112 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
113 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
114 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
115 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
116 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
117 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
118 else if (nestedCtx == NCHybrid) {
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
119 LLValue* val = DtoBitCast(ctx, LLPointerType::getUnqual(irfunc->frameType));
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
120 Logger::cout() << "Context: " << *val << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
121 Logger::cout() << "of type: " << *val->getType() << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
122
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
123 unsigned vardepth = vd->ir.irLocal->nestedDepth;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
124 unsigned funcdepth = irfunc->depth;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
125
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
126 Logger::cout() << "Variable: " << vd->toChars() << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
127 Logger::cout() << "Variable depth: " << vardepth << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
128 Logger::cout() << "Function: " << irfunc->decl->toChars() << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
129 Logger::cout() << "Function depth: " << funcdepth << '\n';
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
130
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
131 if (vardepth == funcdepth) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
132 // This is not always handled above because functions without
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
133 // variables accessed by nested functions don't create new frames.
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
134 Logger::println("Same depth");
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
135 } else {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
136 // Load frame pointer and index that...
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
137 Logger::println("Lower depth");
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
138 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth);
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
139 Logger::cout() << "Frame index: " << *val << '\n';
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
140 val = DtoAlignedLoad(val, (std::string(".frame.") + vdparent->toChars()).c_str());
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
141 Logger::cout() << "Frame: " << *val << '\n';
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
142 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
143 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
144 Logger::cout() << "Addr: " << *val << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
145 Logger::cout() << "of type: " << *val->getType() << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
146 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
147 val = DtoAlignedLoad(val);
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
148 Logger::cout() << "Was byref, now: " << *val << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
149 Logger::cout() << "of type: " << *val->getType() << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
150 }
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
151
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
152 return new DVarValue(astype, vd, val);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
153 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
154 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
155 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
156 }
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
157 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
158
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
159 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
160 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
161 Logger::println("DtoNestedInit for %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
162 LOG_SCOPE
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
163
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
164 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
165 LLValue* nestedVar = irfunc->nestedVar;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
166
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
167 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
168 // 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
169 if (!vd->ir.irLocal->value)
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1224
diff changeset
170 vd->ir.irLocal->value = DtoAlloca(vd->type, vd->toChars());
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
171
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
172 // 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
173 assert(vd->ir.irLocal->nestedIndex >= 0);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
174 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
175
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
176 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
177 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
178
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
179 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
180 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
181 else if (nestedCtx == NCHybrid) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
182 assert(vd->ir.irLocal->value && "Nested variable without storage?");
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
183
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
184 if (!vd->isParameter() && (vd->isRef() || vd->isOut())) {
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
185 unsigned vardepth = vd->ir.irLocal->nestedDepth;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
186
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
187 LLValue* val = NULL;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
188 // Retrieve frame pointer
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
189 if (vardepth == irfunc->depth) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
190 val = nestedVar;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
191 } else {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
192 FuncDeclaration *parentfunc = getParentFunc(vd, true);
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
193 assert(parentfunc && "No parent function for nested variable?");
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
194
1467
630fc54f7c1e Fix a bug in DtoNestedInit and update an unrelated comment.
Frits van Bommel <fvbommel wxs.nl>
parents: 1350
diff changeset
195 val = DtoGEPi(nestedVar, 0, vardepth);
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
196 val = DtoAlignedLoad(val, (std::string(".frame.") + parentfunc->toChars()).c_str());
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
197 }
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
198 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
199 DtoAlignedStore(vd->ir.irLocal->value, val);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
200 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
201 // Already initialized in DtoCreateNestedContext
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
202 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
203 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
204 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
205 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
206 }
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
207 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
208
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
209 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
210 {
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 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
212 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
213
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
214 IrFunction* irfunc = gIR->func();
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
215 bool fromParent = true;
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
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
217 LLValue* val;
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
218 // 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
219 // use its own context
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
220 if (irfunc->nestedVar) {
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
221 val = irfunc->nestedVar;
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
222 fromParent = false;
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
223 }
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
224 // 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
225 else if (irfunc->nestArg)
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
226 val = irfunc->nestArg;
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
227 // 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
228 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
229 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
230 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
231 if (!cd || !cd->vthis)
1222
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
232 return llvm::UndefValue::get(getVoidPtrType());
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
233 val = DtoLoad(irfunc->thisArg);
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
234 val = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
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
235 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
236 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
237 {
1222
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
238 return llvm::UndefValue::get(getVoidPtrType());
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
239 }
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
240 if (nestedCtx == NCHybrid) {
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
241 if (FuncDeclaration* symfd = sym->isFuncDeclaration()) {
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
242 // Make sure we've had a chance to analyze nested context usage
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
243 DtoDefineFunction(symfd);
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
244
1222
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
245 // if this is for a function that doesn't access variables from
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
246 // enclosing scopes, it doesn't matter what we pass.
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
247 // Tell LLVM about it by passing an 'undef'.
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
248 if (symfd && symfd->ir.irFunc->depth == -1)
1222
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
249 return llvm::UndefValue::get(getVoidPtrType());
b6370749ec8d Use 'undef' instead of null for unneeded contexts.
Frits van Bommel <fvbommel wxs.nl>
parents: 1218
diff changeset
250
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
251 // If sym is a nested function, and it's parent context is different than the
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
252 // one we got, adjust it.
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
253 if (FuncDeclaration* fd = getParentFunc(symfd, true)) {
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
254 Logger::println("For nested function, parent is %s", fd->toChars());
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
255 FuncDeclaration* ctxfd = irfunc->decl;
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
256 Logger::println("Current function is %s", ctxfd->toChars());
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
257 if (fromParent) {
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
258 ctxfd = getParentFunc(ctxfd, true);
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
259 assert(ctxfd && "Context from outer function, but no outer function?");
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
260 }
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
261 Logger::println("Context is from %s", ctxfd->toChars());
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
262
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
263 unsigned neededDepth = fd->ir.irFunc->depth;
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
264 unsigned ctxDepth = ctxfd->ir.irFunc->depth;
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
265
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
266 Logger::cout() << "Needed depth: " << neededDepth << '\n';
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
267 Logger::cout() << "Context depth: " << ctxDepth << '\n';
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
268
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
269 if (neededDepth >= ctxDepth) {
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
270 assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?");
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
271 // fd needs the same context as we do, so all is well
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
272 Logger::println("Calling sibling function or directly nested function");
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
273 } else {
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
274 val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType));
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
275 val = DtoGEPi(val, 0, neededDepth);
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
276 val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str());
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
277 }
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
278 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
279 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
280 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
281 Logger::cout() << "result = " << *val << '\n';
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
282 Logger::cout() << "of type " << *val->getType() << '\n';
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
283 return val;
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
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 void DtoCreateNestedContext(FuncDeclaration* fd) {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
287 Logger::println("DtoCreateNestedContext for %s", fd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
288 LOG_SCOPE
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
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 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
291 // 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
292 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
293 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
294 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
295 // 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
296 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
297 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
298 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
299 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
300 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
301 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
302 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
303 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
304 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
305 // 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
306 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
307 break;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
308 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
309 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
310 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
311 // nothing needed
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
312 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
313 else
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
314 {
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
315 break;
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
316 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
317
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
318 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
319 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
320 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
321 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
322
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
323 // 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
324 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
325
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
326 // alloca it
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1224
diff changeset
327 // FIXME align ?
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1224
diff changeset
328 LLValue* nestedVars = DtoRawAlloca(nestedVarsTy, 0, ".nested_vars");
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
329
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
330 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
331
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
332 // 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
333 if (nparelems)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
334 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
335 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
336 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
337 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
338 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
339 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
340 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
341 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
342 assert(cd);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
343 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
344 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
345 }
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
346 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
347 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
348 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
349
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
350 // 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
351 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
352
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
353 // 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
354 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
355 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
356 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
357 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
358 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
359 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
360
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
361 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
362 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
363 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
364 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
365 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
366 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
367 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
368 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
369 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
370 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
371 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
372
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
373 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
374 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
375 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
376 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
377 else if (nestedCtx == NCHybrid) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
378 // construct nested variables array
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
379 if (!fd->nestedVars.empty())
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
380 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
381 Logger::println("has nested frame");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
382 // start with adding all enclosing parent frames until a static parent is reached
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
383
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
384 const LLStructType* innerFrameType = NULL;
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
385 unsigned depth = -1;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
386 if (!fd->isStatic()) {
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
387 if (FuncDeclaration* parfd = getParentFunc(fd, true)) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
388 innerFrameType = parfd->ir.irFunc->frameType;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
389 if (innerFrameType)
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
390 depth = parfd->ir.irFunc->depth;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
391 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
392 }
1223
5f340a6dc749 Fix nested functions.
Frits van Bommel <fvbommel wxs.nl>
parents: 1222
diff changeset
393 fd->ir.irFunc->depth = ++depth;
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
394
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
395 Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
396
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
397 typedef std::vector<const LLType*> TypeVec;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
398 TypeVec types;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
399 if (depth != 0) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
400 assert(innerFrameType);
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
401 // Add frame pointer types for all but last frame
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
402 if (depth > 1) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
403 for (unsigned i = 0; i < (depth - 1); ++i) {
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
404 types.push_back(innerFrameType->getElementType(i));
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
405 }
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
406 }
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
407 // Add frame pointer type for last frame
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
408 types.push_back(LLPointerType::getUnqual(innerFrameType));
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
409 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
410
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
411 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
412 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
413 LOG_SCOPE;
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
414 for (TypeVec::iterator i = types.begin(); i != types.end(); ++i)
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
415 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
416 }
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
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
418 // Add the direct nested variables of this function, and update their indices to match.
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
419 // TODO: optimize ordering for minimal space usage?
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
420 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
421 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
422 VarDeclaration* vd = *i;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
423 if (!vd->ir.irLocal)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
424 vd->ir.irLocal = new IrLocal(vd);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
425
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
426 vd->ir.irLocal->nestedIndex = types.size();
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
427 vd->ir.irLocal->nestedDepth = depth;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
428 if (vd->isParameter()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
429 // Parameters already have storage associated with them (to handle byref etc.),
1224
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
430 // so handle those cases specially by storing a pointer instead of a value.
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
431 assert(vd->ir.irLocal->value);
1224
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
432 LLValue* value = vd->ir.irLocal->value;
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
433 const LLType* type = value->getType();
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
434 if (llvm::isa<llvm::AllocaInst>(value->getUnderlyingObject()))
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
435 // This will be copied to the nesting frame.
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
436 type = type->getContainedType(0);
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
437 types.push_back(type);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
438 } else if (vd->isRef() || vd->isOut()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
439 // Foreach variables can also be by reference, for instance.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
440 types.push_back(DtoType(vd->type->pointerTo()));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
441 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
442 types.push_back(DtoType(vd->type));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
443 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
444 if (Logger::enabled()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
445 Logger::println("Nested var: %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
446 Logger::cout() << "of type: " << *types.back() << '\n';
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
447 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
448 }
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
449
1569
755abafbf25d Push the context through StructType::get.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1467
diff changeset
450 const LLStructType* frameType = LLStructType::get(gIR->context(), types);
1218
7977096f0e49 Name some types.
Frits van Bommel <fvbommel wxs.nl>
parents: 1216
diff changeset
451 gIR->module->addTypeName(std::string("nest.") + fd->toChars(), frameType);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
452
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
453 Logger::cout() << "frameType = " << *frameType << '\n';
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
454
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
455 // Store type in IrFunction
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
456 IrFunction* irfunction = fd->ir.irFunc;
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
457 irfunction->frameType = frameType;
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
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 // 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
460 // FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca
1224
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
461 // (Note that it'd also require more aggressive copying of
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
462 // by-value parameters instead of just alloca'd ones)
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1224
diff changeset
463 // FIXME: alignment ?
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1224
diff changeset
464 LLValue* frame = DtoRawAlloca(frameType, 0, ".frame");
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
465
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
466 // copy parent frames into beginning
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
467 if (depth != 0) {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
468 LLValue* src = irfunction->nestArg;
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
469 if (!src) {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
470 assert(irfunction->thisArg);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
471 assert(fd->isMember2());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
472 LLValue* thisval = DtoLoad(irfunction->thisArg);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
473 ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
474 assert(cd);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
475 assert(cd->vthis);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
476 Logger::println("Indexing to 'this'");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
477 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
478 }
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
479 if (depth > 1) {
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
480 src = DtoBitCast(src, getVoidPtrType());
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
481 LLValue* dst = DtoBitCast(frame, getVoidPtrType());
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
482 DtoMemCpy(dst, src, DtoConstSize_t((depth-1) * PTRSIZE),
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
483 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
484 }
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
485 // Copy nestArg into framelist; the outer frame is not in the list of pointers
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
486 src = DtoBitCast(src, types[depth-1]);
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
487 LLValue* gep = DtoGEPi(frame, 0, depth-1);
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
488 DtoAlignedStore(src, gep);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
489 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
490
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
491 // store context in IrFunction
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
492 irfunction->nestedVar = frame;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
493
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
494 // 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
495 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
496 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
497 VarDeclaration* vd = *i;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
498
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
499 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
500 if (vd->isParameter()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
501 Logger::println("nested param: %s", vd->toChars());
1224
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
502 LOG_SCOPE
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
503 LLValue* value = vd->ir.irLocal->value;
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
504 if (llvm::isa<llvm::AllocaInst>(value->getUnderlyingObject())) {
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
505 Logger::println("Copying to nested frame");
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
506 // The parameter value is an alloca'd stack slot.
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
507 // Copy to the nesting frame and leave the alloca for
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
508 // the optimizers to clean up.
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
509 DtoStore(DtoLoad(value), gep);
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
510 gep->takeName(value);
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
511 vd->ir.irLocal->value = gep;
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
512 vd->ir.irLocal->byref = false;
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
513 } else {
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
514 Logger::println("Adding pointer to nested frame");
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
515 // The parameter value is something else, such as a
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
516 // passed-in pointer (for 'ref' or 'out' parameters) or
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
517 // a pointer arg with byval attribute.
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
518 // Store the address into the frame and set the byref flag.
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
519 DtoAlignedStore(vd->ir.irLocal->value, gep);
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
520 vd->ir.irLocal->byref = true;
919fafcc505c Copy alloca'd parameters referenced by nested functions to the nesting frame.
Frits van Bommel <fvbommel wxs.nl>
parents: 1223
diff changeset
521 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
522 } else if (vd->isRef() || vd->isOut()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
523 // 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
524 // which move around in memory.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
525 vd->ir.irLocal->byref = true;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
526 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
527 Logger::println("nested var: %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
528 if (vd->ir.irLocal->value)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
529 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
530 assert(!vd->ir.irLocal->value);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
531 vd->ir.irLocal->value = gep;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
532 vd->ir.irLocal->byref = false;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
533 }
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
534 }
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
535 } else if (FuncDeclaration* parFunc = getParentFunc(fd, true)) {
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
536 // Propagate context arg properties if the context arg is passed on unmodified.
1216
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
537 fd->ir.irFunc->frameType = parFunc->ir.irFunc->frameType;
033f18ec1371 Unify %.frames_list and %.frame into a single data structure, generalizing r1212
Frits van Bommel <fvbommel wxs.nl>
parents: 1213
diff changeset
538 fd->ir.irFunc->depth = parFunc->ir.irFunc->depth;
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
539 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
540 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
541 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
542 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
543 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
544 }