Mercurial > hg > truffle
comparison src/share/vm/adlc/formsopt.hpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | dbbe28fc66b5 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 1998-2006 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 // FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes | |
26 | |
27 // Class List | |
28 class Form; | |
29 class InstructForm; | |
30 class OperandForm; | |
31 class OpClassForm; | |
32 class AttributeForm; | |
33 class RegisterForm; | |
34 class PipelineForm; | |
35 class SourceForm; | |
36 class EncodeForm; | |
37 class Component; | |
38 class Constraint; | |
39 class Predicate; | |
40 class MatchRule; | |
41 class Attribute; | |
42 class Effect; | |
43 class ExpandRule; | |
44 class RewriteRule; | |
45 class ConstructRule; | |
46 class FormatRule; | |
47 class Peephole; | |
48 class PeepMatch; | |
49 class PeepConstraint; | |
50 class EncClass; | |
51 class Interface; | |
52 class RegInterface; | |
53 class ConstInterface; | |
54 class MemInterface; | |
55 class CondInterface; | |
56 class Opcode; | |
57 class InsEncode; | |
58 class RegDef; | |
59 class RegClass; | |
60 class AllocClass; | |
61 class ResourceForm; | |
62 class PipeClassForm; | |
63 class PipeClassOperandForm; | |
64 class PipeClassResourceForm; | |
65 class PeepMatch; | |
66 class PeepConstraint; | |
67 class PeepReplace; | |
68 class MatchList; | |
69 | |
70 class ArchDesc; | |
71 | |
72 //==============================Register Allocation============================ | |
73 //------------------------------RegisterForm----------------------------------- | |
74 class RegisterForm : public Form { | |
75 private: | |
76 AllocClass *_current_ac; // State used by iter_RegDefs() | |
77 | |
78 public: | |
79 // Public Data | |
80 NameList _rdefs; // List of register definition names | |
81 Dict _regDef; // map register name to RegDef* | |
82 | |
83 NameList _rclasses; // List of register class names | |
84 Dict _regClass; // map register class name to RegClass* | |
85 | |
86 NameList _aclasses; // List of allocation class names | |
87 Dict _allocClass; // Dictionary of allocation classes | |
88 | |
89 static int _reg_ctr; // Register counter | |
90 static int RegMask_Size(); // Compute RegMask size | |
91 | |
92 // Public Methods | |
93 RegisterForm(); | |
94 ~RegisterForm(); | |
95 | |
96 void addRegDef(char *regName, char *callingConv, char *c_conv, | |
97 char * idealtype, char *encoding, char* concreteName); | |
98 RegClass *addRegClass(const char *className); | |
99 AllocClass *addAllocClass(char *allocName); | |
100 void addSpillRegClass(); | |
101 | |
102 // Provide iteration over all register definitions | |
103 // in the order used by the register allocator | |
104 void reset_RegDefs(); | |
105 RegDef *iter_RegDefs(); | |
106 RegDef *getRegDef (const char *regName); | |
107 | |
108 RegClass *getRegClass(const char *className); | |
109 | |
110 // Return register mask, compressed chunk and register # | |
111 uint reg_mask(char *register_class); | |
112 | |
113 // Check that register classes are compatible with chunks | |
114 bool verify(); | |
115 | |
116 void dump(); // Debug printer | |
117 void output(FILE *fp); // Write info to output files | |
118 }; | |
119 | |
120 //------------------------------RegDef----------------------------------------- | |
121 class RegDef : public Form { | |
122 public: | |
123 // Public Data | |
124 const char *_regname; // ADLC (Opto) Register name | |
125 const char *_callconv; // Calling convention | |
126 const char *_c_conv; // Native calling convention, 'C' | |
127 const char *_idealtype; // Ideal Type for register save/restore | |
128 const char *_concrete; // concrete register name | |
129 | |
130 private: | |
131 const char *_register_encode; // The register encoding | |
132 // The chunk and register mask bits define info for register allocation | |
133 uint32 _register_num; // Which register am I | |
134 | |
135 public: | |
136 // Public Methods | |
137 RegDef(char *regname, char *callconv, char *c_conv, | |
138 char *idealtype, char *encoding, char *concrete); | |
139 ~RegDef(); // Destructor | |
140 | |
141 // Interface to define/redefine the register number | |
142 void set_register_num(uint32 new_register_num); | |
143 | |
144 // Bit pattern used for generating machine code | |
145 const char *register_encode() const; | |
146 // Register number used in machine-independent code | |
147 uint32 register_num() const; | |
148 | |
149 void dump(); // Debug printer | |
150 void output(FILE *fp); // Write info to output files | |
151 }; | |
152 | |
153 //------------------------------RegClass--------------------------------------- | |
154 class RegClass : public Form { | |
155 public: | |
156 // Public Data | |
157 const char *_classid; // Name of class | |
158 NameList _regDefs; // List of registers in class | |
159 Dict _regDef; // Dictionary of registers in class | |
160 bool _stack_or_reg; // Allowed on any stack slot | |
161 | |
162 // Public Methods | |
163 RegClass(const char *classid);// Constructor | |
164 | |
165 void addReg(RegDef *regDef); // Add a register to this class | |
166 | |
167 uint size() const; // Number of registers in class | |
168 int regs_in_word( int wordnum, bool stack_also ); | |
169 | |
170 const RegDef *get_RegDef(const char *regDef_name) const; | |
171 | |
172 // Returns the lowest numbered register in the mask. | |
173 const RegDef* find_first_elem(); | |
174 | |
175 // Iteration support | |
176 void reset(); // Reset the following two iterators | |
177 RegDef *RegDef_iter(); // which move jointly, | |
178 const char *rd_name_iter(); // invoking either advances both. | |
179 | |
180 void dump(); // Debug printer | |
181 void output(FILE *fp); // Write info to output files | |
182 }; | |
183 | |
184 //------------------------------AllocClass------------------------------------- | |
185 class AllocClass : public Form { | |
186 private: | |
187 | |
188 public: | |
189 // Public Data | |
190 char *_classid; // Name of class | |
191 NameList _regDefs; // List of registers in class | |
192 Dict _regDef; // Dictionary of registers in class | |
193 | |
194 // Public Methods | |
195 AllocClass(char *classid); // Constructor | |
196 | |
197 void addReg(RegDef *regDef); // Add a register to this class | |
198 uint size() {return _regDef.Size();} // Number of registers in class | |
199 | |
200 void dump(); // Debug printer | |
201 void output(FILE *fp); // Write info to output files | |
202 }; | |
203 | |
204 | |
205 //==============================Frame Handling================================ | |
206 //------------------------------FrameForm------------------------------------- | |
207 class FrameForm : public Form { | |
208 private: | |
209 | |
210 public: | |
211 // Public Data | |
212 bool _direction; // Direction of stack growth | |
213 char *_sync_stack_slots; | |
214 char *_inline_cache_reg; | |
215 char *_interpreter_method_oop_reg; | |
216 char *_interpreter_frame_pointer_reg; | |
217 char *_cisc_spilling_operand_name; | |
218 char *_frame_pointer; | |
219 char *_c_frame_pointer; | |
220 char *_alignment; | |
221 bool _return_addr_loc; | |
222 bool _c_return_addr_loc; | |
223 char *_return_addr; | |
224 char *_c_return_addr; | |
225 char *_in_preserve_slots; | |
226 char *_varargs_C_out_slots_killed; | |
227 char *_calling_convention; | |
228 char *_c_calling_convention; | |
229 char *_return_value; | |
230 char *_c_return_value; | |
231 | |
232 // Public Methods | |
233 FrameForm(); | |
234 ~FrameForm(); | |
235 | |
236 void dump(); // Debug printer | |
237 void output(FILE *fp); // Write info to output files | |
238 }; | |
239 | |
240 | |
241 //==============================Scheduling===================================== | |
242 //------------------------------PipelineForm----------------------------------- | |
243 class PipelineForm : public Form { | |
244 private: | |
245 | |
246 public: | |
247 // Public Data | |
248 NameList _reslist; // List of pipeline resources | |
249 FormDict _resdict; // Resource Name -> ResourceForm mapping | |
250 int _rescount; // Number of resources (ignores OR cases) | |
251 int _maxcycleused; // Largest cycle used relative to beginning of instruction | |
252 | |
253 NameList _stages; // List of pipeline stages on architecture | |
254 int _stagecnt; // Number of stages listed | |
255 | |
256 NameList _classlist; // List of pipeline classes | |
257 FormDict _classdict; // Class Name -> PipeClassForm mapping | |
258 int _classcnt; // Number of classes | |
259 | |
260 NameList _noplist; // List of NOP instructions | |
261 int _nopcnt; // Number of nop instructions | |
262 | |
263 bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions | |
264 bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions | |
265 int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP | |
266 int _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP | |
267 int _instrUnitSize; // The minimum instruction unit size, in bytes | |
268 int _bundleUnitSize; // The bundle unit size, in bytes | |
269 int _instrFetchUnitSize; // The size of the I-fetch unit, in bytes [must be power of 2] | |
270 int _instrFetchUnits; // The number of I-fetch units processed per cycle | |
271 | |
272 // Public Methods | |
273 PipelineForm(); | |
274 ~PipelineForm(); | |
275 | |
276 void dump(); // Debug printer | |
277 void output(FILE *fp); // Write info to output files | |
278 }; | |
279 | |
280 //------------------------------ResourceForm----------------------------------- | |
281 class ResourceForm : public Form { | |
282 public: | |
283 unsigned mask() const { return _resmask; }; | |
284 | |
285 private: | |
286 // Public Data | |
287 unsigned _resmask; // Resource Mask (OR of resource specifier bits) | |
288 | |
289 public: | |
290 | |
291 // Virtual Methods | |
292 virtual ResourceForm *is_resource() const; | |
293 | |
294 // Public Methods | |
295 ResourceForm(unsigned resmask); // Constructor | |
296 ~ResourceForm(); // Destructor | |
297 | |
298 void dump(); // Debug printer | |
299 void output(FILE *fp); // Write info to output files | |
300 }; | |
301 | |
302 //------------------------------PipeClassOperandForm----------------------------- | |
303 class PipeClassOperandForm : public Form { | |
304 private: | |
305 | |
306 public: | |
307 // Public Data | |
308 const char *_stage; // Name of Stage | |
309 unsigned _iswrite; // Read or Write | |
310 unsigned _more_instrs; // Additional Instructions | |
311 | |
312 // Public Methods | |
313 PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs) | |
314 : _stage(stage) | |
315 , _iswrite(iswrite) | |
316 , _more_instrs(more_instrs) | |
317 {}; | |
318 | |
319 ~PipeClassOperandForm() {}; // Destructor | |
320 | |
321 bool isWrite() const { return _iswrite != 0; } | |
322 | |
323 void dump(); // Debug printer | |
324 void output(FILE *fp); // Write info to output files | |
325 }; | |
326 | |
327 //------------------------------PipeClassResourceForm-------------------------- | |
328 class PipeClassResourceForm : public Form { | |
329 private: | |
330 | |
331 public: | |
332 // Public Data | |
333 const char *_resource; // Resource | |
334 const char *_stage; // Stage the resource is used in | |
335 int _cycles; // Number of cycles the resource is used | |
336 | |
337 // Public Methods | |
338 PipeClassResourceForm(const char *resource, const char *stage, int cycles) | |
339 // Constructor | |
340 : _resource(resource) | |
341 , _stage(stage) | |
342 , _cycles(cycles) | |
343 {}; | |
344 | |
345 ~PipeClassResourceForm() {}; // Destructor | |
346 | |
347 void dump(); // Debug printer | |
348 void output(FILE *fp); // Write info to output files | |
349 }; | |
350 | |
351 //------------------------------PipeClassForm---------------------------------- | |
352 class PipeClassForm : public Form { | |
353 private: | |
354 | |
355 public: | |
356 | |
357 // Public Data | |
358 const char *_ident; // Name of class | |
359 int _num; // Used in name of MachNode subclass | |
360 NameList _parameters; // Locally defined names | |
361 FormDict _localNames; // Table of operands & their types | |
362 FormDict _localUsage; // Table of operand usage | |
363 FormList _resUsage; // List of resource usage | |
364 NameList _instructs; // List of instructions and machine nodes that use this pipeline class | |
365 bool _has_fixed_latency; // Always takes this number of cycles | |
366 int _fixed_latency; // Always takes this number of cycles | |
367 int _instruction_count; // Number of instructions in first bundle | |
368 bool _has_multiple_bundles; // Indicates if 1 or multiple bundles | |
369 bool _has_branch_delay_slot; // Has branch delay slot as last instruction | |
370 bool _force_serialization; // This node serializes relative to surrounding nodes | |
371 bool _may_have_no_code; // This node may generate no code based on register allocation | |
372 | |
373 // Virtual Methods | |
374 virtual PipeClassForm *is_pipeclass() const; | |
375 | |
376 // Public Methods | |
377 PipeClassForm(const char *id, int num); | |
378 // Constructor | |
379 ~PipeClassForm(); // Destructor | |
380 | |
381 bool hasFixedLatency() { return _has_fixed_latency; } | |
382 int fixedLatency() { return _fixed_latency; } | |
383 | |
384 void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; } | |
385 | |
386 void setInstructionCount(int i) { _instruction_count = i; } | |
387 void setMultipleBundles(bool b) { _has_multiple_bundles = b; } | |
388 void setBranchDelay(bool s) { _has_branch_delay_slot = s; } | |
389 void setForceSerialization(bool s) { _force_serialization = s; } | |
390 void setMayHaveNoCode(bool s) { _may_have_no_code = s; } | |
391 | |
392 int InstructionCount() const { return _instruction_count; } | |
393 bool hasMultipleBundles() const { return _has_multiple_bundles; } | |
394 bool hasBranchDelay() const { return _has_branch_delay_slot; } | |
395 bool forceSerialization() const { return _force_serialization; } | |
396 bool mayHaveNoCode() const { return _may_have_no_code; } | |
397 | |
398 void dump(); // Debug printer | |
399 void output(FILE *fp); // Write info to output files | |
400 }; | |
401 | |
402 | |
403 //==============================Peephole Optimization========================== | |
404 //------------------------------Peephole--------------------------------------- | |
405 class Peephole : public Form { | |
406 private: | |
407 static int _peephole_counter;// Incremented by each peephole rule parsed | |
408 int _peephole_number;// Remember my order in architecture description | |
409 PeepMatch *_match; // Instruction pattern to match | |
410 PeepConstraint *_constraint; // List of additional constraints | |
411 PeepReplace *_replace; // Instruction pattern to substitute in | |
412 | |
413 Peephole *_next; | |
414 | |
415 public: | |
416 // Public Methods | |
417 Peephole(); | |
418 ~Peephole(); | |
419 | |
420 // Append a peephole rule with the same root instruction | |
421 void append_peephole(Peephole *next_peephole); | |
422 | |
423 // Store the components of this peephole rule | |
424 void add_match(PeepMatch *only_one_match); | |
425 void append_constraint(PeepConstraint *next_constraint); | |
426 void add_replace(PeepReplace *only_one_replacement); | |
427 | |
428 // Access the components of this peephole rule | |
429 int peephole_number() { return _peephole_number; } | |
430 PeepMatch *match() { return _match; } | |
431 PeepConstraint *constraints() { return _constraint; } | |
432 PeepReplace *replacement() { return _replace; } | |
433 Peephole *next() { return _next; } | |
434 | |
435 void dump(); // Debug printer | |
436 void output(FILE *fp); // Write info to output files | |
437 }; | |
438 | |
439 | |
440 class PeepMatch : public Form { | |
441 private: | |
442 char *_rule; | |
443 // NameList _depth; // Depth of this instruction | |
444 NameList _parent; | |
445 NameList _position; | |
446 NameList _instrs; // List of instructions in match rule | |
447 NameList _input; // input position in parent's instruction | |
448 int _max_position; | |
449 | |
450 public: | |
451 // Public Methods | |
452 PeepMatch(char *rule); | |
453 ~PeepMatch(); | |
454 | |
455 // Insert info into the match-rule | |
456 void add_instruction(int parent, int position, const char *name, int input); | |
457 | |
458 // Access info about instructions in the peep-match rule | |
459 int max_position(); | |
460 const char *instruction_name(intptr_t position); | |
461 // Iterate through all info on matched instructions | |
462 void reset(); | |
463 void next_instruction( intptr_t &parent, intptr_t &position, const char * &name, intptr_t &input ); | |
464 // 'true' if current position in iteration is a placeholder, not matched. | |
465 bool is_placeholder(); | |
466 | |
467 void dump(); | |
468 void output(FILE *fp); | |
469 }; | |
470 | |
471 | |
472 class PeepConstraint : public Form { | |
473 private: | |
474 PeepConstraint *_next; // Additional constraints ANDed together | |
475 | |
476 public: | |
477 const intptr_t _left_inst; | |
478 const char *_left_op; | |
479 const char *_relation; | |
480 const intptr_t _right_inst; | |
481 const char *_right_op; | |
482 | |
483 public: | |
484 // Public Methods | |
485 PeepConstraint(intptr_t left_inst, char *left_op, char *relation, | |
486 intptr_t right_inst, char *right_op); | |
487 ~PeepConstraint(); | |
488 | |
489 // Check if constraints use instruction at position | |
490 bool constrains_instruction(intptr_t position); | |
491 | |
492 // Add another constraint | |
493 void append(PeepConstraint *next_peep_constraint); | |
494 // Access the next constraint in the list | |
495 PeepConstraint *next(); | |
496 | |
497 void dump(); | |
498 void output(FILE *fp); | |
499 }; | |
500 | |
501 | |
502 class PeepReplace : public Form { | |
503 private: | |
504 char *_rule; | |
505 NameList _instruction; | |
506 NameList _operand_inst_num; | |
507 NameList _operand_op_name; | |
508 | |
509 public: | |
510 | |
511 // Public Methods | |
512 PeepReplace(char *rule); | |
513 ~PeepReplace(); | |
514 | |
515 // Add contents of peepreplace | |
516 void add_instruction(char *root); | |
517 void add_operand( int inst_num, char *inst_operand ); | |
518 | |
519 // Access contents of peepreplace | |
520 void reset(); | |
521 void next_instruction(const char * &root); | |
522 void next_operand( intptr_t &inst_num, const char * &inst_operand ); | |
523 | |
524 // Utilities | |
525 void dump(); | |
526 void output(FILE *fp); | |
527 }; | |
528 | |
529 | |
530 class PeepChild : public Form { | |
531 public: | |
532 const int _inst_num; // Number of instruction (-1 if only named) | |
533 const char *_inst_op; // Instruction's operand, NULL if number == -1 | |
534 const char *_inst_name; // Name of the instruction | |
535 | |
536 public: | |
537 PeepChild(char *inst_name) | |
538 : _inst_num(-1), _inst_op(NULL), _inst_name(inst_name) {}; | |
539 PeepChild(int inst_num, char *inst_op, char *inst_name) | |
540 : _inst_num(inst_num), _inst_op(inst_op), _inst_name(inst_name) {}; | |
541 ~PeepChild(); | |
542 | |
543 bool use_leaf_operand() { return _inst_num != -1; }; | |
544 bool generate_an_instruction() { return _inst_num == -1; } | |
545 | |
546 void dump(); | |
547 void output(FILE *fp); | |
548 }; |