1 /*
  2  * Copyright (c) 1998, 2024, 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  */
 24 
 25 // FORMS.CPP - Definitions for ADL Parser Forms Classes
 26 #include "adlc.hpp"
 27 
 28 //==============================Register Allocation============================
 29 int RegisterForm::_reg_ctr = 0;
 30 
 31 //------------------------------RegisterForm-----------------------------------
 32 // Constructor
 33 RegisterForm::RegisterForm()
 34   : _current_ac(nullptr),
 35     _regDef(cmpstr,hashstr, Form::arena),
 36     _regClass(cmpstr,hashstr, Form::arena),
 37     _allocClass(cmpstr,hashstr, Form::arena) {
 38 }
 39 RegisterForm::~RegisterForm() {
 40 }
 41 
 42 // record a new register definition
 43 void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,
 44                              char *idealtype, char *encoding, char* concrete) {
 45   RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);
 46   _rdefs.addName(name);
 47   _regDef.Insert(name,regDef);
 48 }
 49 
 50 // record a new register class
 51 template <typename T>
 52 T* RegisterForm::addRegClass(const char* className) {
 53   T* regClass = new T(className);
 54   _rclasses.addName(className);
 55   _regClass.Insert(className, regClass);
 56   return regClass;
 57 }
 58 
 59 // Explicit instantiation for all supported register classes.
 60 template RegClass* RegisterForm::addRegClass<RegClass>(const char* className);
 61 template CodeSnippetRegClass* RegisterForm::addRegClass<CodeSnippetRegClass>(const char* className);
 62 template ConditionalRegClass* RegisterForm::addRegClass<ConditionalRegClass>(const char* className);
 63 
 64 // record a new register class
 65 AllocClass *RegisterForm::addAllocClass(char *className) {
 66   AllocClass *allocClass = new AllocClass(className);
 67   _aclasses.addName(className);
 68   _allocClass.Insert(className,allocClass);
 69   return allocClass;
 70 }
 71 
 72 // Called after parsing the Register block.  Record the register class
 73 // for spill-slots/regs.
 74 void RegisterForm::addSpillRegClass() {
 75   // Stack slots start at the next available even register number.
 76   _reg_ctr = (_reg_ctr+7) & ~7;
 77   const char *rc_name = "stack_slots";
 78   RegClass* reg_class = new RegClass(rc_name);
 79   reg_class->set_stack_version(true);
 80   _rclasses.addName(rc_name);
 81   _regClass.Insert(rc_name,reg_class);
 82 }
 83 
 84 // Called after parsing the Register block.  Record the register class
 85 // for operands which are overwritten after matching.
 86 void RegisterForm::addDynamicRegClass() {
 87   const char *rc_name = "dynamic";
 88   RegClass* reg_class = new RegClass(rc_name);
 89   reg_class->set_stack_version(false);
 90   _rclasses.addName(rc_name);
 91   _regClass.Insert(rc_name,reg_class);
 92 }
 93 
 94 // Provide iteration over all register definitions
 95 // in the order used by the register allocator
 96 void        RegisterForm::reset_RegDefs() {
 97   _current_ac = nullptr;
 98   _aclasses.reset();
 99 }
