formsopt.hpp revision 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
28class Form;
29class InstructForm;
30class OperandForm;
31class OpClassForm;
32class AttributeForm;
33class RegisterForm;
34class PipelineForm;
35class SourceForm;
36class EncodeForm;
37class Component;
38class Constraint;
39class Predicate;
40class MatchRule;
41class Attribute;
42class Effect;
43class ExpandRule;
44class RewriteRule;
45class ConstructRule;
46class FormatRule;
47class Peephole;
48class PeepMatch;
49class PeepConstraint;
50class EncClass;
51class Interface;
52class RegInterface;
53class ConstInterface;
54class MemInterface;
55class CondInterface;
56class Opcode;
57class InsEncode;
58class RegDef;
59class RegClass;
60class AllocClass;
61class ResourceForm;
62class PipeClassForm;
63class PipeClassOperandForm;
64class PipeClassResourceForm;
65class PeepMatch;
66class PeepConstraint;
67class PeepReplace;
68class MatchList;
69
70class ArchDesc;
71
72//==============================Register Allocation============================
73//------------------------------RegisterForm-----------------------------------
74class RegisterForm : public Form {
75private:
76  AllocClass *_current_ac;         // State used by iter_RegDefs()
77
78public:
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-----------------------------------------
121class RegDef : public Form {
122public:
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
130private:
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
135public:
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---------------------------------------
154class RegClass : public Form {
155public:
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-------------------------------------
185class AllocClass : public Form {
186private:
187
188public:
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-------------------------------------
207class FrameForm : public Form {
208private:
209
210public:
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-----------------------------------
243class PipelineForm : public Form {
244private:
245
246public:
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-----------------------------------
281class ResourceForm : public Form {
282public:
283  unsigned mask() const { return _resmask; };
284
285private:
286  // Public Data
287  unsigned _resmask;         // Resource Mask (OR of resource specifier bits)
288
289public:
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-----------------------------
303class PipeClassOperandForm : public Form {
304private:
305
306public:
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--------------------------
328class PipeClassResourceForm : public Form {
329private:
330
331public:
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----------------------------------
352class PipeClassForm : public Form {
353private:
354
355public:
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---------------------------------------
405class Peephole : public Form {
406private:
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
415public:
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
440class PeepMatch : public Form {
441private:
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
450public:
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
472class PeepConstraint : public Form {
473private:
474  PeepConstraint *_next;           // Additional constraints ANDed together
475
476public:
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
483public:
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
502class PeepReplace : public Form {
503private:
504  char *_rule;
505  NameList _instruction;
506  NameList _operand_inst_num;
507  NameList _operand_op_name;
508
509public:
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
530class PeepChild : public Form {
531public:
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
536public:
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};
549