src/share/vm/adlc/formsopt.cpp

changeset 435
a61af66fc99e
child 1038
dbbe28fc66b5
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/adlc/formsopt.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,724 @@
     1.4 +/*
     1.5 + * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +// FORMS.CPP - Definitions for ADL Parser Forms Classes
    1.29 +#include "adlc.hpp"
    1.30 +
    1.31 +//==============================Register Allocation============================
    1.32 +int RegisterForm::_reg_ctr = 0;
    1.33 +
    1.34 +//------------------------------RegisterForm-----------------------------------
    1.35 +// Constructor
    1.36 +RegisterForm::RegisterForm()
    1.37 +  : _regDef(cmpstr,hashstr, Form::arena),
    1.38 +    _regClass(cmpstr,hashstr, Form::arena),
    1.39 +    _allocClass(cmpstr,hashstr, Form::arena) {
    1.40 +}
    1.41 +RegisterForm::~RegisterForm() {
    1.42 +}
    1.43 +
    1.44 +// record a new register definition
    1.45 +void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,
    1.46 +                             char *idealtype, char *encoding, char* concrete) {
    1.47 +  RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);
    1.48 +  _rdefs.addName(name);
    1.49 +  _regDef.Insert(name,regDef);
    1.50 +}
    1.51 +
    1.52 +// record a new register class
    1.53 +RegClass *RegisterForm::addRegClass(const char *className) {
    1.54 +  RegClass *regClass = new RegClass(className);
    1.55 +  _rclasses.addName(className);
    1.56 +  _regClass.Insert(className,regClass);
    1.57 +  return regClass;
    1.58 +}
    1.59 +
    1.60 +// record a new register class
    1.61 +AllocClass *RegisterForm::addAllocClass(char *className) {
    1.62 +  AllocClass *allocClass = new AllocClass(className);
    1.63 +  _aclasses.addName(className);
    1.64 +  _allocClass.Insert(className,allocClass);
    1.65 +  return allocClass;
    1.66 +}
    1.67 +
    1.68 +// Called after parsing the Register block.  Record the register class
    1.69 +// for spill-slots/regs.
    1.70 +void RegisterForm::addSpillRegClass() {
    1.71 +  // Stack slots start at the next available even register number.
    1.72 +  _reg_ctr = (_reg_ctr+1) & ~1;
    1.73 +  const char *rc_name   = "stack_slots";
    1.74 +  RegClass   *reg_class = new RegClass(rc_name);
    1.75 +  reg_class->_stack_or_reg = true;
    1.76 +  _rclasses.addName(rc_name);
    1.77 +  _regClass.Insert(rc_name,reg_class);
    1.78 +}
    1.79 +
    1.80 +
    1.81 +// Provide iteration over all register definitions
    1.82 +// in the order used by the register allocator
    1.83 +void        RegisterForm::reset_RegDefs() {
    1.84 +  _current_ac = NULL;
    1.85 +  _aclasses.reset();
    1.86 +}
    1.87 +
    1.88 +RegDef     *RegisterForm::iter_RegDefs() {
    1.89 +  // Check if we need to get the next AllocClass
    1.90 +  if ( _current_ac == NULL ) {
    1.91 +    const char *ac_name = _aclasses.iter();
    1.92 +    if( ac_name == NULL )   return NULL;   // No more allocation classes
    1.93 +    _current_ac = (AllocClass*)_allocClass[ac_name];
    1.94 +    _current_ac->_regDefs.reset();
    1.95 +    assert( _current_ac != NULL, "Name must match an allocation class");
    1.96 +  }
    1.97 +
    1.98 +  const char *rd_name = _current_ac->_regDefs.iter();
    1.99 +  if( rd_name == NULL ) {
   1.100 +    // At end of this allocation class, check the next
   1.101 +    _current_ac = NULL;
   1.102 +    return iter_RegDefs();
   1.103 +  }
   1.104 +  RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];
   1.105 +  assert( reg_def != NULL, "Name must match a register definition");
   1.106 +  return reg_def;
   1.107 +}
   1.108 +
   1.109 +// return the register definition with name 'regName'
   1.110 +RegDef *RegisterForm::getRegDef(const char *regName) {
   1.111 +  RegDef *regDef = (RegDef*)_regDef[regName];
   1.112 +  return  regDef;
   1.113 +}
   1.114 +
   1.115 +// return the register class with name 'className'
   1.116 +RegClass *RegisterForm::getRegClass(const char *className) {
   1.117 +  RegClass *regClass = (RegClass*)_regClass[className];
   1.118 +  return    regClass;
   1.119 +}
   1.120 +
   1.121 +
   1.122 +// Check that register classes are compatible with chunks
   1.123 +bool   RegisterForm::verify() {
   1.124 +  bool valid = true;
   1.125 +
   1.126 +  // Verify Register Classes
   1.127 +  // check that each register class contains registers from one chunk
   1.128 +  const char *rc_name = NULL;
   1.129 +  _rclasses.reset();
   1.130 +  while ( (rc_name = _rclasses.iter()) != NULL ) {
   1.131 +    // Check the chunk value for all registers in this class
   1.132 +    RegClass *reg_class = getRegClass(rc_name);
   1.133 +    assert( reg_class != NULL, "InternalError() no matching register class");
   1.134 +  } // end of RegClasses
   1.135 +
   1.136 +  // Verify that every register has been placed into an allocation class
   1.137 +  RegDef *reg_def = NULL;
   1.138 +  reset_RegDefs();
   1.139 +  uint  num_register_zero = 0;
   1.140 +  while ( (reg_def = iter_RegDefs()) != NULL ) {
   1.141 +    if( reg_def->register_num() == 0 )  ++num_register_zero;
   1.142 +  }
   1.143 +  if( num_register_zero > 1 ) {
   1.144 +    fprintf(stderr,
   1.145 +            "ERROR: More than one register has been assigned register-number 0.\n"
   1.146 +            "Probably because a register has not been entered into an allocation class.\n");
   1.147 +  }
   1.148 +
   1.149 +  return  valid;
   1.150 +}
   1.151 +
   1.152 +// Compute RegMask size
   1.153 +int RegisterForm::RegMask_Size() {
   1.154 +  // Need at least this many words
   1.155 +  int words_for_regs = (_reg_ctr + 31)>>5;
   1.156 +  // Add a few for incoming & outgoing arguments to calls.
   1.157 +  // Round up to the next doubleword size.
   1.158 +  return (words_for_regs + 2 + 1) & ~1;
   1.159 +}
   1.160 +
   1.161 +void RegisterForm::dump() {                  // Debug printer
   1.162 +  output(stderr);
   1.163 +}
   1.164 +
   1.165 +void RegisterForm::output(FILE *fp) {          // Write info to output files
   1.166 +  const char *name;
   1.167 +  fprintf(fp,"\n");
   1.168 +  fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
   1.169 +  for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {
   1.170 +    ((RegDef*)_regDef[name])->output(fp);
   1.171 +  }
   1.172 +  fprintf(fp,"\n");
   1.173 +  for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {
   1.174 +    ((RegClass*)_regClass[name])->output(fp);
   1.175 +  }
   1.176 +  fprintf(fp,"\n");
   1.177 +  for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {
   1.178 +    ((AllocClass*)_allocClass[name])->output(fp);
   1.179 +  }
   1.180 +  fprintf(fp,"-------------------- end  RegisterForm --------------------\n");
   1.181 +}
   1.182 +
   1.183 +//------------------------------RegDef-----------------------------------------
   1.184 +// Constructor
   1.185 +RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
   1.186 +  : _regname(regname), _callconv(callconv), _c_conv(c_conv),
   1.187 +    _idealtype(idealtype),
   1.188 +    _register_encode(encode),
   1.189 +    _concrete(concrete),
   1.190 +    _register_num(0) {
   1.191 +
   1.192 +  // Chunk and register mask are determined by the register number
   1.193 +  // _register_num is set when registers are added to an allocation class
   1.194 +}
   1.195 +RegDef::~RegDef() {                      // Destructor
   1.196 +}
   1.197 +
   1.198 +void RegDef::set_register_num(uint32 register_num) {
   1.199 +  _register_num      = register_num;
   1.200 +}
   1.201 +
   1.202 +// Bit pattern used for generating machine code
   1.203 +const char* RegDef::register_encode() const {
   1.204 +  return _register_encode;
   1.205 +}
   1.206 +
   1.207 +// Register number used in machine-independent code
   1.208 +uint32 RegDef::register_num()    const {
   1.209 +  return _register_num;
   1.210 +}
   1.211 +
   1.212 +void RegDef::dump() {
   1.213 +  output(stderr);
   1.214 +}
   1.215 +
   1.216 +void RegDef::output(FILE *fp) {         // Write info to output files
   1.217 +  fprintf(fp,"RegDef: %s (%s) encode as %s  using number %d\n",
   1.218 +          _regname, (_callconv?_callconv:""), _register_encode, _register_num);
   1.219 +  fprintf(fp,"\n");
   1.220 +}
   1.221 +
   1.222 +
   1.223 +//------------------------------RegClass---------------------------------------
   1.224 +// Construct a register class into which registers will be inserted
   1.225 +RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
   1.226 +}
   1.227 +
   1.228 +// record a register in this class
   1.229 +void RegClass::addReg(RegDef *regDef) {
   1.230 +  _regDefs.addName(regDef->_regname);
   1.231 +  _regDef.Insert((void*)regDef->_regname, regDef);
   1.232 +}
   1.233 +
   1.234 +// Number of registers in class
   1.235 +uint RegClass::size() const {
   1.236 +  return _regDef.Size();
   1.237 +}
   1.238 +
   1.239 +const RegDef *RegClass::get_RegDef(const char *rd_name) const {
   1.240 +  return  (const RegDef*)_regDef[rd_name];
   1.241 +}
   1.242 +
   1.243 +void RegClass::reset() {
   1.244 +  _regDefs.reset();
   1.245 +}
   1.246 +
   1.247 +const char *RegClass::rd_name_iter() {
   1.248 +  return _regDefs.iter();
   1.249 +}
   1.250 +
   1.251 +RegDef *RegClass::RegDef_iter() {
   1.252 +  const char *rd_name  = rd_name_iter();
   1.253 +  RegDef     *reg_def  = rd_name ? (RegDef*)_regDef[rd_name] : NULL;
   1.254 +  return      reg_def;
   1.255 +}
   1.256 +
   1.257 +const RegDef* RegClass::find_first_elem() {
   1.258 +  const RegDef* first = NULL;
   1.259 +  const RegDef* def = NULL;
   1.260 +
   1.261 +  reset();
   1.262 +  while ((def = RegDef_iter()) != NULL) {
   1.263 +    if (first == NULL || def->register_num() < first->register_num()) {
   1.264 +      first = def;
   1.265 +    }
   1.266 +  }
   1.267 +
   1.268 +  assert(first != NULL, "empty mask?");
   1.269 +  return first;;
   1.270 +}
   1.271 +
   1.272 +// Collect all the registers in this register-word.  One bit per register.
   1.273 +int RegClass::regs_in_word( int wordnum, bool stack_also ) {
   1.274 +  int         word = 0;
   1.275 +  const char *name;
   1.276 +  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
   1.277 +    int rnum = ((RegDef*)_regDef[name])->register_num();
   1.278 +    if( (rnum >> 5) == wordnum )
   1.279 +      word |= (1L<<(rnum&31));
   1.280 +  }
   1.281 +  if( stack_also ) {
   1.282 +    // Now also collect stack bits
   1.283 +    for( int i = 0; i < 32; i++ )
   1.284 +      if( wordnum*32+i >= RegisterForm::_reg_ctr )
   1.285 +        word |= (1L<<i);
   1.286 +  }
   1.287 +
   1.288 +  return word;
   1.289 +}
   1.290 +
   1.291 +void RegClass::dump() {
   1.292 +  output(stderr);
   1.293 +}
   1.294 +
   1.295 +void RegClass::output(FILE *fp) {           // Write info to output files
   1.296 +  fprintf(fp,"RegClass: %s\n",_classid);
   1.297 +  const char *name;
   1.298 +  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
   1.299 +    ((RegDef*)_regDef[name])->output(fp);
   1.300 +  }
   1.301 +  fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
   1.302 +}
   1.303 +
   1.304 +
   1.305 +//------------------------------AllocClass-------------------------------------
   1.306 +AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
   1.307 +}
   1.308 +
   1.309 +// record a register in this class
   1.310 +void AllocClass::addReg(RegDef *regDef) {
   1.311 +  assert( regDef != NULL, "Can not add a NULL to an allocation class");
   1.312 +  regDef->set_register_num( RegisterForm::_reg_ctr++ );
   1.313 +  // Add regDef to this allocation class
   1.314 +  _regDefs.addName(regDef->_regname);
   1.315 +  _regDef.Insert((void*)regDef->_regname, regDef);
   1.316 +}
   1.317 +
   1.318 +void AllocClass::dump() {
   1.319 +  output(stderr);
   1.320 +}
   1.321 +
   1.322 +void AllocClass::output(FILE *fp) {       // Write info to output files
   1.323 +  fprintf(fp,"AllocClass: %s \n",_classid);
   1.324 +  const char *name;
   1.325 +  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
   1.326 +    ((RegDef*)_regDef[name])->output(fp);
   1.327 +  }
   1.328 +  fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
   1.329 +}
   1.330 +
   1.331 +//==============================Frame Handling=================================
   1.332 +//------------------------------FrameForm--------------------------------------
   1.333 +FrameForm::FrameForm() {
   1.334 +  _frame_pointer = NULL;
   1.335 +  _c_frame_pointer = NULL;
   1.336 +  _alignment = NULL;
   1.337 +  _return_addr = NULL;
   1.338 +  _c_return_addr = NULL;
   1.339 +  _in_preserve_slots = NULL;
   1.340 +  _varargs_C_out_slots_killed = NULL;
   1.341 +  _calling_convention = NULL;
   1.342 +  _c_calling_convention = NULL;
   1.343 +  _return_value = NULL;
   1.344 +  _c_return_value = NULL;
   1.345 +  _interpreter_frame_pointer_reg = NULL;
   1.346 +}
   1.347 +
   1.348 +FrameForm::~FrameForm() {
   1.349 +}
   1.350 +
   1.351 +void FrameForm::dump() {
   1.352 +  output(stderr);
   1.353 +}
   1.354 +
   1.355 +void FrameForm::output(FILE *fp) {           // Write info to output files
   1.356 +  fprintf(fp,"\nFrame:\n");
   1.357 +}
   1.358 +
   1.359 +//==============================Scheduling=====================================
   1.360 +//------------------------------PipelineForm-----------------------------------
   1.361 +PipelineForm::PipelineForm()
   1.362 +  :  _reslist               ()
   1.363 +  ,  _resdict               (cmpstr, hashstr, Form::arena)
   1.364 +  ,  _classdict             (cmpstr, hashstr, Form::arena)
   1.365 +  ,  _rescount              (0)
   1.366 +  ,  _maxcycleused          (0)
   1.367 +  ,  _stages                ()
   1.368 +  ,  _stagecnt              (0)
   1.369 +  ,  _classlist             ()
   1.370 +  ,  _classcnt              (0)
   1.371 +  ,  _noplist               ()
   1.372 +  ,  _nopcnt                (0)
   1.373 +  ,  _variableSizeInstrs    (false)
   1.374 +  ,  _branchHasDelaySlot    (false)
   1.375 +  ,  _maxInstrsPerBundle    (0)
   1.376 +  ,  _maxBundlesPerCycle    (1)
   1.377 +  ,  _instrUnitSize         (0)
   1.378 +  ,  _bundleUnitSize        (0)
   1.379 +  ,  _instrFetchUnitSize    (0)
   1.380 +  ,  _instrFetchUnits       (0) {
   1.381 +}
   1.382 +PipelineForm::~PipelineForm() {
   1.383 +}
   1.384 +
   1.385 +void PipelineForm::dump() {
   1.386 +  output(stderr);
   1.387 +}
   1.388 +
   1.389 +void PipelineForm::output(FILE *fp) {           // Write info to output files
   1.390 +  const char *res;
   1.391 +  const char *stage;
   1.392 +  const char *cls;
   1.393 +  const char *nop;
   1.394 +  int count = 0;
   1.395 +
   1.396 +  fprintf(fp,"\nPipeline:");
   1.397 +  if (_variableSizeInstrs)
   1.398 +    if (_instrUnitSize > 0)
   1.399 +      fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
   1.400 +    else
   1.401 +      fprintf(fp," variable-sized instructions");
   1.402 +  else
   1.403 +    if (_instrUnitSize > 0)
   1.404 +      fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
   1.405 +    else if (_bundleUnitSize > 0)
   1.406 +      fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
   1.407 +    else
   1.408 +      fprintf(fp," fixed-sized instructions");
   1.409 +  if (_branchHasDelaySlot)
   1.410 +    fprintf(fp,", branch has delay slot");
   1.411 +  if (_maxInstrsPerBundle > 0)
   1.412 +    fprintf(fp,", max of %d instruction%s in parallel",
   1.413 +      _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
   1.414 +  if (_maxBundlesPerCycle > 0)
   1.415 +    fprintf(fp,", max of %d bundle%s in parallel",
   1.416 +      _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
   1.417 +  if (_instrFetchUnitSize > 0 && _instrFetchUnits)
   1.418 +    fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);
   1.419 +
   1.420 +  fprintf(fp,"\nResource:");
   1.421 +  for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )
   1.422 +    fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
   1.423 +  fprintf(fp,"\n");
   1.424 +
   1.425 +  fprintf(fp,"\nDescription:\n");
   1.426 +  for ( _stages.reset(); (stage = _stages.iter()) != NULL; )
   1.427 +    fprintf(fp," %s(%d)", stage, count++);
   1.428 +  fprintf(fp,"\n");
   1.429 +
   1.430 +  fprintf(fp,"\nClasses:\n");
   1.431 +  for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )
   1.432 +    _classdict[cls]->is_pipeclass()->output(fp);
   1.433 +
   1.434 +  fprintf(fp,"\nNop Instructions:");
   1.435 +  for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )
   1.436 +    fprintf(fp, " \"%s\"", nop);
   1.437 +  fprintf(fp,"\n");
   1.438 +}
   1.439 +
   1.440 +
   1.441 +//------------------------------ResourceForm-----------------------------------
   1.442 +ResourceForm::ResourceForm(unsigned resmask)
   1.443 +: _resmask(resmask) {
   1.444 +}
   1.445 +ResourceForm::~ResourceForm() {
   1.446 +}
   1.447 +
   1.448 +ResourceForm  *ResourceForm::is_resource() const {
   1.449 +  return (ResourceForm *)(this);
   1.450 +}
   1.451 +
   1.452 +void ResourceForm::dump() {
   1.453 +  output(stderr);
   1.454 +}
   1.455 +
   1.456 +void ResourceForm::output(FILE *fp) {          // Write info to output files
   1.457 +  fprintf(fp, "resource: 0x%08x;\n", mask());
   1.458 +}
   1.459 +
   1.460 +
   1.461 +//------------------------------PipeClassOperandForm----------------------------------
   1.462 +
   1.463 +void PipeClassOperandForm::dump() {
   1.464 +  output(stderr);
   1.465 +}
   1.466 +
   1.467 +void PipeClassOperandForm::output(FILE *fp) {         // Write info to output files
   1.468 +  fprintf(stderr,"PipeClassOperandForm: %s", _stage);
   1.469 +  fflush(stderr);
   1.470 +  if (_more_instrs > 0)
   1.471 +    fprintf(stderr,"+%d", _more_instrs);
   1.472 +  fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
   1.473 +  fflush(stderr);
   1.474 +  fprintf(fp,"PipeClassOperandForm: %s", _stage);
   1.475 +  if (_more_instrs > 0)
   1.476 +    fprintf(fp,"+%d", _more_instrs);
   1.477 +  fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
   1.478 +}
   1.479 +
   1.480 +
   1.481 +//------------------------------PipeClassResourceForm----------------------------------
   1.482 +
   1.483 +void PipeClassResourceForm::dump() {
   1.484 +  output(stderr);
   1.485 +}
   1.486 +
   1.487 +void PipeClassResourceForm::output(FILE *fp) {         // Write info to output files
   1.488 +  fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
   1.489 +     _resource, _stage, _cycles);
   1.490 +}
   1.491 +
   1.492 +
   1.493 +//------------------------------PipeClassForm----------------------------------
   1.494 +PipeClassForm::PipeClassForm(const char *id, int num)
   1.495 +  : _ident(id)
   1.496 +  , _num(num)
   1.497 +  , _localNames(cmpstr, hashstr, Form::arena)
   1.498 +  , _localUsage(cmpstr, hashstr, Form::arena)
   1.499 +  , _has_fixed_latency(0)
   1.500 +  , _fixed_latency(0)
   1.501 +  , _instruction_count(0)
   1.502 +  , _has_multiple_bundles(false)
   1.503 +  , _has_branch_delay_slot(false)
   1.504 +  , _force_serialization(false)
   1.505 +  , _may_have_no_code(false) {
   1.506 +}
   1.507 +
   1.508 +PipeClassForm::~PipeClassForm() {
   1.509 +}
   1.510 +
   1.511 +PipeClassForm  *PipeClassForm::is_pipeclass() const {
   1.512 +  return (PipeClassForm *)(this);
   1.513 +}
   1.514 +
   1.515 +void PipeClassForm::dump() {
   1.516 +  output(stderr);
   1.517 +}
   1.518 +
   1.519 +void PipeClassForm::output(FILE *fp) {         // Write info to output files
   1.520 +  fprintf(fp,"PipeClassForm: #%03d", _num);
   1.521 +  if (_ident)
   1.522 +     fprintf(fp," \"%s\":", _ident);
   1.523 +  if (_has_fixed_latency)
   1.524 +     fprintf(fp," latency %d", _fixed_latency);
   1.525 +  if (_force_serialization)
   1.526 +     fprintf(fp, ", force serialization");
   1.527 +  if (_may_have_no_code)
   1.528 +     fprintf(fp, ", may have no code");
   1.529 +  fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
   1.530 +}
   1.531 +
   1.532 +
   1.533 +//==============================Peephole Optimization==========================
   1.534 +int Peephole::_peephole_counter = 0;
   1.535 +//------------------------------Peephole---------------------------------------
   1.536 +Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {
   1.537 +  _peephole_number = _peephole_counter++;
   1.538 +}
   1.539 +Peephole::~Peephole() {
   1.540 +}
   1.541 +
   1.542 +// Append a peephole rule with the same root instruction
   1.543 +void Peephole::append_peephole(Peephole *next_peephole) {
   1.544 +  if( _next == NULL ) {
   1.545 +    _next = next_peephole;
   1.546 +  } else {
   1.547 +    _next->append_peephole( next_peephole );
   1.548 +  }
   1.549 +}
   1.550 +
   1.551 +// Store the components of this peephole rule
   1.552 +void Peephole::add_match(PeepMatch *match) {
   1.553 +  assert( _match == NULL, "fatal()" );
   1.554 +  _match = match;
   1.555 +}
   1.556 +
   1.557 +void Peephole::append_constraint(PeepConstraint *next_constraint) {
   1.558 +  if( _constraint == NULL ) {
   1.559 +    _constraint = next_constraint;
   1.560 +  } else {
   1.561 +    _constraint->append( next_constraint );
   1.562 +  }
   1.563 +}
   1.564 +
   1.565 +void Peephole::add_replace(PeepReplace *replace) {
   1.566 +  assert( _replace == NULL, "fatal()" );
   1.567 +  _replace = replace;
   1.568 +}
   1.569 +
   1.570 +// class Peephole accessor methods are in the declaration.
   1.571 +
   1.572 +
   1.573 +void Peephole::dump() {
   1.574 +  output(stderr);
   1.575 +}
   1.576 +
   1.577 +void Peephole::output(FILE *fp) {         // Write info to output files
   1.578 +  fprintf(fp,"Peephole:\n");
   1.579 +  if( _match != NULL )       _match->output(fp);
   1.580 +  if( _constraint != NULL )  _constraint->output(fp);
   1.581 +  if( _replace != NULL )     _replace->output(fp);
   1.582 +  // Output the next entry
   1.583 +  if( _next ) _next->output(fp);
   1.584 +}
   1.585 +
   1.586 +//------------------------------PeepMatch--------------------------------------
   1.587 +PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
   1.588 +}
   1.589 +PeepMatch::~PeepMatch() {
   1.590 +}
   1.591 +
   1.592 +
   1.593 +// Insert info into the match-rule
   1.594 +void  PeepMatch::add_instruction(int parent, int position, const char *name,
   1.595 +                                 int input) {
   1.596 +  if( position > _max_position ) _max_position = position;
   1.597 +
   1.598 +  _parent.addName((char *)parent);
   1.599 +  _position.addName((char *)position);
   1.600 +  _instrs.addName(name);
   1.601 +  _input.addName((char *)input);
   1.602 +}
   1.603 +
   1.604 +// Access info about instructions in the peep-match rule
   1.605 +int   PeepMatch::max_position() {
   1.606 +  return _max_position;
   1.607 +}
   1.608 +
   1.609 +const char *PeepMatch::instruction_name(intptr_t position) {
   1.610 +  return _instrs.name(position);
   1.611 +}
   1.612 +
   1.613 +// Iterate through all info on matched instructions
   1.614 +void  PeepMatch::reset() {
   1.615 +  _parent.reset();
   1.616 +  _position.reset();
   1.617 +  _instrs.reset();
   1.618 +  _input.reset();
   1.619 +}
   1.620 +
   1.621 +void  PeepMatch::next_instruction( intptr_t &parent, intptr_t &position, const char * &name, intptr_t &input ){
   1.622 +  parent   = (intptr_t)_parent.iter();
   1.623 +  position = (intptr_t)_position.iter();
   1.624 +  name     = _instrs.iter();
   1.625 +  input    = (intptr_t)_input.iter();
   1.626 +}
   1.627 +
   1.628 +// 'true' if current position in iteration is a placeholder, not matched.
   1.629 +bool  PeepMatch::is_placeholder() {
   1.630 +  return _instrs.current_is_signal();
   1.631 +}
   1.632 +
   1.633 +
   1.634 +void PeepMatch::dump() {
   1.635 +  output(stderr);
   1.636 +}
   1.637 +
   1.638 +void PeepMatch::output(FILE *fp) {        // Write info to output files
   1.639 +  fprintf(fp,"PeepMatch:\n");
   1.640 +}
   1.641 +
   1.642 +//------------------------------PeepConstraint---------------------------------
   1.643 +PeepConstraint::PeepConstraint(intptr_t  left_inst,  char *left_op, char *relation,
   1.644 +                               intptr_t  right_inst, char *right_op)
   1.645 +  : _left_inst(left_inst), _left_op(left_op), _relation(relation),
   1.646 +    _right_inst(right_inst), _right_op(right_op), _next(NULL) {}
   1.647 +PeepConstraint::~PeepConstraint() {
   1.648 +}
   1.649 +
   1.650 +// Check if constraints use instruction at position
   1.651 +bool PeepConstraint::constrains_instruction(intptr_t position) {
   1.652 +  // Check local instruction constraints
   1.653 +  if( _left_inst  == position ) return true;
   1.654 +  if( _right_inst == position ) return true;
   1.655 +
   1.656 +  // Check remaining constraints in list
   1.657 +  if( _next == NULL )  return false;
   1.658 +  else                 return _next->constrains_instruction(position);
   1.659 +}
   1.660 +
   1.661 +// Add another constraint
   1.662 +void PeepConstraint::append(PeepConstraint *next_constraint) {
   1.663 +  if( _next == NULL ) {
   1.664 +    _next = next_constraint;
   1.665 +  } else {
   1.666 +    _next->append( next_constraint );
   1.667 +  }
   1.668 +}
   1.669 +
   1.670 +// Access the next constraint in the list
   1.671 +PeepConstraint *PeepConstraint::next() {
   1.672 +  return _next;
   1.673 +}
   1.674 +
   1.675 +
   1.676 +void PeepConstraint::dump() {
   1.677 +  output(stderr);
   1.678 +}
   1.679 +
   1.680 +void PeepConstraint::output(FILE *fp) {   // Write info to output files
   1.681 +  fprintf(fp,"PeepConstraint:\n");
   1.682 +}
   1.683 +
   1.684 +//------------------------------PeepReplace------------------------------------
   1.685 +PeepReplace::PeepReplace(char *rule) : _rule(rule) {
   1.686 +}
   1.687 +PeepReplace::~PeepReplace() {
   1.688 +}
   1.689 +
   1.690 +// Add contents of peepreplace
   1.691 +void  PeepReplace::add_instruction(char *root) {
   1.692 +  _instruction.addName(root);
   1.693 +  _operand_inst_num.add_signal();
   1.694 +  _operand_op_name.add_signal();
   1.695 +}
   1.696 +void  PeepReplace::add_operand( int inst_num, char *inst_operand ) {
   1.697 +  _instruction.add_signal();
   1.698 +  _operand_inst_num.addName((char*)inst_num);
   1.699 +  _operand_op_name.addName(inst_operand);
   1.700 +}
   1.701 +
   1.702 +// Access contents of peepreplace
   1.703 +void  PeepReplace::reset() {
   1.704 +  _instruction.reset();
   1.705 +  _operand_inst_num.reset();
   1.706 +  _operand_op_name.reset();
   1.707 +}
   1.708 +void  PeepReplace::next_instruction(const char * &inst){
   1.709 +  inst                     = _instruction.iter();
   1.710 +  intptr_t   inst_num      = (intptr_t)_operand_inst_num.iter();
   1.711 +  const char *inst_operand = _operand_op_name.iter();
   1.712 +}
   1.713 +void  PeepReplace::next_operand( intptr_t &inst_num, const char * &inst_operand ) {
   1.714 +  const char *inst   = _instruction.iter();
   1.715 +  inst_num           = (intptr_t)_operand_inst_num.iter();
   1.716 +  inst_operand       = _operand_op_name.iter();
   1.717 +}
   1.718 +
   1.719 +
   1.720 +
   1.721 +void PeepReplace::dump() {
   1.722 +  output(stderr);
   1.723 +}
   1.724 +
   1.725 +void PeepReplace::output(FILE *fp) {      // Write info to output files
   1.726 +  fprintf(fp,"PeepReplace:\n");
   1.727 +}

mercurial