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