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