Mercurial > projects > ldc
annotate gen/nested.cpp @ 1489:a048f31bf9f6
Move locating the configuration file into a separate function. Also look in PREFIX/etc/ldc. Fixes #322.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Mon, 08 Jun 2009 19:48:20 +0200 |
parents | 630fc54f7c1e |
children | 755abafbf25d |
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 | 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 | 241 if (FuncDeclaration* symfd = sym->isFuncDeclaration()) { |
242 // Make sure we've had a chance to analyze nested context usage | |
243 DtoDefineFunction(symfd); | |
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 | 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 | 251 // If sym is a nested function, and it's parent context is different than the |
252 // one we got, adjust it. | |
253 if (FuncDeclaration* fd = getParentFunc(symfd, true)) { | |
254 Logger::println("For nested function, parent is %s", fd->toChars()); | |
255 FuncDeclaration* ctxfd = irfunc->decl; | |
256 Logger::println("Current function is %s", ctxfd->toChars()); | |
257 if (fromParent) { | |
258 ctxfd = getParentFunc(ctxfd, true); | |
259 assert(ctxfd && "Context from outer function, but no outer function?"); | |
260 } | |
261 Logger::println("Context is from %s", ctxfd->toChars()); | |
262 | |
263 unsigned neededDepth = fd->ir.irFunc->depth; | |
264 unsigned ctxDepth = ctxfd->ir.irFunc->depth; | |
265 | |
266 Logger::cout() << "Needed depth: " << neededDepth << '\n'; | |
267 Logger::cout() << "Context depth: " << ctxDepth << '\n'; | |
268 | |
269 if (neededDepth >= ctxDepth) { | |
270 assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?"); | |
271 // fd needs the same context as we do, so all is well | |
272 Logger::println("Calling sibling function or directly nested function"); | |
273 } else { | |
274 val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType)); | |
275 val = DtoGEPi(val, 0, neededDepth); | |
276 val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str()); | |
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 | 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 | 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 | 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 |
df2227fdc860
For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents:
1210
diff
changeset
|
450 const LLStructType* frameType = LLStructType::get(types); |
1218 | 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 } |