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