author | never |
Tue, 28 Oct 2008 09:31:30 -0700 | |
changeset 1495 | 128fe18951ed |
parent 670 | ddf3e9583f2f |
child 2129 | e810a33b5c67 |
permissions | -rw-r--r-- |
1 | 1 |
/* |
670 | 2 |
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. |
1 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. |
|
8 |
* |
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
13 |
* accompanied this code). |
|
14 |
* |
|
15 |
* You should have received a copy of the GNU General Public License version |
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 |
* |
|
19 |
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
20 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
|
21 |
* have any questions. |
|
22 |
* |
|
23 |
*/ |
|
24 |
||
25 |
// FORMS.HPP - ADL Parser Generic and Utility Forms Classes |
|
26 |
||
27 |
#define TRUE 1 |
|
28 |
#define FALSE 0 |
|
29 |
||
30 |
// DEFINITIONS OF LEGAL ATTRIBUTE TYPES |
|
31 |
#define INS_ATTR 0 |
|
32 |
#define OP_ATTR 1 |
|
33 |
||
34 |
// DEFINITIONS OF LEGAL CONSTRAINT TYPES |
|
35 |
||
36 |
// Class List |
|
37 |
class Form; |
|
38 |
class InstructForm; |
|
39 |
class MachNodeForm; |
|
40 |
class OperandForm; |
|
41 |
class OpClassForm; |
|
42 |
class AttributeForm; |
|
43 |
class RegisterForm; |
|
44 |
class PipelineForm; |
|
45 |
class SourceForm; |
|
46 |
class EncodeForm; |
|
47 |
class Component; |
|
48 |
class Constraint; |
|
49 |
class Predicate; |
|
50 |
class MatchRule; |
|
51 |
class Attribute; |
|
52 |
class Effect; |
|
53 |
class ExpandRule; |
|
54 |
class RewriteRule; |
|
55 |
class ConstructRule; |
|
56 |
class FormatRule; |
|
57 |
class Peephole; |
|
58 |
class EncClass; |
|
59 |
class Interface; |
|
60 |
class RegInterface; |
|
61 |
class ConstInterface; |
|
62 |
class MemInterface; |
|
63 |
class CondInterface; |
|
64 |
class Opcode; |
|
65 |
class InsEncode; |
|
66 |
class RegDef; |
|
67 |
class RegClass; |
|
68 |
class AllocClass; |
|
69 |
class ResourceForm; |
|
70 |
class PipeClassForm; |
|
71 |
class PeepMatch; |
|
72 |
class PeepConstraint; |
|
73 |
class PeepReplace; |
|
74 |
class MatchList; |
|
75 |
||
76 |
class ArchDesc; |
|
77 |
||
78 |
//------------------------------FormDict--------------------------------------- |
|
79 |
// Dictionary containing Forms, and objects derived from forms |
|
80 |
class FormDict { |
|
81 |
private: |
|
82 |
Dict _form; // map names, char*, to their Form* or NULL |
|
83 |
||
84 |
// Disable public use of constructor, copy-ctor, operator =, operator == |
|
85 |
FormDict( ); |
|
86 |
FormDict &operator =( const FormDict & ); |
|
87 |
// == compares two dictionaries; they must have the same keys (their keys |
|
88 |
// must match using CmpKey) and they must have the same values (pointer |
|
89 |
// comparison). If so 1 is returned, if not 0 is returned. |
|
90 |
bool operator ==(const FormDict &d) const; // Compare dictionaries for equal |
|
91 |
||
92 |
public: |
|
93 |
// cmp is a key comparision routine. hash is a routine to hash a key. |
|
94 |
// FormDict( CmpKey cmp, Hash hash ); |
|
95 |
FormDict( CmpKey cmp, Hash hash, Arena *arena ); |
|
96 |
FormDict( const FormDict & fd ); // Deep-copy guts |
|
97 |
~FormDict(); |
|
98 |
||
99 |
// Return # of key-value pairs in dict |
|
100 |
int Size(void) const; |
|
101 |
||
102 |
// Insert inserts the given key-value pair into the dictionary. The prior |
|
103 |
// value of the key is returned; NULL if the key was not previously defined. |
|
104 |
const Form *Insert(const char *name, Form *form); // A new key-value |
|
105 |
||
106 |
// Find finds the value of a given key; or NULL if not found. |
|
107 |
// The dictionary is NOT changed. |
|
108 |
const Form *operator [](const char *name) const; // Do a lookup |
|
109 |
||
110 |
void dump(); |
|
111 |
}; |
|
112 |
||
113 |
// ***** Master Class for ADL Parser Forms ***** |
|
114 |
//------------------------------Form------------------------------------------- |
|
115 |
class Form { |
|
116 |
public: |
|
117 |
static Arena *arena; // arena used by forms |
|
118 |
private: |
|
119 |
static Arena *generate_arena(); // allocate arena used by forms |
|
120 |
||
121 |
protected: |
|
122 |
int _ftype; // Indicator for derived class type |
|
123 |
||
124 |
public: |
|
125 |
// Public Data |
|
126 |
Form *_next; // Next pointer for form lists |
|
127 |
long _linenum; // Line number for debugging |
|
128 |
||
129 |
// Dynamic type check for common forms. |
|
130 |
virtual OpClassForm *is_opclass() const; |
|
131 |
virtual OperandForm *is_operand() const; |
|
132 |
virtual InstructForm *is_instruction() const; |
|
133 |
virtual MachNodeForm *is_machnode() const; |
|
134 |
virtual AttributeForm *is_attribute() const; |
|
135 |
virtual Effect *is_effect() const; |
|
136 |
virtual ResourceForm *is_resource() const; |
|
137 |
virtual PipeClassForm *is_pipeclass() const; |
|
138 |
||
139 |
// Check if this form is an operand usable for cisc-spilling |
|
140 |
virtual bool is_cisc_reg(FormDict &globals) const { return false; } |
|
141 |
virtual bool is_cisc_mem(FormDict &globals) const { return false; } |
|
142 |
||
143 |
// Public Methods |
|
144 |
Form(int formType=0, int line=0) |
|
145 |
: _next(NULL), _linenum(line), _ftype(formType) { }; |
|
146 |
~Form() {}; |
|
147 |
||
148 |
virtual bool ideal_only() const { |
|
149 |
assert(0,"Check of ideal status on non-instruction/operand form.\n"); |
|
150 |
return FALSE; |
|
151 |
} |
|
152 |
||
153 |
// Check constraints after parsing |
|
154 |
virtual bool verify() { return true; } |
|
155 |
||
156 |
virtual void dump() { output(stderr); } // Debug printer |
|
157 |
// Write info to output files |
|
158 |
virtual void output(FILE *fp) { fprintf(fp,"Form Output"); } |
|
159 |
||
160 |
public: |
|
161 |
// ADLC types, match the last character on ideal operands and instructions |
|
162 |
enum DataType { |
|
163 |
none = 0, // Not a simple type |
|
164 |
idealI = 1, // Integer type |
|
165 |
idealP = 2, // Pointer types, oop(s) |
|
166 |
idealL = 3, // Long type |
|
167 |
idealF = 4, // Float type |
|
168 |
idealD = 5, // Double type |
|
169 |
idealB = 6, // Byte type |
|
170 |
idealC = 7, // Char type |
|
360
21d113ecbf6a
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
1
diff
changeset
|
171 |
idealS = 8, // String type |
21d113ecbf6a
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
1
diff
changeset
|
172 |
idealN = 9 // Narrow oop types |
1 | 173 |
}; |
174 |
// Convert ideal name to a DataType, return DataType::none if not a 'ConX' |
|
175 |
Form::DataType ideal_to_const_type(const char *ideal_type_name) const; |
|
176 |
// Convert ideal name to a DataType, return DataType::none if not a 'sRegX |
|
177 |
Form::DataType ideal_to_sReg_type(const char *name) const; |
|
178 |
// Convert ideal name to a DataType, return DataType::none if not a 'RegX |
|
179 |
Form::DataType ideal_to_Reg_type(const char *name) const; |
|
180 |
||
181 |
// Convert ideal name to a DataType, return DataType::none if not a 'LoadX |
|
182 |
Form::DataType is_load_from_memory(const char *opType) const; |
|
183 |
// Convert ideal name to a DataType, return DataType::none if not a 'StoreX |
|
184 |
Form::DataType is_store_to_memory(const char *opType) const; |
|
185 |
||
186 |
// ADLC call types, matched with ideal world |
|
187 |
enum CallType { |
|
188 |
invalid_type = 0, // invalid call type |
|
189 |
JAVA_STATIC = 1, // monomorphic entry |
|
190 |
JAVA_DYNAMIC = 2, // possibly megamorphic, inline cache call |
|
191 |
JAVA_COMPILED = 3, // callee will be compiled java |
|
192 |
JAVA_INTERP = 4, // callee will be executed by interpreter |
|
193 |
JAVA_NATIVE = 5, // native entrypoint |
|
194 |
JAVA_RUNTIME = 6, // runtime entrypoint |
|
195 |
JAVA_LEAF = 7 // calling leaf |
|
196 |
}; |
|
197 |
||
198 |
// Interface types for operands and operand classes |
|
199 |
enum InterfaceType { |
|
200 |
no_interface = 0, // unknown or inconsistent interface type |
|
201 |
constant_interface = 1, // interface to constants |
|
202 |
register_interface = 2, // interface to registers |
|
203 |
memory_interface = 3, // interface to memory |
|
204 |
conditional_interface = 4 // interface for condition codes |
|
205 |
}; |
|
206 |
virtual Form::InterfaceType interface_type(FormDict &globals) const; |
|
207 |
||
208 |
enum CiscSpillInfo { |
|
209 |
Not_cisc_spillable = AdlcVMDeps::Not_cisc_spillable, |
|
210 |
Maybe_cisc_spillable = 0, |
|
211 |
Is_cisc_spillable = 1 |
|
212 |
// ... |
|
213 |
}; |
|
214 |
||
215 |
// LEGAL FORM TYPES |
|
216 |
enum { |
|
217 |
INS, |
|
218 |
OPER, |
|
219 |
OPCLASS, |
|
220 |
SRC, |
|
221 |
ADEF, |
|
222 |
REG, |
|
223 |
PIPE, |
|
224 |
CNST, |
|
225 |
PRED, |
|
226 |
ATTR, |
|
227 |
MAT, |
|
228 |
ENC, |
|
229 |
FOR, |
|
230 |
EXP, |
|
231 |
REW, |
|
232 |
EFF, |
|
233 |
RDEF, |
|
234 |
RCL, |
|
235 |
ACL, |
|
236 |
RES, |
|
237 |
PCL, |
|
238 |
PDEF, |
|
239 |
REGL, |
|
240 |
RESL, |
|
241 |
STAL, |
|
242 |
COMP, |
|
243 |
PEEP, |
|
244 |
RESO |
|
245 |
}; |
|
246 |
||
247 |
}; |
|
248 |
||
249 |
//------------------------------FormList--------------------------------------- |
|
250 |
class FormList { |
|
251 |
private: |
|
252 |
Form *_root; |
|
253 |
Form *_tail; |
|
254 |
Form *_cur; |
|
255 |
int _justReset; // Set immediately after reset |
|
256 |
Form *_cur2; // Nested iterator |
|
257 |
int _justReset2; |
|
258 |
||
259 |
public: |
|
260 |
void addForm(Form * entry) { |
|
261 |
if (_tail==NULL) { _root = _tail = _cur = entry;} |
|
262 |
else { _tail->_next = entry; _tail = entry;} |
|
263 |
}; |
|
264 |
Form * current() { return _cur; }; |
|
265 |
Form * iter() { if (_justReset) _justReset = 0; |
|
266 |
else if (_cur) _cur = _cur->_next; |
|
267 |
return _cur;}; |
|
268 |
void reset() { if (_root) {_cur = _root; _justReset = 1;} }; |
|
269 |
||
270 |
// Second iterator, state is internal |
|
271 |
Form * current2(){ return _cur2; }; |
|
272 |
Form * iter2() { if (_justReset2) _justReset2 = 0; |
|
273 |
else if (_cur2) _cur2 = _cur2->_next; |
|
274 |
return _cur2;}; |
|
275 |
void reset2() { if (_root) {_cur2 = _root; _justReset2 = 1;} }; |
|
276 |
||
277 |
int count() { |
|
278 |
int count = 0; reset(); |
|
279 |
for( Form *cur; (cur = iter()) != NULL; ) { ++count; }; |
|
280 |
return count; |
|
281 |
} |
|
282 |
||
283 |
void dump() { |
|
284 |
reset(); |
|
285 |
Form *cur; |
|
286 |
for(; (cur = iter()) != NULL; ) { |
|
287 |
cur->dump(); |
|
288 |
}; |
|
289 |
} |
|
290 |
||
291 |
bool verify() { |
|
292 |
bool verified = true; |
|
293 |
||
294 |
reset(); |
|
295 |
Form *cur; |
|
296 |
for(; (cur = iter()) != NULL; ) { |
|
297 |
if ( ! cur->verify() ) verified = false; |
|
298 |
}; |
|
299 |
||
300 |
return verified; |
|
301 |
} |
|
302 |
||
303 |
void output(FILE* fp) { |
|
304 |
reset(); |
|
305 |
Form *cur; |
|
306 |
for( ; (cur = iter()) != NULL; ) { |
|
307 |
cur->output(fp); |
|
308 |
}; |
|
309 |
} |
|
310 |
||
311 |
FormList() { _justReset = 1; _justReset2 = 1; _root = NULL; _tail = NULL; _cur = NULL; _cur2 = NULL;}; |
|
312 |
~FormList(); |
|
313 |
}; |
|
314 |
||
315 |
//------------------------------NameList--------------------------------------- |
|
316 |
// Extendable list of pointers, <char *> |
|
317 |
class NameList { |
|
318 |
friend class PreserveIter; |
|
319 |
||
320 |
private: |
|
321 |
int _cur; // Insert next entry here; count of entries |
|
322 |
int _max; // Number of spaces allocated |
|
323 |
const char **_names; // Array of names |
|
324 |
||
325 |
protected: |
|
326 |
int _iter; // position during iteration |
|
327 |
bool _justReset; // Set immediately after reset |
|
328 |
||
329 |
||
330 |
public: |
|
331 |
static const char *_signal; // reserved user-defined string |
|
1495
128fe18951ed
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
670
diff
changeset
|
332 |
static const char *_signal2; // reserved user-defined string |
128fe18951ed
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
670
diff
changeset
|
333 |
static const char *_signal3; // reserved user-defined string |
1 | 334 |
enum { Not_in_list = -1 }; |
335 |
||
336 |
void addName(const char *name); |
|
337 |
void add_signal(); |
|
338 |
void clear(); // Remove all entries |
|
339 |
||
340 |
int count() const; |
|
341 |
||
342 |
void reset(); // Reset iteration |
|
343 |
const char *iter(); // after reset(), first element : else next |
|
344 |
const char *current(); // return current element in iteration. |
|
345 |
||
346 |
bool current_is_signal(); // Return 'true' if current entry is signal |
|
347 |
bool is_signal(const char *entry); // Return true if entry is a signal |
|
348 |
||
349 |
bool search(const char *); // Search for a name in the list |
|
350 |
int index(const char *); // Return index of name in list |
|
351 |
const char *name (intptr_t index);// Return name at index in list |
|
352 |
||
353 |
void dump(); // output to stderr |
|
354 |
void output(FILE *fp); // Output list of names to 'fp' |
|
355 |
||
356 |
NameList(); |
|
357 |
~NameList(); |
|
358 |
}; |
|
359 |
||
360 |
||
361 |
// Convenience class to preserve iteration state since iterators are |
|
362 |
// internal instead of being external. |
|
363 |
class PreserveIter { |
|
364 |
private: |
|
365 |
NameList* _list; |
|
366 |
int _iter; |
|
367 |
bool _justReset; |
|
368 |
||
369 |
public: |
|
370 |
PreserveIter(NameList* nl) { |
|
371 |
_list = nl; |
|
372 |
_iter = _list->_iter; |
|
373 |
_justReset = _list->_justReset; |
|
374 |
} |
|
375 |
~PreserveIter() { |
|
376 |
_list->_iter = _iter; |
|
377 |
_list->_justReset = _justReset; |
|
378 |
} |
|
379 |
||
380 |
}; |
|
381 |
||
382 |
||
383 |
//------------------------------NameAndList------------------------------------ |
|
384 |
// Storage for a name and an associated list of names |
|
385 |
class NameAndList { |
|
386 |
private: |
|
387 |
const char *_name; |
|
388 |
NameList _list; |
|
389 |
||
390 |
public: |
|
391 |
NameAndList(char *name); |
|
392 |
~NameAndList(); |
|
393 |
||
394 |
// Add to entries in list |
|
395 |
void add_entry(const char *entry); |
|
396 |
||
397 |
// Access the name and its associated list. |
|
398 |
const char *name() const; |
|
399 |
void reset(); |
|
400 |
const char *iter(); |
|
401 |
||
402 |
int count() { return _list.count(); } |
|
403 |
||
404 |
// Return the "index" entry in the list, zero-based |
|
405 |
const char *operator[](int index); |
|
406 |
||
407 |
||
408 |
void dump(); // output to stderr |
|
409 |
void output(FILE *fp); // Output list of names to 'fp' |
|
410 |
}; |
|
411 |
||
412 |
//------------------------------ComponentList--------------------------------- |
|
413 |
// Component lists always have match rule operands first, followed by parameter |
|
414 |
// operands which do not appear in the match list (in order of declaration). |
|
415 |
class ComponentList : private NameList { |
|
416 |
private: |
|
417 |
int _matchcnt; // Count of match rule operands |
|
418 |
||
419 |
public: |
|
420 |
||
421 |
// This is a batch program. (And I have a destructor bug!) |
|
422 |
void operator delete( void *ptr ) {} |
|
423 |
||
424 |
void insert(Component *component, bool mflag); |
|
425 |
void insert(const char *name, const char *opType, int usedef, bool mflag); |
|
426 |
||
427 |
int count(); |
|
428 |
int match_count() { return _matchcnt; } // Get count of match rule opers |
|
429 |
||
430 |
Component *iter(); // after reset(), first element : else next |
|
431 |
Component *match_iter(); // after reset(), first element : else next |
|
432 |
Component *post_match_iter(); // after reset(), first element : else next |
|
433 |
void reset(); // Reset iteration |
|
434 |
Component *current(); // return current element in iteration. |
|
435 |
||
436 |
// Return element at "position", else NULL |
|
437 |
Component *operator[](int position); |
|
438 |
Component *at(int position) { return (*this)[position]; } |
|
439 |
||
440 |
// Return first component having this name. |
|
441 |
const Component *search(const char *name); |
|
442 |
||
443 |
// Return number of USEs + number of DEFs |
|
444 |
int num_operands(); |
|
445 |
// Return zero-based position in list; -1 if not in list. |
|
446 |
int operand_position(const char *name, int usedef); |
|
447 |
// Find position for this name, regardless of use/def information |
|
448 |
int operand_position(const char *name); |
|
449 |
// Find position for this name when looked up for output via "format" |
|
450 |
int operand_position_format(const char *name); |
|
451 |
// Find position for the Label when looked up for output via "format" |
|
452 |
int label_position(); |
|
453 |
// Find position for the Method when looked up for output via "format" |
|
454 |
int method_position(); |
|
455 |
||
456 |
void dump(); // output to stderr |
|
457 |
void output(FILE *fp); // Output list of names to 'fp' |
|
458 |
||
459 |
ComponentList(); |
|
460 |
~ComponentList(); |
|
461 |
}; |
|
462 |
||
463 |
//------------------------------SourceForm------------------------------------- |
|
464 |
class SourceForm : public Form { |
|
465 |
private: |
|
466 |
||
467 |
public: |
|
468 |
// Public Data |
|
469 |
char *_code; // Buffer for storing code text |
|
470 |
||
471 |
// Public Methods |
|
472 |
SourceForm(char* code); |
|
473 |
~SourceForm(); |
|
474 |
||
475 |
virtual const char* classname() { return "SourceForm"; } |
|
476 |
||
477 |
void dump(); // Debug printer |
|
478 |
void output(FILE *fp); // Write output files |
|
479 |
}; |
|
480 |
||
481 |
class HeaderForm : public SourceForm { |
|
482 |
public: |
|
483 |
HeaderForm(char* code) : SourceForm(code) { } |
|
484 |
||
485 |
virtual const char* classname() { return "HeaderForm"; } |
|
486 |
}; |
|
487 |
||
488 |
class PreHeaderForm : public SourceForm { |
|
489 |
public: |
|
490 |
PreHeaderForm(char* code) : SourceForm(code) { } |
|
491 |
||
492 |
virtual const char* classname() { return "PreHeaderForm"; } |
|
493 |
}; |
|
494 |
||
495 |
||
496 |
||
497 |
||
498 |
//------------------------------Expr------------------------------------------ |
|
499 |
#define STRING_BUFFER_LENGTH 2048 |
|
500 |
// class Expr represents integer expressions containing constants and addition |
|
501 |
// Value must be in range zero through maximum positive integer. 32bits. |
|
502 |
// Expected use: instruction and operand costs |
|
503 |
class Expr { |
|
504 |
public: |
|
505 |
enum { |
|
506 |
Zero = 0, |
|
507 |
Max = 0x7fffffff |
|
508 |
}; |
|
509 |
const char *_external_name; // if !NULL, then print this instead of _expr |
|
510 |
const char *_expr; |
|
511 |
int _min_value; |
|
512 |
int _max_value; |
|
513 |
||
514 |
Expr(); |
|
515 |
Expr(const char *cost); |
|
516 |
Expr(const char *name, const char *expression, int min_value, int max_value); |
|
517 |
Expr *clone() const; |
|
518 |
||
519 |
bool is_unknown() const { return (this == Expr::get_unknown()); } |
|
520 |
bool is_zero() const { return (_min_value == Expr::Zero && _max_value == Expr::Zero); } |
|
521 |
bool less_than_or_equal(const Expr *c) const { return (_max_value <= c->_min_value); } |
|
522 |
||
523 |
void add(const Expr *c); |
|
524 |
void add(const char *c); |
|
525 |
void add(const char *c, ArchDesc &AD); // check if 'c' is defined in <arch>.ad |
|
526 |
void set_external_name(const char *name) { _external_name = name; } |
|
527 |
||
528 |
const char *as_string() const { return (_external_name != NULL ? _external_name : _expr); } |
|
529 |
void print() const; |
|
530 |
void print_define(FILE *fp) const; |
|
531 |
void print_assert(FILE *fp) const; |
|
532 |
||
533 |
static Expr *get_unknown(); // Returns pointer to shared unknown cost instance |
|
534 |
||
535 |
static char *buffer() { return &external_buffer[0]; } |
|
536 |
static bool init_buffers(); // Fill buffers with 0 |
|
537 |
static bool check_buffers(); // if buffer use may have overflowed, assert |
|
538 |
||
539 |
private: |
|
540 |
static Expr *_unknown_expr; |
|
541 |
static char string_buffer[STRING_BUFFER_LENGTH]; |
|
542 |
static char external_buffer[STRING_BUFFER_LENGTH]; |
|
543 |
static bool _init_buffers; |
|
544 |
const char *compute_expr(const Expr *c1, const Expr *c2); // cost as string after adding 'c1' and 'c2' |
|
545 |
int compute_min (const Expr *c1, const Expr *c2); // minimum after adding 'c1' and 'c2' |
|
546 |
int compute_max (const Expr *c1, const Expr *c2); // maximum after adding 'c1' and 'c2' |
|
547 |
const char *compute_external(const Expr *c1, const Expr *c2); // external name after adding 'c1' and 'c2' |
|
548 |
}; |
|
549 |
||
550 |
//------------------------------ExprDict--------------------------------------- |
|
551 |
// Dictionary containing Exprs |
|
552 |
class ExprDict { |
|
553 |
private: |
|
554 |
Dict _expr; // map names, char*, to their Expr* or NULL |
|
555 |
NameList _defines; // record the order of definitions entered with define call |
|
556 |
||
557 |
// Disable public use of constructor, copy-ctor, operator =, operator == |
|
558 |
ExprDict( ); |
|
559 |
ExprDict( const ExprDict & ); // Deep-copy guts |
|
560 |
ExprDict &operator =( const ExprDict & ); |
|
561 |
// == compares two dictionaries; they must have the same keys (their keys |
|
562 |
// must match using CmpKey) and they must have the same values (pointer |
|
563 |
// comparison). If so 1 is returned, if not 0 is returned. |
|
564 |
bool operator ==(const ExprDict &d) const; // Compare dictionaries for equal |
|
565 |
||
566 |
public: |
|
567 |
// cmp is a key comparision routine. hash is a routine to hash a key. |
|
568 |
ExprDict( CmpKey cmp, Hash hash, Arena *arena ); |
|
569 |
~ExprDict(); |
|
570 |
||
571 |
// Return # of key-value pairs in dict |
|
572 |
int Size(void) const; |
|
573 |
||
574 |
// define inserts the given key-value pair into the dictionary, |
|
575 |
// and records the name in order for later output, ... |
|
576 |
const Expr *define(const char *name, Expr *expr); |
|
577 |
||
578 |
// Insert inserts the given key-value pair into the dictionary. The prior |
|
579 |
// value of the key is returned; NULL if the key was not previously defined. |
|
580 |
const Expr *Insert(const char *name, Expr *expr); // A new key-value |
|
581 |
||
582 |
// Find finds the value of a given key; or NULL if not found. |
|
583 |
// The dictionary is NOT changed. |
|
584 |
const Expr *operator [](const char *name) const; // Do a lookup |
|
585 |
||
586 |
void print_defines(FILE *fp); |
|
587 |
void print_asserts(FILE *fp); |
|
588 |
void dump(); |
|
589 |
}; |