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