src/share/vm/adlc/formsopt.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/adlc/formsopt.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,731 @@
     1.4 +/*
     1.5 + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * 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+7) & ~7;
    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 +  // The array of Register Mask bits should be large enough to cover
   1.157 +  // all the machine registers and all parameters that need to be passed
   1.158 +  // on the stack (stack registers) up to some interesting limit.  Methods
   1.159 +  // that need more parameters will NOT be compiled.  On Intel, the limit
   1.160 +  // is something like 90+ parameters.
   1.161 +  // Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls.
   1.162 +  // Round up to the next doubleword size.
   1.163 +  return (words_for_regs + 3 + 1) & ~1;
   1.164 +}
   1.165 +
   1.166 +void RegisterForm::dump() {                  // Debug printer
   1.167 +  output(stderr);
   1.168 +}
   1.169 +
   1.170 +void RegisterForm::output(FILE *fp) {          // Write info to output files
   1.171 +  const char *name;
   1.172 +  fprintf(fp,"\n");
   1.173 +  fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
   1.174 +  for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {
   1.175 +    ((RegDef*)_regDef[name])->output(fp);
   1.176 +  }
   1.177 +  fprintf(fp,"\n");
   1.178 +  for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {
   1.179 +    ((RegClass*)_regClass[name])->output(fp);
   1.180 +  }
   1.181 +  fprintf(fp,"\n");
   1.182 +  for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {
   1.183 +    ((AllocClass*)_allocClass[name])->output(fp);
   1.184 +  }
   1.185 +  fprintf(fp,"-------------------- end  RegisterForm --------------------\n");
   1.186 +}
   1.187 +
   1.188 +//------------------------------RegDef-----------------------------------------
   1.189 +// Constructor
   1.190 +RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
   1.191 +  : _regname(regname), _callconv(callconv), _c_conv(c_conv),
   1.192 +    _idealtype(idealtype),
   1.193 +    _register_encode(encode),
   1.194 +    _concrete(concrete),
   1.195 +    _register_num(0) {
   1.196 +
   1.197 +  // Chunk and register mask are determined by the register number
   1.198 +  // _register_num is set when registers are added to an allocation class
   1.199 +}
   1.200 +RegDef::~RegDef() {                      // Destructor
   1.201 +}
   1.202 +
   1.203 +void RegDef::set_register_num(uint32 register_num) {
   1.204 +  _register_num      = register_num;
   1.205 +}
   1.206 +
   1.207 +// Bit pattern used for generating machine code
   1.208 +const char* RegDef::register_encode() const {
   1.209 +  return _register_encode;
   1.210 +}
   1.211 +
   1.212 +// Register number used in machine-independent code
   1.213 +uint32 RegDef::register_num()    const {
   1.214 +  return _register_num;
   1.215 +}
   1.216 +
   1.217 +void RegDef::dump() {
   1.218 +  output(stderr);
   1.219 +}
   1.220 +
   1.221 +void RegDef::output(FILE *fp) {         // Write info to output files
   1.222 +  fprintf(fp,"RegDef: %s (%s) encode as %s  using number %d\n",
   1.223 +          _regname, (_callconv?_callconv:""), _register_encode, _register_num);
   1.224 +  fprintf(fp,"\n");
   1.225 +}
   1.226 +
   1.227 +
   1.228 +//------------------------------RegClass---------------------------------------
   1.229 +// Construct a register class into which registers will be inserted
   1.230 +RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena),
   1.231 +                                          _user_defined(NULL)
   1.232 +{
   1.233 +}
   1.234 +
   1.235 +// record a register in this class
   1.236 +void RegClass::addReg(RegDef *regDef) {
   1.237 +  _regDefs.addName(regDef->_regname);
   1.238 +  _regDef.Insert((void*)regDef->_regname, regDef);
   1.239 +}
   1.240 +
   1.241 +// Number of registers in class
   1.242 +uint RegClass::size() const {
   1.243 +  return _regDef.Size();
   1.244 +}
   1.245 +
   1.246 +const RegDef *RegClass::get_RegDef(const char *rd_name) const {
   1.247 +  return  (const RegDef*)_regDef[rd_name];
   1.248 +}
   1.249 +
   1.250 +void RegClass::reset() {
   1.251 +  _regDefs.reset();
   1.252 +}
   1.253 +
   1.254 +const char *RegClass::rd_name_iter() {
   1.255 +  return _regDefs.iter();
   1.256 +}
   1.257 +
   1.258 +RegDef *RegClass::RegDef_iter() {
   1.259 +  const char *rd_name  = rd_name_iter();
   1.260 +  RegDef     *reg_def  = rd_name ? (RegDef*)_regDef[rd_name] : NULL;
   1.261 +  return      reg_def;
   1.262 +}
   1.263 +
   1.264 +const RegDef* RegClass::find_first_elem() {
   1.265 +  const RegDef* first = NULL;
   1.266 +  const RegDef* def = NULL;
   1.267 +
   1.268 +  reset();
   1.269 +  while ((def = RegDef_iter()) != NULL) {
   1.270 +    if (first == NULL || def->register_num() < first->register_num()) {
   1.271 +      first = def;
   1.272 +    }
   1.273 +  }
   1.274 +
   1.275 +  assert(first != NULL, "empty mask?");
   1.276 +  return first;;
   1.277 +}
   1.278 +
   1.279 +// Collect all the registers in this register-word.  One bit per register.
   1.280 +int RegClass::regs_in_word( int wordnum, bool stack_also ) {
   1.281 +  int         word = 0;
   1.282 +  const char *name;
   1.283 +  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
   1.284 +    int rnum = ((RegDef*)_regDef[name])->register_num();
   1.285 +    if( (rnum >> 5) == wordnum )
   1.286 +      word |= (1 << (rnum & 31));
   1.287 +  }
   1.288 +  if( stack_also ) {
   1.289 +    // Now also collect stack bits
   1.290 +    for( int i = 0; i < 32; i++ )
   1.291 +      if( wordnum*32+i >= RegisterForm::_reg_ctr )
   1.292 +        word |= (1 << i);
   1.293 +  }
   1.294 +
   1.295 +  return word;
   1.296 +}
   1.297 +
   1.298 +void RegClass::dump() {
   1.299 +  output(stderr);
   1.300 +}
   1.301 +
   1.302 +void RegClass::output(FILE *fp) {           // Write info to output files
   1.303 +  fprintf(fp,"RegClass: %s\n",_classid);
   1.304 +  const char *name;
   1.305 +  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
   1.306 +    ((RegDef*)_regDef[name])->output(fp);
   1.307 +  }
   1.308 +  fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
   1.309 +}
   1.310 +
   1.311 +
   1.312 +//------------------------------AllocClass-------------------------------------
   1.313 +AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
   1.314 +}
   1.315 +
   1.316 +// record a register in this class
   1.317 +void AllocClass::addReg(RegDef *regDef) {
   1.318 +  assert( regDef != NULL, "Can not add a NULL to an allocation class");
   1.319 +  regDef->set_register_num( RegisterForm::_reg_ctr++ );
   1.320 +  // Add regDef to this allocation class
   1.321 +  _regDefs.addName(regDef->_regname);
   1.322 +  _regDef.Insert((void*)regDef->_regname, regDef);
   1.323 +}
   1.324 +
   1.325 +void AllocClass::dump() {
   1.326 +  output(stderr);
   1.327 +}
   1.328 +
   1.329 +void AllocClass::output(FILE *fp) {       // Write info to output files
   1.330 +  fprintf(fp,"AllocClass: %s \n",_classid);
   1.331 +  const char *name;
   1.332 +  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
   1.333 +    ((RegDef*)_regDef[name])->output(fp);
   1.334 +  }
   1.335 +  fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
   1.336 +}
   1.337 +
   1.338 +//==============================Frame Handling=================================
   1.339 +//------------------------------FrameForm--------------------------------------
   1.340 +FrameForm::FrameForm() {
   1.341 +  _frame_pointer = NULL;
   1.342 +  _c_frame_pointer = NULL;
   1.343 +  _alignment = NULL;
   1.344 +  _return_addr = NULL;
   1.345 +  _c_return_addr = NULL;
   1.346 +  _in_preserve_slots = NULL;
   1.347 +  _varargs_C_out_slots_killed = NULL;
   1.348 +  _calling_convention = NULL;
   1.349 +  _c_calling_convention = NULL;
   1.350 +  _return_value = NULL;
   1.351 +  _c_return_value = NULL;
   1.352 +  _interpreter_frame_pointer_reg = NULL;
   1.353 +}
   1.354 +
   1.355 +FrameForm::~FrameForm() {
   1.356 +}
   1.357 +
   1.358 +void FrameForm::dump() {
   1.359 +  output(stderr);
   1.360 +}
   1.361 +
   1.362 +void FrameForm::output(FILE *fp) {           // Write info to output files
   1.363 +  fprintf(fp,"\nFrame:\n");
   1.364 +}
   1.365 +
   1.366 +//==============================Scheduling=====================================
   1.367 +//------------------------------PipelineForm-----------------------------------
   1.368 +PipelineForm::PipelineForm()
   1.369 +  :  _reslist               ()
   1.370 +  ,  _resdict               (cmpstr, hashstr, Form::arena)
   1.371 +  ,  _classdict             (cmpstr, hashstr, Form::arena)
   1.372 +  ,  _rescount              (0)
   1.373 +  ,  _maxcycleused          (0)
   1.374 +  ,  _stages                ()
   1.375 +  ,  _stagecnt              (0)
   1.376 +  ,  _classlist             ()
   1.377 +  ,  _classcnt              (0)
   1.378 +  ,  _noplist               ()
   1.379 +  ,  _nopcnt                (0)
   1.380 +  ,  _variableSizeInstrs    (false)
   1.381 +  ,  _branchHasDelaySlot    (false)
   1.382 +  ,  _maxInstrsPerBundle    (0)
   1.383 +  ,  _maxBundlesPerCycle    (1)
   1.384 +  ,  _instrUnitSize         (0)
   1.385 +  ,  _bundleUnitSize        (0)
   1.386 +  ,  _instrFetchUnitSize    (0)
   1.387 +  ,  _instrFetchUnits       (0) {
   1.388 +}
   1.389 +PipelineForm::~PipelineForm() {
   1.390 +}
   1.391 +
   1.392 +void PipelineForm::dump() {
   1.393 +  output(stderr);
   1.394 +}
   1.395 +
   1.396 +void PipelineForm::output(FILE *fp) {           // Write info to output files
   1.397 +  const char *res;
   1.398 +  const char *stage;
   1.399 +  const char *cls;
   1.400 +  const char *nop;
   1.401 +  int count = 0;
   1.402 +
   1.403 +  fprintf(fp,"\nPipeline:");
   1.404 +  if (_variableSizeInstrs)
   1.405 +    if (_instrUnitSize > 0)
   1.406 +      fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
   1.407 +    else
   1.408 +      fprintf(fp," variable-sized instructions");
   1.409 +  else
   1.410 +    if (_instrUnitSize > 0)
   1.411 +      fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
   1.412 +    else if (_bundleUnitSize > 0)
   1.413 +      fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
   1.414 +    else
   1.415 +      fprintf(fp," fixed-sized instructions");
   1.416 +  if (_branchHasDelaySlot)
   1.417 +    fprintf(fp,", branch has delay slot");
   1.418 +  if (_maxInstrsPerBundle > 0)
   1.419 +    fprintf(fp,", max of %d instruction%s in parallel",
   1.420 +      _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
   1.421 +  if (_maxBundlesPerCycle > 0)
   1.422 +    fprintf(fp,", max of %d bundle%s in parallel",
   1.423 +      _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
   1.424 +  if (_instrFetchUnitSize > 0 && _instrFetchUnits)
   1.425 +    fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);
   1.426 +
   1.427 +  fprintf(fp,"\nResource:");
   1.428 +  for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )
   1.429 +    fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
   1.430 +  fprintf(fp,"\n");
   1.431 +
   1.432 +  fprintf(fp,"\nDescription:\n");
   1.433 +  for ( _stages.reset(); (stage = _stages.iter()) != NULL; )
   1.434 +    fprintf(fp," %s(%d)", stage, count++);
   1.435 +  fprintf(fp,"\n");
   1.436 +
   1.437 +  fprintf(fp,"\nClasses:\n");
   1.438 +  for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )
   1.439 +    _classdict[cls]->is_pipeclass()->output(fp);
   1.440 +
   1.441 +  fprintf(fp,"\nNop Instructions:");
   1.442 +  for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )
   1.443 +    fprintf(fp, " \"%s\"", nop);
   1.444 +  fprintf(fp,"\n");
   1.445 +}
   1.446 +
   1.447 +
   1.448 +//------------------------------ResourceForm-----------------------------------
   1.449 +ResourceForm::ResourceForm(unsigned resmask)
   1.450 +: _resmask(resmask) {
   1.451 +}
   1.452 +ResourceForm::~ResourceForm() {
   1.453 +}
   1.454 +
   1.455 +ResourceForm  *ResourceForm::is_resource() const {
   1.456 +  return (ResourceForm *)(this);
   1.457 +}
   1.458 +
   1.459 +void ResourceForm::dump() {
   1.460 +  output(stderr);
   1.461 +}
   1.462 +
   1.463 +void ResourceForm::output(FILE *fp) {          // Write info to output files
   1.464 +  fprintf(fp, "resource: 0x%08x;\n", mask());
   1.465 +}
   1.466 +
   1.467 +
   1.468 +//------------------------------PipeClassOperandForm----------------------------------
   1.469 +
   1.470 +void PipeClassOperandForm::dump() {
   1.471 +  output(stderr);
   1.472 +}
   1.473 +
   1.474 +void PipeClassOperandForm::output(FILE *fp) {         // Write info to output files
   1.475 +  fprintf(stderr,"PipeClassOperandForm: %s", _stage);
   1.476 +  fflush(stderr);
   1.477 +  if (_more_instrs > 0)
   1.478 +    fprintf(stderr,"+%d", _more_instrs);
   1.479 +  fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
   1.480 +  fflush(stderr);
   1.481 +  fprintf(fp,"PipeClassOperandForm: %s", _stage);
   1.482 +  if (_more_instrs > 0)
   1.483 +    fprintf(fp,"+%d", _more_instrs);
   1.484 +  fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
   1.485 +}
   1.486 +
   1.487 +
   1.488 +//------------------------------PipeClassResourceForm----------------------------------
   1.489 +
   1.490 +void PipeClassResourceForm::dump() {
   1.491 +  output(stderr);
   1.492 +}
   1.493 +
   1.494 +void PipeClassResourceForm::output(FILE *fp) {         // Write info to output files
   1.495 +  fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
   1.496 +     _resource, _stage, _cycles);
   1.497 +}
   1.498 +
   1.499 +
   1.500 +//------------------------------PipeClassForm----------------------------------
   1.501 +PipeClassForm::PipeClassForm(const char *id, int num)
   1.502 +  : _ident(id)
   1.503 +  , _num(num)
   1.504 +  , _localNames(cmpstr, hashstr, Form::arena)
   1.505 +  , _localUsage(cmpstr, hashstr, Form::arena)
   1.506 +  , _has_fixed_latency(0)
   1.507 +  , _fixed_latency(0)
   1.508 +  , _instruction_count(0)
   1.509 +  , _has_multiple_bundles(false)
   1.510 +  , _has_branch_delay_slot(false)
   1.511 +  , _force_serialization(false)
   1.512 +  , _may_have_no_code(false) {
   1.513 +}
   1.514 +
   1.515 +PipeClassForm::~PipeClassForm() {
   1.516 +}
   1.517 +
   1.518 +PipeClassForm  *PipeClassForm::is_pipeclass() const {
   1.519 +  return (PipeClassForm *)(this);
   1.520 +}
   1.521 +
   1.522 +void PipeClassForm::dump() {
   1.523 +  output(stderr);
   1.524 +}
   1.525 +
   1.526 +void PipeClassForm::output(FILE *fp) {         // Write info to output files
   1.527 +  fprintf(fp,"PipeClassForm: #%03d", _num);
   1.528 +  if (_ident)
   1.529 +     fprintf(fp," \"%s\":", _ident);
   1.530 +  if (_has_fixed_latency)
   1.531 +     fprintf(fp," latency %d", _fixed_latency);
   1.532 +  if (_force_serialization)
   1.533 +     fprintf(fp, ", force serialization");
   1.534 +  if (_may_have_no_code)
   1.535 +     fprintf(fp, ", may have no code");
   1.536 +  fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
   1.537 +}
   1.538 +
   1.539 +
   1.540 +//==============================Peephole Optimization==========================
   1.541 +int Peephole::_peephole_counter = 0;
   1.542 +//------------------------------Peephole---------------------------------------
   1.543 +Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {
   1.544 +  _peephole_number = _peephole_counter++;
   1.545 +}
   1.546 +Peephole::~Peephole() {
   1.547 +}
   1.548 +
   1.549 +// Append a peephole rule with the same root instruction
   1.550 +void Peephole::append_peephole(Peephole *next_peephole) {
   1.551 +  if( _next == NULL ) {
   1.552 +    _next = next_peephole;
   1.553 +  } else {
   1.554 +    _next->append_peephole( next_peephole );
   1.555 +  }
   1.556 +}
   1.557 +
   1.558 +// Store the components of this peephole rule
   1.559 +void Peephole::add_match(PeepMatch *match) {
   1.560 +  assert( _match == NULL, "fatal()" );
   1.561 +  _match = match;
   1.562 +}
   1.563 +
   1.564 +void Peephole::append_constraint(PeepConstraint *next_constraint) {
   1.565 +  if( _constraint == NULL ) {
   1.566 +    _constraint = next_constraint;
   1.567 +  } else {
   1.568 +    _constraint->append( next_constraint );
   1.569 +  }
   1.570 +}
   1.571 +
   1.572 +void Peephole::add_replace(PeepReplace *replace) {
   1.573 +  assert( _replace == NULL, "fatal()" );
   1.574 +  _replace = replace;
   1.575 +}
   1.576 +
   1.577 +// class Peephole accessor methods are in the declaration.
   1.578 +
   1.579 +
   1.580 +void Peephole::dump() {
   1.581 +  output(stderr);
   1.582 +}
   1.583 +
   1.584 +void Peephole::output(FILE *fp) {         // Write info to output files
   1.585 +  fprintf(fp,"Peephole:\n");
   1.586 +  if( _match != NULL )       _match->output(fp);
   1.587 +  if( _constraint != NULL )  _constraint->output(fp);
   1.588 +  if( _replace != NULL )     _replace->output(fp);
   1.589 +  // Output the next entry
   1.590 +  if( _next ) _next->output(fp);
   1.591 +}
   1.592 +
   1.593 +//------------------------------PeepMatch--------------------------------------
   1.594 +PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
   1.595 +}
   1.596 +PeepMatch::~PeepMatch() {
   1.597 +}
   1.598 +
   1.599 +
   1.600 +// Insert info into the match-rule
   1.601 +void  PeepMatch::add_instruction(int parent, int position, const char *name,
   1.602 +                                 int input) {
   1.603 +  if( position > _max_position ) _max_position = position;
   1.604 +
   1.605 +  _parent.addName((char*) (intptr_t) parent);
   1.606 +  _position.addName((char*) (intptr_t) position);
   1.607 +  _instrs.addName(name);
   1.608 +  _input.addName((char*) (intptr_t) input);
   1.609 +}
   1.610 +
   1.611 +// Access info about instructions in the peep-match rule
   1.612 +int   PeepMatch::max_position() {
   1.613 +  return _max_position;
   1.614 +}
   1.615 +
   1.616 +const char *PeepMatch::instruction_name(int position) {
   1.617 +  return _instrs.name(position);
   1.618 +}
   1.619 +
   1.620 +// Iterate through all info on matched instructions
   1.621 +void  PeepMatch::reset() {
   1.622 +  _parent.reset();
   1.623 +  _position.reset();
   1.624 +  _instrs.reset();
   1.625 +  _input.reset();
   1.626 +}
   1.627 +
   1.628 +void  PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {
   1.629 +  parent   = (int) (intptr_t) _parent.iter();
   1.630 +  position = (int) (intptr_t) _position.iter();
   1.631 +  name     = _instrs.iter();
   1.632 +  input    = (int) (intptr_t) _input.iter();
   1.633 +}
   1.634 +
   1.635 +// 'true' if current position in iteration is a placeholder, not matched.
   1.636 +bool  PeepMatch::is_placeholder() {
   1.637 +  return _instrs.current_is_signal();
   1.638 +}
   1.639 +
   1.640 +
   1.641 +void PeepMatch::dump() {
   1.642 +  output(stderr);
   1.643 +}
   1.644 +
   1.645 +void PeepMatch::output(FILE *fp) {        // Write info to output files
   1.646 +  fprintf(fp,"PeepMatch:\n");
   1.647 +}
   1.648 +
   1.649 +//------------------------------PeepConstraint---------------------------------
   1.650 +PeepConstraint::PeepConstraint(int left_inst,  char* left_op, char* relation,
   1.651 +                               int right_inst, char* right_op)
   1.652 +  : _left_inst(left_inst), _left_op(left_op), _relation(relation),
   1.653 +    _right_inst(right_inst), _right_op(right_op), _next(NULL) {}
   1.654 +PeepConstraint::~PeepConstraint() {
   1.655 +}
   1.656 +
   1.657 +// Check if constraints use instruction at position
   1.658 +bool PeepConstraint::constrains_instruction(int position) {
   1.659 +  // Check local instruction constraints
   1.660 +  if( _left_inst  == position ) return true;
   1.661 +  if( _right_inst == position ) return true;
   1.662 +
   1.663 +  // Check remaining constraints in list
   1.664 +  if( _next == NULL )  return false;
   1.665 +  else                 return _next->constrains_instruction(position);
   1.666 +}
   1.667 +
   1.668 +// Add another constraint
   1.669 +void PeepConstraint::append(PeepConstraint *next_constraint) {
   1.670 +  if( _next == NULL ) {
   1.671 +    _next = next_constraint;
   1.672 +  } else {
   1.673 +    _next->append( next_constraint );
   1.674 +  }
   1.675 +}
   1.676 +
   1.677 +// Access the next constraint in the list
   1.678 +PeepConstraint *PeepConstraint::next() {
   1.679 +  return _next;
   1.680 +}
   1.681 +
   1.682 +
   1.683 +void PeepConstraint::dump() {
   1.684 +  output(stderr);
   1.685 +}
   1.686 +
   1.687 +void PeepConstraint::output(FILE *fp) {   // Write info to output files
   1.688 +  fprintf(fp,"PeepConstraint:\n");
   1.689 +}
   1.690 +
   1.691 +//------------------------------PeepReplace------------------------------------
   1.692 +PeepReplace::PeepReplace(char *rule) : _rule(rule) {
   1.693 +}
   1.694 +PeepReplace::~PeepReplace() {
   1.695 +}
   1.696 +
   1.697 +// Add contents of peepreplace
   1.698 +void  PeepReplace::add_instruction(char *root) {
   1.699 +  _instruction.addName(root);
   1.700 +  _operand_inst_num.add_signal();
   1.701 +  _operand_op_name.add_signal();
   1.702 +}
   1.703 +void  PeepReplace::add_operand( int inst_num, char *inst_operand ) {
   1.704 +  _instruction.add_signal();
   1.705 +  _operand_inst_num.addName((char*) (intptr_t) inst_num);
   1.706 +  _operand_op_name.addName(inst_operand);
   1.707 +}
   1.708 +
   1.709 +// Access contents of peepreplace
   1.710 +void  PeepReplace::reset() {
   1.711 +  _instruction.reset();
   1.712 +  _operand_inst_num.reset();
   1.713 +  _operand_op_name.reset();
   1.714 +}
   1.715 +void  PeepReplace::next_instruction(const char* &inst){
   1.716 +  inst                     = _instruction.iter();
   1.717 +  int         inst_num     = (int) (intptr_t) _operand_inst_num.iter();
   1.718 +  const char* inst_operand = _operand_op_name.iter();
   1.719 +}
   1.720 +void  PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {
   1.721 +  const char* inst = _instruction.iter();
   1.722 +  inst_num         = (int) (intptr_t) _operand_inst_num.iter();
   1.723 +  inst_operand     = _operand_op_name.iter();
   1.724 +}
   1.725 +
   1.726 +
   1.727 +
   1.728 +void PeepReplace::dump() {
   1.729 +  output(stderr);
   1.730 +}
   1.731 +
   1.732 +void PeepReplace::output(FILE *fp) {      // Write info to output files
   1.733 +  fprintf(fp,"PeepReplace:\n");
   1.734 +}

mercurial