Mercurial > projects > ldc
annotate gen/nested.cpp @ 1650:40bd4a0d4870
Update to work with LLVM 2.7.
Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).
Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.
Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.
author | Tomas Lindquist Olsen |
---|---|
date | Wed, 19 May 2010 12:42:32 +0200 |
parents | 755abafbf25d |
children |
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 |
1569
755abafbf25d
Push the context through StructType::get.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1467
diff
changeset
|
450 const LLStructType* frameType = LLStructType::get(gIR->context(), types); |
1218 | 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 } |