100 
101 RegDef     *RegisterForm::iter_RegDefs() {
102   // Check if we need to get the next AllocClass
103   if ( _current_ac == nullptr ) {
104     const char *ac_name = _aclasses.iter();
105     if( ac_name == nullptr )   return nullptr;   // No more allocation classes
106     _current_ac = (AllocClass*)_allocClass[ac_name];
107     _current_ac->_regDefs.reset();
108     assert( _current_ac != nullptr, "Name must match an allocation class");
109   }
110 
111   const char *rd_name = _current_ac->_regDefs.iter();
112   if( rd_name == nullptr ) {
113     // At end of this allocation class, check the next
114     _current_ac = nullptr;
115     return iter_RegDefs();
116   }
117   RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];
118   assert( reg_def != nullptr, "Name must match a register definition");
119   return reg_def;
120 }
121 
122 // return the register definition with name 'regName'
123 RegDef *RegisterForm::getRegDef(const char *regName) {
124   RegDef *regDef = (RegDef*)_regDef[regName];
125   return  regDef;
126 }
127 
128 // return the register class with name 'className'
129 RegClass *RegisterForm::getRegClass(const char *className) {
130   RegClass *regClass = (RegClass*)_regClass[className];
131   return    regClass;
132 }
133 
134 
135 // Check that register classes are compatible with chunks
136 bool   RegisterForm::verify() {
137   bool valid = true;
138 
139   // Verify Register Classes
140   // check that each register class contains registers from one chunk
141   const char *rc_name = nullptr;
142   _rclasses.reset();
143   while ( (rc_name = _rclasses.iter()) != nullptr ) {
144     // Check the chunk value for all registers in this class
145     RegClass *reg_class = getRegClass(rc_name);
146     assert( reg_class != nullptr, "InternalError() no matching register class");
147   } // end of RegClasses
148 
149   // Verify that every register has been placed into an allocation class
150   RegDef *reg_def = nullptr;
151   reset_RegDefs();
152   uint  num_register_zero = 0;
153   while ( (reg_def = iter_RegDefs()) != nullptr ) {
154     if( reg_def->register_num() == 0 )  ++num_register_zero;
155   }
156   if( num_register_zero > 1 ) {
157     fprintf(stderr,
158             "ERROR: More than one register has been assigned register-number 0.\n"
159             "Probably because a register has not been entered into an allocation class.\n");
160   }
161 
162   return  valid;
163 }
164 
165 // Compute RegMask size
166 int RegisterForm::RegMask_Size() {
167   // Need at least this many words
168   int words_for_regs = (_reg_ctr + 31)>>5;
169   // The array of Register Mask bits should be large enough to cover
170   // all the machine registers and all parameters that need to be passed
171   // on the stack (stack registers) up to some interesting limit.  Methods
172   // that need more parameters will NOT be compiled.  On Intel, the limit
173   // is something like 90+ parameters.
174   // - Add a few (3 words == 96 bits) for incoming & outgoing arguments to
175   //   calls.
176   // - Round up to the next doubleword size.
177   // - Add one more word to accommodate a reasonable number of stack locations
178   //   in the register mask regardless of how much slack is created by rounding.
179   //   This was found necessary after adding 16 new registers for APX.
180   return (words_for_regs + 3 + 1 + 1) & ~1;
181 }
182 
183 void RegisterForm::dump() {                  // Debug printer
184   output(stderr);
185 }
186 
187 void RegisterForm::output(FILE *fp) {          // Write info to output files
188   const char *name;
189   fprintf(fp,"\n");
190   fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
191   for(_rdefs.reset(); (name = _rdefs.iter()) != nullptr;) {
192     ((RegDef*)_regDef[name])->output(fp);
193   }
194   fprintf(fp,"\n");
195   for (_rclasses.reset(); (name = _rclasses.iter()) != nullptr;) {
196     ((RegClass*)_regClass[name])->output(fp);
197   }
198   fprintf(fp,"\n");
199   for (_aclasses.reset(); (name = _aclasses.iter()) != nullptr;) {
200     ((AllocClass*)_allocClass[name])->output(fp);
201   }
202   fprintf(fp,"-------------------- end  RegisterForm --------------------\n");
203 }
204 
205 void RegisterForm::forms_do(FormClosure *f) {
206   const char *name = nullptr;
207   if (_current_ac) f->do_form(_current_ac);
208   for(_rdefs.reset(); (name = _rdefs.iter()) != nullptr;) {
209     f->do_form((RegDef*)_regDef[name]);
210   }
211   for (_rclasses.reset(); (name = _rclasses.iter()) != nullptr;) {
212     f->do_form((RegClass*)_regClass[name]);
213   }
214   for (_aclasses.reset(); (name = _aclasses.iter()) != nullptr;) {
215     f->do_form((AllocClass*)_allocClass[name]);
216   }
217 }
218 
219 //------------------------------RegDef-----------------------------------------
220 // Constructor
221 RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
222   : _regname(regname), _callconv(callconv), _c_conv(c_conv),
223     _idealtype(idealtype),
224     _register_encode(encode),
225     _concrete(concrete),
226     _register_num(0) {
227 
228   // AdlChunk and register mask are determined by the register number
229   // _register_num is set when registers are added to an allocation class
230 }
231 RegDef::~RegDef() {                      // Destructor
232 }
233 
234 void RegDef::set_register_num(uint32 register_num) {
235   _register_num      = register_num;
236 }
237 
238 // Bit pattern used for generating machine code
239 const char* RegDef::register_encode() const {
240   return _register_encode;
241 }
242 
243 // Register number used in machine-independent code
244 uint32 RegDef::register_num()    const {
245   return _register_num;
246 }
247 
248 void RegDef::dump() {
249   output(stderr);
250 }
251 
252 void RegDef::output(FILE *fp) {         // Write info to output files
253   fprintf(fp,"RegDef: %s (%s) encode as %s  using number %d\n",
254           _regname, (_callconv?_callconv:""), _register_encode, _register_num);
255   fprintf(fp,"\n");
256 }
257 
258 
259 //------------------------------RegClass---------------------------------------
260 // Construct a register class into which registers will be inserted
261 RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) {
262 }
263 
264 RegClass::~RegClass() {
265 }
266 
267 // record a register in this class
268 void RegClass::addReg(RegDef *regDef) {
269   _regDefs.addName(regDef->_regname);
270   _regDef.Insert((void*)regDef->_regname, regDef);
271 }
272 
273 // Number of registers in class
274 uint RegClass::size() const {
275   return _regDef.Size();
276 }
277 
278 const RegDef *RegClass::get_RegDef(const char *rd_name) const {
279   return  (const RegDef*)_regDef[rd_name];
280 }
281 
282 void RegClass::reset() {
283   _regDefs.reset();
284 }
285 
286 const char *RegClass::rd_name_iter() {
287   return _regDefs.iter();
288 }
289 
290 RegDef *RegClass::RegDef_iter() {
291   const char *rd_name  = rd_name_iter();
292   RegDef     *reg_def  = rd_name ? (RegDef*)_regDef[rd_name] : nullptr;
293   return      reg_def;
294 }
295 
296 const RegDef* RegClass::find_first_elem() {
297   const RegDef* first = nullptr;
298   const RegDef* def = nullptr;
299 
300   reset();
301   while ((def = RegDef_iter()) != nullptr) {
302     if (first == nullptr || def->register_num() < first->register_num()) {
303       first = def;
304     }
305   }
306 
307   assert(first != nullptr, "empty mask?");
308   return first;;
309 }
310 
311 // Collect all the registers in this register-word.  One bit per register.
312 int RegClass::regs_in_word( int wordnum, bool stack_also ) {
313   int         word = 0;
314   const char *name;
315   for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
316     int rnum = ((RegDef*)_regDef[name])->register_num();
317     if( (rnum >> 5) == wordnum )
318       word |= (1 << (rnum & 31));
319   }
320   if( stack_also ) {
321     // Now also collect stack bits
322     for( int i = 0; i < 32; i++ )
323       if( wordnum*32+i >= RegisterForm::_reg_ctr )
324         word |= (1 << i);
325   }
326 
327   return word;
328 }
329 
330 void RegClass::dump() {
331   output(stderr);
332 }
333 
334 void RegClass::output(FILE *fp) {           // Write info to output files
335   fprintf(fp,"RegClass: %s\n",_classid);
336   const char *name;
337   for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
338     ((RegDef*)_regDef[name])->output(fp);
339   }
340   fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
341 }
342 
343 void RegClass::forms_do(FormClosure *f) {
344   const char *name = nullptr;
345   for( _regDefs.reset(); (name = _regDefs.iter()) != nullptr; ) {
346     f->do_form((RegDef*)_regDef[name]);
347   }
348 }
349 
350 void RegClass::declare_register_masks(FILE* fp) {
351   const char* prefix = "";
352   const char* rc_name_to_upper = toUpper(_classid);
353   fprintf(fp, "extern const RegMask _%s%s_mask;\n", prefix,  rc_name_to_upper);
354   fprintf(fp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);
355   if (_stack_or_reg) {
356     fprintf(fp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, rc_name_to_upper);
357     fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);
358   }
359   delete[] rc_name_to_upper;
360 }
361 
362 void RegClass::build_register_masks(FILE* fp) {
363   int len = RegisterForm::RegMask_Size();
364   const char *prefix = "";
365   const char* rc_name_to_upper = toUpper(_classid);
366   fprintf(fp, "const RegMask _%s%s_mask(", prefix, rc_name_to_upper);
367 
368   int i;
369   for(i = 0; i < len - 1; i++) {
370     fprintf(fp," 0x%x,", regs_in_word(i, false));
371   }
372   fprintf(fp," 0x%x );\n", regs_in_word(i, false));
373 
374   if (_stack_or_reg) {
375     fprintf(fp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, rc_name_to_upper);
376     for(i = 0; i < len - 1; i++) {
377       fprintf(fp," 0x%x,", regs_in_word(i, true));
378     }
379     fprintf(fp," 0x%x );\n", regs_in_word(i, true));
380   }
381   delete[] rc_name_to_upper;
382 }
383 
384 //------------------------------CodeSnippetRegClass---------------------------
385 CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(nullptr) {
386 }
387 
388 CodeSnippetRegClass::~CodeSnippetRegClass() {
389   delete _code_snippet;
390 }
391 
392 void CodeSnippetRegClass::declare_register_masks(FILE* fp) {
393   const char* prefix = "";
394   const char* rc_name_to_upper = toUpper(_classid);
395   fprintf(fp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, rc_name_to_upper, _code_snippet);
396   delete[] rc_name_to_upper;
397 }
398 
399 //------------------------------ConditionalRegClass---------------------------
400 ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(nullptr) {
401     _rclasses[0] = nullptr;
402     _rclasses[1] = nullptr;
403 }
404 
405 ConditionalRegClass::~ConditionalRegClass() {
406   delete _condition_code;
407 }
408 
409 void ConditionalRegClass::declare_register_masks(FILE* fp) {
410   const char* prefix = "";
411   const char* rc_name_to_upper = toUpper(_classid);
412   const char* rclass_0_to_upper = toUpper(_rclasses[0]->_classid);
413   const char* rclass_1_to_upper = toUpper(_rclasses[1]->_classid);
414   fprintf(fp, "inline const RegMask &%s%s_mask() {"
415               " return (%s) ?"
416               " %s%s_mask() :"
417               " %s%s_mask(); }\n",
418               prefix, rc_name_to_upper,
419               _condition_code,
420               prefix, rclass_0_to_upper,
421               prefix, rclass_1_to_upper);
422   if (_stack_or_reg) {
423     fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() {"
424                   " return (%s) ?"
425                   " %sSTACK_OR_%s_mask() :"
426                   " %sSTACK_OR_%s_mask(); }\n",
427                   prefix, rc_name_to_upper,
428                   _condition_code,
429                   prefix, rclass_0_to_upper,
430                   prefix, rclass_1_to_upper);
431   }
432   delete[] rc_name_to_upper;
433   delete[] rclass_0_to_upper;
434   delete[] rclass_1_to_upper;
435   return;
436 }
437 
438 //------------------------------AllocClass-------------------------------------
439 AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
440 }
441 
442 // record a register in this class
443 void AllocClass::addReg(RegDef *regDef) {
444   assert( regDef != nullptr, "Can not add a null to an allocation class");
445   regDef->set_register_num( RegisterForm::_reg_ctr++ );
446   // Add regDef to this allocation class
447   _regDefs.addName(regDef->_regname);
448   _regDef.Insert((void*)regDef->_regname, regDef);
449 }
450 
451 void AllocClass::dump() {
452   output(stderr);
453 }
454 
455 void AllocClass::output(FILE *fp) {       // Write info to output files
456   fprintf(fp,"AllocClass: %s \n",_classid);
457   const char *name;
458   for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
459     ((RegDef*)_regDef[name])->output(fp);
460   }
461   fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
462 }
463 
464 void AllocClass::forms_do(FormClosure* f) {
465   const char *name;
466   for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
467     f->do_form((RegDef*)_regDef[name]);
468   }
469   return;
470 }
471 
472 //==============================Frame Handling=================================
473 //------------------------------FrameForm--------------------------------------
474 FrameForm::FrameForm() {
475   _sync_stack_slots = nullptr;
476   _inline_cache_reg = nullptr;
477   _interpreter_frame_pointer_reg = nullptr;
478   _cisc_spilling_operand_name = nullptr;
479   _frame_pointer = nullptr;
480   _c_frame_pointer = nullptr;
481   _alignment = nullptr;
482   _return_addr_loc = false;
483   _c_return_addr_loc = false;
484   _return_addr = nullptr;
485   _c_return_addr = nullptr;
486   _varargs_C_out_slots_killed = nullptr;
487   _return_value = nullptr;
488   _c_return_value = nullptr;
489 }
490 
491 FrameForm::~FrameForm() {
492 }
493 
494 void FrameForm::dump() {
495   output(stderr);
496 }
497 
498 void FrameForm::output(FILE *fp) {           // Write info to output files
499   fprintf(fp,"\nFrame:\n");
500 }
501 
502 //==============================Scheduling=====================================
503 //------------------------------PipelineForm-----------------------------------
504 PipelineForm::PipelineForm()
505   :  _reslist               ()
506   ,  _resdict               (cmpstr, hashstr, Form::arena)
507   ,  _classdict             (cmpstr, hashstr, Form::arena)
508   ,  _rescount              (0)
509   ,  _maxcycleused          (0)
510   ,  _stages                ()
511   ,  _stagecnt              (0)
512   ,  _classlist             ()
513   ,  _classcnt              (0)
514   ,  _noplist               ()
515   ,  _nopcnt                (0)
516   ,  _variableSizeInstrs    (false)
517   ,  _branchHasDelaySlot    (false)
518   ,  _maxInstrsPerBundle    (0)
519   ,  _maxBundlesPerCycle    (1)
520   ,  _instrUnitSize         (0)
521   ,  _bundleUnitSize        (0)
522   ,  _instrFetchUnitSize    (0)
523   ,  _instrFetchUnits       (0) {
524 }
525 PipelineForm::~PipelineForm() {
526 }
527 
528 void PipelineForm::dump() {
529   output(stderr);
530 }
531 
532 void PipelineForm::output(FILE *fp) {           // Write info to output files
533   const char *res;
534   const char *stage;
535   const char *cls;
536   const char *nop;
537   int count = 0;
538 
539   fprintf(fp,"\nPipeline:");
540   if (_variableSizeInstrs)
541     if (_instrUnitSize > 0)
542       fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
543     else
544       fprintf(fp," variable-sized instructions");
545   else
546     if (_instrUnitSize > 0)
547       fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
548     else if (_bundleUnitSize > 0)
549       fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
550     else
551       fprintf(fp," fixed-sized instructions");
552   if (_branchHasDelaySlot)
553     fprintf(fp,", branch has delay slot");
554   if (_maxInstrsPerBundle > 0)
555     fprintf(fp,", max of %d instruction%s in parallel",
556       _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
557   if (_maxBundlesPerCycle > 0)
558     fprintf(fp,", max of %d bundle%s in parallel",
559       _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
560   if (_instrFetchUnitSize > 0 && _instrFetchUnits)
561     fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);
562 
563   fprintf(fp,"\nResource:");
564   for ( _reslist.reset(); (res = _reslist.iter()) != nullptr; )
565     fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
566   fprintf(fp,"\n");
567 
568   fprintf(fp,"\nDescription:\n");
569   for ( _stages.reset(); (stage = _stages.iter()) != nullptr; )
570     fprintf(fp," %s(%d)", stage, count++);
571   fprintf(fp,"\n");
572 
573   fprintf(fp,"\nClasses:\n");
574   for ( _classlist.reset(); (cls = _classlist.iter()) != nullptr; )
575     _classdict[cls]->is_pipeclass()->output(fp);
576 
577   fprintf(fp,"\nNop Instructions:");
578   for ( _noplist.reset(); (nop = _noplist.iter()) != nullptr; )
579     fprintf(fp, " \"%s\"", nop);
580   fprintf(fp,"\n");
581 }
582 
583 
584 //------------------------------ResourceForm-----------------------------------
585 ResourceForm::ResourceForm(unsigned resmask)
586 : _resmask(resmask) {
587 }
588 ResourceForm::~ResourceForm() {
589 }
590 
591 ResourceForm  *ResourceForm::is_resource() const {
592   return (ResourceForm *)(this);
593 }
594 
595 void ResourceForm::dump() {
596   output(stderr);
597 }
598 
599 void ResourceForm::output(FILE *fp) {          // Write info to output files
600   fprintf(fp, "resource: 0x%08x;\n", mask());
601 }
602 
603 
604 //------------------------------PipeClassOperandForm----------------------------------
605 
606 void PipeClassOperandForm::dump() {
607   output(stderr);
608 }
609 
610 void PipeClassOperandForm::output(FILE *fp) {         // Write info to output files
611   fprintf(stderr,"PipeClassOperandForm: %s", _stage);
612   fflush(stderr);
613   if (_more_instrs > 0)
614     fprintf(stderr,"+%d", _more_instrs);
615   fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
616   fflush(stderr);
617   fprintf(fp,"PipeClassOperandForm: %s", _stage);
618   if (_more_instrs > 0)
619     fprintf(fp,"+%d", _more_instrs);
620   fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
621 }
622 
623 
624 //------------------------------PipeClassResourceForm----------------------------------
625 
626 void PipeClassResourceForm::dump() {
627   output(stderr);
628 }
629 
630 void PipeClassResourceForm::output(FILE *fp) {         // Write info to output files
631   fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
632      _resource, _stage, _cycles);
633 }
634 
635 
636 //------------------------------PipeClassForm----------------------------------
637 PipeClassForm::PipeClassForm(const char *id, int num)
638   : _ident(id)
639   , _num(num)
640   , _localNames(cmpstr, hashstr, Form::arena)
641   , _localUsage(cmpstr, hashstr, Form::arena)
642   , _has_fixed_latency(0)
643   , _fixed_latency(0)
644   , _instruction_count(0)
645   , _has_multiple_bundles(false)
646   , _has_branch_delay_slot(false)
647   , _force_serialization(false)
648   , _may_have_no_code(false) {
649 }
650 
651 PipeClassForm::~PipeClassForm() {
652 }
653 
654 PipeClassForm  *PipeClassForm::is_pipeclass() const {
655   return (PipeClassForm *)(this);
656 }
657 
658 void PipeClassForm::dump() {
659   output(stderr);
660 }
661 
662 void PipeClassForm::output(FILE *fp) {         // Write info to output files
663   fprintf(fp,"PipeClassForm: #%03d", _num);
664   if (_ident)
665      fprintf(fp," \"%s\":", _ident);
666   if (_has_fixed_latency)
667      fprintf(fp," latency %d", _fixed_latency);
668   if (_force_serialization)
669      fprintf(fp, ", force serialization");
670   if (_may_have_no_code)
671      fprintf(fp, ", may have no code");
672   fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
673 }
674 
675 
676 //==============================Peephole Optimization==========================
677 int Peephole::_peephole_counter = 0;
678 //------------------------------Peephole---------------------------------------
679 Peephole::Peephole() : _predicate(nullptr), _match(nullptr), _procedure(nullptr),
680                        _constraint(nullptr), _replace(nullptr), _next(nullptr) {
681   _peephole_number = _peephole_counter++;
682 }
683 Peephole::~Peephole() {
684 }
685 
686 // Append a peephole rule with the same root instruction
687 void Peephole::append_peephole(Peephole *next_peephole) {
688   if( _next == nullptr ) {
689     _next = next_peephole;
690   } else {
691     _next->append_peephole( next_peephole );
692   }
693 }
694 
695 // Add a predicate to this peephole rule
696 void Peephole::add_predicate(PeepPredicate* predicate) {
697   assert( _predicate == nullptr, "fatal()" );
698   _predicate = predicate;
699 }
700 
701 // Store the components of this peephole rule
702 void Peephole::add_match(PeepMatch *match) {
703   assert( _match == nullptr, "fatal()" );
704   _match = match;
705 }
706 
707 // Add a procedure to this peephole rule
708 void Peephole::add_procedure(PeepProcedure* procedure) {
709   assert( _procedure == nullptr, "fatal()" );
710   _procedure = procedure;
711 }
712 
713 void Peephole::append_constraint(PeepConstraint *next_constraint) {
714   if( _constraint == nullptr ) {
715     _constraint = next_constraint;
716   } else {
717     _constraint->append( next_constraint );
718   }
719 }
720 
721 void Peephole::add_replace(PeepReplace *replace) {
722   assert( _replace == nullptr, "fatal()" );
723   _replace = replace;
724 }
725 
726 // class Peephole accessor methods are in the declaration.
727 
728 
729 void Peephole::dump() {
730   output(stderr);
731 }
732 
733 void Peephole::output(FILE *fp) {         // Write info to output files
734   fprintf(fp,"Peephole:\n");
735   if( _match != nullptr )       _match->output(fp);
736   if( _constraint != nullptr )  _constraint->output(fp);
737   if( _replace != nullptr )     _replace->output(fp);
738   // Output the next entry
739   if( _next ) _next->output(fp);
740 }
741 
742 void Peephole::forms_do(FormClosure *f) {
743   if (_predicate) f->do_form(_predicate);
744   if (_match) f->do_form(_match);
745   if (_procedure) f->do_form(_procedure);
746   if (_constraint) f->do_form(_constraint);
747   if (_replace) f->do_form(_replace);
748   return;
749 }
750 
751 //----------------------------PeepPredicate------------------------------------
752 PeepPredicate::PeepPredicate(const char* rule) : _rule(rule) {
753 }
754 PeepPredicate::~PeepPredicate() {
755 }
756 
757 const char* PeepPredicate::rule() const {
758   return _rule;
759 }
760 
761 void PeepPredicate::dump() {
762   output(stderr);
763 }
764 
765 void PeepPredicate::output(FILE* fp) {
766   fprintf(fp, "PeepPredicate\n");
767 }
768 
769 //------------------------------PeepMatch--------------------------------------
770 PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
771 }
772 PeepMatch::~PeepMatch() {
773 }
774 
775 // Insert info into the match-rule
776 void  PeepMatch::add_instruction(int parent, int position, const char *name,
777                                  int input) {
778   if( position > _max_position ) _max_position = position;
779 
780   _parent.addName((char*) (intptr_t) parent);
781   _position.addName((char*) (intptr_t) position);
782   _instrs.addName(name);
783   _input.addName((char*) (intptr_t) input);
784 }
785 
786 // Access info about instructions in the peep-match rule
787 int   PeepMatch::max_position() {
788   return _max_position;
789 }
790 
791 const char *PeepMatch::instruction_name(int position) {
792   return _instrs.name(position);
793 }
794 
795 // Iterate through all info on matched instructions
796 void  PeepMatch::reset() {
797   _parent.reset();
798   _position.reset();
799   _instrs.reset();
800   _input.reset();
801 }
802 
803 void  PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {
804   parent   = (int) (intptr_t) _parent.iter();
805   position = (int) (intptr_t) _position.iter();
806   name     = _instrs.iter();
807   input    = (int) (intptr_t) _input.iter();
808 }
809 
810 // 'true' if current position in iteration is a placeholder, not matched.
811 bool  PeepMatch::is_placeholder() {
812   return _instrs.current_is_signal();
813 }
814 
815 
816 void PeepMatch::dump() {
817   output(stderr);
818 }
819 
820 void PeepMatch::output(FILE *fp) {        // Write info to output files
821   fprintf(fp,"PeepMatch:\n");
822 }
823 
824 //----------------------------PeepProcedure------------------------------------
825 PeepProcedure::PeepProcedure(const char* name) : _name(name) {
826 }
827 PeepProcedure::~PeepProcedure() {
828 }
829 
830 const char* PeepProcedure::name() const {
831   return _name;
832 }
833 
834 void PeepProcedure::dump() {
835   output(stderr);
836 }
837 
838 void PeepProcedure::output(FILE* fp) {
839   fprintf(fp, "PeepProcedure\n");
840 }
841 
842 //------------------------------PeepConstraint---------------------------------
843 PeepConstraint::PeepConstraint(int left_inst,  char* left_op, char* relation,
844                                int right_inst, char* right_op)
845   : _left_inst(left_inst), _left_op(left_op), _relation(relation),
846     _right_inst(right_inst), _right_op(right_op), _next(nullptr) {}
847 PeepConstraint::~PeepConstraint() {
848 }
849 
850 // Check if constraints use instruction at position
851 bool PeepConstraint::constrains_instruction(int position) {
852   // Check local instruction constraints
853   if( _left_inst  == position ) return true;
854   if( _right_inst == position ) return true;
855 
856   // Check remaining constraints in list
857   if( _next == nullptr )  return false;
858   else                 return _next->constrains_instruction(position);
859 }
860 
861 // Add another constraint
862 void PeepConstraint::append(PeepConstraint *next_constraint) {
863   if( _next == nullptr ) {
864     _next = next_constraint;
865   } else {
866     _next->append( next_constraint );
867   }
868 }
869 
870 // Access the next constraint in the list
871 PeepConstraint *PeepConstraint::next() {
872   return _next;
873 }
874 
875 
876 void PeepConstraint::dump() {
877   output(stderr);
878 }
879 
880 void PeepConstraint::output(FILE *fp) {   // Write info to output files
881   fprintf(fp,"PeepConstraint:\n");
882 }
883 
884 //------------------------------PeepReplace------------------------------------
885 PeepReplace::PeepReplace(char *rule) : _rule(rule) {
886 }
887 PeepReplace::~PeepReplace() {
888 }
889 
890 // Add contents of peepreplace
891 void  PeepReplace::add_instruction(char *root) {
892   _instruction.addName(root);
893   _operand_inst_num.add_signal();
894   _operand_op_name.add_signal();
895 }
896 void  PeepReplace::add_operand( int inst_num, char *inst_operand ) {
897   _instruction.add_signal();
898   _operand_inst_num.addName((char*) (intptr_t) inst_num);
899   _operand_op_name.addName(inst_operand);
900 }
901 
902 // Access contents of peepreplace
903 void  PeepReplace::reset() {
904   _instruction.reset();
905   _operand_inst_num.reset();
906   _operand_op_name.reset();
907 }
908 void  PeepReplace::next_instruction(const char* &inst){
909   inst                     = _instruction.iter();
910   int         inst_num     = (int) (intptr_t) _operand_inst_num.iter();
911   const char* inst_operand = _operand_op_name.iter();
912 }
913 void  PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {
914   const char* inst = _instruction.iter();
915   inst_num         = (int) (intptr_t) _operand_inst_num.iter();
916   inst_operand     = _operand_op_name.iter();
917 }
918 
919 
920 
921 void PeepReplace::dump() {
922   output(stderr);
923 }
924 
925 void PeepReplace::output(FILE *fp) {      // Write info to output files
926   fprintf(fp,"PeepReplace:\n");
927 }