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 +}