1
|
1 |
/*
|
|
2 |
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
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
|
|
171 |
idealS = 8 // String type
|
|
172 |
};
|
|
173 |
// Convert ideal name to a DataType, return DataType::none if not a 'ConX'
|
|
174 |
Form::DataType ideal_to_const_type(const char *ideal_type_name) const;
|
|
175 |
// Convert ideal name to a DataType, return DataType::none if not a 'sRegX
|
|
176 |
Form::DataType ideal_to_sReg_type(const char *name) const;
|
|
177 |
// Convert ideal name to a DataType, return DataType::none if not a 'RegX
|
|
178 |
Form::DataType ideal_to_Reg_type(const char *name) const;
|
|
179 |
|
|
180 |
// Convert ideal name to a DataType, return DataType::none if not a 'LoadX
|
|
181 |
Form::DataType is_load_from_memory(const char *opType) const;
|
|
182 |
// Convert ideal name to a DataType, return DataType::none if not a 'StoreX
|
|
183 |
Form::DataType is_store_to_memory(const char *opType) const;
|
|
184 |
|
|
185 |
// ADLC call types, matched with ideal world
|
|
186 |
enum CallType {
|
|
187 |
invalid_type = 0, // invalid call type
|
|
188 |
JAVA_STATIC = 1, // monomorphic entry
|
|
189 |
JAVA_DYNAMIC = 2, // possibly megamorphic, inline cache call
|
|
190 |
JAVA_COMPILED = 3, // callee will be compiled java
|
|
191 |
JAVA_INTERP = 4, // callee will be executed by interpreter
|
|
192 |
JAVA_NATIVE = 5, // native entrypoint
|
|
193 |
JAVA_RUNTIME = 6, // runtime entrypoint
|
|
194 |
JAVA_LEAF = 7 // calling leaf
|
|
195 |
};
|
|
196 |
|
|
197 |
// Interface types for operands and operand classes
|
|
198 |
enum InterfaceType {
|
|
199 |
no_interface = 0, // unknown or inconsistent interface type
|
|
200 |
constant_interface = 1, // interface to constants
|
|
201 |
register_interface = 2, // interface to registers
|
|
202 |
memory_interface = 3, // interface to memory
|
|
203 |
conditional_interface = 4 // interface for condition codes
|
|
204 |
};
|
|
205 |
virtual Form::InterfaceType interface_type(FormDict &globals) const;
|
|
206 |
|
|
207 |
enum CiscSpillInfo {
|
|
208 |
Not_cisc_spillable = AdlcVMDeps::Not_cisc_spillable,
|
|
209 |
Maybe_cisc_spillable = 0,
|
|
210 |
Is_cisc_spillable = 1
|
|
211 |
// ...
|
|
212 |
};
|
|
213 |
|
|
214 |
// LEGAL FORM TYPES
|
|
215 |
enum {
|
|
216 |
INS,
|
|
217 |
OPER,
|
|
218 |
OPCLASS,
|
|
219 |
SRC,
|
|
220 |
ADEF,
|
|
221 |
REG,
|
|
222 |
PIPE,
|
|
223 |
CNST,
|
|
224 |
PRED,
|
|
225 |
ATTR,
|
|
226 |
MAT,
|
|
227 |
ENC,
|
|
228 |
FOR,
|
|
229 |
EXP,
|
|
230 |
REW,
|
|
231 |
EFF,
|
|
232 |
RDEF,
|
|
233 |
RCL,
|
|
234 |
ACL,
|
|
235 |
RES,
|
|
236 |
PCL,
|
|
237 |
PDEF,
|
|
238 |
REGL,
|
|
239 |
RESL,
|
|
240 |
STAL,
|
|
241 |
COMP,
|
|
242 |
PEEP,
|
|
243 |
RESO
|
|
244 |
};
|
|
245 |
|
|
246 |
};
|
|
247 |
|
|
248 |
//------------------------------FormList---------------------------------------
|
|
249 |
class FormList {
|
|
250 |
private:
|
|
251 |
Form *_root;
|
|
252 |
Form *_tail;
|
|
253 |
Form *_cur;
|
|
254 |
int _justReset; // Set immediately after reset
|
|
255 |
Form *_cur2; // Nested iterator
|
|
256 |
int _justReset2;
|
|
257 |
|
|
258 |
public:
|
|
259 |
void addForm(Form * entry) {
|
|
260 |
if (_tail==NULL) { _root = _tail = _cur = entry;}
|
|
261 |
else { _tail->_next = entry; _tail = entry;}
|
|
262 |
};
|
|
263 |
Form * current() { return _cur; };
|
|
264 |
Form * iter() { if (_justReset) _justReset = 0;
|
|
265 |
else if (_cur) _cur = _cur->_next;
|
|
266 |
return _cur;};
|
|
267 |
void reset() { if (_root) {_cur = _root; _justReset = 1;} };
|
|
268 |
|
|
269 |
// Second iterator, state is internal
|
|
270 |
Form * current2(){ return _cur2; };
|
|
271 |
Form * iter2() { if (_justReset2) _justReset2 = 0;
|
|
272 |
else if (_cur2) _cur2 = _cur2->_next;
|
|
273 |
return _cur2;};
|
|
274 |
void reset2() { if (_root) {_cur2 = _root; _justReset2 = 1;} };
|
|
275 |
|
|
276 |
int count() {
|
|
277 |
int count = 0; reset();
|
|
278 |
for( Form *cur; (cur = iter()) != NULL; ) { ++count; };
|
|
279 |
return count;
|
|
280 |
}
|
|
281 |
|
|
282 |
void dump() {
|
|
283 |
reset();
|
|
284 |
Form *cur;
|
|
285 |
for(; (cur = iter()) != NULL; ) {
|
|
286 |
cur->dump();
|
|
287 |
};
|
|
288 |
}
|
|
289 |
|
|
290 |
bool verify() {
|
|
291 |
bool verified = true;
|
|
292 |
|
|
293 |
reset();
|
|
294 |
Form *cur;
|
|
295 |
for(; (cur = iter()) != NULL; ) {
|
|
296 |
if ( ! cur->verify() ) verified = false;
|
|
297 |
};
|
|
298 |
|
|
299 |
return verified;
|
|
300 |
}
|
|
301 |
|
|
302 |
void output(FILE* fp) {
|
|
303 |
reset();
|
|
304 |
Form *cur;
|
|
305 |
for( ; (cur = iter()) != NULL; ) {
|
|
306 |
cur->output(fp);
|
|
307 |
};
|
|
308 |
}
|
|
309 |
|
|
310 |
FormList() { _justReset = 1; _justReset2 = 1; _root = NULL; _tail = NULL; _cur = NULL; _cur2 = NULL;};
|
|
311 |
~FormList();
|
|
312 |
};
|
|
313 |
|
|
314 |
//------------------------------NameList---------------------------------------
|
|
315 |
// Extendable list of pointers, <char *>
|
|
316 |
class NameList {
|
|
317 |
friend class PreserveIter;
|
|
318 |
|
|
319 |
private:
|
|
320 |
int _cur; // Insert next entry here; count of entries
|
|
321 |
int _max; // Number of spaces allocated
|
|
322 |
const char **_names; // Array of names
|
|
323 |
|
|
324 |
protected:
|
|
325 |
int _iter; // position during iteration
|
|
326 |
bool _justReset; // Set immediately after reset
|
|
327 |
|
|
328 |
|
|
329 |
public:
|
|
330 |
static const char *_signal; // reserved user-defined string
|
|
331 |
enum { Not_in_list = -1 };
|
|
332 |
|
|
333 |
void addName(const char *name);
|
|
334 |
void add_signal();
|
|
335 |
void clear(); // Remove all entries
|
|
336 |
|
|
337 |
int count() const;
|
|
338 |
|
|
339 |
void reset(); // Reset iteration
|
|
340 |
const char *iter(); // after reset(), first element : else next
|
|
341 |
const char *current(); // return current element in iteration.
|
|
342 |
|
|
343 |
bool current_is_signal(); // Return 'true' if current entry is signal
|
|
344 |
bool is_signal(const char *entry); // Return true if entry is a signal
|
|
345 |
|
|
346 |
bool search(const char *); // Search for a name in the list
|
|
347 |
int index(const char *); // Return index of name in list
|
|
348 |
const char *name (intptr_t index);// Return name at index in list
|
|
349 |
|
|
350 |
void dump(); // output to stderr
|
|
351 |
void output(FILE *fp); // Output list of names to 'fp'
|
|
352 |
|
|
353 |
NameList();
|
|
354 |
~NameList();
|
|
355 |
};
|
|
356 |
|
|
357 |
|
|
358 |
// Convenience class to preserve iteration state since iterators are
|
|
359 |
// internal instead of being external.
|
|
360 |
class PreserveIter {
|
|
361 |
private:
|
|
362 |
NameList* _list;
|
|
363 |
int _iter;
|
|
364 |
bool _justReset;
|
|
365 |
|
|
366 |
public:
|
|
367 |
PreserveIter(NameList* nl) {
|
|
368 |
_list = nl;
|
|
369 |
_iter = _list->_iter;
|
|
370 |
_justReset = _list->_justReset;
|
|
371 |
}
|
|
372 |
~PreserveIter() {
|
|
373 |
_list->_iter = _iter;
|
|
374 |
_list->_justReset = _justReset;
|
|
375 |
}
|
|
376 |
|
|
377 |
};
|
|
378 |
|
|
379 |
|
|
380 |
//------------------------------NameAndList------------------------------------
|
|
381 |
// Storage for a name and an associated list of names
|
|
382 |
class NameAndList {
|
|
383 |
private:
|
|
384 |
const char *_name;
|
|
385 |
NameList _list;
|
|
386 |
|
|
387 |
public:
|
|
388 |
NameAndList(char *name);
|
|
389 |
~NameAndList();
|
|
390 |
|
|
391 |
// Add to entries in list
|
|
392 |
void add_entry(const char *entry);
|
|
393 |
|
|
394 |
// Access the name and its associated list.
|
|
395 |
const char *name() const;
|
|
396 |
void reset();
|
|
397 |
const char *iter();
|
|
398 |
|
|
399 |
int count() { return _list.count(); }
|
|
400 |
|
|
401 |
// Return the "index" entry in the list, zero-based
|
|
402 |
const char *operator[](int index);
|
|
403 |
|
|
404 |
|
|
405 |
void dump(); // output to stderr
|
|
406 |
void output(FILE *fp); // Output list of names to 'fp'
|
|
407 |
};
|
|
408 |
|
|
409 |
//------------------------------ComponentList---------------------------------
|
|
410 |
// Component lists always have match rule operands first, followed by parameter
|
|
411 |
// operands which do not appear in the match list (in order of declaration).
|
|
412 |
class ComponentList : private NameList {
|
|
413 |
private:
|
|
414 |
int _matchcnt; // Count of match rule operands
|
|
415 |
|
|
416 |
public:
|
|
417 |
|
|
418 |
// This is a batch program. (And I have a destructor bug!)
|
|
419 |
void operator delete( void *ptr ) {}
|
|
420 |
|
|
421 |
void insert(Component *component, bool mflag);
|
|
422 |
void insert(const char *name, const char *opType, int usedef, bool mflag);
|
|
423 |
|
|
424 |
int count();
|
|
425 |
int match_count() { return _matchcnt; } // Get count of match rule opers
|
|
426 |
|
|
427 |
Component *iter(); // after reset(), first element : else next
|
|
428 |
Component *match_iter(); // after reset(), first element : else next
|
|
429 |
Component *post_match_iter(); // after reset(), first element : else next
|
|
430 |
void reset(); // Reset iteration
|
|
431 |
Component *current(); // return current element in iteration.
|
|
432 |
|
|
433 |
// Return element at "position", else NULL
|
|
434 |
Component *operator[](int position);
|
|
435 |
Component *at(int position) { return (*this)[position]; }
|
|
436 |
|
|
437 |
// Return first component having this name.
|
|
438 |
const Component *search(const char *name);
|
|
439 |
|
|
440 |
// Return number of USEs + number of DEFs
|
|
441 |
int num_operands();
|
|
442 |
// Return zero-based position in list; -1 if not in list.
|
|
443 |
int operand_position(const char *name, int usedef);
|
|
444 |
// Find position for this name, regardless of use/def information
|
|
445 |
int operand_position(const char *name);
|
|
446 |
// Find position for this name when looked up for output via "format"
|
|
447 |
int operand_position_format(const char *name);
|
|
448 |
// Find position for the Label when looked up for output via "format"
|
|
449 |
int label_position();
|
|
450 |
// Find position for the Method when looked up for output via "format"
|
|
451 |
int method_position();
|
|
452 |
|
|
453 |
void dump(); // output to stderr
|
|
454 |
void output(FILE *fp); // Output list of names to 'fp'
|
|
455 |
|
|
456 |
ComponentList();
|
|
457 |
~ComponentList();
|
|
458 |
};
|
|
459 |
|
|
460 |
//------------------------------SourceForm-------------------------------------
|
|
461 |
class SourceForm : public Form {
|
|
462 |
private:
|
|
463 |
|
|
464 |
public:
|
|
465 |
// Public Data
|
|
466 |
char *_code; // Buffer for storing code text
|
|
467 |
|
|
468 |
// Public Methods
|
|
469 |
SourceForm(char* code);
|
|
470 |
~SourceForm();
|
|
471 |
|
|
472 |
virtual const char* classname() { return "SourceForm"; }
|
|
473 |
|
|
474 |
void dump(); // Debug printer
|
|
475 |
void output(FILE *fp); // Write output files
|
|
476 |
};
|
|
477 |
|
|
478 |
class HeaderForm : public SourceForm {
|
|
479 |
public:
|
|
480 |
HeaderForm(char* code) : SourceForm(code) { }
|
|
481 |
|
|
482 |
virtual const char* classname() { return "HeaderForm"; }
|
|
483 |
};
|
|
484 |
|
|
485 |
class PreHeaderForm : public SourceForm {
|
|
486 |
public:
|
|
487 |
PreHeaderForm(char* code) : SourceForm(code) { }
|
|
488 |
|
|
489 |
virtual const char* classname() { return "PreHeaderForm"; }
|
|
490 |
};
|
|
491 |
|
|
492 |
|
|
493 |
|
|
494 |
|
|
495 |
//------------------------------Expr------------------------------------------
|
|
496 |
#define STRING_BUFFER_LENGTH 2048
|
|
497 |
// class Expr represents integer expressions containing constants and addition
|
|
498 |
// Value must be in range zero through maximum positive integer. 32bits.
|
|
499 |
// Expected use: instruction and operand costs
|
|
500 |
class Expr {
|
|
501 |
public:
|
|
502 |
enum {
|
|
503 |
Zero = 0,
|
|
504 |
Max = 0x7fffffff
|
|
505 |
};
|
|
506 |
const char *_external_name; // if !NULL, then print this instead of _expr
|
|
507 |
const char *_expr;
|
|
508 |
int _min_value;
|
|
509 |
int _max_value;
|
|
510 |
|
|
511 |
Expr();
|
|
512 |
Expr(const char *cost);
|
|
513 |
Expr(const char *name, const char *expression, int min_value, int max_value);
|
|
514 |
Expr *clone() const;
|
|
515 |
|
|
516 |
bool is_unknown() const { return (this == Expr::get_unknown()); }
|
|
517 |
bool is_zero() const { return (_min_value == Expr::Zero && _max_value == Expr::Zero); }
|
|
518 |
bool less_than_or_equal(const Expr *c) const { return (_max_value <= c->_min_value); }
|
|
519 |
|
|
520 |
void add(const Expr *c);
|
|
521 |
void add(const char *c);
|
|
522 |
void add(const char *c, ArchDesc &AD); // check if 'c' is defined in <arch>.ad
|
|
523 |
void set_external_name(const char *name) { _external_name = name; }
|
|
524 |
|
|
525 |
const char *as_string() const { return (_external_name != NULL ? _external_name : _expr); }
|
|
526 |
void print() const;
|
|
527 |
void print_define(FILE *fp) const;
|
|
528 |
void print_assert(FILE *fp) const;
|
|
529 |
|
|
530 |
static Expr *get_unknown(); // Returns pointer to shared unknown cost instance
|
|
531 |
|
|
532 |
static char *buffer() { return &external_buffer[0]; }
|
|
533 |
static bool init_buffers(); // Fill buffers with 0
|
|
534 |
static bool check_buffers(); // if buffer use may have overflowed, assert
|
|
535 |
|
|
536 |
private:
|
|
537 |
static Expr *_unknown_expr;
|
|
538 |
static char string_buffer[STRING_BUFFER_LENGTH];
|
|
539 |
static char external_buffer[STRING_BUFFER_LENGTH];
|
|
540 |
static bool _init_buffers;
|
|
541 |
const char *compute_expr(const Expr *c1, const Expr *c2); // cost as string after adding 'c1' and 'c2'
|
|
542 |
int compute_min (const Expr *c1, const Expr *c2); // minimum after adding 'c1' and 'c2'
|
|
543 |
int compute_max (const Expr *c1, const Expr *c2); // maximum after adding 'c1' and 'c2'
|
|
544 |
const char *compute_external(const Expr *c1, const Expr *c2); // external name after adding 'c1' and 'c2'
|
|
545 |
};
|
|
546 |
|
|
547 |
//------------------------------ExprDict---------------------------------------
|
|
548 |
// Dictionary containing Exprs
|
|
549 |
class ExprDict {
|
|
550 |
private:
|
|
551 |
Dict _expr; // map names, char*, to their Expr* or NULL
|
|
552 |
NameList _defines; // record the order of definitions entered with define call
|
|
553 |
|
|
554 |
// Disable public use of constructor, copy-ctor, operator =, operator ==
|
|
555 |
ExprDict( );
|
|
556 |
ExprDict( const ExprDict & ); // Deep-copy guts
|
|
557 |
ExprDict &operator =( const ExprDict & );
|
|
558 |
// == compares two dictionaries; they must have the same keys (their keys
|
|
559 |
// must match using CmpKey) and they must have the same values (pointer
|
|
560 |
// comparison). If so 1 is returned, if not 0 is returned.
|
|
561 |
bool operator ==(const ExprDict &d) const; // Compare dictionaries for equal
|
|
562 |
|
|
563 |
public:
|
|
564 |
// cmp is a key comparision routine. hash is a routine to hash a key.
|
|
565 |
ExprDict( CmpKey cmp, Hash hash, Arena *arena );
|
|
566 |
~ExprDict();
|
|
567 |
|
|
568 |
// Return # of key-value pairs in dict
|
|
569 |
int Size(void) const;
|
|
570 |
|
|
571 |
// define inserts the given key-value pair into the dictionary,
|
|
572 |
// and records the name in order for later output, ...
|
|
573 |
const Expr *define(const char *name, Expr *expr);
|
|
574 |
|
|
575 |
// Insert inserts the given key-value pair into the dictionary. The prior
|
|
576 |
// value of the key is returned; NULL if the key was not previously defined.
|
|
577 |
const Expr *Insert(const char *name, Expr *expr); // A new key-value
|
|
578 |
|
|
579 |
// Find finds the value of a given key; or NULL if not found.
|
|
580 |
// The dictionary is NOT changed.
|
|
581 |
const Expr *operator [](const char *name) const; // Do a lookup
|
|
582 |
|
|
583 |
void print_defines(FILE *fp);
|
|
584 |
void print_asserts(FILE *fp);
|
|
585 |
void dump();
|
|
586 |
};
|