1 #include <freehdl/vaul.h>
2 #include "v2cc-chunk.h"
3 #include "mapping.h"
4 #include "v2cc-util.h"
5
6
7
8 // Used to generate error messages
9 extern vaul_error_printer codegen_error;
10
11
12 // This function moves an item within a declaration region to the
13 // declarative region defined by static_declarative_region. E.g., if a
14 // constant has been defined in an architechture then it will be
15 // defined globally in the generated C++ code if the initialization
16 // value is locally static. This is done in order to prevent the code
17 // generator from generating an identical constant within each
18 // instance of the architecture.
19 void
reschedule_declaration_region(RegionStack & rstack)20 reschedule_declaration_region(RegionStack &rstack)
21 {
22 const bool is_architecture_top_region =
23 TopDeclarativeRegion (rstack)->is (IR_ARCHITECTURE_DECLARATION);
24
25 pIIR_DeclarativeRegion active_region = ActiveDeclarativeRegion (rstack);
26 pIIR_DeclarativeRegion root_region = RootDeclarativeRegion (rstack);
27
28 pIIR_DeclarationList *dlp = &extended_declarations (active_region);
29 while ((*dlp) != NULL) {
30 pIIR_DeclarativeRegion static_region = static_declarative_region ((*dlp)->first);
31
32 if ((*dlp)->first->is(IR_SUBPROGRAM_DECLARATION))
33 optimize ((*dlp)->first, rstack);
34
35 else if (static_region != NULL &&
36 active_region != root_region &&
37 static_region != active_region &&
38 ((*dlp)->first->is(IR_CONSTANT_DECLARATION) ||
39 (*dlp)->first->is(IR_TYPE_DECLARATION)) &&
40 // If we are processing architecture declarations and the
41 // object is static with respect to the entity, then do
42 // nothing as we cannot move declarations into entities. Same
43 // for package and package body declarations.
44 !(static_region->is (IR_ENTITY_DECLARATION) &&
45 active_region->is (IR_ARCHITECTURE_DECLARATION)) &&
46 !(static_region->is (IR_PACKAGE_DECLARATION) &&
47 active_region->is (IR_PACKAGE_BODY_DECLARATION)))
48 {
49 //cout << (*dlp)->first->declarator->text.to_chars() << " "
50 // << static_region->kind_name () << endl;
51 // Test whether we are currently processing an architecture
52 // and the object is static with respect to the entity
53 // region. As we cannot insert any declarations into the
54 // entity declaration list, move it to the architecture
55 // declaration.
56 if (is_architecture_top_region &&
57 static_region->is (IR_ENTITY_DECLARATION))
58 static_region = TopDeclarativeRegion (rstack);
59
60 pIIR_DeclarationList *listp =
61 get_last_rest_address (&extended_declarations (static_region));
62 *listp = new IIR_DeclarationList ((*dlp)->first->pos, (*dlp)->first, *listp);
63 *dlp = (*dlp)->rest;
64 continue;
65 }
66
67 dlp = &(*dlp)->rest;
68 }
69 }
70
71
72
73
74
75 // ******************************************************************************************
76 // Name: m_optimize, generic function
77 //
78 // Description: performs some optimizations on the node tree
79 //
80 // Return value: void
81 //
82 // ******************************************************************************************
83
84 void
m_optimize(pIIR_PredefinedFunctionDeclaration sp,RegionStack & rstack)85 m_optimize (pIIR_PredefinedFunctionDeclaration sp, RegionStack &rstack)
86 {
87 rstack.push(sp);
88 rstack.pop();
89 }
90
91
92
93 void
m_optimize(pIIR_SubprogramDeclaration sp,RegionStack & rstack)94 m_optimize (pIIR_SubprogramDeclaration sp, RegionStack &rstack)
95 {
96 rstack.push(sp);
97
98 // Note that if the subprogram is declared in a package (or in
99 // another subprogram that is declared in a package) then do not try
100 // to move declaration as this might cause initialization races:
101
102 // package race is
103 // function func return integer;
104 // constant const : integer := func;
105 // end package;
106 // package body race is
107 // function func return integer is
108 // constant const2 : integer := 1;
109 // begin
110 // return const2;
111 // end func;
112 // end package body;
113
114 // In the C++ code the package body is elaborated AFTER the package
115 // declaration. Hence, if const2 is initialized globally, if will
116 // get its initial value too late!
117 pIIR_DeclarativeRegion top_region = TopDeclarativeRegion(rstack);
118 if (!top_region->is(IR_PACKAGE_BODY_DECLARATION))
119 {
120 if (extended_declarations(sp) != NULL)
121 reschedule_declaration_region (rstack);
122 }
123
124 rstack.pop();
125 }
126
127
128 void
m_optimize(pIIR_EntityDeclaration e,RegionStack & rstack)129 m_optimize (pIIR_EntityDeclaration e, RegionStack &rstack)
130 {
131 rstack.push(e);
132 reschedule_declaration_region (rstack);
133 if (e->entity_statement_part != NULL)
134 optimize(e->entity_statement_part, rstack);
135 rstack.pop();
136 }
137
138
139
140 void
m_optimize(pIIR_Type st,RegionStack & rstack)141 m_optimize (pIIR_Type st, RegionStack &rstack)
142 {
143 }
144
145
146 void
m_optimize(pIIR_ArchitectureDeclaration a,RegionStack & rstack)147 m_optimize (pIIR_ArchitectureDeclaration a, RegionStack &rstack)
148 {
149 rstack.push(a);
150
151 if (extended_declarations(a) != NULL)
152 reschedule_declaration_region (rstack);
153 if (a->architecture_statement_part != NULL)
154 optimize(a->architecture_statement_part, rstack);
155
156 rstack.pop();
157 }
158
159
160 void
m_optimize(pIIR_ConcurrentStatementList csl,RegionStack & rstack)161 m_optimize (pIIR_ConcurrentStatementList csl, RegionStack &rstack)
162 {
163 for (pIIR_ConcurrentStatementList l = csl; l; l = l->rest)
164 optimize(l->first, rstack);
165 }
166
167
168 void
m_optimize(pIIR_ProcessStatement p,RegionStack & rstack)169 m_optimize (pIIR_ProcessStatement p, RegionStack &rstack)
170 {
171 rstack.push(p);
172 if (extended_declarations(p) != NULL)
173 reschedule_declaration_region (rstack);
174 rstack.pop();
175 }
176
177
178 // Do not re-order delcaration in packages as they will be already
179 // emitted at a global level. Re-scheduling may break correct
180 // initialization order!
181 void
m_optimize(pIIR_PackageDeclaration p,RegionStack & rstack)182 m_optimize (pIIR_PackageDeclaration p, RegionStack &rstack)
183 {
184 rstack.push(p);
185 rstack.pop();
186 }
187
188
189 // Do not re-order delcaration in packages as they will be already
190 // emitted at a global level. Re-scheduling may break correct
191 // initialization order!
192 void
m_optimize(pIIR_PackageBodyDeclaration pb,RegionStack & rstack)193 m_optimize (pIIR_PackageBodyDeclaration pb, RegionStack &rstack)
194 {
195 rstack.push(pb);
196 rstack.pop();
197 }
198
199
200 void
m_optimize(pIIR_ConfigurationDeclaration c,RegionStack & rstack)201 m_optimize (pIIR_ConfigurationDeclaration c, RegionStack &rstack)
202 {
203 rstack.push(c);
204 rstack.pop();
205 }
206
207
208 void
m_optimize(pIIR_ComponentInstantiationStatement cis,RegionStack & rstack)209 m_optimize (pIIR_ComponentInstantiationStatement cis, RegionStack &rstack)
210 {
211 rstack.push(cis);
212 rstack.pop();
213 }
214
215
216 void
m_optimize(pIIR_ComponentDeclaration c,RegionStack & rstack)217 m_optimize (pIIR_ComponentDeclaration c, RegionStack &rstack)
218 {
219 rstack.push(c);
220 rstack.pop();
221 }
222
223
224 void
m_optimize(pIIR_ConcurrentGenerateIfStatement gs,RegionStack & rstack)225 m_optimize(pIIR_ConcurrentGenerateIfStatement gs, RegionStack &rstack)
226 {
227 rstack.push(gs);
228 if (extended_declarations(gs) != NULL)
229 reschedule_declaration_region (rstack);
230 if (gs->concurrent_statement_part!= NULL)
231 optimize(gs->concurrent_statement_part, rstack);
232 rstack.pop();
233 }
234
235
236 void
m_optimize(pIIR_ConcurrentGenerateForStatement gs,RegionStack & rstack)237 m_optimize(pIIR_ConcurrentGenerateForStatement gs, RegionStack &rstack)
238 {
239 rstack.push(gs);
240 if (extended_declarations(gs) != NULL)
241 reschedule_declaration_region (rstack);
242 if (gs->concurrent_statement_part != NULL)
243 optimize(gs->concurrent_statement_part, rstack);
244 rstack.pop();
245 }
246
247
248
249