formsopt.cpp revision 0:a61af66fc99e
1343181Sdim/*
2343181Sdim * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
3353358Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4353358Sdim *
5353358Sdim * This code is free software; you can redistribute it and/or modify it
6343181Sdim * under the terms of the GNU General Public License version 2 only, as
7343181Sdim * published by the Free Software Foundation.
8343181Sdim *
9343181Sdim * This code is distributed in the hope that it will be useful, but WITHOUT
10343181Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11343181Sdim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12343181Sdim * version 2 for more details (a copy is included in the LICENSE file that
13343181Sdim * accompanied this code).
14343181Sdim *
15343181Sdim * You should have received a copy of the GNU General Public License version
16343181Sdim * 2 along with this work; if not, write to the Free Software Foundation,
17343181Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18343181Sdim *
19343181Sdim * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20343181Sdim * CA 95054 USA or visit www.sun.com if you need additional information or
21343181Sdim * have any questions.
22343181Sdim *
23343181Sdim */
24343181Sdim
25353358Sdim// FORMS.CPP - Definitions for ADL Parser Forms Classes
26353358Sdim#include "adlc.hpp"
27343181Sdim
28343181Sdim//==============================Register Allocation============================
29343181Sdimint RegisterForm::_reg_ctr = 0;
30343181Sdim
31343181Sdim//------------------------------RegisterForm-----------------------------------
32343181Sdim// Constructor
33343181SdimRegisterForm::RegisterForm()
34343181Sdim  : _regDef(cmpstr,hashstr, Form::arena),
35343181Sdim    _regClass(cmpstr,hashstr, Form::arena),
36343181Sdim    _allocClass(cmpstr,hashstr, Form::arena) {
37343181Sdim}
38343181SdimRegisterForm::~RegisterForm() {
39343181Sdim}
40343181Sdim
41343181Sdim// record a new register definition
42343181Sdimvoid RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,
43343181Sdim                             char *idealtype, char *encoding, char* concrete) {
44343181Sdim  RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);
45343181Sdim  _rdefs.addName(name);
46343181Sdim  _regDef.Insert(name,regDef);
47343181Sdim}
48343181Sdim
49343181Sdim// record a new register class
50343181SdimRegClass *RegisterForm::addRegClass(const char *className) {
51343181Sdim  RegClass *regClass = new RegClass(className);
52343181Sdim  _rclasses.addName(className);
53343181Sdim  _regClass.Insert(className,regClass);
54343181Sdim  return regClass;
55343181Sdim}
56343181Sdim
57343181Sdim// record a new register class
58343181SdimAllocClass *RegisterForm::addAllocClass(char *className) {
59343181Sdim  AllocClass *allocClass = new AllocClass(className);
60343181Sdim  _aclasses.addName(className);
61343181Sdim  _allocClass.Insert(className,allocClass);
62343181Sdim  return allocClass;
63343181Sdim}
64343181Sdim
65343181Sdim// Called after parsing the Register block.  Record the register class
66343181Sdim// for spill-slots/regs.
67343181Sdimvoid RegisterForm::addSpillRegClass() {
68343181Sdim  // Stack slots start at the next available even register number.
69343181Sdim  _reg_ctr = (_reg_ctr+1) & ~1;
70343181Sdim  const char *rc_name   = "stack_slots";
71343181Sdim  RegClass   *reg_class = new RegClass(rc_name);
72343181Sdim  reg_class->_stack_or_reg = true;
73343181Sdim  _rclasses.addName(rc_name);
74343181Sdim  _regClass.Insert(rc_name,reg_class);
75343181Sdim}
76343181Sdim
77343181Sdim
78343181Sdim// Provide iteration over all register definitions
79343181Sdim// in the order used by the register allocator
80343181Sdimvoid        RegisterForm::reset_RegDefs() {
81343181Sdim  _current_ac = NULL;
82343181Sdim  _aclasses.reset();
83343181Sdim}
84343181Sdim
85343181SdimRegDef     *RegisterForm::iter_RegDefs() {
86343181Sdim  // Check if we need to get the next AllocClass
87343181Sdim  if ( _current_ac == NULL ) {
88343181Sdim    const char *ac_name = _aclasses.iter();
89343181Sdim    if( ac_name == NULL )   return NULL;   // No more allocation classes
90343181Sdim    _current_ac = (AllocClass*)_allocClass[ac_name];
91343181Sdim    _current_ac->_regDefs.reset();
92343181Sdim    assert( _current_ac != NULL, "Name must match an allocation class");
93343181Sdim  }
94343181Sdim
95343181Sdim  const char *rd_name = _current_ac->_regDefs.iter();
96343181Sdim  if( rd_name == NULL ) {
97343181Sdim    // At end of this allocation class, check the next
98343181Sdim    _current_ac = NULL;
99343181Sdim    return iter_RegDefs();
100343181Sdim  }
101343181Sdim  RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];
102343181Sdim  assert( reg_def != NULL, "Name must match a register definition");
103343181Sdim  return reg_def;
104343181Sdim}
105343181Sdim
106343181Sdim// return the register definition with name 'regName'
107343181SdimRegDef *RegisterForm::getRegDef(const char *regName) {
108343181Sdim  RegDef *regDef = (RegDef*)_regDef[regName];
109343181Sdim  return  regDef;
110343181Sdim}
111343181Sdim
112343181Sdim// return the register class with name 'className'
113343181SdimRegClass *RegisterForm::getRegClass(const char *className) {
114353358Sdim  RegClass *regClass = (RegClass*)_regClass[className];
115343181Sdim  return    regClass;
116343181Sdim}
117343181Sdim
118343181Sdim
119343181Sdim// Check that register classes are compatible with chunks
120353358Sdimbool   RegisterForm::verify() {
121343181Sdim  bool valid = true;
122343181Sdim
123343181Sdim  // Verify Register Classes
124343181Sdim  // check that each register class contains registers from one chunk
125360784Sdim  const char *rc_name = NULL;
126343181Sdim  _rclasses.reset();
127343181Sdim  while ( (rc_name = _rclasses.iter()) != NULL ) {
128343181Sdim    // Check the chunk value for all registers in this class
129343181Sdim    RegClass *reg_class = getRegClass(rc_name);
130343181Sdim    assert( reg_class != NULL, "InternalError() no matching register class");
131343181Sdim  } // end of RegClasses
132343181Sdim
133343181Sdim  // Verify that every register has been placed into an allocation class
134343181Sdim  RegDef *reg_def = NULL;
135343181Sdim  reset_RegDefs();
136343181Sdim  uint  num_register_zero = 0;
137343181Sdim  while ( (reg_def = iter_RegDefs()) != NULL ) {
138343181Sdim    if( reg_def->register_num() == 0 )  ++num_register_zero;
139343181Sdim  }
140343181Sdim  if( num_register_zero > 1 ) {
141343181Sdim    fprintf(stderr,
142343181Sdim            "ERROR: More than one register has been assigned register-number 0.\n"
143343181Sdim            "Probably because a register has not been entered into an allocation class.\n");
144343181Sdim  }
145343181Sdim
146343181Sdim  return  valid;
147343181Sdim}
148343181Sdim
149343181Sdim// Compute RegMask size
150343181Sdimint RegisterForm::RegMask_Size() {
151343181Sdim  // Need at least this many words
152343181Sdim  int words_for_regs = (_reg_ctr + 31)>>5;
153343181Sdim  // Add a few for incoming & outgoing arguments to calls.
154343181Sdim  // Round up to the next doubleword size.
155343181Sdim  return (words_for_regs + 2 + 1) & ~1;
156343181Sdim}
157343181Sdim
158343181Sdimvoid RegisterForm::dump() {                  // Debug printer
159343181Sdim  output(stderr);
160343181Sdim}
161343181Sdim
162343181Sdimvoid RegisterForm::output(FILE *fp) {          // Write info to output files
163343181Sdim  const char *name;
164343181Sdim  fprintf(fp,"\n");
165343181Sdim  fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
166343181Sdim  for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {
167343181Sdim    ((RegDef*)_regDef[name])->output(fp);
168343181Sdim  }
169343181Sdim  fprintf(fp,"\n");
170343181Sdim  for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {
171353358Sdim    ((RegClass*)_regClass[name])->output(fp);
172353358Sdim  }
173353358Sdim  fprintf(fp,"\n");
174353358Sdim  for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {
175353358Sdim    ((AllocClass*)_allocClass[name])->output(fp);
176353358Sdim  }
177353358Sdim  fprintf(fp,"-------------------- end  RegisterForm --------------------\n");
178353358Sdim}
179353358Sdim
180353358Sdim//------------------------------RegDef-----------------------------------------
181353358Sdim// Constructor
182353358SdimRegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
183353358Sdim  : _regname(regname), _callconv(callconv), _c_conv(c_conv),
184353358Sdim    _idealtype(idealtype),
185353358Sdim    _register_encode(encode),
186353358Sdim    _concrete(concrete),
187353358Sdim    _register_num(0) {
188353358Sdim
189353358Sdim  // Chunk and register mask are determined by the register number
190353358Sdim  // _register_num is set when registers are added to an allocation class
191353358Sdim}
192353358SdimRegDef::~RegDef() {                      // Destructor
193353358Sdim}
194353358Sdim
195353358Sdimvoid RegDef::set_register_num(uint32 register_num) {
196353358Sdim  _register_num      = register_num;
197353358Sdim}
198343181Sdim
199343181Sdim// Bit pattern used for generating machine code
200343181Sdimconst char* RegDef::register_encode() const {
201343181Sdim  return _register_encode;
202343181Sdim}
203343181Sdim
204343181Sdim// Register number used in machine-independent code
205343181Sdimuint32 RegDef::register_num()    const {
206343181Sdim  return _register_num;
207343181Sdim}
208343181Sdim
209343181Sdimvoid RegDef::dump() {
210353358Sdim  output(stderr);
211343181Sdim}
212343181Sdim
213343181Sdimvoid RegDef::output(FILE *fp) {         // Write info to output files
214343181Sdim  fprintf(fp,"RegDef: %s (%s) encode as %s  using number %d\n",
215343181Sdim          _regname, (_callconv?_callconv:""), _register_encode, _register_num);
216343181Sdim  fprintf(fp,"\n");
217343181Sdim}
218343181Sdim
219343181Sdim
220343181Sdim//------------------------------RegClass---------------------------------------
221343181Sdim// Construct a register class into which registers will be inserted
222343181SdimRegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
223343181Sdim}
224343181Sdim
225343181Sdim// record a register in this class
226343181Sdimvoid RegClass::addReg(RegDef *regDef) {
227343181Sdim  _regDefs.addName(regDef->_regname);
228343181Sdim  _regDef.Insert((void*)regDef->_regname, regDef);
229343181Sdim}
230343181Sdim
231343181Sdim// Number of registers in class
232343181Sdimuint RegClass::size() const {
233343181Sdim  return _regDef.Size();
234343181Sdim}
235343181Sdim
236343181Sdimconst RegDef *RegClass::get_RegDef(const char *rd_name) const {
237343181Sdim  return  (const RegDef*)_regDef[rd_name];
238343181Sdim}
239343181Sdim
240343181Sdimvoid RegClass::reset() {
241343181Sdim  _regDefs.reset();
242343181Sdim}
243343181Sdim
244343181Sdimconst char *RegClass::rd_name_iter() {
245343181Sdim  return _regDefs.iter();
246343181Sdim}
247343181Sdim
248343181SdimRegDef *RegClass::RegDef_iter() {
249343181Sdim  const char *rd_name  = rd_name_iter();
250360784Sdim  RegDef     *reg_def  = rd_name ? (RegDef*)_regDef[rd_name] : NULL;
251343181Sdim  return      reg_def;
252343181Sdim}
253
254const RegDef* RegClass::find_first_elem() {
255  const RegDef* first = NULL;
256  const RegDef* def = NULL;
257
258  reset();
259  while ((def = RegDef_iter()) != NULL) {
260    if (first == NULL || def->register_num() < first->register_num()) {
261      first = def;
262    }
263  }
264
265  assert(first != NULL, "empty mask?");
266  return first;;
267}
268
269// Collect all the registers in this register-word.  One bit per register.
270int RegClass::regs_in_word( int wordnum, bool stack_also ) {
271  int         word = 0;
272  const char *name;
273  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
274    int rnum = ((RegDef*)_regDef[name])->register_num();
275    if( (rnum >> 5) == wordnum )
276      word |= (1L<<(rnum&31));
277  }
278  if( stack_also ) {
279    // Now also collect stack bits
280    for( int i = 0; i < 32; i++ )
281      if( wordnum*32+i >= RegisterForm::_reg_ctr )
282        word |= (1L<<i);
283  }
284
285  return word;
286}
287
288void RegClass::dump() {
289  output(stderr);
290}
291
292void RegClass::output(FILE *fp) {           // Write info to output files
293  fprintf(fp,"RegClass: %s\n",_classid);
294  const char *name;
295  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
296    ((RegDef*)_regDef[name])->output(fp);
297  }
298  fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
299}
300
301
302//------------------------------AllocClass-------------------------------------
303AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
304}
305
306// record a register in this class
307void AllocClass::addReg(RegDef *regDef) {
308  assert( regDef != NULL, "Can not add a NULL to an allocation class");
309  regDef->set_register_num( RegisterForm::_reg_ctr++ );
310  // Add regDef to this allocation class
311  _regDefs.addName(regDef->_regname);
312  _regDef.Insert((void*)regDef->_regname, regDef);
313}
314
315void AllocClass::dump() {
316  output(stderr);
317}
318
319void AllocClass::output(FILE *fp) {       // Write info to output files
320  fprintf(fp,"AllocClass: %s \n",_classid);
321  const char *name;
322  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
323    ((RegDef*)_regDef[name])->output(fp);
324  }
325  fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
326}
327
328//==============================Frame Handling=================================
329//------------------------------FrameForm--------------------------------------
330FrameForm::FrameForm() {
331  _frame_pointer = NULL;
332  _c_frame_pointer = NULL;
333  _alignment = NULL;
334  _return_addr = NULL;
335  _c_return_addr = NULL;
336  _in_preserve_slots = NULL;
337  _varargs_C_out_slots_killed = NULL;
338  _calling_convention = NULL;
339  _c_calling_convention = NULL;
340  _return_value = NULL;
341  _c_return_value = NULL;
342  _interpreter_frame_pointer_reg = NULL;
343}
344
345FrameForm::~FrameForm() {
346}
347
348void FrameForm::dump() {
349  output(stderr);
350}
351
352void FrameForm::output(FILE *fp) {           // Write info to output files
353  fprintf(fp,"\nFrame:\n");
354}
355
356//==============================Scheduling=====================================
357//------------------------------PipelineForm-----------------------------------
358PipelineForm::PipelineForm()
359  :  _reslist               ()
360  ,  _resdict               (cmpstr, hashstr, Form::arena)
361  ,  _classdict             (cmpstr, hashstr, Form::arena)
362  ,  _rescount              (0)
363  ,  _maxcycleused          (0)
364  ,  _stages                ()
365  ,  _stagecnt              (0)
366  ,  _classlist             ()
367  ,  _classcnt              (0)
368  ,  _noplist               ()
369  ,  _nopcnt                (0)
370  ,  _variableSizeInstrs    (false)
371  ,  _branchHasDelaySlot    (false)
372  ,  _maxInstrsPerBundle    (0)
373  ,  _maxBundlesPerCycle    (1)
374  ,  _instrUnitSize         (0)
375  ,  _bundleUnitSize        (0)
376  ,  _instrFetchUnitSize    (0)
377  ,  _instrFetchUnits       (0) {
378}
379PipelineForm::~PipelineForm() {
380}
381
382void PipelineForm::dump() {
383  output(stderr);
384}
385
386void PipelineForm::output(FILE *fp) {           // Write info to output files
387  const char *res;
388  const char *stage;
389  const char *cls;
390  const char *nop;
391  int count = 0;
392
393  fprintf(fp,"\nPipeline:");
394  if (_variableSizeInstrs)
395    if (_instrUnitSize > 0)
396      fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
397    else
398      fprintf(fp," variable-sized instructions");
399  else
400    if (_instrUnitSize > 0)
401      fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
402    else if (_bundleUnitSize > 0)
403      fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
404    else
405      fprintf(fp," fixed-sized instructions");
406  if (_branchHasDelaySlot)
407    fprintf(fp,", branch has delay slot");
408  if (_maxInstrsPerBundle > 0)
409    fprintf(fp,", max of %d instruction%s in parallel",
410      _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
411  if (_maxBundlesPerCycle > 0)
412    fprintf(fp,", max of %d bundle%s in parallel",
413      _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
414  if (_instrFetchUnitSize > 0 && _instrFetchUnits)
415    fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);
416
417  fprintf(fp,"\nResource:");
418  for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )
419    fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
420  fprintf(fp,"\n");
421
422  fprintf(fp,"\nDescription:\n");
423  for ( _stages.reset(); (stage = _stages.iter()) != NULL; )
424    fprintf(fp," %s(%d)", stage, count++);
425  fprintf(fp,"\n");
426
427  fprintf(fp,"\nClasses:\n");
428  for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )
429    _classdict[cls]->is_pipeclass()->output(fp);
430
431  fprintf(fp,"\nNop Instructions:");
432  for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )
433    fprintf(fp, " \"%s\"", nop);
434  fprintf(fp,"\n");
435}
436
437
438//------------------------------ResourceForm-----------------------------------
439ResourceForm::ResourceForm(unsigned resmask)
440: _resmask(resmask) {
441}
442ResourceForm::~ResourceForm() {
443}
444
445ResourceForm  *ResourceForm::is_resource() const {
446  return (ResourceForm *)(this);
447}
448
449void ResourceForm::dump() {
450  output(stderr);
451}
452
453void ResourceForm::output(FILE *fp) {          // Write info to output files
454  fprintf(fp, "resource: 0x%08x;\n", mask());
455}
456
457
458//------------------------------PipeClassOperandForm----------------------------------
459
460void PipeClassOperandForm::dump() {
461  output(stderr);
462}
463
464void PipeClassOperandForm::output(FILE *fp) {         // Write info to output files
465  fprintf(stderr,"PipeClassOperandForm: %s", _stage);
466  fflush(stderr);
467  if (_more_instrs > 0)
468    fprintf(stderr,"+%d", _more_instrs);
469  fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
470  fflush(stderr);
471  fprintf(fp,"PipeClassOperandForm: %s", _stage);
472  if (_more_instrs > 0)
473    fprintf(fp,"+%d", _more_instrs);
474  fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
475}
476
477
478//------------------------------PipeClassResourceForm----------------------------------
479
480void PipeClassResourceForm::dump() {
481  output(stderr);
482}
483
484void PipeClassResourceForm::output(FILE *fp) {         // Write info to output files
485  fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
486     _resource, _stage, _cycles);
487}
488
489
490//------------------------------PipeClassForm----------------------------------
491PipeClassForm::PipeClassForm(const char *id, int num)
492  : _ident(id)
493  , _num(num)
494  , _localNames(cmpstr, hashstr, Form::arena)
495  , _localUsage(cmpstr, hashstr, Form::arena)
496  , _has_fixed_latency(0)
497  , _fixed_latency(0)
498  , _instruction_count(0)
499  , _has_multiple_bundles(false)
500  , _has_branch_delay_slot(false)
501  , _force_serialization(false)
502  , _may_have_no_code(false) {
503}
504
505PipeClassForm::~PipeClassForm() {
506}
507
508PipeClassForm  *PipeClassForm::is_pipeclass() const {
509  return (PipeClassForm *)(this);
510}
511
512void PipeClassForm::dump() {
513  output(stderr);
514}
515
516void PipeClassForm::output(FILE *fp) {         // Write info to output files
517  fprintf(fp,"PipeClassForm: #%03d", _num);
518  if (_ident)
519     fprintf(fp," \"%s\":", _ident);
520  if (_has_fixed_latency)
521     fprintf(fp," latency %d", _fixed_latency);
522  if (_force_serialization)
523     fprintf(fp, ", force serialization");
524  if (_may_have_no_code)
525     fprintf(fp, ", may have no code");
526  fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
527}
528
529
530//==============================Peephole Optimization==========================
531int Peephole::_peephole_counter = 0;
532//------------------------------Peephole---------------------------------------
533Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {
534  _peephole_number = _peephole_counter++;
535}
536Peephole::~Peephole() {
537}
538
539// Append a peephole rule with the same root instruction
540void Peephole::append_peephole(Peephole *next_peephole) {
541  if( _next == NULL ) {
542    _next = next_peephole;
543  } else {
544    _next->append_peephole( next_peephole );
545  }
546}
547
548// Store the components of this peephole rule
549void Peephole::add_match(PeepMatch *match) {
550  assert( _match == NULL, "fatal()" );
551  _match = match;
552}
553
554void Peephole::append_constraint(PeepConstraint *next_constraint) {
555  if( _constraint == NULL ) {
556    _constraint = next_constraint;
557  } else {
558    _constraint->append( next_constraint );
559  }
560}
561
562void Peephole::add_replace(PeepReplace *replace) {
563  assert( _replace == NULL, "fatal()" );
564  _replace = replace;
565}
566
567// class Peephole accessor methods are in the declaration.
568
569
570void Peephole::dump() {
571  output(stderr);
572}
573
574void Peephole::output(FILE *fp) {         // Write info to output files
575  fprintf(fp,"Peephole:\n");
576  if( _match != NULL )       _match->output(fp);
577  if( _constraint != NULL )  _constraint->output(fp);
578  if( _replace != NULL )     _replace->output(fp);
579  // Output the next entry
580  if( _next ) _next->output(fp);
581}
582
583//------------------------------PeepMatch--------------------------------------
584PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
585}
586PeepMatch::~PeepMatch() {
587}
588
589
590// Insert info into the match-rule
591void  PeepMatch::add_instruction(int parent, int position, const char *name,
592                                 int input) {
593  if( position > _max_position ) _max_position = position;
594
595  _parent.addName((char *)parent);
596  _position.addName((char *)position);
597  _instrs.addName(name);
598  _input.addName((char *)input);
599}
600
601// Access info about instructions in the peep-match rule
602int   PeepMatch::max_position() {
603  return _max_position;
604}
605
606const char *PeepMatch::instruction_name(intptr_t position) {
607  return _instrs.name(position);
608}
609
610// Iterate through all info on matched instructions
611void  PeepMatch::reset() {
612  _parent.reset();
613  _position.reset();
614  _instrs.reset();
615  _input.reset();
616}
617
618void  PeepMatch::next_instruction( intptr_t &parent, intptr_t &position, const char * &name, intptr_t &input ){
619  parent   = (intptr_t)_parent.iter();
620  position = (intptr_t)_position.iter();
621  name     = _instrs.iter();
622  input    = (intptr_t)_input.iter();
623}
624
625// 'true' if current position in iteration is a placeholder, not matched.
626bool  PeepMatch::is_placeholder() {
627  return _instrs.current_is_signal();
628}
629
630
631void PeepMatch::dump() {
632  output(stderr);
633}
634
635void PeepMatch::output(FILE *fp) {        // Write info to output files
636  fprintf(fp,"PeepMatch:\n");
637}
638
639//------------------------------PeepConstraint---------------------------------
640PeepConstraint::PeepConstraint(intptr_t  left_inst,  char *left_op, char *relation,
641                               intptr_t  right_inst, char *right_op)
642  : _left_inst(left_inst), _left_op(left_op), _relation(relation),
643    _right_inst(right_inst), _right_op(right_op), _next(NULL) {}
644PeepConstraint::~PeepConstraint() {
645}
646
647// Check if constraints use instruction at position
648bool PeepConstraint::constrains_instruction(intptr_t position) {
649  // Check local instruction constraints
650  if( _left_inst  == position ) return true;
651  if( _right_inst == position ) return true;
652
653  // Check remaining constraints in list
654  if( _next == NULL )  return false;
655  else                 return _next->constrains_instruction(position);
656}
657
658// Add another constraint
659void PeepConstraint::append(PeepConstraint *next_constraint) {
660  if( _next == NULL ) {
661    _next = next_constraint;
662  } else {
663    _next->append( next_constraint );
664  }
665}
666
667// Access the next constraint in the list
668PeepConstraint *PeepConstraint::next() {
669  return _next;
670}
671
672
673void PeepConstraint::dump() {
674  output(stderr);
675}
676
677void PeepConstraint::output(FILE *fp) {   // Write info to output files
678  fprintf(fp,"PeepConstraint:\n");
679}
680
681//------------------------------PeepReplace------------------------------------
682PeepReplace::PeepReplace(char *rule) : _rule(rule) {
683}
684PeepReplace::~PeepReplace() {
685}
686
687// Add contents of peepreplace
688void  PeepReplace::add_instruction(char *root) {
689  _instruction.addName(root);
690  _operand_inst_num.add_signal();
691  _operand_op_name.add_signal();
692}
693void  PeepReplace::add_operand( int inst_num, char *inst_operand ) {
694  _instruction.add_signal();
695  _operand_inst_num.addName((char*)inst_num);
696  _operand_op_name.addName(inst_operand);
697}
698
699// Access contents of peepreplace
700void  PeepReplace::reset() {
701  _instruction.reset();
702  _operand_inst_num.reset();
703  _operand_op_name.reset();
704}
705void  PeepReplace::next_instruction(const char * &inst){
706  inst                     = _instruction.iter();
707  intptr_t   inst_num      = (intptr_t)_operand_inst_num.iter();
708  const char *inst_operand = _operand_op_name.iter();
709}
710void  PeepReplace::next_operand( intptr_t &inst_num, const char * &inst_operand ) {
711  const char *inst   = _instruction.iter();
712  inst_num           = (intptr_t)_operand_inst_num.iter();
713  inst_operand       = _operand_op_name.iter();
714}
715
716
717
718void PeepReplace::dump() {
719  output(stderr);
720}
721
722void PeepReplace::output(FILE *fp) {      // Write info to output files
723  fprintf(fp,"PeepReplace:\n");
724}
725