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