1 /* 2 * Copyright (c) 1998, 2023, 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 #define remaining_buflen(buffer, position) (sizeof(buffer) - ((position) - (buffer))) 29 30 //==============================Instructions=================================== 31 //------------------------------InstructForm----------------------------------- 32 InstructForm::InstructForm(const char *id, bool ideal_only) 33 : _ident(id), _ideal_only(ideal_only), 34 _localNames(cmpstr, hashstr, Form::arena), 35 _effects(cmpstr, hashstr, Form::arena), 36 _is_mach_constant(false), 37 _needs_constant_base(false), 38 _has_call(false) 39 { 40 _ftype = Form::INS; 41 42 _matrule = nullptr; 43 _insencode = nullptr; 44 _constant = nullptr; 45 _is_postalloc_expand = false; 46 _opcode = nullptr; 47 _size = nullptr; 48 _attribs = nullptr; 49 _predicate = nullptr; 50 _exprule = nullptr; 51 _rewrule = nullptr; 52 _format = nullptr; 53 _peephole = nullptr; 54 _ins_pipe = nullptr; 55 _flag = nullptr; 56 _uniq_idx = nullptr; 57 _num_uniq = 0; 58 _cisc_spill_operand = Not_cisc_spillable;// Which operand may cisc-spill 59 _cisc_spill_alternate = nullptr; // possible cisc replacement 60 _cisc_reg_mask_name = nullptr; 61 _is_cisc_alternate = false; 62 _is_short_branch = false; 63 _short_branch_form = nullptr; 64 _alignment = 1; 65 } 66 67 InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule) 68 : _ident(id), _ideal_only(false), 69 _localNames(instr->_localNames), 70 _effects(instr->_effects), 71 _is_mach_constant(instr->_is_mach_constant), 72 _needs_constant_base(false), 73 _has_call(false) 74 { 75 _ftype = Form::INS; 76 77 _matrule = rule; 78 _insencode = instr->_insencode; 79 _constant = instr->_constant; 80 _is_postalloc_expand = instr->_is_postalloc_expand; 81 _opcode = instr->_opcode; 82 _size = instr->_size; 83 _attribs = instr->_attribs; 84 _predicate = instr->_predicate; 85 _exprule = instr->_exprule; 86 _rewrule = instr->_rewrule; 87 _format = instr->_format; 88 _peephole = instr->_peephole; 89 _ins_pipe = instr->_ins_pipe; 90 _flag = instr->_flag; 91 _uniq_idx = instr->_uniq_idx; 92 _num_uniq = instr->_num_uniq; 93 _cisc_spill_operand = Not_cisc_spillable; // Which operand may cisc-spill 94 _cisc_spill_alternate = nullptr; // possible cisc replacement 95 _cisc_reg_mask_name = nullptr; 96 _is_cisc_alternate = false; 97 _is_short_branch = false; 98 _short_branch_form = nullptr; 99 _alignment = 1; 100 // Copy parameters 101 const char *name; 102 instr->_parameters.reset(); 103 for (; (name = instr->_parameters.iter()) != nullptr;) 104 _parameters.addName(name); 105 } 106 107 InstructForm::~InstructForm() { 108 } 109 110 InstructForm *InstructForm::is_instruction() const { 111 return (InstructForm*)this; 112 } 113 114 bool InstructForm::ideal_only() const { 115 return _ideal_only; 116 } 117 118 bool InstructForm::sets_result() const { 119 return (_matrule != nullptr && _matrule->sets_result()); 120 } 121 122 bool InstructForm::needs_projections() { 123 _components.reset(); 124 for( Component *comp; (comp = _components.iter()) != nullptr; ) { 125 if (comp->isa(Component::KILL)) { 126 return true; 127 } 128 } 129 return false; 130 } 131 132 133 bool InstructForm::has_temps() { 134 if (_matrule) { 135 // Examine each component to see if it is a TEMP 136 _components.reset(); 137 // Skip the first component, if already handled as (SET dst (...)) 138 Component *comp = nullptr; 139 if (sets_result()) comp = _components.iter(); 140 while ((comp = _components.iter()) != nullptr) { 141 if (comp->isa(Component::TEMP)) { 142 return true; 143 } 144 } 145 } 146 147 return false; 148 } 149 150 uint InstructForm::num_defs_or_kills() { 151 uint defs_or_kills = 0; 152 153 _components.reset(); 154 for( Component *comp; (comp = _components.iter()) != nullptr; ) { 155 if( comp->isa(Component::DEF) || comp->isa(Component::KILL) ) { 156 ++defs_or_kills; 157 } 158 } 159 160 return defs_or_kills; 161 } 162 163 // This instruction has an expand rule? 164 bool InstructForm::expands() const { 165 return ( _exprule != nullptr ); 166 } 167 168 // This instruction has a late expand rule? 169 bool InstructForm::postalloc_expands() const { 170 return _is_postalloc_expand; 171 } 172 173 // This instruction has a peephole rule? 174 Peephole *InstructForm::peepholes() const { 175 return _peephole; 176 } 177 178 // This instruction has a peephole rule? 179 void InstructForm::append_peephole(Peephole *peephole) { 180 if( _peephole == nullptr ) { 181 _peephole = peephole; 182 } else { 183 _peephole->append_peephole(peephole); 184 } 185 } 186 187 188 // ideal opcode enumeration 189 const char *InstructForm::ideal_Opcode( FormDict &globalNames ) const { 190 if( !_matrule ) return "Node"; // Something weird 191 // Chain rules do not really have ideal Opcodes; use their source 192 // operand ideal Opcode instead. 193 if( is_simple_chain_rule(globalNames) ) { 194 const char *src = _matrule->_rChild->_opType; 195 OperandForm *src_op = globalNames[src]->is_operand(); 196 assert( src_op, "Not operand class of chain rule" ); 197 if( !src_op->_matrule ) return "Node"; 198 return src_op->_matrule->_opType; 199 } 200 // Operand chain rules do not really have ideal Opcodes 201 if( _matrule->is_chain_rule(globalNames) ) 202 return "Node"; 203 return strcmp(_matrule->_opType,"Set") 204 ? _matrule->_opType 205 : _matrule->_rChild->_opType; 206 } 207 208 // Recursive check on all operands' match rules in my match rule 209 bool InstructForm::is_pinned(FormDict &globals) { 210 if ( ! _matrule) return false; 211 212 int index = 0; 213 if (_matrule->find_type("Goto", index)) return true; 214 if (_matrule->find_type("If", index)) return true; 215 if (_matrule->find_type("CountedLoopEnd",index)) return true; 216 if (_matrule->find_type("Return", index)) return true; 217 if (_matrule->find_type("Rethrow", index)) return true; 218 if (_matrule->find_type("TailCall", index)) return true; 219 if (_matrule->find_type("TailJump", index)) return true; 220 if (_matrule->find_type("Halt", index)) return true; 221 if (_matrule->find_type("Jump", index)) return true; 222 223 return is_parm(globals); 224 } 225 226 // Recursive check on all operands' match rules in my match rule 227 bool InstructForm::is_projection(FormDict &globals) { 228 if ( ! _matrule) return false; 229 230 int index = 0; 231 if (_matrule->find_type("Goto", index)) return true; 232 if (_matrule->find_type("Return", index)) return true; 233 if (_matrule->find_type("Rethrow", index)) return true; 234 if (_matrule->find_type("TailCall",index)) return true; 235 if (_matrule->find_type("TailJump",index)) return true; 236 if (_matrule->find_type("Halt", index)) return true; 237 238 return false; 239 } 240 241 // Recursive check on all operands' match rules in my match rule 242 bool InstructForm::is_parm(FormDict &globals) { 243 if ( ! _matrule) return false; 244 245 int index = 0; 246 if (_matrule->find_type("Parm",index)) return true; 247 248 return false; 249 } 250 251 bool InstructForm::is_ideal_negD() const { 252 return (_matrule && _matrule->_rChild && strcmp(_matrule->_rChild->_opType, "NegD") == 0); 253 } 254 255 // Return 'true' if this instruction matches an ideal 'Copy*' node 256 int InstructForm::is_ideal_copy() const { 257 return _matrule ? _matrule->is_ideal_copy() : 0; 258 } 259 260 // Return 'true' if this instruction is too complex to rematerialize. 261 int InstructForm::is_expensive() const { 262 // We can prove it is cheap if it has an empty encoding. 263 // This helps with platform-specific nops like ThreadLocal and RoundFloat. 264 if (is_empty_encoding()) 265 return 0; 266 267 if (is_tls_instruction()) 268 return 1; 269 270 if (_matrule == nullptr) return 0; 271 272 return _matrule->is_expensive(); 273 } 274 275 // Has an empty encoding if _size is a constant zero or there 276 // are no ins_encode tokens. 277 int InstructForm::is_empty_encoding() const { 278 if (_insencode != nullptr) { 279 _insencode->reset(); 280 if (_insencode->encode_class_iter() == nullptr) { 281 return 1; 282 } 283 } 284 if (_size != nullptr && strcmp(_size, "0") == 0) { 285 return 1; 286 } 287 return 0; 288 } 289 290 int InstructForm::is_tls_instruction() const { 291 if (_ident != nullptr && 292 ( ! strcmp( _ident,"tlsLoadP") || 293 ! strncmp(_ident,"tlsLoadP_",9)) ) { 294 return 1; 295 } 296 297 if (_matrule != nullptr && _insencode != nullptr) { 298 const char* opType = _matrule->_opType; 299 if (strcmp(opType, "Set")==0) 300 opType = _matrule->_rChild->_opType; 301 if (strcmp(opType,"ThreadLocal")==0) { 302 fprintf(stderr, "Warning: ThreadLocal instruction %s should be named 'tlsLoadP_*'\n", 303 (_ident == nullptr ? "nullptr" : _ident)); 304 return 1; 305 } 306 } 307 308 return 0; 309 } 310 311 312 // Return 'true' if this instruction matches an ideal 'If' node 313 bool InstructForm::is_ideal_if() const { 314 if( _matrule == nullptr ) return false; 315 316 return _matrule->is_ideal_if(); 317 } 318 319 // Return 'true' if this instruction matches an ideal 'FastLock' node 320 bool InstructForm::is_ideal_fastlock() const { 321 if( _matrule == nullptr ) return false; 322 323 return _matrule->is_ideal_fastlock(); 324 } 325 326 // Return 'true' if this instruction matches an ideal 'MemBarXXX' node 327 bool InstructForm::is_ideal_membar() const { 328 if( _matrule == nullptr ) return false; 329 330 return _matrule->is_ideal_membar(); 331 } 332 333 // Return 'true' if this instruction matches an ideal 'LoadPC' node 334 bool InstructForm::is_ideal_loadPC() const { 335 if( _matrule == nullptr ) return false; 336 337 return _matrule->is_ideal_loadPC(); 338 } 339 340 // Return 'true' if this instruction matches an ideal 'Box' node 341 bool InstructForm::is_ideal_box() const { 342 if( _matrule == nullptr ) return false; 343 344 return _matrule->is_ideal_box(); 345 } 346 347 // Return 'true' if this instruction matches an ideal 'Goto' node 348 bool InstructForm::is_ideal_goto() const { 349 if( _matrule == nullptr ) return false; 350 351 return _matrule->is_ideal_goto(); 352 } 353 354 // Return 'true' if this instruction matches an ideal 'Jump' node 355 bool InstructForm::is_ideal_jump() const { 356 if( _matrule == nullptr ) return false; 357 358 return _matrule->is_ideal_jump(); 359 } 360 361 // Return 'true' if instruction matches ideal 'If' | 'Goto' | 'CountedLoopEnd' 362 bool InstructForm::is_ideal_branch() const { 363 if( _matrule == nullptr ) return false; 364 365 return _matrule->is_ideal_if() || _matrule->is_ideal_goto(); 366 } 367 368 369 // Return 'true' if this instruction matches an ideal 'Return' node 370 bool InstructForm::is_ideal_return() const { 371 if( _matrule == nullptr ) return false; 372 373 // Check MatchRule to see if the first entry is the ideal "Return" node 374 int index = 0; 375 if (_matrule->find_type("Return",index)) return true; 376 if (_matrule->find_type("Rethrow",index)) return true; 377 if (_matrule->find_type("TailCall",index)) return true; 378 if (_matrule->find_type("TailJump",index)) return true; 379 380 return false; 381 } 382 383 // Return 'true' if this instruction matches an ideal 'Halt' node 384 bool InstructForm::is_ideal_halt() const { 385 int index = 0; 386 return _matrule && _matrule->find_type("Halt",index); 387 } 388 389 // Return 'true' if this instruction matches an ideal 'SafePoint' node 390 bool InstructForm::is_ideal_safepoint() const { 391 int index = 0; 392 return _matrule && _matrule->find_type("SafePoint",index); 393 } 394 395 // Return 'true' if this instruction matches an ideal 'Nop' node 396 bool InstructForm::is_ideal_nop() const { 397 return _ident && _ident[0] == 'N' && _ident[1] == 'o' && _ident[2] == 'p' && _ident[3] == '_'; 398 } 399 400 bool InstructForm::is_ideal_control() const { 401 if ( ! _matrule) return false; 402 403 return is_ideal_return() || is_ideal_branch() || _matrule->is_ideal_jump() || is_ideal_halt(); 404 } 405 406 // Return 'true' if this instruction matches an ideal 'Call' node 407 Form::CallType InstructForm::is_ideal_call() const { 408 if( _matrule == nullptr ) return Form::invalid_type; 409 410 // Check MatchRule to see if the first entry is the ideal "Call" node 411 int idx = 0; 412 if(_matrule->find_type("CallStaticJava",idx)) return Form::JAVA_STATIC; 413 idx = 0; 414 if(_matrule->find_type("Lock",idx)) return Form::JAVA_STATIC; 415 idx = 0; 416 if(_matrule->find_type("Unlock",idx)) return Form::JAVA_STATIC; 417 idx = 0; 418 if(_matrule->find_type("CallDynamicJava",idx)) return Form::JAVA_DYNAMIC; 419 idx = 0; 420 if(_matrule->find_type("CallRuntime",idx)) return Form::JAVA_RUNTIME; 421 idx = 0; 422 if(_matrule->find_type("CallLeaf",idx)) return Form::JAVA_LEAF; 423 idx = 0; 424 if(_matrule->find_type("CallLeafNoFP",idx)) return Form::JAVA_LEAF; 425 idx = 0; 426 if(_matrule->find_type("CallLeafVector",idx)) return Form::JAVA_LEAF; 427 idx = 0; 428 429 return Form::invalid_type; 430 } 431 432 // Return 'true' if this instruction matches an ideal 'Load?' node 433 Form::DataType InstructForm::is_ideal_load() const { 434 if( _matrule == nullptr ) return Form::none; 435 436 return _matrule->is_ideal_load(); 437 } 438 439 // Return 'true' if this instruction matches an ideal 'LoadKlass' node 440 bool InstructForm::skip_antidep_check() const { 441 if( _matrule == nullptr ) return false; 442 443 return _matrule->skip_antidep_check(); 444 } 445 446 // Return 'true' if this instruction matches an ideal 'Load?' node 447 Form::DataType InstructForm::is_ideal_store() const { 448 if( _matrule == nullptr ) return Form::none; 449 450 return _matrule->is_ideal_store(); 451 } 452 453 // Return 'true' if this instruction matches an ideal vector node 454 bool InstructForm::is_vector() const { 455 if( _matrule == nullptr ) return false; 456 457 return _matrule->is_vector(); 458 } 459 460 461 // Return the input register that must match the output register 462 // If this is not required, return 0 463 uint InstructForm::two_address(FormDict &globals) { 464 uint matching_input = 0; 465 if(_components.count() == 0) return 0; 466 467 _components.reset(); 468 Component *comp = _components.iter(); 469 // Check if there is a DEF 470 if( comp->isa(Component::DEF) ) { 471 // Check that this is a register 472 const char *def_type = comp->_type; 473 const Form *form = globals[def_type]; 474 OperandForm *op = form->is_operand(); 475 if( op ) { 476 if( op->constrained_reg_class() != nullptr && 477 op->interface_type(globals) == Form::register_interface ) { 478 // Remember the local name for equality test later 479 const char *def_name = comp->_name; 480 // Check if a component has the same name and is a USE 481 do { 482 if( comp->isa(Component::USE) && strcmp(comp->_name,def_name)==0 ) { 483 return operand_position_format(def_name); 484 } 485 } while( (comp = _components.iter()) != nullptr); 486 } 487 } 488 } 489 490 return 0; 491 } 492 493 494 // when chaining a constant to an instruction, returns 'true' and sets opType 495 Form::DataType InstructForm::is_chain_of_constant(FormDict &globals) { 496 const char *dummy = nullptr; 497 const char *dummy2 = nullptr; 498 return is_chain_of_constant(globals, dummy, dummy2); 499 } 500 Form::DataType InstructForm::is_chain_of_constant(FormDict &globals, 501 const char * &opTypeParam) { 502 const char *result = nullptr; 503 504 return is_chain_of_constant(globals, opTypeParam, result); 505 } 506 507 Form::DataType InstructForm::is_chain_of_constant(FormDict &globals, 508 const char * &opTypeParam, const char * &resultParam) { 509 Form::DataType data_type = Form::none; 510 if ( ! _matrule) return data_type; 511 512 // !!!!! 513 // The source of the chain rule is 'position = 1' 514 uint position = 1; 515 const char *result = nullptr; 516 const char *name = nullptr; 517 const char *opType = nullptr; 518 // Here base_operand is looking for an ideal type to be returned (opType). 519 if ( _matrule->is_chain_rule(globals) 520 && _matrule->base_operand(position, globals, result, name, opType) ) { 521 data_type = ideal_to_const_type(opType); 522 523 // if it isn't an ideal constant type, just return 524 if ( data_type == Form::none ) return data_type; 525 526 // Ideal constant types also adjust the opType parameter. 527 resultParam = result; 528 opTypeParam = opType; 529 return data_type; 530 } 531 532 return data_type; 533 } 534 535 // Check if a simple chain rule 536 bool InstructForm::is_simple_chain_rule(FormDict &globals) const { 537 if( _matrule && _matrule->sets_result() 538 && _matrule->_rChild->_lChild == nullptr 539 && globals[_matrule->_rChild->_opType] 540 && globals[_matrule->_rChild->_opType]->is_opclass() ) { 541 return true; 542 } 543 return false; 544 } 545 546 // check for structural rematerialization 547 bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) { 548 bool rematerialize = false; 549 550 Form::DataType data_type = is_chain_of_constant(globals); 551 if( data_type != Form::none ) 552 rematerialize = true; 553 554 // Constants 555 if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) ) 556 rematerialize = true; 557 558 // Pseudo-constants (values easily available to the runtime) 559 if (is_empty_encoding() && is_tls_instruction()) 560 rematerialize = true; 561 562 // 1-input, 1-output, such as copies or increments. 563 if( _components.count() == 2 && 564 _components[0]->is(Component::DEF) && 565 _components[1]->isa(Component::USE) ) 566 rematerialize = true; 567 568 // Check for an ideal 'Load?' and eliminate rematerialize option 569 if ( is_ideal_load() != Form::none || // Ideal load? Do not rematerialize 570 is_ideal_copy() != Form::none || // Ideal copy? Do not rematerialize 571 is_expensive() != Form::none) { // Expensive? Do not rematerialize 572 rematerialize = false; 573 } 574 575 // Always rematerialize the flags. They are more expensive to save & 576 // restore than to recompute (and possibly spill the compare's inputs). 577 if( _components.count() >= 1 ) { 578 Component *c = _components[0]; 579 const Form *form = globals[c->_type]; 580 OperandForm *opform = form->is_operand(); 581 if( opform ) { 582 // Avoid the special stack_slots register classes 583 const char *rc_name = opform->constrained_reg_class(); 584 if( rc_name ) { 585 if( strcmp(rc_name,"stack_slots") ) { 586 // Check for ideal_type of RegFlags 587 const char *type = opform->ideal_type( globals, registers ); 588 if( (type != nullptr) && !strcmp(type, "RegFlags") ) 589 rematerialize = true; 590 } else 591 rematerialize = false; // Do not rematerialize things target stk 592 } 593 } 594 } 595 596 return rematerialize; 597 } 598 599 // loads from memory, so must check for anti-dependence 600 bool InstructForm::needs_anti_dependence_check(FormDict &globals) const { 601 if ( skip_antidep_check() ) return false; 602 603 // Machine independent loads must be checked for anti-dependences 604 if( is_ideal_load() != Form::none ) return true; 605 606 // !!!!! !!!!! !!!!! 607 // TEMPORARY 608 // if( is_simple_chain_rule(globals) ) return false; 609 610 // String.(compareTo/equals/indexOf/hashCode) and Arrays.(equals/hashCode) 611 // use many memorys edges, but writes none 612 if( _matrule && _matrule->_rChild && 613 ( strcmp(_matrule->_rChild->_opType,"StrComp" )==0 || 614 strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 || 615 strcmp(_matrule->_rChild->_opType,"StrIndexOf" )==0 || 616 strcmp(_matrule->_rChild->_opType,"StrIndexOfChar" )==0 || 617 strcmp(_matrule->_rChild->_opType,"CountPositives" )==0 || 618 strcmp(_matrule->_rChild->_opType,"AryEq" )==0 || 619 strcmp(_matrule->_rChild->_opType,"VectorizedHashCode")==0 )) 620 return true; 621 622 // Check if instruction has a USE of a memory operand class, but no defs 623 bool USE_of_memory = false; 624 bool DEF_of_memory = false; 625 Component *comp = nullptr; 626 ComponentList &components = (ComponentList &)_components; 627 628 components.reset(); 629 while( (comp = components.iter()) != nullptr ) { 630 const Form *form = globals[comp->_type]; 631 if( !form ) continue; 632 OpClassForm *op = form->is_opclass(); 633 if( !op ) continue; 634 if( form->interface_type(globals) == Form::memory_interface ) { 635 if( comp->isa(Component::USE) ) USE_of_memory = true; 636 if( comp->isa(Component::DEF) ) { 637 OperandForm *oper = form->is_operand(); 638 if( oper && oper->is_user_name_for_sReg() ) { 639 // Stack slots are unaliased memory handled by allocator 640 oper = oper; // debug stopping point !!!!! 641 } else { 642 DEF_of_memory = true; 643 } 644 } 645 } 646 } 647 return (USE_of_memory && !DEF_of_memory); 648 } 649 650 651 int InstructForm::memory_operand(FormDict &globals) const { 652 // Machine independent loads must be checked for anti-dependences 653 // Check if instruction has a USE of a memory operand class, or a def. 654 int USE_of_memory = 0; 655 int DEF_of_memory = 0; 656 const char* last_memory_DEF = nullptr; // to test DEF/USE pairing in asserts 657 const char* last_memory_USE = nullptr; 658 Component *unique = nullptr; 659 Component *comp = nullptr; 660 ComponentList &components = (ComponentList &)_components; 661 662 components.reset(); 663 while( (comp = components.iter()) != nullptr ) { 664 const Form *form = globals[comp->_type]; 665 if( !form ) continue; 666 OpClassForm *op = form->is_opclass(); 667 if( !op ) continue; 668 if( op->stack_slots_only(globals) ) continue; 669 if( form->interface_type(globals) == Form::memory_interface ) { 670 if( comp->isa(Component::DEF) ) { 671 last_memory_DEF = comp->_name; 672 DEF_of_memory++; 673 unique = comp; 674 } else if( comp->isa(Component::USE) ) { 675 if( last_memory_DEF != nullptr ) { 676 assert(0 == strcmp(last_memory_DEF, comp->_name), "every memory DEF is followed by a USE of the same name"); 677 last_memory_DEF = nullptr; 678 } 679 // Handles same memory being used multiple times in the case of BMI1 instructions. 680 if (last_memory_USE != nullptr) { 681 if (strcmp(comp->_name, last_memory_USE) != 0) { 682 USE_of_memory++; 683 } 684 } else { 685 USE_of_memory++; 686 } 687 last_memory_USE = comp->_name; 688 689 if (DEF_of_memory == 0) // defs take precedence 690 unique = comp; 691 } else { 692 assert(last_memory_DEF == nullptr, "unpaired memory DEF"); 693 } 694 } 695 } 696 assert(last_memory_DEF == nullptr, "unpaired memory DEF"); 697 assert(USE_of_memory >= DEF_of_memory, "unpaired memory DEF"); 698 USE_of_memory -= DEF_of_memory; // treat paired DEF/USE as one occurrence 699 if( (USE_of_memory + DEF_of_memory) > 0 ) { 700 if( is_simple_chain_rule(globals) ) { 701 //fprintf(stderr, "Warning: chain rule is not really a memory user.\n"); 702 //((InstructForm*)this)->dump(); 703 // Preceding code prints nothing on sparc and these insns on intel: 704 // leaP8 leaP32 leaPIdxOff leaPIdxScale leaPIdxScaleOff leaP8 leaP32 705 // leaPIdxOff leaPIdxScale leaPIdxScaleOff 706 return NO_MEMORY_OPERAND; 707 } 708 709 if( DEF_of_memory == 1 ) { 710 assert(unique != nullptr, ""); 711 if( USE_of_memory == 0 ) { 712 // unique def, no uses 713 } else { 714 // // unique def, some uses 715 // // must return bottom unless all uses match def 716 // unique = nullptr; 717 #ifdef S390 718 // This case is important for move instructions on s390x. 719 // On other platforms (e.g. x86), all uses always match the def. 720 unique = nullptr; 721 #endif 722 } 723 } else if( DEF_of_memory > 0 ) { 724 // multiple defs, don't care about uses 725 unique = nullptr; 726 } else if( USE_of_memory == 1) { 727 // unique use, no defs 728 assert(unique != nullptr, ""); 729 } else if( USE_of_memory > 0 ) { 730 // multiple uses, no defs 731 unique = nullptr; 732 } else { 733 assert(false, "bad case analysis"); 734 } 735 // process the unique DEF or USE, if there is one 736 if( unique == nullptr ) { 737 return MANY_MEMORY_OPERANDS; 738 } else { 739 int pos = components.operand_position(unique->_name); 740 if( unique->isa(Component::DEF) ) { 741 pos += 1; // get corresponding USE from DEF 742 } 743 assert(pos >= 1, "I was just looking at it!"); 744 return pos; 745 } 746 } 747 748 // missed the memory op?? 749 if( true ) { // %%% should not be necessary 750 if( is_ideal_store() != Form::none ) { 751 fprintf(stderr, "Warning: cannot find memory opnd in instr.\n"); 752 ((InstructForm*)this)->dump(); 753 // pretend it has multiple defs and uses 754 return MANY_MEMORY_OPERANDS; 755 } 756 if( is_ideal_load() != Form::none ) { 757 fprintf(stderr, "Warning: cannot find memory opnd in instr.\n"); 758 ((InstructForm*)this)->dump(); 759 // pretend it has multiple uses and no defs 760 return MANY_MEMORY_OPERANDS; 761 } 762 } 763 764 return NO_MEMORY_OPERAND; 765 } 766 767 // This instruction captures the machine-independent bottom_type 768 // Expected use is for pointer vs oop determination for LoadP 769 bool InstructForm::captures_bottom_type(FormDict &globals) const { 770 if (_matrule && _matrule->_rChild && 771 (!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type 772 !strcmp(_matrule->_rChild->_opType,"CastDD") || 773 !strcmp(_matrule->_rChild->_opType,"CastFF") || 774 !strcmp(_matrule->_rChild->_opType,"CastII") || 775 !strcmp(_matrule->_rChild->_opType,"CastLL") || 776 !strcmp(_matrule->_rChild->_opType,"CastVV") || 777 !strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type 778 !strcmp(_matrule->_rChild->_opType,"DecodeN") || 779 !strcmp(_matrule->_rChild->_opType,"EncodeP") || 780 !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") || 781 !strcmp(_matrule->_rChild->_opType,"EncodePKlass") || 782 !strcmp(_matrule->_rChild->_opType,"LoadN") || 783 !strcmp(_matrule->_rChild->_opType,"LoadNKlass") || 784 !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception 785 !strcmp(_matrule->_rChild->_opType,"CheckCastPP") || 786 !strcmp(_matrule->_rChild->_opType,"GetAndSetP") || 787 !strcmp(_matrule->_rChild->_opType,"GetAndSetN") || 788 !strcmp(_matrule->_rChild->_opType,"RotateLeft") || 789 !strcmp(_matrule->_rChild->_opType,"RotateRight") || 790 #if INCLUDE_SHENANDOAHGC 791 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") || 792 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") || 793 #endif 794 !strcmp(_matrule->_rChild->_opType,"StrInflatedCopy") || 795 !strcmp(_matrule->_rChild->_opType,"VectorCmpMasked")|| 796 !strcmp(_matrule->_rChild->_opType,"VectorMaskGen")|| 797 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") || 798 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true; 799 else if ( is_ideal_load() == Form::idealP ) return true; 800 else if ( is_ideal_store() != Form::none ) return true; 801 802 if (needs_base_oop_edge(globals)) return true; 803 804 if (is_vector()) return true; 805 if (is_mach_constant()) return true; 806 807 return false; 808 } 809 810 811 // Access instr_cost attribute or return null. 812 const char* InstructForm::cost() { 813 for (Attribute* cur = _attribs; cur != nullptr; cur = (Attribute*)cur->_next) { 814 if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) { 815 return cur->_val; 816 } 817 } 818 return nullptr; 819 } 820 821 // Return count of top-level operands. 822 uint InstructForm::num_opnds() { 823 int num_opnds = _components.num_operands(); 824 825 // Need special handling for matching some ideal nodes 826 // i.e. Matching a return node 827 /* 828 if( _matrule ) { 829 if( strcmp(_matrule->_opType,"Return" )==0 || 830 strcmp(_matrule->_opType,"Halt" )==0 ) 831 return 3; 832 } 833 */ 834 return num_opnds; 835 } 836 837 const char* InstructForm::opnd_ident(int idx) { 838 return _components.at(idx)->_name; 839 } 840 841 const char* InstructForm::unique_opnd_ident(uint idx) { 842 uint i; 843 for (i = 1; i < num_opnds(); ++i) { 844 if (unique_opnds_idx(i) == idx) { 845 break; 846 } 847 } 848 return (_components.at(i) != nullptr) ? _components.at(i)->_name : ""; 849 } 850 851 // Return count of unmatched operands. 852 uint InstructForm::num_post_match_opnds() { 853 uint num_post_match_opnds = _components.count(); 854 uint num_match_opnds = _components.match_count(); 855 num_post_match_opnds = num_post_match_opnds - num_match_opnds; 856 857 return num_post_match_opnds; 858 } 859 860 // Return the number of leaves below this complex operand 861 uint InstructForm::num_consts(FormDict &globals) const { 862 if ( ! _matrule) return 0; 863 864 // This is a recursive invocation on all operands in the matchrule 865 return _matrule->num_consts(globals); 866 } 867 868 // Constants in match rule with specified type 869 uint InstructForm::num_consts(FormDict &globals, Form::DataType type) const { 870 if ( ! _matrule) return 0; 871 872 // This is a recursive invocation on all operands in the matchrule 873 return _matrule->num_consts(globals, type); 874 } 875 876 877 // Return the register class associated with 'leaf'. 878 const char *InstructForm::out_reg_class(FormDict &globals) { 879 assert( false, "InstructForm::out_reg_class(FormDict &globals); Not Implemented"); 880 881 return nullptr; 882 } 883 884 885 886 // Lookup the starting position of inputs we are interested in wrt. ideal nodes 887 uint InstructForm::oper_input_base(FormDict &globals) { 888 if( !_matrule ) return 1; // Skip control for most nodes 889 890 // Need special handling for matching some ideal nodes 891 // i.e. Matching a return node 892 if( strcmp(_matrule->_opType,"Return" )==0 || 893 strcmp(_matrule->_opType,"Rethrow" )==0 || 894 strcmp(_matrule->_opType,"TailCall" )==0 || 895 strcmp(_matrule->_opType,"TailJump" )==0 || 896 strcmp(_matrule->_opType,"SafePoint" )==0 || 897 strcmp(_matrule->_opType,"Halt" )==0 || 898 strcmp(_matrule->_opType,"CallLeafNoFP")==0) 899 return AdlcVMDeps::Parms; // Skip the machine-state edges 900 901 if( _matrule->_rChild && 902 ( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 || 903 strcmp(_matrule->_rChild->_opType,"VectorizedHashCode")==0 || 904 strcmp(_matrule->_rChild->_opType,"StrComp" )==0 || 905 strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 || 906 strcmp(_matrule->_rChild->_opType,"StrInflatedCopy" )==0 || 907 strcmp(_matrule->_rChild->_opType,"StrCompressedCopy" )==0 || 908 strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 || 909 strcmp(_matrule->_rChild->_opType,"StrIndexOfChar")==0 || 910 strcmp(_matrule->_rChild->_opType,"CountPositives")==0 || 911 strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) { 912 // String.(compareTo/equals/indexOf/hashCode) and Arrays.equals 913 // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray 914 // take 1 control and 1 memory edges. 915 // Also String.(compressedCopy/inflatedCopy). 916 return 2; 917 } 918 919 // Check for handling of 'Memory' input/edge in the ideal world. 920 // The AD file writer is shielded from knowledge of these edges. 921 int base = 1; // Skip control 922 base += _matrule->needs_ideal_memory_edge(globals); 923 924 // Also skip the base-oop value for uses of derived oops. 925 // The AD file writer is shielded from knowledge of these edges. 926 base += needs_base_oop_edge(globals); 927 928 return base; 929 } 930 931 // This function determines the order of the MachOper in _opnds[] 932 // by writing the operand names into the _components list. 933 // 934 // Implementation does not modify state of internal structures 935 void InstructForm::build_components() { 936 // Add top-level operands to the components 937 if (_matrule) _matrule->append_components(_localNames, _components); 938 939 // Add parameters that "do not appear in match rule". 940 bool has_temp = false; 941 const char *name; 942 const char *kill_name = nullptr; 943 for (_parameters.reset(); (name = _parameters.iter()) != nullptr;) { 944 OpClassForm *opForm = _localNames[name]->is_opclass(); 945 assert(opForm != nullptr, "sanity"); 946 947 Effect* e = nullptr; 948 { 949 const Form* form = _effects[name]; 950 e = form ? form->is_effect() : nullptr; 951 } 952 953 if (e != nullptr) { 954 has_temp |= e->is(Component::TEMP); 955 956 // KILLs must be declared after any TEMPs because TEMPs are real 957 // uses so their operand numbering must directly follow the real 958 // inputs from the match rule. Fixing the numbering seems 959 // complex so simply enforce the restriction during parse. 960 if (kill_name != nullptr && 961 e->isa(Component::TEMP) && !e->isa(Component::DEF)) { 962 OpClassForm* kill = _localNames[kill_name]->is_opclass(); 963 assert(kill != nullptr, "sanity"); 964 globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n", 965 _ident, kill->_ident, kill_name); 966 } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) { 967 kill_name = name; 968 } 969 } 970 971 const Component *component = _components.search(name); 972 if ( component == nullptr ) { 973 if (e) { 974 _components.insert(name, opForm->_ident, e->_use_def, false); 975 component = _components.search(name); 976 if (component->isa(Component::USE) && !component->isa(Component::TEMP) && _matrule) { 977 const Form *form = globalAD->globalNames()[component->_type]; 978 assert( form, "component type must be a defined form"); 979 OperandForm *op = form->is_operand(); 980 if (op->_interface && op->_interface->is_RegInterface()) { 981 globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n", 982 _ident, opForm->_ident, name); 983 } 984 } 985 } else { 986 // This would be a nice warning but it triggers in a few places in a benign way 987 // if (_matrule != nullptr && !expands()) { 988 // globalAD->syntax_err(_linenum, "%s: %s %s not mentioned in effect or match rule\n", 989 // _ident, opForm->_ident, name); 990 // } 991 _components.insert(name, opForm->_ident, Component::INVALID, false); 992 } 993 } 994 else if (e) { 995 // Component was found in the list 996 // Check if there is a new effect that requires an extra component. 997 // This happens when adding 'USE' to a component that is not yet one. 998 if ((!component->isa( Component::USE) && ((e->_use_def & Component::USE) != 0))) { 999 if (component->isa(Component::USE) && _matrule) { 1000 const Form *form = globalAD->globalNames()[component->_type]; 1001 assert( form, "component type must be a defined form"); 1002 OperandForm *op = form->is_operand(); 1003 if (op->_interface && op->_interface->is_RegInterface()) { 1004 globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n", 1005 _ident, opForm->_ident, name); 1006 } 1007 } 1008 _components.insert(name, opForm->_ident, e->_use_def, false); 1009 } else { 1010 Component *comp = (Component*)component; 1011 comp->promote_use_def_info(e->_use_def); 1012 } 1013 // Component positions are zero based. 1014 int pos = _components.operand_position(name); 1015 assert( ! (component->isa(Component::DEF) && (pos >= 1)), 1016 "Component::DEF can only occur in the first position"); 1017 } 1018 } 1019 1020 // Resolving the interactions between expand rules and TEMPs would 1021 // be complex so simply disallow it. 1022 if (_matrule == nullptr && has_temp) { 1023 globalAD->syntax_err(_linenum, "%s: TEMPs without match rule isn't supported\n", _ident); 1024 } 1025 1026 return; 1027 } 1028 1029 // Return zero-based position in component list; -1 if not in list. 1030 int InstructForm::operand_position(const char *name, int usedef) { 1031 return unique_opnds_idx(_components.operand_position(name, usedef, this)); 1032 } 1033 1034 int InstructForm::operand_position_format(const char *name) { 1035 return unique_opnds_idx(_components.operand_position_format(name, this)); 1036 } 1037 1038 // Return zero-based position in component list; -1 if not in list. 1039 int InstructForm::label_position() { 1040 return unique_opnds_idx(_components.label_position()); 1041 } 1042 1043 int InstructForm::method_position() { 1044 return unique_opnds_idx(_components.method_position()); 1045 } 1046 1047 // Return number of relocation entries needed for this instruction. 1048 uint InstructForm::reloc(FormDict &globals) { 1049 uint reloc_entries = 0; 1050 // Check for "Call" nodes 1051 if ( is_ideal_call() ) ++reloc_entries; 1052 if ( is_ideal_return() ) ++reloc_entries; 1053 if ( is_ideal_safepoint() ) ++reloc_entries; 1054 1055 1056 // Check if operands MAYBE oop pointers, by checking for ConP elements 1057 // Proceed through the leaves of the match-tree and check for ConPs 1058 if ( _matrule != nullptr ) { 1059 uint position = 0; 1060 const char *result = nullptr; 1061 const char *name = nullptr; 1062 const char *opType = nullptr; 1063 while (_matrule->base_operand(position, globals, result, name, opType)) { 1064 if ( strcmp(opType,"ConP") == 0 ) { 1065 ++reloc_entries; 1066 } 1067 ++position; 1068 } 1069 } 1070 1071 // Above is only a conservative estimate 1072 // because it did not check contents of operand classes. 1073 // !!!!! !!!!! 1074 // Add 1 to reloc info for each operand class in the component list. 1075 Component *comp; 1076 _components.reset(); 1077 while ( (comp = _components.iter()) != nullptr ) { 1078 const Form *form = globals[comp->_type]; 1079 assert( form, "Did not find component's type in global names"); 1080 const OpClassForm *opc = form->is_opclass(); 1081 const OperandForm *oper = form->is_operand(); 1082 if ( opc && (oper == nullptr) ) { 1083 ++reloc_entries; 1084 } else if ( oper ) { 1085 // floats and doubles loaded out of method's constant pool require reloc info 1086 Form::DataType type = oper->is_base_constant(globals); 1087 if ( (type == Form::idealF) || (type == Form::idealD) ) { 1088 ++reloc_entries; 1089 } 1090 } 1091 } 1092 1093 // Float and Double constants may come from the CodeBuffer table 1094 // and require relocatable addresses for access 1095 // !!!!! 1096 // Check for any component being an immediate float or double. 1097 Form::DataType data_type = is_chain_of_constant(globals); 1098 if( data_type==idealD || data_type==idealF ) { 1099 reloc_entries++; 1100 } 1101 1102 return reloc_entries; 1103 } 1104 1105 // Utility function defined in archDesc.cpp 1106 extern bool is_def(int usedef); 1107 1108 // Return the result of reducing an instruction 1109 const char *InstructForm::reduce_result() { 1110 const char* result = "Universe"; // default 1111 _components.reset(); 1112 Component *comp = _components.iter(); 1113 if (comp != nullptr && comp->isa(Component::DEF)) { 1114 result = comp->_type; 1115 // Override this if the rule is a store operation: 1116 if (_matrule && _matrule->_rChild && 1117 is_store_to_memory(_matrule->_rChild->_opType)) 1118 result = "Universe"; 1119 } 1120 return result; 1121 } 1122 1123 // Return the name of the operand on the right hand side of the binary match 1124 // Return null if there is no right hand side 1125 const char *InstructForm::reduce_right(FormDict &globals) const { 1126 if( _matrule == nullptr ) return nullptr; 1127 return _matrule->reduce_right(globals); 1128 } 1129 1130 // Similar for left 1131 const char *InstructForm::reduce_left(FormDict &globals) const { 1132 if( _matrule == nullptr ) return nullptr; 1133 return _matrule->reduce_left(globals); 1134 } 1135 1136 1137 // Base class for this instruction, MachNode except for calls 1138 const char *InstructForm::mach_base_class(FormDict &globals) const { 1139 if( is_ideal_call() == Form::JAVA_STATIC ) { 1140 return "MachCallStaticJavaNode"; 1141 } 1142 else if( is_ideal_call() == Form::JAVA_DYNAMIC ) { 1143 return "MachCallDynamicJavaNode"; 1144 } 1145 else if( is_ideal_call() == Form::JAVA_RUNTIME ) { 1146 return "MachCallRuntimeNode"; 1147 } 1148 else if( is_ideal_call() == Form::JAVA_LEAF ) { 1149 return "MachCallLeafNode"; 1150 } 1151 else if (is_ideal_return()) { 1152 return "MachReturnNode"; 1153 } 1154 else if (is_ideal_halt()) { 1155 return "MachHaltNode"; 1156 } 1157 else if (is_ideal_safepoint()) { 1158 return "MachSafePointNode"; 1159 } 1160 else if (is_ideal_if()) { 1161 return "MachIfNode"; 1162 } 1163 else if (is_ideal_goto()) { 1164 return "MachGotoNode"; 1165 } 1166 else if (is_ideal_fastlock()) { 1167 return "MachFastLockNode"; 1168 } 1169 else if (is_ideal_nop()) { 1170 return "MachNopNode"; 1171 } 1172 else if( is_ideal_membar()) { 1173 return "MachMemBarNode"; 1174 } 1175 else if (is_ideal_jump()) { 1176 return "MachJumpNode"; 1177 } 1178 else if (is_mach_constant()) { 1179 return "MachConstantNode"; 1180 } 1181 else if (captures_bottom_type(globals)) { 1182 return "MachTypeNode"; 1183 } else { 1184 return "MachNode"; 1185 } 1186 assert( false, "ShouldNotReachHere()"); 1187 return nullptr; 1188 } 1189 1190 // Compare the instruction predicates for textual equality 1191 bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) { 1192 const Predicate *pred1 = instr1->_predicate; 1193 const Predicate *pred2 = instr2->_predicate; 1194 if( pred1 == nullptr && pred2 == nullptr ) { 1195 // no predicates means they are identical 1196 return true; 1197 } 1198 if( pred1 != nullptr && pred2 != nullptr ) { 1199 // compare the predicates 1200 if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) { 1201 return true; 1202 } 1203 } 1204 1205 return false; 1206 } 1207 1208 // Check if this instruction can cisc-spill to 'alternate' 1209 bool InstructForm::cisc_spills_to(ArchDesc &AD, InstructForm *instr) { 1210 assert( _matrule != nullptr && instr->_matrule != nullptr, "must have match rules"); 1211 // Do not replace if a cisc-version has been found. 1212 if( cisc_spill_operand() != Not_cisc_spillable ) return false; 1213 1214 int cisc_spill_operand = Maybe_cisc_spillable; 1215 char *result = nullptr; 1216 char *result2 = nullptr; 1217 const char *op_name = nullptr; 1218 const char *reg_type = nullptr; 1219 FormDict &globals = AD.globalNames(); 1220 cisc_spill_operand = _matrule->matchrule_cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type); 1221 if( (cisc_spill_operand != Not_cisc_spillable) && (op_name != nullptr) && equivalent_predicates(this, instr) ) { 1222 cisc_spill_operand = operand_position(op_name, Component::USE); 1223 int def_oper = operand_position(op_name, Component::DEF); 1224 if( def_oper == NameList::Not_in_list && instr->num_opnds() == num_opnds()) { 1225 // Do not support cisc-spilling for destination operands and 1226 // make sure they have the same number of operands. 1227 _cisc_spill_alternate = instr; 1228 instr->set_cisc_alternate(true); 1229 if( AD._cisc_spill_debug ) { 1230 fprintf(stderr, "Instruction %s cisc-spills-to %s\n", _ident, instr->_ident); 1231 fprintf(stderr, " using operand %s %s at index %d\n", reg_type, op_name, cisc_spill_operand); 1232 } 1233 // Record that a stack-version of the reg_mask is needed 1234 // !!!!! 1235 OperandForm *oper = (OperandForm*)(globals[reg_type]->is_operand()); 1236 assert( oper != nullptr, "cisc-spilling non operand"); 1237 const char *reg_class_name = oper->constrained_reg_class(); 1238 AD.set_stack_or_reg(reg_class_name); 1239 const char *reg_mask_name = AD.reg_mask(*oper); 1240 set_cisc_reg_mask_name(reg_mask_name); 1241 const char *stack_or_reg_mask_name = AD.stack_or_reg_mask(*oper); 1242 } else { 1243 cisc_spill_operand = Not_cisc_spillable; 1244 } 1245 } else { 1246 cisc_spill_operand = Not_cisc_spillable; 1247 } 1248 1249 set_cisc_spill_operand(cisc_spill_operand); 1250 return (cisc_spill_operand != Not_cisc_spillable); 1251 } 1252 1253 // Check to see if this instruction can be replaced with the short branch 1254 // instruction `short-branch' 1255 bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch) { 1256 if (_matrule != nullptr && 1257 this != short_branch && // Don't match myself 1258 !is_short_branch() && // Don't match another short branch variant 1259 reduce_result() != nullptr && 1260 strstr(_ident, "restoreMask") == nullptr && // Don't match side effects 1261 strcmp(reduce_result(), short_branch->reduce_result()) == 0 && 1262 _matrule->equivalent(AD.globalNames(), short_branch->_matrule)) { 1263 // The instructions are equivalent. 1264 1265 // Now verify that both instructions have the same parameters and 1266 // the same effects. Both branch forms should have the same inputs 1267 // and resulting projections to correctly replace a long branch node 1268 // with corresponding short branch node during code generation. 1269 1270 bool different = false; 1271 if (short_branch->_components.count() != _components.count()) { 1272 different = true; 1273 } else if (_components.count() > 0) { 1274 short_branch->_components.reset(); 1275 _components.reset(); 1276 Component *comp; 1277 while ((comp = _components.iter()) != nullptr) { 1278 Component *short_comp = short_branch->_components.iter(); 1279 if (short_comp == nullptr || 1280 short_comp->_type != comp->_type || 1281 short_comp->_usedef != comp->_usedef) { 1282 different = true; 1283 break; 1284 } 1285 } 1286 if (short_branch->_components.iter() != nullptr) 1287 different = true; 1288 } 1289 if (different) { 1290 globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident); 1291 } 1292 if (AD._adl_debug > 1 || AD._short_branch_debug) { 1293 fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident); 1294 } 1295 _short_branch_form = short_branch; 1296 return true; 1297 } 1298 return false; 1299 } 1300 1301 1302 // --------------------------- FILE *output_routines 1303 // 1304 // Generate the format call for the replacement variable 1305 void InstructForm::rep_var_format(FILE *fp, const char *rep_var) { 1306 // Handle special constant table variables. 1307 if (strcmp(rep_var, "constanttablebase") == 0) { 1308 fprintf(fp, "char reg[128]; ra->dump_register(in(mach_constant_base_node_input()), reg, sizeof(reg));\n"); 1309 fprintf(fp, " st->print(\"%%s\", reg);\n"); 1310 return; 1311 } 1312 if (strcmp(rep_var, "constantoffset") == 0) { 1313 fprintf(fp, "st->print(\"#%%d\", constant_offset_unchecked());\n"); 1314 return; 1315 } 1316 if (strcmp(rep_var, "constantaddress") == 0) { 1317 fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset_unchecked());\n"); 1318 return; 1319 } 1320 1321 // Find replacement variable's type 1322 const Form *form = _localNames[rep_var]; 1323 if (form == nullptr) { 1324 globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.", 1325 rep_var, _ident); 1326 return; 1327 } 1328 OpClassForm *opc = form->is_opclass(); 1329 assert( opc, "replacement variable was not found in local names"); 1330 // Lookup the index position of the replacement variable 1331 int idx = operand_position_format(rep_var); 1332 if ( idx == -1 ) { 1333 globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n", 1334 rep_var, _ident); 1335 assert(strcmp(opc->_ident, "label") == 0, "Unimplemented"); 1336 return; 1337 } 1338 1339 if (is_noninput_operand(idx)) { 1340 // This component isn't in the input array. Print out the static 1341 // name of the register. 1342 OperandForm* oper = form->is_operand(); 1343 if (oper != nullptr && oper->is_bound_register()) { 1344 const RegDef* first = oper->get_RegClass()->find_first_elem(); 1345 fprintf(fp, " st->print_raw(\"%s\");\n", first->_regname); 1346 } else { 1347 globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var); 1348 } 1349 } else { 1350 // Output the format call for this operand 1351 fprintf(fp,"opnd_array(%d)->",idx); 1352 if (idx == 0) 1353 fprintf(fp,"int_format(ra, this, st); // %s\n", rep_var); 1354 else 1355 fprintf(fp,"ext_format(ra, this,idx%d, st); // %s\n", idx, rep_var ); 1356 } 1357 } 1358 1359 // Search through operands to determine parameters unique positions. 1360 void InstructForm::set_unique_opnds() { 1361 uint* uniq_idx = nullptr; 1362 uint nopnds = num_opnds(); 1363 uint num_uniq = nopnds; 1364 uint i; 1365 _uniq_idx_length = 0; 1366 if (nopnds > 0) { 1367 // Allocate index array. Worst case we're mapping from each 1368 // component back to an index and any DEF always goes at 0 so the 1369 // length of the array has to be the number of components + 1. 1370 _uniq_idx_length = _components.count() + 1; 1371 uniq_idx = (uint*) AdlAllocateHeap(sizeof(uint) * _uniq_idx_length); 1372 for (i = 0; i < _uniq_idx_length; i++) { 1373 uniq_idx[i] = i; 1374 } 1375 } 1376 // Do it only if there is a match rule and no expand rule. With an 1377 // expand rule it is done by creating new mach node in Expand() 1378 // method. 1379 if (nopnds > 0 && _matrule != nullptr && _exprule == nullptr) { 1380 const char *name; 1381 uint count; 1382 bool has_dupl_use = false; 1383 1384 _parameters.reset(); 1385 while ((name = _parameters.iter()) != nullptr) { 1386 count = 0; 1387 uint position = 0; 1388 uint uniq_position = 0; 1389 _components.reset(); 1390 Component *comp = nullptr; 1391 if (sets_result()) { 1392 comp = _components.iter(); 1393 position++; 1394 } 1395 // The next code is copied from the method operand_position(). 1396 for (; (comp = _components.iter()) != nullptr; ++position) { 1397 // When the first component is not a DEF, 1398 // leave space for the result operand! 1399 if (position==0 && (!comp->isa(Component::DEF))) { 1400 ++position; 1401 } 1402 if (strcmp(name, comp->_name) == 0) { 1403 if (++count > 1) { 1404 assert(position < _uniq_idx_length, "out of bounds"); 1405 uniq_idx[position] = uniq_position; 1406 has_dupl_use = true; 1407 } else { 1408 uniq_position = position; 1409 } 1410 } 1411 if (comp->isa(Component::DEF) && comp->isa(Component::USE)) { 1412 ++position; 1413 if (position != 1) 1414 --position; // only use two slots for the 1st USE_DEF 1415 } 1416 } 1417 } 1418 if (has_dupl_use) { 1419 for (i = 1; i < nopnds; i++) { 1420 if (i != uniq_idx[i]) { 1421 break; 1422 } 1423 } 1424 uint j = i; 1425 for (; i < nopnds; i++) { 1426 if (i == uniq_idx[i]) { 1427 uniq_idx[i] = j++; 1428 } 1429 } 1430 num_uniq = j; 1431 } 1432 } 1433 _uniq_idx = uniq_idx; 1434 _num_uniq = num_uniq; 1435 } 1436 1437 // Generate index values needed for determining the operand position 1438 void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix, const char *receiver) { 1439 uint idx = 0; // position of operand in match rule 1440 int cur_num_opnds = num_opnds(); 1441 1442 // Compute the index into vector of operand pointers: 1443 // idx0=0 is used to indicate that info comes from this same node, not from input edge. 1444 // idx1 starts at oper_input_base() 1445 if ( cur_num_opnds >= 1 ) { 1446 fprintf(fp," // Start at oper_input_base() and count operands\n"); 1447 fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals)); 1448 fprintf(fp," unsigned %sidx1 = %d;", prefix, oper_input_base(globals)); 1449 fprintf(fp," \t// %s\n", unique_opnd_ident(1)); 1450 1451 // Generate starting points for other unique operands if they exist 1452 for ( idx = 2; idx < num_unique_opnds(); ++idx ) { 1453 if( *receiver == 0 ) { 1454 fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();", 1455 prefix, idx, prefix, idx-1, idx-1 ); 1456 } else { 1457 fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();", 1458 prefix, idx, prefix, idx-1, receiver, idx-1 ); 1459 } 1460 fprintf(fp," \t// %s\n", unique_opnd_ident(idx)); 1461 } 1462 } 1463 if( *receiver != 0 ) { 1464 // This value is used by generate_peepreplace when copying a node. 1465 // Don't emit it in other cases since it can hide bugs with the 1466 // use invalid idx's. 1467 fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver); 1468 } 1469 1470 } 1471 1472 // --------------------------- 1473 bool InstructForm::verify() { 1474 // !!!!! !!!!! 1475 // Check that a "label" operand occurs last in the operand list, if present 1476 return true; 1477 } 1478 1479 void InstructForm::dump() { 1480 output(stderr); 1481 } 1482 1483 void InstructForm::output(FILE *fp) { 1484 fprintf(fp,"\nInstruction: %s\n", (_ident?_ident:"")); 1485 if (_matrule) _matrule->output(fp); 1486 if (_insencode) _insencode->output(fp); 1487 if (_constant) _constant->output(fp); 1488 if (_opcode) _opcode->output(fp); 1489 if (_attribs) _attribs->output(fp); 1490 if (_predicate) _predicate->output(fp); 1491 if (_effects.Size()) { 1492 fprintf(fp,"Effects\n"); 1493 _effects.dump(); 1494 } 1495 if (_exprule) _exprule->output(fp); 1496 if (_rewrule) _rewrule->output(fp); 1497 if (_format) _format->output(fp); 1498 if (_peephole) _peephole->output(fp); 1499 } 1500 1501 void MachNodeForm::dump() { 1502 output(stderr); 1503 } 1504 1505 void MachNodeForm::output(FILE *fp) { 1506 fprintf(fp,"\nMachNode: %s\n", (_ident?_ident:"")); 1507 } 1508 1509 //------------------------------build_predicate-------------------------------- 1510 // Build instruction predicates. If the user uses the same operand name 1511 // twice, we need to check that the operands are pointer-eequivalent in 1512 // the DFA during the labeling process. 1513 Predicate *InstructForm::build_predicate() { 1514 const int buflen = 1024; 1515 char buf[buflen], *s=buf; 1516 Dict names(cmpstr,hashstr,Form::arena); // Map Names to counts 1517 1518 MatchNode *mnode = 1519 strcmp(_matrule->_opType, "Set") ? _matrule : _matrule->_rChild; 1520 if (mnode != nullptr) mnode->count_instr_names(names); 1521 1522 uint first = 1; 1523 // Start with the predicate supplied in the .ad file. 1524 if (_predicate) { 1525 if (first) first = 0; 1526 strcpy(s, "("); s += strlen(s); 1527 strncpy(s, _predicate->_pred, buflen - strlen(s) - 1); 1528 s += strlen(s); 1529 strcpy(s, ")"); s += strlen(s); 1530 } 1531 for( DictI i(&names); i.test(); ++i ) { 1532 uintptr_t cnt = (uintptr_t)i._value; 1533 if( cnt > 1 ) { // Need a predicate at all? 1534 int path_bitmask = 0; 1535 assert( cnt == 2, "Unimplemented" ); 1536 // Handle many pairs 1537 if( first ) first=0; 1538 else { // All tests must pass, so use '&&' 1539 strcpy(s," && "); 1540 s += strlen(s); 1541 } 1542 // Add predicate to working buffer 1543 snprintf_checked(s, remaining_buflen(buf, s), "/*%s*/(",(char*)i._key); 1544 s += strlen(s); 1545 mnode->build_instr_pred(s,(char*)i._key, 0, path_bitmask, 0); 1546 s += strlen(s); 1547 strcpy(s," == "); s += strlen(s); 1548 mnode->build_instr_pred(s,(char*)i._key, 1, path_bitmask, 0); 1549 s += strlen(s); 1550 strcpy(s,")"); s += strlen(s); 1551 } 1552 } 1553 if( s == buf ) s = nullptr; 1554 else { 1555 assert( strlen(buf) < sizeof(buf), "String buffer overflow" ); 1556 s = strdup(buf); 1557 } 1558 return new Predicate(s); 1559 } 1560 1561 //------------------------------EncodeForm------------------------------------- 1562 // Constructor 1563 EncodeForm::EncodeForm() 1564 : _encClass(cmpstr,hashstr, Form::arena) { 1565 } 1566 EncodeForm::~EncodeForm() { 1567 } 1568 1569 // record a new register class 1570 EncClass *EncodeForm::add_EncClass(const char *className) { 1571 EncClass *encClass = new EncClass(className); 1572 _eclasses.addName(className); 1573 _encClass.Insert(className,encClass); 1574 return encClass; 1575 } 1576 1577 // Lookup the function body for an encoding class 1578 EncClass *EncodeForm::encClass(const char *className) { 1579 assert( className != nullptr, "Must provide a defined encoding name"); 1580 1581 EncClass *encClass = (EncClass*)_encClass[className]; 1582 return encClass; 1583 } 1584 1585 // Lookup the function body for an encoding class 1586 const char *EncodeForm::encClassBody(const char *className) { 1587 if( className == nullptr ) return nullptr; 1588 1589 EncClass *encClass = (EncClass*)_encClass[className]; 1590 assert( encClass != nullptr, "Encode Class is missing."); 1591 encClass->_code.reset(); 1592 const char *code = (const char*)encClass->_code.iter(); 1593 assert( code != nullptr, "Found an empty encode class body."); 1594 1595 return code; 1596 } 1597 1598 // Lookup the function body for an encoding class 1599 const char *EncodeForm::encClassPrototype(const char *className) { 1600 assert( className != nullptr, "Encode class name must be non null."); 1601 1602 return className; 1603 } 1604 1605 void EncodeForm::dump() { // Debug printer 1606 output(stderr); 1607 } 1608 1609 void EncodeForm::output(FILE *fp) { // Write info to output files 1610 const char *name; 1611 fprintf(fp,"\n"); 1612 fprintf(fp,"-------------------- Dump EncodeForm --------------------\n"); 1613 for (_eclasses.reset(); (name = _eclasses.iter()) != nullptr;) { 1614 ((EncClass*)_encClass[name])->output(fp); 1615 } 1616 fprintf(fp,"-------------------- end EncodeForm --------------------\n"); 1617 } 1618 //------------------------------EncClass--------------------------------------- 1619 EncClass::EncClass(const char *name) 1620 : _localNames(cmpstr,hashstr, Form::arena), _name(name) { 1621 } 1622 EncClass::~EncClass() { 1623 } 1624 1625 // Add a parameter <type,name> pair 1626 void EncClass::add_parameter(const char *parameter_type, const char *parameter_name) { 1627 _parameter_type.addName( parameter_type ); 1628 _parameter_name.addName( parameter_name ); 1629 } 1630 1631 // Verify operand types in parameter list 1632 bool EncClass::check_parameter_types(FormDict &globals) { 1633 // !!!!! 1634 return false; 1635 } 1636 1637 // Add the decomposed "code" sections of an encoding's code-block 1638 void EncClass::add_code(const char *code) { 1639 _code.addName(code); 1640 } 1641 1642 // Add the decomposed "replacement variables" of an encoding's code-block 1643 void EncClass::add_rep_var(char *replacement_var) { 1644 _code.addName(NameList::_signal); 1645 _rep_vars.addName(replacement_var); 1646 } 1647 1648 // Lookup the function body for an encoding class 1649 int EncClass::rep_var_index(const char *rep_var) { 1650 uint position = 0; 1651 const char *name = nullptr; 1652 1653 _parameter_name.reset(); 1654 while ( (name = _parameter_name.iter()) != nullptr ) { 1655 if ( strcmp(rep_var,name) == 0 ) return position; 1656 ++position; 1657 } 1658 1659 return -1; 1660 } 1661 1662 // Check after parsing 1663 bool EncClass::verify() { 1664 // 1!!!! 1665 // Check that each replacement variable, '$name' in architecture description 1666 // is actually a local variable for this encode class, or a reserved name 1667 // "primary, secondary, tertiary" 1668 return true; 1669 } 1670 1671 void EncClass::dump() { 1672 output(stderr); 1673 } 1674 1675 // Write info to output files 1676 void EncClass::output(FILE *fp) { 1677 fprintf(fp,"EncClass: %s", (_name ? _name : "")); 1678 1679 // Output the parameter list 1680 _parameter_type.reset(); 1681 _parameter_name.reset(); 1682 const char *type = _parameter_type.iter(); 1683 const char *name = _parameter_name.iter(); 1684 fprintf(fp, " ( "); 1685 for ( ; (type != nullptr) && (name != nullptr); 1686 (type = _parameter_type.iter()), (name = _parameter_name.iter()) ) { 1687 fprintf(fp, " %s %s,", type, name); 1688 } 1689 fprintf(fp, " ) "); 1690 1691 // Output the code block 1692 _code.reset(); 1693 _rep_vars.reset(); 1694 const char *code; 1695 while ( (code = _code.iter()) != nullptr ) { 1696 if ( _code.is_signal(code) ) { 1697 // A replacement variable 1698 const char *rep_var = _rep_vars.iter(); 1699 fprintf(fp,"($%s)", rep_var); 1700 } else { 1701 // A section of code 1702 fprintf(fp,"%s", code); 1703 } 1704 } 1705 1706 } 1707 1708 //------------------------------Opcode----------------------------------------- 1709 Opcode::Opcode(char *primary, char *secondary, char *tertiary) 1710 : _primary(primary), _secondary(secondary), _tertiary(tertiary) { 1711 } 1712 1713 Opcode::~Opcode() { 1714 } 1715 1716 Opcode::opcode_type Opcode::as_opcode_type(const char *param) { 1717 if( strcmp(param,"primary") == 0 ) { 1718 return Opcode::PRIMARY; 1719 } 1720 else if( strcmp(param,"secondary") == 0 ) { 1721 return Opcode::SECONDARY; 1722 } 1723 else if( strcmp(param,"tertiary") == 0 ) { 1724 return Opcode::TERTIARY; 1725 } 1726 return Opcode::NOT_AN_OPCODE; 1727 } 1728 1729 bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) { 1730 // Default values previously provided by MachNode::primary()... 1731 const char *description = nullptr; 1732 const char *value = nullptr; 1733 // Check if user provided any opcode definitions 1734 // Update 'value' if user provided a definition in the instruction 1735 switch (desired_opcode) { 1736 case PRIMARY: 1737 description = "primary()"; 1738 if( _primary != nullptr) { value = _primary; } 1739 break; 1740 case SECONDARY: 1741 description = "secondary()"; 1742 if( _secondary != nullptr ) { value = _secondary; } 1743 break; 1744 case TERTIARY: 1745 description = "tertiary()"; 1746 if( _tertiary != nullptr ) { value = _tertiary; } 1747 break; 1748 default: 1749 assert( false, "ShouldNotReachHere();"); 1750 break; 1751 } 1752 1753 if (value != nullptr) { 1754 fprintf(fp, "(%s /*%s*/)", value, description); 1755 } 1756 return value != nullptr; 1757 } 1758 1759 void Opcode::dump() { 1760 output(stderr); 1761 } 1762 1763 // Write info to output files 1764 void Opcode::output(FILE *fp) { 1765 if (_primary != nullptr) fprintf(fp,"Primary opcode: %s\n", _primary); 1766 if (_secondary != nullptr) fprintf(fp,"Secondary opcode: %s\n", _secondary); 1767 if (_tertiary != nullptr) fprintf(fp,"Tertiary opcode: %s\n", _tertiary); 1768 } 1769 1770 //------------------------------InsEncode-------------------------------------- 1771 InsEncode::InsEncode() { 1772 } 1773 InsEncode::~InsEncode() { 1774 } 1775 1776 // Add "encode class name" and its parameters 1777 NameAndList *InsEncode::add_encode(char *encoding) { 1778 assert( encoding != nullptr, "Must provide name for encoding"); 1779 1780 // add_parameter(NameList::_signal); 1781 NameAndList *encode = new NameAndList(encoding); 1782 _encoding.addName((char*)encode); 1783 1784 return encode; 1785 } 1786 1787 // Access the list of encodings 1788 void InsEncode::reset() { 1789 _encoding.reset(); 1790 // _parameter.reset(); 1791 } 1792 const char* InsEncode::encode_class_iter() { 1793 NameAndList *encode_class = (NameAndList*)_encoding.iter(); 1794 return ( encode_class != nullptr ? encode_class->name() : nullptr ); 1795 } 1796 // Obtain parameter name from zero based index 1797 const char *InsEncode::rep_var_name(InstructForm &inst, uint param_no) { 1798 NameAndList *params = (NameAndList*)_encoding.current(); 1799 assert( params != nullptr, "Internal Error"); 1800 const char *param = (*params)[param_no]; 1801 1802 // Remove '$' if parser placed it there. 1803 return ( param != nullptr && *param == '$') ? (param+1) : param; 1804 } 1805 1806 void InsEncode::dump() { 1807 output(stderr); 1808 } 1809 1810 // Write info to output files 1811 void InsEncode::output(FILE *fp) { 1812 NameAndList *encoding = nullptr; 1813 const char *parameter = nullptr; 1814 1815 fprintf(fp,"InsEncode: "); 1816 _encoding.reset(); 1817 1818 while ( (encoding = (NameAndList*)_encoding.iter()) != 0 ) { 1819 // Output the encoding being used 1820 fprintf(fp,"%s(", encoding->name() ); 1821 1822 // Output its parameter list, if any 1823 bool first_param = true; 1824 encoding->reset(); 1825 while ( (parameter = encoding->iter()) != 0 ) { 1826 // Output the ',' between parameters 1827 if ( ! first_param ) fprintf(fp,", "); 1828 first_param = false; 1829 // Output the parameter 1830 fprintf(fp,"%s", parameter); 1831 } // done with parameters 1832 fprintf(fp,") "); 1833 } // done with encodings 1834 1835 fprintf(fp,"\n"); 1836 } 1837 1838 //------------------------------Effect----------------------------------------- 1839 static int effect_lookup(const char *name) { 1840 if (!strcmp(name, "USE")) return Component::USE; 1841 if (!strcmp(name, "DEF")) return Component::DEF; 1842 if (!strcmp(name, "USE_DEF")) return Component::USE_DEF; 1843 if (!strcmp(name, "KILL")) return Component::KILL; 1844 if (!strcmp(name, "USE_KILL")) return Component::USE_KILL; 1845 if (!strcmp(name, "TEMP")) return Component::TEMP; 1846 if (!strcmp(name, "TEMP_DEF")) return Component::TEMP_DEF; 1847 if (!strcmp(name, "INVALID")) return Component::INVALID; 1848 if (!strcmp(name, "CALL")) return Component::CALL; 1849 assert(false,"Invalid effect name specified\n"); 1850 return Component::INVALID; 1851 } 1852 1853 const char *Component::getUsedefName() { 1854 switch (_usedef) { 1855 case Component::INVALID: return "INVALID"; break; 1856 case Component::USE: return "USE"; break; 1857 case Component::USE_DEF: return "USE_DEF"; break; 1858 case Component::USE_KILL: return "USE_KILL"; break; 1859 case Component::KILL: return "KILL"; break; 1860 case Component::TEMP: return "TEMP"; break; 1861 case Component::TEMP_DEF: return "TEMP_DEF"; break; 1862 case Component::DEF: return "DEF"; break; 1863 case Component::CALL: return "CALL"; break; 1864 default: assert(false, "unknown effect"); 1865 } 1866 return "Undefined Use/Def info"; 1867 } 1868 1869 Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) { 1870 _ftype = Form::EFF; 1871 } 1872 1873 Effect::~Effect() { 1874 } 1875 1876 // Dynamic type check 1877 Effect *Effect::is_effect() const { 1878 return (Effect*)this; 1879 } 1880 1881 1882 // True if this component is equal to the parameter. 1883 bool Effect::is(int use_def_kill_enum) const { 1884 return (_use_def == use_def_kill_enum ? true : false); 1885 } 1886 // True if this component is used/def'd/kill'd as the parameter suggests. 1887 bool Effect::isa(int use_def_kill_enum) const { 1888 return (_use_def & use_def_kill_enum) == use_def_kill_enum; 1889 } 1890 1891 void Effect::dump() { 1892 output(stderr); 1893 } 1894 1895 void Effect::output(FILE *fp) { // Write info to output files 1896 fprintf(fp,"Effect: %s\n", (_name?_name:"")); 1897 } 1898 1899 //---------------------------------Flag---------------------------------------- 1900 Flag::Flag(const char *name) : _name(name), _next(nullptr) { 1901 _ftype = Form::FLG; 1902 } 1903 1904 Flag::~Flag() { 1905 } 1906 1907 void Flag::append_flag(Flag *next_flag) { 1908 if( _next == nullptr ) { 1909 _next = next_flag; 1910 } else { 1911 _next->append_flag( next_flag ); 1912 } 1913 } 1914 1915 Flag* Flag::next() { 1916 return _next; 1917 } 1918 1919 void Flag::dump() { 1920 output(stderr); 1921 } 1922 1923 void Flag::output(FILE *fp) { // Write info to output files 1924 fprintf(fp,"Flag: %s\n", (_name?_name:"")); 1925 } 1926 1927 //------------------------------ExpandRule------------------------------------- 1928 ExpandRule::ExpandRule() : _expand_instrs(), 1929 _newopconst(cmpstr, hashstr, Form::arena) { 1930 _ftype = Form::EXP; 1931 } 1932 1933 ExpandRule::~ExpandRule() { // Destructor 1934 } 1935 1936 void ExpandRule::add_instruction(NameAndList *instruction_name_and_operand_list) { 1937 _expand_instrs.addName((char*)instruction_name_and_operand_list); 1938 } 1939 1940 void ExpandRule::reset_instructions() { 1941 _expand_instrs.reset(); 1942 } 1943 1944 NameAndList* ExpandRule::iter_instructions() { 1945 return (NameAndList*)_expand_instrs.iter(); 1946 } 1947 1948 1949 void ExpandRule::dump() { 1950 output(stderr); 1951 } 1952 1953 void ExpandRule::output(FILE *fp) { // Write info to output files 1954 NameAndList *expand_instr = nullptr; 1955 const char *opid = nullptr; 1956 1957 fprintf(fp,"\nExpand Rule:\n"); 1958 1959 // Iterate over the instructions 'node' expands into 1960 for(reset_instructions(); (expand_instr = iter_instructions()) != nullptr; ) { 1961 fprintf(fp,"%s(", expand_instr->name()); 1962 1963 // iterate over the operand list 1964 for( expand_instr->reset(); (opid = expand_instr->iter()) != nullptr; ) { 1965 fprintf(fp,"%s ", opid); 1966 } 1967 fprintf(fp,");\n"); 1968 } 1969 } 1970 1971 //------------------------------RewriteRule------------------------------------ 1972 RewriteRule::RewriteRule(char* params, char* block) 1973 : _tempParams(params), _tempBlock(block) { }; // Constructor 1974 RewriteRule::~RewriteRule() { // Destructor 1975 } 1976 1977 void RewriteRule::dump() { 1978 output(stderr); 1979 } 1980 1981 void RewriteRule::output(FILE *fp) { // Write info to output files 1982 fprintf(fp,"\nRewrite Rule:\n%s\n%s\n", 1983 (_tempParams?_tempParams:""), 1984 (_tempBlock?_tempBlock:"")); 1985 } 1986 1987 1988 //==============================MachNodes====================================== 1989 //------------------------------MachNodeForm----------------------------------- 1990 MachNodeForm::MachNodeForm(char *id) 1991 : _ident(id) { 1992 } 1993 1994 MachNodeForm::~MachNodeForm() { 1995 } 1996 1997 MachNodeForm *MachNodeForm::is_machnode() const { 1998 return (MachNodeForm*)this; 1999 } 2000 2001 //==============================Operand Classes================================ 2002 //------------------------------OpClassForm------------------------------------ 2003 OpClassForm::OpClassForm(const char* id) : _ident(id) { 2004 _ftype = Form::OPCLASS; 2005 } 2006 2007 OpClassForm::~OpClassForm() { 2008 } 2009 2010 bool OpClassForm::ideal_only() const { return 0; } 2011 2012 OpClassForm *OpClassForm::is_opclass() const { 2013 return (OpClassForm*)this; 2014 } 2015 2016 Form::InterfaceType OpClassForm::interface_type(FormDict &globals) const { 2017 if( _oplst.count() == 0 ) return Form::no_interface; 2018 2019 // Check that my operands have the same interface type 2020 Form::InterfaceType interface; 2021 bool first = true; 2022 NameList &op_list = (NameList &)_oplst; 2023 op_list.reset(); 2024 const char *op_name; 2025 while( (op_name = op_list.iter()) != nullptr ) { 2026 const Form *form = globals[op_name]; 2027 OperandForm *operand = form->is_operand(); 2028 assert( operand, "Entry in operand class that is not an operand"); 2029 if( first ) { 2030 first = false; 2031 interface = operand->interface_type(globals); 2032 } else { 2033 interface = (interface == operand->interface_type(globals) ? interface : Form::no_interface); 2034 } 2035 } 2036 return interface; 2037 } 2038 2039 bool OpClassForm::stack_slots_only(FormDict &globals) const { 2040 if( _oplst.count() == 0 ) return false; // how? 2041 2042 NameList &op_list = (NameList &)_oplst; 2043 op_list.reset(); 2044 const char *op_name; 2045 while( (op_name = op_list.iter()) != nullptr ) { 2046 const Form *form = globals[op_name]; 2047 OperandForm *operand = form->is_operand(); 2048 assert( operand, "Entry in operand class that is not an operand"); 2049 if( !operand->stack_slots_only(globals) ) return false; 2050 } 2051 return true; 2052 } 2053 2054 2055 void OpClassForm::dump() { 2056 output(stderr); 2057 } 2058 2059 void OpClassForm::output(FILE *fp) { 2060 const char *name; 2061 fprintf(fp,"\nOperand Class: %s\n", (_ident?_ident:"")); 2062 fprintf(fp,"\nCount = %d\n", _oplst.count()); 2063 for(_oplst.reset(); (name = _oplst.iter()) != nullptr;) { 2064 fprintf(fp,"%s, ",name); 2065 } 2066 fprintf(fp,"\n"); 2067 } 2068 2069 2070 //==============================Operands======================================= 2071 //------------------------------OperandForm------------------------------------ 2072 OperandForm::OperandForm(const char* id) 2073 : OpClassForm(id), _ideal_only(false), 2074 _localNames(cmpstr, hashstr, Form::arena) { 2075 _ftype = Form::OPER; 2076 2077 _matrule = nullptr; 2078 _interface = nullptr; 2079 _attribs = nullptr; 2080 _predicate = nullptr; 2081 _constraint= nullptr; 2082 _construct = nullptr; 2083 _format = nullptr; 2084 } 2085 OperandForm::OperandForm(const char* id, bool ideal_only) 2086 : OpClassForm(id), _ideal_only(ideal_only), 2087 _localNames(cmpstr, hashstr, Form::arena) { 2088 _ftype = Form::OPER; 2089 2090 _matrule = nullptr; 2091 _interface = nullptr; 2092 _attribs = nullptr; 2093 _predicate = nullptr; 2094 _constraint= nullptr; 2095 _construct = nullptr; 2096 _format = nullptr; 2097 } 2098 OperandForm::~OperandForm() { 2099 } 2100 2101 2102 OperandForm *OperandForm::is_operand() const { 2103 return (OperandForm*)this; 2104 } 2105 2106 bool OperandForm::ideal_only() const { 2107 return _ideal_only; 2108 } 2109 2110 Form::InterfaceType OperandForm::interface_type(FormDict &globals) const { 2111 if( _interface == nullptr ) return Form::no_interface; 2112 2113 return _interface->interface_type(globals); 2114 } 2115 2116 2117 bool OperandForm::stack_slots_only(FormDict &globals) const { 2118 if( _constraint == nullptr ) return false; 2119 return _constraint->stack_slots_only(); 2120 } 2121 2122 2123 // Access op_cost attribute or return null. 2124 const char* OperandForm::cost() { 2125 for (Attribute* cur = _attribs; cur != nullptr; cur = (Attribute*)cur->_next) { 2126 if( strcmp(cur->_ident,AttributeForm::_op_cost) == 0 ) { 2127 return cur->_val; 2128 } 2129 } 2130 return nullptr; 2131 } 2132 2133 // Return the number of leaves below this complex operand 2134 uint OperandForm::num_leaves() const { 2135 if ( ! _matrule) return 0; 2136 2137 int num_leaves = _matrule->_numleaves; 2138 return num_leaves; 2139 } 2140 2141 // Return the number of constants contained within this complex operand 2142 uint OperandForm::num_consts(FormDict &globals) const { 2143 if ( ! _matrule) return 0; 2144 2145 // This is a recursive invocation on all operands in the matchrule 2146 return _matrule->num_consts(globals); 2147 } 2148 2149 // Return the number of constants in match rule with specified type 2150 uint OperandForm::num_consts(FormDict &globals, Form::DataType type) const { 2151 if ( ! _matrule) return 0; 2152 2153 // This is a recursive invocation on all operands in the matchrule 2154 return _matrule->num_consts(globals, type); 2155 } 2156 2157 // Return the number of pointer constants contained within this complex operand 2158 uint OperandForm::num_const_ptrs(FormDict &globals) const { 2159 if ( ! _matrule) return 0; 2160 2161 // This is a recursive invocation on all operands in the matchrule 2162 return _matrule->num_const_ptrs(globals); 2163 } 2164 2165 uint OperandForm::num_edges(FormDict &globals) const { 2166 uint edges = 0; 2167 uint leaves = num_leaves(); 2168 uint consts = num_consts(globals); 2169 2170 // If we are matching a constant directly, there are no leaves. 2171 edges = ( leaves > consts ) ? leaves - consts : 0; 2172 2173 // !!!!! 2174 // Special case operands that do not have a corresponding ideal node. 2175 if( (edges == 0) && (consts == 0) ) { 2176 if( constrained_reg_class() != nullptr ) { 2177 edges = 1; 2178 } else { 2179 if( _matrule 2180 && (_matrule->_lChild == nullptr) && (_matrule->_rChild == nullptr) ) { 2181 const Form *form = globals[_matrule->_opType]; 2182 OperandForm *oper = form ? form->is_operand() : nullptr; 2183 if( oper ) { 2184 return oper->num_edges(globals); 2185 } 2186 } 2187 } 2188 } 2189 2190 return edges; 2191 } 2192 2193 2194 // Check if this operand is usable for cisc-spilling 2195 bool OperandForm::is_cisc_reg(FormDict &globals) const { 2196 const char *ideal = ideal_type(globals); 2197 bool is_cisc_reg = (ideal && (ideal_to_Reg_type(ideal) != none)); 2198 return is_cisc_reg; 2199 } 2200 2201 bool OpClassForm::is_cisc_mem(FormDict &globals) const { 2202 Form::InterfaceType my_interface = interface_type(globals); 2203 return (my_interface == memory_interface); 2204 } 2205 2206 2207 // node matches ideal 'Bool' 2208 bool OperandForm::is_ideal_bool() const { 2209 if( _matrule == nullptr ) return false; 2210 2211 return _matrule->is_ideal_bool(); 2212 } 2213 2214 // Require user's name for an sRegX to be stackSlotX 2215 Form::DataType OperandForm::is_user_name_for_sReg() const { 2216 DataType data_type = none; 2217 if( _ident != nullptr ) { 2218 if( strcmp(_ident,"stackSlotI") == 0 ) data_type = Form::idealI; 2219 else if( strcmp(_ident,"stackSlotP") == 0 ) data_type = Form::idealP; 2220 else if( strcmp(_ident,"stackSlotD") == 0 ) data_type = Form::idealD; 2221 else if( strcmp(_ident,"stackSlotF") == 0 ) data_type = Form::idealF; 2222 else if( strcmp(_ident,"stackSlotL") == 0 ) data_type = Form::idealL; 2223 } 2224 assert((data_type == none) || (_matrule == nullptr), "No match-rule for stackSlotX"); 2225 2226 return data_type; 2227 } 2228 2229 2230 // Return ideal type, if there is a single ideal type for this operand 2231 const char *OperandForm::ideal_type(FormDict &globals, RegisterForm *registers) const { 2232 const char *type = nullptr; 2233 if (ideal_only()) type = _ident; 2234 else if( _matrule == nullptr ) { 2235 // Check for condition code register 2236 const char *rc_name = constrained_reg_class(); 2237 // !!!!! 2238 if (rc_name == nullptr) return nullptr; 2239 // !!!!! !!!!! 2240 // Check constraints on result's register class 2241 if( registers ) { 2242 RegClass *reg_class = registers->getRegClass(rc_name); 2243 assert( reg_class != nullptr, "Register class is not defined"); 2244 2245 // Check for ideal type of entries in register class, all are the same type 2246 reg_class->reset(); 2247 RegDef *reg_def = reg_class->RegDef_iter(); 2248 assert( reg_def != nullptr, "No entries in register class"); 2249 assert( reg_def->_idealtype != nullptr, "Did not define ideal type for register"); 2250 // Return substring that names the register's ideal type 2251 type = reg_def->_idealtype + 3; 2252 assert( *(reg_def->_idealtype + 0) == 'O', "Expect Op_ prefix"); 2253 assert( *(reg_def->_idealtype + 1) == 'p', "Expect Op_ prefix"); 2254 assert( *(reg_def->_idealtype + 2) == '_', "Expect Op_ prefix"); 2255 } 2256 } 2257 else if( _matrule->_lChild == nullptr && _matrule->_rChild == nullptr ) { 2258 // This operand matches a single type, at the top level. 2259 // Check for ideal type 2260 type = _matrule->_opType; 2261 if( strcmp(type,"Bool") == 0 ) 2262 return "Bool"; 2263 // transitive lookup 2264 const Form *frm = globals[type]; 2265 OperandForm *op = frm->is_operand(); 2266 type = op->ideal_type(globals, registers); 2267 } 2268 return type; 2269 } 2270 2271 2272 // If there is a single ideal type for this interface field, return it. 2273 const char *OperandForm::interface_ideal_type(FormDict &globals, 2274 const char *field) const { 2275 const char *ideal_type = nullptr; 2276 const char *value = nullptr; 2277 2278 // Check if "field" is valid for this operand's interface 2279 if ( ! is_interface_field(field, value) ) return ideal_type; 2280 2281 // !!!!! !!!!! !!!!! 2282 // If a valid field has a constant value, identify "ConI" or "ConP" or ... 2283 2284 // Else, lookup type of field's replacement variable 2285 2286 return ideal_type; 2287 } 2288 2289 2290 RegClass* OperandForm::get_RegClass() const { 2291 if (_interface && !_interface->is_RegInterface()) return nullptr; 2292 return globalAD->get_registers()->getRegClass(constrained_reg_class()); 2293 } 2294 2295 2296 bool OperandForm::is_bound_register() const { 2297 RegClass* reg_class = get_RegClass(); 2298 if (reg_class == nullptr) { 2299 return false; 2300 } 2301 2302 const char* name = ideal_type(globalAD->globalNames()); 2303 if (name == nullptr) { 2304 return false; 2305 } 2306 2307 uint size = 0; 2308 if (strcmp(name, "RegFlags") == 0) size = 1; 2309 if (strcmp(name, "RegI") == 0) size = 1; 2310 if (strcmp(name, "RegF") == 0) size = 1; 2311 if (strcmp(name, "RegD") == 0) size = 2; 2312 if (strcmp(name, "RegL") == 0) size = 2; 2313 if (strcmp(name, "RegN") == 0) size = 1; 2314 if (strcmp(name, "RegVectMask") == 0) size = globalAD->get_preproc_def("AARCH64") ? 1 : 2; 2315 if (strcmp(name, "VecX") == 0) size = 4; 2316 if (strcmp(name, "VecY") == 0) size = 8; 2317 if (strcmp(name, "VecZ") == 0) size = 16; 2318 if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1; 2319 if (size == 0) { 2320 return false; 2321 } 2322 return size == reg_class->size(); 2323 } 2324 2325 2326 // Check if this is a valid field for this operand, 2327 // Return 'true' if valid, and set the value to the string the user provided. 2328 bool OperandForm::is_interface_field(const char *field, 2329 const char * &value) const { 2330 return false; 2331 } 2332 2333 2334 // Return register class name if a constraint specifies the register class. 2335 const char *OperandForm::constrained_reg_class() const { 2336 const char *reg_class = nullptr; 2337 if ( _constraint ) { 2338 // !!!!! 2339 Constraint *constraint = _constraint; 2340 if ( strcmp(_constraint->_func,"ALLOC_IN_RC") == 0 ) { 2341 reg_class = _constraint->_arg; 2342 } 2343 } 2344 2345 return reg_class; 2346 } 2347 2348 2349 // Return the register class associated with 'leaf'. 2350 const char *OperandForm::in_reg_class(uint leaf, FormDict &globals) { 2351 const char *reg_class = nullptr; // "RegMask::Empty"; 2352 2353 if((_matrule == nullptr) || (_matrule->is_chain_rule(globals))) { 2354 reg_class = constrained_reg_class(); 2355 return reg_class; 2356 } 2357 const char *result = nullptr; 2358 const char *name = nullptr; 2359 const char *type = nullptr; 2360 // iterate through all base operands 2361 // until we reach the register that corresponds to "leaf" 2362 // This function is not looking for an ideal type. It needs the first 2363 // level user type associated with the leaf. 2364 for(uint idx = 0;_matrule->base_operand(idx,globals,result,name,type);++idx) { 2365 const Form *form = (_localNames[name] ? _localNames[name] : globals[result]); 2366 OperandForm *oper = form ? form->is_operand() : nullptr; 2367 if( oper ) { 2368 reg_class = oper->constrained_reg_class(); 2369 if( reg_class ) { 2370 reg_class = reg_class; 2371 } else { 2372 // ShouldNotReachHere(); 2373 } 2374 } else { 2375 // ShouldNotReachHere(); 2376 } 2377 2378 // Increment our target leaf position if current leaf is not a candidate. 2379 if( reg_class == nullptr) ++leaf; 2380 // Exit the loop with the value of reg_class when at the correct index 2381 if( idx == leaf ) break; 2382 // May iterate through all base operands if reg_class for 'leaf' is null 2383 } 2384 return reg_class; 2385 } 2386 2387 2388 // Recursive call to construct list of top-level operands. 2389 // Implementation does not modify state of internal structures 2390 void OperandForm::build_components() { 2391 if (_matrule) _matrule->append_components(_localNames, _components); 2392 2393 // Add parameters that "do not appear in match rule". 2394 const char *name; 2395 for (_parameters.reset(); (name = _parameters.iter()) != nullptr;) { 2396 OpClassForm *opForm = _localNames[name]->is_opclass(); 2397 assert(opForm != nullptr, "sanity"); 2398 2399 if ( _components.operand_position(name) == -1 ) { 2400 _components.insert(name, opForm->_ident, Component::INVALID, false); 2401 } 2402 } 2403 2404 return; 2405 } 2406 2407 int OperandForm::operand_position(const char *name, int usedef) { 2408 return _components.operand_position(name, usedef, this); 2409 } 2410 2411 2412 // Return zero-based position in component list, only counting constants; 2413 // Return -1 if not in list. 2414 int OperandForm::constant_position(FormDict &globals, const Component *last) { 2415 // Iterate through components and count constants preceding 'constant' 2416 int position = 0; 2417 Component *comp; 2418 _components.reset(); 2419 while( (comp = _components.iter()) != nullptr && (comp != last) ) { 2420 // Special case for operands that take a single user-defined operand 2421 // Skip the initial definition in the component list. 2422 if( strcmp(comp->_name,this->_ident) == 0 ) continue; 2423 2424 const char *type = comp->_type; 2425 // Lookup operand form for replacement variable's type 2426 const Form *form = globals[type]; 2427 assert( form != nullptr, "Component's type not found"); 2428 OperandForm *oper = form ? form->is_operand() : nullptr; 2429 if( oper ) { 2430 if( oper->_matrule->is_base_constant(globals) != Form::none ) { 2431 ++position; 2432 } 2433 } 2434 } 2435 2436 // Check for being passed a component that was not in the list 2437 if( comp != last ) position = -1; 2438 2439 return position; 2440 } 2441 // Provide position of constant by "name" 2442 int OperandForm::constant_position(FormDict &globals, const char *name) { 2443 const Component *comp = _components.search(name); 2444 int idx = constant_position( globals, comp ); 2445 2446 return idx; 2447 } 2448 2449 2450 // Return zero-based position in component list, only counting constants; 2451 // Return -1 if not in list. 2452 int OperandForm::register_position(FormDict &globals, const char *reg_name) { 2453 // Iterate through components and count registers preceding 'last' 2454 uint position = 0; 2455 Component *comp; 2456 _components.reset(); 2457 while( (comp = _components.iter()) != nullptr 2458 && (strcmp(comp->_name,reg_name) != 0) ) { 2459 // Special case for operands that take a single user-defined operand 2460 // Skip the initial definition in the component list. 2461 if( strcmp(comp->_name,this->_ident) == 0 ) continue; 2462 2463 const char *type = comp->_type; 2464 // Lookup operand form for component's type 2465 const Form *form = globals[type]; 2466 assert( form != nullptr, "Component's type not found"); 2467 OperandForm *oper = form ? form->is_operand() : nullptr; 2468 if( oper ) { 2469 if( oper->_matrule->is_base_register(globals) ) { 2470 ++position; 2471 } 2472 } 2473 } 2474 2475 return position; 2476 } 2477 2478 2479 const char *OperandForm::reduce_result() const { 2480 return _ident; 2481 } 2482 // Return the name of the operand on the right hand side of the binary match 2483 // Return null if there is no right hand side 2484 const char *OperandForm::reduce_right(FormDict &globals) const { 2485 return ( _matrule ? _matrule->reduce_right(globals) : nullptr ); 2486 } 2487 2488 // Similar for left 2489 const char *OperandForm::reduce_left(FormDict &globals) const { 2490 return ( _matrule ? _matrule->reduce_left(globals) : nullptr ); 2491 } 2492 2493 2494 // --------------------------- FILE *output_routines 2495 // 2496 // Output code for disp_is_oop, if true. 2497 void OperandForm::disp_is_oop(FILE *fp, FormDict &globals) { 2498 // Check it is a memory interface with a non-user-constant disp field 2499 if ( this->_interface == nullptr ) return; 2500 MemInterface *mem_interface = this->_interface->is_MemInterface(); 2501 if ( mem_interface == nullptr ) return; 2502 const char *disp = mem_interface->_disp; 2503 if ( *disp != '$' ) return; 2504 2505 // Lookup replacement variable in operand's component list 2506 const char *rep_var = disp + 1; 2507 const Component *comp = this->_components.search(rep_var); 2508 assert( comp != nullptr, "Replacement variable not found in components"); 2509 // Lookup operand form for replacement variable's type 2510 const char *type = comp->_type; 2511 Form *form = (Form*)globals[type]; 2512 assert( form != nullptr, "Replacement variable's type not found"); 2513 OperandForm *op = form->is_operand(); 2514 assert( op, "Memory Interface 'disp' can only emit an operand form"); 2515 // Check if this is a ConP, which may require relocation 2516 if ( op->is_base_constant(globals) == Form::idealP ) { 2517 // Find the constant's index: _c0, _c1, _c2, ... , _cN 2518 uint idx = op->constant_position( globals, rep_var); 2519 fprintf(fp," virtual relocInfo::relocType disp_reloc() const {"); 2520 fprintf(fp, " return _c%d->reloc();", idx); 2521 fprintf(fp, " }\n"); 2522 } 2523 } 2524 2525 // Generate code for internal and external format methods 2526 // 2527 // internal access to reg# node->_idx 2528 // access to subsumed constant _c0, _c1, 2529 void OperandForm::int_format(FILE *fp, FormDict &globals, uint index) { 2530 Form::DataType dtype; 2531 if (_matrule && (_matrule->is_base_register(globals) || 2532 strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) { 2533 // !!!!! !!!!! 2534 fprintf(fp," { char reg_str[128];\n"); 2535 fprintf(fp," ra->dump_register(node,reg_str, sizeof(reg_str));\n"); 2536 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); 2537 fprintf(fp," }\n"); 2538 } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) { 2539 format_constant( fp, index, dtype ); 2540 } else if (ideal_to_sReg_type(_ident) != Form::none) { 2541 // Special format for Stack Slot Register 2542 fprintf(fp," { char reg_str[128];\n"); 2543 fprintf(fp," ra->dump_register(node,reg_str, sizeof(reg_str));\n"); 2544 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); 2545 fprintf(fp," }\n"); 2546 } else { 2547 fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident); 2548 fflush(fp); 2549 fprintf(stderr,"No format defined for %s\n", _ident); 2550 dump(); 2551 assert( false,"Internal error:\n output_internal_operand() attempting to output other than a Register or Constant"); 2552 } 2553 } 2554 2555 // Similar to "int_format" but for cases where data is external to operand 2556 // external access to reg# node->in(idx)->_idx, 2557 void OperandForm::ext_format(FILE *fp, FormDict &globals, uint index) { 2558 Form::DataType dtype; 2559 if (_matrule && (_matrule->is_base_register(globals) || 2560 strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) { 2561 fprintf(fp," { char reg_str[128];\n"); 2562 fprintf(fp," ra->dump_register(node->in(idx"); 2563 if ( index != 0 ) fprintf(fp, "+%d",index); 2564 fprintf(fp, "),reg_str,sizeof(reg_str));\n"); 2565 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); 2566 fprintf(fp," }\n"); 2567 } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) { 2568 format_constant( fp, index, dtype ); 2569 } else if (ideal_to_sReg_type(_ident) != Form::none) { 2570 // Special format for Stack Slot Register 2571 fprintf(fp," { char reg_str[128];\n"); 2572 fprintf(fp," ra->dump_register(node->in(idx"); 2573 if ( index != 0 ) fprintf(fp, "+%d",index); 2574 fprintf(fp, "),reg_str,sizeof(reg_str));\n"); 2575 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); 2576 fprintf(fp," }\n"); 2577 } else { 2578 fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident); 2579 assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant"); 2580 } 2581 } 2582 2583 void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) { 2584 switch(const_type) { 2585 case Form::idealI: fprintf(fp," st->print(\"#%%d\", _c%d);\n", const_index); break; 2586 case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; 2587 case Form::idealNKlass: 2588 case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; 2589 case Form::idealL: fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break; 2590 case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; 2591 case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; 2592 default: 2593 assert( false, "ShouldNotReachHere()"); 2594 } 2595 } 2596 2597 // Return the operand form corresponding to the given index, else null. 2598 OperandForm *OperandForm::constant_operand(FormDict &globals, 2599 uint index) { 2600 // !!!!! 2601 // Check behavior on complex operands 2602 uint n_consts = num_consts(globals); 2603 if( n_consts > 0 ) { 2604 uint i = 0; 2605 const char *type; 2606 Component *comp; 2607 _components.reset(); 2608 if ((comp = _components.iter()) == nullptr) { 2609 assert(n_consts == 1, "Bad component list detected.\n"); 2610 // Current operand is THE operand 2611 if ( index == 0 ) { 2612 return this; 2613 } 2614 } // end if null 2615 else { 2616 // Skip the first component, it can not be a DEF of a constant 2617 do { 2618 type = comp->base_type(globals); 2619 // Check that "type" is a 'ConI', 'ConP', ... 2620 if ( ideal_to_const_type(type) != Form::none ) { 2621 // When at correct component, get corresponding Operand 2622 if ( index == 0 ) { 2623 return globals[comp->_type]->is_operand(); 2624 } 2625 // Decrement number of constants to go 2626 --index; 2627 } 2628 } while((comp = _components.iter()) != nullptr); 2629 } 2630 } 2631 2632 // Did not find a constant for this index. 2633 return nullptr; 2634 } 2635 2636 // If this operand has a single ideal type, return its type 2637 Form::DataType OperandForm::simple_type(FormDict &globals) const { 2638 const char *type_name = ideal_type(globals); 2639 Form::DataType type = type_name ? ideal_to_const_type( type_name ) 2640 : Form::none; 2641 return type; 2642 } 2643 2644 Form::DataType OperandForm::is_base_constant(FormDict &globals) const { 2645 if ( _matrule == nullptr ) return Form::none; 2646 2647 return _matrule->is_base_constant(globals); 2648 } 2649 2650 // "true" if this operand is a simple type that is swallowed 2651 bool OperandForm::swallowed(FormDict &globals) const { 2652 Form::DataType type = simple_type(globals); 2653 if( type != Form::none ) { 2654 return true; 2655 } 2656 2657 return false; 2658 } 2659 2660 // Output code to access the value of the index'th constant 2661 void OperandForm::access_constant(FILE *fp, FormDict &globals, 2662 uint const_index) { 2663 OperandForm *oper = constant_operand(globals, const_index); 2664 assert( oper, "Index exceeds number of constants in operand"); 2665 Form::DataType dtype = oper->is_base_constant(globals); 2666 2667 switch(dtype) { 2668 case idealI: fprintf(fp,"_c%d", const_index); break; 2669 case idealP: fprintf(fp,"_c%d->get_con()",const_index); break; 2670 case idealL: fprintf(fp,"_c%d", const_index); break; 2671 case idealF: fprintf(fp,"_c%d", const_index); break; 2672 case idealD: fprintf(fp,"_c%d", const_index); break; 2673 default: 2674 assert( false, "ShouldNotReachHere()"); 2675 } 2676 } 2677 2678 2679 void OperandForm::dump() { 2680 output(stderr); 2681 } 2682 2683 void OperandForm::output(FILE *fp) { 2684 fprintf(fp,"\nOperand: %s\n", (_ident?_ident:"")); 2685 if (_matrule) _matrule->dump(); 2686 if (_interface) _interface->dump(); 2687 if (_attribs) _attribs->dump(); 2688 if (_predicate) _predicate->dump(); 2689 if (_constraint) _constraint->dump(); 2690 if (_construct) _construct->dump(); 2691 if (_format) _format->dump(); 2692 } 2693 2694 //------------------------------Constraint------------------------------------- 2695 Constraint::Constraint(const char *func, const char *arg) 2696 : _func(func), _arg(arg) { 2697 } 2698 Constraint::~Constraint() { /* not owner of char* */ 2699 } 2700 2701 bool Constraint::stack_slots_only() const { 2702 return strcmp(_func, "ALLOC_IN_RC") == 0 2703 && strcmp(_arg, "stack_slots") == 0; 2704 } 2705 2706 void Constraint::dump() { 2707 output(stderr); 2708 } 2709 2710 void Constraint::output(FILE *fp) { // Write info to output files 2711 assert((_func != nullptr && _arg != nullptr),"missing constraint function or arg"); 2712 fprintf(fp,"Constraint: %s ( %s )\n", _func, _arg); 2713 } 2714 2715 //------------------------------Predicate-------------------------------------- 2716 Predicate::Predicate(char *pr) 2717 : _pred(pr) { 2718 } 2719 Predicate::~Predicate() { 2720 } 2721 2722 void Predicate::dump() { 2723 output(stderr); 2724 } 2725 2726 void Predicate::output(FILE *fp) { 2727 fprintf(fp,"Predicate"); // Write to output files 2728 } 2729 //------------------------------Interface-------------------------------------- 2730 Interface::Interface(const char *name) : _name(name) { 2731 } 2732 Interface::~Interface() { 2733 } 2734 2735 Form::InterfaceType Interface::interface_type(FormDict &globals) const { 2736 Interface *thsi = (Interface*)this; 2737 if ( thsi->is_RegInterface() ) return Form::register_interface; 2738 if ( thsi->is_MemInterface() ) return Form::memory_interface; 2739 if ( thsi->is_ConstInterface() ) return Form::constant_interface; 2740 if ( thsi->is_CondInterface() ) return Form::conditional_interface; 2741 2742 return Form::no_interface; 2743 } 2744 2745 RegInterface *Interface::is_RegInterface() { 2746 if ( strcmp(_name,"REG_INTER") != 0 ) 2747 return nullptr; 2748 return (RegInterface*)this; 2749 } 2750 MemInterface *Interface::is_MemInterface() { 2751 if ( strcmp(_name,"MEMORY_INTER") != 0 ) return nullptr; 2752 return (MemInterface*)this; 2753 } 2754 ConstInterface *Interface::is_ConstInterface() { 2755 if ( strcmp(_name,"CONST_INTER") != 0 ) return nullptr; 2756 return (ConstInterface*)this; 2757 } 2758 CondInterface *Interface::is_CondInterface() { 2759 if ( strcmp(_name,"COND_INTER") != 0 ) return nullptr; 2760 return (CondInterface*)this; 2761 } 2762 2763 2764 void Interface::dump() { 2765 output(stderr); 2766 } 2767 2768 // Write info to output files 2769 void Interface::output(FILE *fp) { 2770 fprintf(fp,"Interface: %s\n", (_name ? _name : "") ); 2771 } 2772 2773 //------------------------------RegInterface----------------------------------- 2774 RegInterface::RegInterface() : Interface("REG_INTER") { 2775 } 2776 RegInterface::~RegInterface() { 2777 } 2778 2779 void RegInterface::dump() { 2780 output(stderr); 2781 } 2782 2783 // Write info to output files 2784 void RegInterface::output(FILE *fp) { 2785 Interface::output(fp); 2786 } 2787 2788 //------------------------------ConstInterface--------------------------------- 2789 ConstInterface::ConstInterface() : Interface("CONST_INTER") { 2790 } 2791 ConstInterface::~ConstInterface() { 2792 } 2793 2794 void ConstInterface::dump() { 2795 output(stderr); 2796 } 2797 2798 // Write info to output files 2799 void ConstInterface::output(FILE *fp) { 2800 Interface::output(fp); 2801 } 2802 2803 //------------------------------MemInterface----------------------------------- 2804 MemInterface::MemInterface(char *base, char *index, char *scale, char *disp) 2805 : Interface("MEMORY_INTER"), _base(base), _index(index), _scale(scale), _disp(disp) { 2806 } 2807 MemInterface::~MemInterface() { 2808 // not owner of any character arrays 2809 } 2810 2811 void MemInterface::dump() { 2812 output(stderr); 2813 } 2814 2815 // Write info to output files 2816 void MemInterface::output(FILE *fp) { 2817 Interface::output(fp); 2818 if ( _base != nullptr ) fprintf(fp," base == %s\n", _base); 2819 if ( _index != nullptr ) fprintf(fp," index == %s\n", _index); 2820 if ( _scale != nullptr ) fprintf(fp," scale == %s\n", _scale); 2821 if ( _disp != nullptr ) fprintf(fp," disp == %s\n", _disp); 2822 // fprintf(fp,"\n"); 2823 } 2824 2825 //------------------------------CondInterface---------------------------------- 2826 CondInterface::CondInterface(const char* equal, const char* equal_format, 2827 const char* not_equal, const char* not_equal_format, 2828 const char* less, const char* less_format, 2829 const char* greater_equal, const char* greater_equal_format, 2830 const char* less_equal, const char* less_equal_format, 2831 const char* greater, const char* greater_format, 2832 const char* overflow, const char* overflow_format, 2833 const char* no_overflow, const char* no_overflow_format) 2834 : Interface("COND_INTER"), 2835 _equal(equal), _equal_format(equal_format), 2836 _not_equal(not_equal), _not_equal_format(not_equal_format), 2837 _less(less), _less_format(less_format), 2838 _greater_equal(greater_equal), _greater_equal_format(greater_equal_format), 2839 _less_equal(less_equal), _less_equal_format(less_equal_format), 2840 _greater(greater), _greater_format(greater_format), 2841 _overflow(overflow), _overflow_format(overflow_format), 2842 _no_overflow(no_overflow), _no_overflow_format(no_overflow_format) { 2843 } 2844 CondInterface::~CondInterface() { 2845 // not owner of any character arrays 2846 } 2847 2848 void CondInterface::dump() { 2849 output(stderr); 2850 } 2851 2852 // Write info to output files 2853 void CondInterface::output(FILE *fp) { 2854 Interface::output(fp); 2855 if ( _equal != nullptr ) fprintf(fp," equal == %s\n", _equal); 2856 if ( _not_equal != nullptr ) fprintf(fp," not_equal == %s\n", _not_equal); 2857 if ( _less != nullptr ) fprintf(fp," less == %s\n", _less); 2858 if ( _greater_equal != nullptr ) fprintf(fp," greater_equal == %s\n", _greater_equal); 2859 if ( _less_equal != nullptr ) fprintf(fp," less_equal == %s\n", _less_equal); 2860 if ( _greater != nullptr ) fprintf(fp," greater == %s\n", _greater); 2861 if ( _overflow != nullptr ) fprintf(fp," overflow == %s\n", _overflow); 2862 if ( _no_overflow != nullptr ) fprintf(fp," no_overflow == %s\n", _no_overflow); 2863 // fprintf(fp,"\n"); 2864 } 2865 2866 //------------------------------ConstructRule---------------------------------- 2867 ConstructRule::ConstructRule(char *cnstr) 2868 : _construct(cnstr) { 2869 } 2870 ConstructRule::~ConstructRule() { 2871 } 2872 2873 void ConstructRule::dump() { 2874 output(stderr); 2875 } 2876 2877 void ConstructRule::output(FILE *fp) { 2878 fprintf(fp,"\nConstruct Rule\n"); // Write to output files 2879 } 2880 2881 2882 //==============================Shared Forms=================================== 2883 //------------------------------AttributeForm---------------------------------- 2884 int AttributeForm::_insId = 0; // start counter at 0 2885 int AttributeForm::_opId = 0; // start counter at 0 2886 const char* AttributeForm::_ins_cost = "ins_cost"; // required name 2887 const char* AttributeForm::_op_cost = "op_cost"; // required name 2888 2889 AttributeForm::AttributeForm(char *attr, int type, char *attrdef) 2890 : Form(Form::ATTR), _attrname(attr), _atype(type), _attrdef(attrdef) { 2891 if (type==OP_ATTR) { 2892 id = ++_opId; 2893 } 2894 else if (type==INS_ATTR) { 2895 id = ++_insId; 2896 } 2897 else assert( false,""); 2898 } 2899 AttributeForm::~AttributeForm() { 2900 } 2901 2902 // Dynamic type check 2903 AttributeForm *AttributeForm::is_attribute() const { 2904 return (AttributeForm*)this; 2905 } 2906 2907 2908 // inlined // int AttributeForm::type() { return id;} 2909 2910 void AttributeForm::dump() { 2911 output(stderr); 2912 } 2913 2914 void AttributeForm::output(FILE *fp) { 2915 if( _attrname && _attrdef ) { 2916 fprintf(fp,"\n// AttributeForm \nstatic const int %s = %s;\n", 2917 _attrname, _attrdef); 2918 } 2919 else { 2920 fprintf(fp,"\n// AttributeForm missing name %s or definition %s\n", 2921 (_attrname?_attrname:""), (_attrdef?_attrdef:"") ); 2922 } 2923 } 2924 2925 //------------------------------Component-------------------------------------- 2926 Component::Component(const char *name, const char *type, int usedef) 2927 : _name(name), _type(type), _usedef(usedef) { 2928 _ftype = Form::COMP; 2929 } 2930 Component::~Component() { 2931 } 2932 2933 // True if this component is equal to the parameter. 2934 bool Component::is(int use_def_kill_enum) const { 2935 return (_usedef == use_def_kill_enum ? true : false); 2936 } 2937 // True if this component is used/def'd/kill'd as the parameter suggests. 2938 bool Component::isa(int use_def_kill_enum) const { 2939 return (_usedef & use_def_kill_enum) == use_def_kill_enum; 2940 } 2941 2942 // Extend this component with additional use/def/kill behavior 2943 int Component::promote_use_def_info(int new_use_def) { 2944 _usedef |= new_use_def; 2945 2946 return _usedef; 2947 } 2948 2949 // Check the base type of this component, if it has one 2950 const char *Component::base_type(FormDict &globals) { 2951 const Form *frm = globals[_type]; 2952 if (frm == nullptr) return nullptr; 2953 OperandForm *op = frm->is_operand(); 2954 if (op == nullptr) return nullptr; 2955 if (op->ideal_only()) return op->_ident; 2956 return (char *)op->ideal_type(globals); 2957 } 2958 2959 void Component::dump() { 2960 output(stderr); 2961 } 2962 2963 void Component::output(FILE *fp) { 2964 fprintf(fp,"Component:"); // Write to output files 2965 fprintf(fp, " name = %s", _name); 2966 fprintf(fp, ", type = %s", _type); 2967 assert(_usedef != 0, "unknown effect"); 2968 fprintf(fp, ", use/def = %s\n", getUsedefName()); 2969 } 2970 2971 2972 //------------------------------ComponentList--------------------------------- 2973 ComponentList::ComponentList() : NameList(), _matchcnt(0) { 2974 } 2975 ComponentList::~ComponentList() { 2976 // // This list may not own its elements if copied via assignment 2977 // Component *component; 2978 // for (reset(); (component = iter()) != nullptr;) { 2979 // delete component; 2980 // } 2981 } 2982 2983 void ComponentList::insert(Component *component, bool mflag) { 2984 NameList::addName((char *)component); 2985 if(mflag) _matchcnt++; 2986 } 2987 void ComponentList::insert(const char *name, const char *opType, int usedef, 2988 bool mflag) { 2989 Component * component = new Component(name, opType, usedef); 2990 insert(component, mflag); 2991 } 2992 Component *ComponentList::current() { return (Component*)NameList::current(); } 2993 Component *ComponentList::iter() { return (Component*)NameList::iter(); } 2994 Component *ComponentList::match_iter() { 2995 if(_iter < _matchcnt) return (Component*)NameList::iter(); 2996 return nullptr; 2997 } 2998 Component *ComponentList::post_match_iter() { 2999 Component *comp = iter(); 3000 // At end of list? 3001 if ( comp == nullptr ) { 3002 return comp; 3003 } 3004 // In post-match components? 3005 if (_iter > match_count()-1) { 3006 return comp; 3007 } 3008 3009 return post_match_iter(); 3010 } 3011 3012 void ComponentList::reset() { NameList::reset(); } 3013 int ComponentList::count() { return NameList::count(); } 3014 3015 Component *ComponentList::operator[](int position) { 3016 // Shortcut complete iteration if there are not enough entries 3017 if (position >= count()) return nullptr; 3018 3019 int index = 0; 3020 Component *component = nullptr; 3021 for (reset(); (component = iter()) != nullptr;) { 3022 if (index == position) { 3023 return component; 3024 } 3025 ++index; 3026 } 3027 3028 return nullptr; 3029 } 3030 3031 const Component *ComponentList::search(const char *name) { 3032 PreserveIter pi(this); 3033 reset(); 3034 for( Component *comp = nullptr; ((comp = iter()) != nullptr); ) { 3035 if( strcmp(comp->_name,name) == 0 ) return comp; 3036 } 3037 3038 return nullptr; 3039 } 3040 3041 // Return number of USEs + number of DEFs 3042 // When there are no components, or the first component is a USE, 3043 // then we add '1' to hold a space for the 'result' operand. 3044 int ComponentList::num_operands() { 3045 PreserveIter pi(this); 3046 uint count = 1; // result operand 3047 uint position = 0; 3048 3049 Component *component = nullptr; 3050 for( reset(); (component = iter()) != nullptr; ++position ) { 3051 if( component->isa(Component::USE) || 3052 ( position == 0 && (! component->isa(Component::DEF))) ) { 3053 ++count; 3054 } 3055 } 3056 3057 return count; 3058 } 3059 3060 // Return zero-based position of operand 'name' in list; -1 if not in list. 3061 // if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ... 3062 int ComponentList::operand_position(const char *name, int usedef, Form *fm) { 3063 PreserveIter pi(this); 3064 int position = 0; 3065 int num_opnds = num_operands(); 3066 Component *component; 3067 Component* preceding_non_use = nullptr; 3068 Component* first_def = nullptr; 3069 for (reset(); (component = iter()) != nullptr; ++position) { 3070 // When the first component is not a DEF, 3071 // leave space for the result operand! 3072 if ( position==0 && (! component->isa(Component::DEF)) ) { 3073 ++position; 3074 ++num_opnds; 3075 } 3076 if (strcmp(name, component->_name)==0 && (component->isa(usedef))) { 3077 // When the first entry in the component list is a DEF and a USE 3078 // Treat them as being separate, a DEF first, then a USE 3079 if( position==0 3080 && usedef==Component::USE && component->isa(Component::DEF) ) { 3081 assert(position+1 < num_opnds, "advertised index in bounds"); 3082 return position+1; 3083 } else { 3084 if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) { 3085 fprintf(stderr, "the name '%s(%s)' should not precede the name '%s(%s)'", 3086 preceding_non_use->_name, preceding_non_use->getUsedefName(), 3087 name, component->getUsedefName()); 3088 if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident); 3089 if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident); 3090 fprintf(stderr, "\n"); 3091 } 3092 if( position >= num_opnds ) { 3093 fprintf(stderr, "the name '%s' is too late in its name list", name); 3094 if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident); 3095 if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident); 3096 fprintf(stderr, "\n"); 3097 } 3098 assert(position < num_opnds, "advertised index in bounds"); 3099 return position; 3100 } 3101 } 3102 if( component->isa(Component::DEF) 3103 && component->isa(Component::USE) ) { 3104 ++position; 3105 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF 3106 } 3107 if( component->isa(Component::DEF) && !first_def ) { 3108 first_def = component; 3109 } 3110 if( !component->isa(Component::USE) && component != first_def ) { 3111 preceding_non_use = component; 3112 } else if( preceding_non_use && !strcmp(component->_name, preceding_non_use->_name) ) { 3113 preceding_non_use = nullptr; 3114 } 3115 } 3116 return Not_in_list; 3117 } 3118 3119 // Find position for this name, regardless of use/def information 3120 int ComponentList::operand_position(const char *name) { 3121 PreserveIter pi(this); 3122 int position = 0; 3123 Component *component; 3124 for (reset(); (component = iter()) != nullptr; ++position) { 3125 // When the first component is not a DEF, 3126 // leave space for the result operand! 3127 if ( position==0 && (! component->isa(Component::DEF)) ) { 3128 ++position; 3129 } 3130 if (strcmp(name, component->_name)==0) { 3131 return position; 3132 } 3133 if( component->isa(Component::DEF) 3134 && component->isa(Component::USE) ) { 3135 ++position; 3136 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF 3137 } 3138 } 3139 return Not_in_list; 3140 } 3141 3142 int ComponentList::operand_position_format(const char *name, Form *fm) { 3143 PreserveIter pi(this); 3144 int first_position = operand_position(name); 3145 int use_position = operand_position(name, Component::USE, fm); 3146 3147 return ((first_position < use_position) ? use_position : first_position); 3148 } 3149 3150 int ComponentList::label_position() { 3151 PreserveIter pi(this); 3152 int position = 0; 3153 reset(); 3154 for( Component *comp; (comp = iter()) != nullptr; ++position) { 3155 // When the first component is not a DEF, 3156 // leave space for the result operand! 3157 if ( position==0 && (! comp->isa(Component::DEF)) ) { 3158 ++position; 3159 } 3160 if (strcmp(comp->_type, "label")==0) { 3161 return position; 3162 } 3163 if( comp->isa(Component::DEF) 3164 && comp->isa(Component::USE) ) { 3165 ++position; 3166 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF 3167 } 3168 } 3169 3170 return -1; 3171 } 3172 3173 int ComponentList::method_position() { 3174 PreserveIter pi(this); 3175 int position = 0; 3176 reset(); 3177 for( Component *comp; (comp = iter()) != nullptr; ++position) { 3178 // When the first component is not a DEF, 3179 // leave space for the result operand! 3180 if ( position==0 && (! comp->isa(Component::DEF)) ) { 3181 ++position; 3182 } 3183 if (strcmp(comp->_type, "method")==0) { 3184 return position; 3185 } 3186 if( comp->isa(Component::DEF) 3187 && comp->isa(Component::USE) ) { 3188 ++position; 3189 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF 3190 } 3191 } 3192 3193 return -1; 3194 } 3195 3196 void ComponentList::dump() { output(stderr); } 3197 3198 void ComponentList::output(FILE *fp) { 3199 PreserveIter pi(this); 3200 fprintf(fp, "\n"); 3201 Component *component; 3202 for (reset(); (component = iter()) != nullptr;) { 3203 component->output(fp); 3204 } 3205 fprintf(fp, "\n"); 3206 } 3207 3208 //------------------------------MatchNode-------------------------------------- 3209 MatchNode::MatchNode(ArchDesc &ad, const char *result, const char *mexpr, 3210 const char *opType, MatchNode *lChild, MatchNode *rChild) 3211 : _AD(ad), _result(result), _name(mexpr), _opType(opType), 3212 _lChild(lChild), _rChild(rChild), _internalop(0), _numleaves(0), 3213 _commutative_id(0) { 3214 _numleaves = (lChild ? lChild->_numleaves : 0) 3215 + (rChild ? rChild->_numleaves : 0); 3216 } 3217 3218 MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode) 3219 : _AD(ad), _result(mnode._result), _name(mnode._name), 3220 _opType(mnode._opType), _lChild(mnode._lChild), _rChild(mnode._rChild), 3221 _internalop(0), _numleaves(mnode._numleaves), 3222 _commutative_id(mnode._commutative_id) { 3223 } 3224 3225 MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode, int clone) 3226 : _AD(ad), _result(mnode._result), _name(mnode._name), 3227 _opType(mnode._opType), 3228 _internalop(0), _numleaves(mnode._numleaves), 3229 _commutative_id(mnode._commutative_id) { 3230 if (mnode._lChild) { 3231 _lChild = new MatchNode(ad, *mnode._lChild, clone); 3232 } else { 3233 _lChild = nullptr; 3234 } 3235 if (mnode._rChild) { 3236 _rChild = new MatchNode(ad, *mnode._rChild, clone); 3237 } else { 3238 _rChild = nullptr; 3239 } 3240 } 3241 3242 MatchNode::~MatchNode() { 3243 // // This node may not own its children if copied via assignment 3244 // if( _lChild ) delete _lChild; 3245 // if( _rChild ) delete _rChild; 3246 } 3247 3248 bool MatchNode::find_type(const char *type, int &position) const { 3249 if ( (_lChild != nullptr) && (_lChild->find_type(type, position)) ) return true; 3250 if ( (_rChild != nullptr) && (_rChild->find_type(type, position)) ) return true; 3251 3252 if (strcmp(type,_opType)==0) { 3253 return true; 3254 } else { 3255 ++position; 3256 } 3257 return false; 3258 } 3259 3260 // Recursive call collecting info on top-level operands, not transitive. 3261 // Implementation does not modify state of internal structures. 3262 void MatchNode::append_components(FormDict& locals, ComponentList& components, 3263 bool def_flag) const { 3264 int usedef = def_flag ? Component::DEF : Component::USE; 3265 FormDict &globals = _AD.globalNames(); 3266 3267 assert (_name != nullptr, "MatchNode::build_components encountered empty node\n"); 3268 // Base case 3269 if (_lChild==nullptr && _rChild==nullptr) { 3270 // If _opType is not an operation, do not build a component for it ##### 3271 const Form *f = globals[_opType]; 3272 if( f != nullptr ) { 3273 // Add non-ideals that are operands, operand-classes, 3274 if( ! f->ideal_only() 3275 && (f->is_opclass() || f->is_operand()) ) { 3276 components.insert(_name, _opType, usedef, true); 3277 } 3278 } 3279 return; 3280 } 3281 // Promote results of "Set" to DEF 3282 bool tmpdef_flag = (!strcmp(_opType, "Set")) ? true : false; 3283 if (_lChild) _lChild->append_components(locals, components, tmpdef_flag); 3284 tmpdef_flag = false; // only applies to component immediately following 'Set' 3285 if (_rChild) _rChild->append_components(locals, components, tmpdef_flag); 3286 } 3287 3288 // Find the n'th base-operand in the match node, 3289 // recursively investigates match rules of user-defined operands. 3290 // 3291 // Implementation does not modify state of internal structures since they 3292 // can be shared. 3293 bool MatchNode::base_operand(uint &position, FormDict &globals, 3294 const char * &result, const char * &name, 3295 const char * &opType) const { 3296 assert (_name != nullptr, "MatchNode::base_operand encountered empty node\n"); 3297 // Base case 3298 if (_lChild==nullptr && _rChild==nullptr) { 3299 // Check for special case: "Universe", "label" 3300 if (strcmp(_opType,"Universe") == 0 || strcmp(_opType,"label")==0 ) { 3301 if (position == 0) { 3302 result = _result; 3303 name = _name; 3304 opType = _opType; 3305 return 1; 3306 } else { 3307 -- position; 3308 return 0; 3309 } 3310 } 3311 3312 const Form *form = globals[_opType]; 3313 MatchNode *matchNode = nullptr; 3314 // Check for user-defined type 3315 if (form) { 3316 // User operand or instruction? 3317 OperandForm *opForm = form->is_operand(); 3318 InstructForm *inForm = form->is_instruction(); 3319 if ( opForm ) { 3320 matchNode = (MatchNode*)opForm->_matrule; 3321 } else if ( inForm ) { 3322 matchNode = (MatchNode*)inForm->_matrule; 3323 } 3324 } 3325 // if this is user-defined, recurse on match rule 3326 // User-defined operand and instruction forms have a match-rule. 3327 if (matchNode) { 3328 return (matchNode->base_operand(position,globals,result,name,opType)); 3329 } else { 3330 // Either not a form, or a system-defined form (no match rule). 3331 if (position==0) { 3332 result = _result; 3333 name = _name; 3334 opType = _opType; 3335 return 1; 3336 } else { 3337 --position; 3338 return 0; 3339 } 3340 } 3341 3342 } else { 3343 // Examine the left child and right child as well 3344 if (_lChild) { 3345 if (_lChild->base_operand(position, globals, result, name, opType)) 3346 return 1; 3347 } 3348 3349 if (_rChild) { 3350 if (_rChild->base_operand(position, globals, result, name, opType)) 3351 return 1; 3352 } 3353 } 3354 3355 return 0; 3356 } 3357 3358 // Recursive call on all operands' match rules in my match rule. 3359 uint MatchNode::num_consts(FormDict &globals) const { 3360 uint index = 0; 3361 uint num_consts = 0; 3362 const char *result; 3363 const char *name; 3364 const char *opType; 3365 3366 for (uint position = index; 3367 base_operand(position,globals,result,name,opType); position = index) { 3368 ++index; 3369 if( ideal_to_const_type(opType) ) num_consts++; 3370 } 3371 3372 return num_consts; 3373 } 3374 3375 // Recursive call on all operands' match rules in my match rule. 3376 // Constants in match rule subtree with specified type 3377 uint MatchNode::num_consts(FormDict &globals, Form::DataType type) const { 3378 uint index = 0; 3379 uint num_consts = 0; 3380 const char *result; 3381 const char *name; 3382 const char *opType; 3383 3384 for (uint position = index; 3385 base_operand(position,globals,result,name,opType); position = index) { 3386 ++index; 3387 if( ideal_to_const_type(opType) == type ) num_consts++; 3388 } 3389 3390 return num_consts; 3391 } 3392 3393 // Recursive call on all operands' match rules in my match rule. 3394 uint MatchNode::num_const_ptrs(FormDict &globals) const { 3395 return num_consts( globals, Form::idealP ); 3396 } 3397 3398 bool MatchNode::sets_result() const { 3399 return ( (strcmp(_name,"Set") == 0) ? true : false ); 3400 } 3401 3402 const char *MatchNode::reduce_right(FormDict &globals) const { 3403 // If there is no right reduction, return null. 3404 const char *rightStr = nullptr; 3405 3406 // If we are a "Set", start from the right child. 3407 const MatchNode *const mnode = sets_result() ? 3408 (const MatchNode *)this->_rChild : 3409 (const MatchNode *)this; 3410 3411 // If our right child exists, it is the right reduction 3412 if ( mnode->_rChild ) { 3413 rightStr = mnode->_rChild->_internalop ? mnode->_rChild->_internalop 3414 : mnode->_rChild->_opType; 3415 } 3416 // Else, May be simple chain rule: (Set dst operand_form), rightStr=nullptr; 3417 return rightStr; 3418 } 3419 3420 const char *MatchNode::reduce_left(FormDict &globals) const { 3421 // If there is no left reduction, return null. 3422 const char *leftStr = nullptr; 3423 3424 // If we are a "Set", start from the right child. 3425 const MatchNode *const mnode = sets_result() ? 3426 (const MatchNode *)this->_rChild : 3427 (const MatchNode *)this; 3428 3429 // If our left child exists, it is the left reduction 3430 if ( mnode->_lChild ) { 3431 leftStr = mnode->_lChild->_internalop ? mnode->_lChild->_internalop 3432 : mnode->_lChild->_opType; 3433 } else { 3434 // May be simple chain rule: (Set dst operand_form_source) 3435 if ( sets_result() ) { 3436 OperandForm *oper = globals[mnode->_opType]->is_operand(); 3437 if( oper ) { 3438 leftStr = mnode->_opType; 3439 } 3440 } 3441 } 3442 return leftStr; 3443 } 3444 3445 //------------------------------count_instr_names------------------------------ 3446 // Count occurrences of operands names in the leaves of the instruction 3447 // match rule. 3448 void MatchNode::count_instr_names( Dict &names ) { 3449 if( _lChild ) _lChild->count_instr_names(names); 3450 if( _rChild ) _rChild->count_instr_names(names); 3451 if( !_lChild && !_rChild ) { 3452 uintptr_t cnt = (uintptr_t)names[_name]; 3453 cnt++; // One more name found 3454 names.Insert(_name,(void*)cnt); 3455 } 3456 } 3457 3458 //------------------------------build_instr_pred------------------------------- 3459 // Build a path to 'name' in buf. Actually only build if cnt is zero, so we 3460 // can skip some leading instances of 'name'. 3461 int MatchNode::build_instr_pred( char *buf, const char *name, int cnt, int path_bitmask, int level) { 3462 if( _lChild ) { 3463 cnt = _lChild->build_instr_pred(buf, name, cnt, path_bitmask, level+1); 3464 if( cnt < 0 ) { 3465 return cnt; // Found it, all done 3466 } 3467 } 3468 if( _rChild ) { 3469 path_bitmask |= 1 << level; 3470 cnt = _rChild->build_instr_pred( buf, name, cnt, path_bitmask, level+1); 3471 if( cnt < 0 ) { 3472 return cnt; // Found it, all done 3473 } 3474 } 3475 if( !_lChild && !_rChild ) { // Found a leaf 3476 // Wrong name? Give up... 3477 if( strcmp(name,_name) ) return cnt; 3478 if( !cnt ) { 3479 for(int i = 0; i < level; i++) { 3480 int kid = path_bitmask & (1 << i); 3481 if (0 == kid) { 3482 strcpy( buf, "_kids[0]->" ); 3483 } else { 3484 strcpy( buf, "_kids[1]->" ); 3485 } 3486 buf += 10; 3487 } 3488 strcpy( buf, "_leaf" ); 3489 } 3490 return cnt-1; 3491 } 3492 return cnt; 3493 } 3494 3495 3496 //------------------------------build_internalop------------------------------- 3497 // Build string representation of subtree 3498 void MatchNode::build_internalop( ) { 3499 char *iop, *subtree; 3500 const char *lstr, *rstr; 3501 // Build string representation of subtree 3502 // Operation lchildType rchildType 3503 int len = (int)strlen(_opType) + 4; 3504 lstr = (_lChild) ? ((_lChild->_internalop) ? 3505 _lChild->_internalop : _lChild->_opType) : ""; 3506 rstr = (_rChild) ? ((_rChild->_internalop) ? 3507 _rChild->_internalop : _rChild->_opType) : ""; 3508 len += (int)strlen(lstr) + (int)strlen(rstr); 3509 subtree = (char *)AdlAllocateHeap(len); 3510 snprintf_checked(subtree, len, "_%s_%s_%s", _opType, lstr, rstr); 3511 // Hash the subtree string in _internalOps; if a name exists, use it 3512 iop = (char *)_AD._internalOps[subtree]; 3513 // Else create a unique name, and add it to the hash table 3514 if (iop == nullptr) { 3515 iop = subtree; 3516 _AD._internalOps.Insert(subtree, iop); 3517 _AD._internalOpNames.addName(iop); 3518 _AD._internalMatch.Insert(iop, this); 3519 } 3520 // Add the internal operand name to the MatchNode 3521 _internalop = iop; 3522 _result = iop; 3523 } 3524 3525 3526 void MatchNode::dump() { 3527 output(stderr); 3528 } 3529 3530 void MatchNode::output(FILE *fp) { 3531 if (_lChild==0 && _rChild==0) { 3532 fprintf(fp," %s",_name); // operand 3533 } 3534 else { 3535 fprintf(fp," (%s ",_name); // " (opcodeName " 3536 if(_lChild) _lChild->output(fp); // left operand 3537 if(_rChild) _rChild->output(fp); // right operand 3538 fprintf(fp,")"); // ")" 3539 } 3540 } 3541 3542 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const { 3543 static const char *needs_ideal_memory_list[] = { 3544 "StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" , 3545 "StoreB","StoreC","Store" ,"StoreFP", 3546 "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" , 3547 "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" , 3548 "StoreVector", "LoadVector", "LoadVectorMasked", "StoreVectorMasked", 3549 "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked", 3550 "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned", 3551 "CompareAndSwapB", "CompareAndSwapS", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN", 3552 "WeakCompareAndSwapB", "WeakCompareAndSwapS", "WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN", 3553 "CompareAndExchangeB", "CompareAndExchangeS", "CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN", 3554 #if INCLUDE_SHENANDOAHGC 3555 "ShenandoahCompareAndSwapN", "ShenandoahCompareAndSwapP", "ShenandoahWeakCompareAndSwapP", "ShenandoahWeakCompareAndSwapN", "ShenandoahCompareAndExchangeP", "ShenandoahCompareAndExchangeN", 3556 #endif 3557 "StoreCM", 3558 "GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP", 3559 "GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN", 3560 "ClearArray" 3561 }; 3562 int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*); 3563 if( strcmp(_opType,"PrefetchAllocation")==0 ) 3564 return 1; 3565 if( strcmp(_opType,"CacheWB")==0 ) 3566 return 1; 3567 if( strcmp(_opType,"CacheWBPreSync")==0 ) 3568 return 1; 3569 if( strcmp(_opType,"CacheWBPostSync")==0 ) 3570 return 1; 3571 if( _lChild ) { 3572 const char *opType = _lChild->_opType; 3573 for( int i=0; i<cnt; i++ ) 3574 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 ) 3575 return 1; 3576 if( _lChild->needs_ideal_memory_edge(globals) ) 3577 return 1; 3578 } 3579 if( _rChild ) { 3580 const char *opType = _rChild->_opType; 3581 for( int i=0; i<cnt; i++ ) 3582 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 ) 3583 return 1; 3584 if( _rChild->needs_ideal_memory_edge(globals) ) 3585 return 1; 3586 } 3587 3588 return 0; 3589 } 3590 3591 // TRUE if defines a derived oop, and so needs a base oop edge present 3592 // post-matching. 3593 int MatchNode::needs_base_oop_edge() const { 3594 if( !strcmp(_opType,"AddP") ) return 1; 3595 if( strcmp(_opType,"Set") ) return 0; 3596 return !strcmp(_rChild->_opType,"AddP"); 3597 } 3598 3599 int InstructForm::needs_base_oop_edge(FormDict &globals) const { 3600 if( is_simple_chain_rule(globals) ) { 3601 const char *src = _matrule->_rChild->_opType; 3602 OperandForm *src_op = globals[src]->is_operand(); 3603 assert( src_op, "Not operand class of chain rule" ); 3604 return src_op->_matrule ? src_op->_matrule->needs_base_oop_edge() : 0; 3605 } // Else check instruction 3606 3607 return _matrule ? _matrule->needs_base_oop_edge() : 0; 3608 } 3609 3610 3611 //-------------------------cisc spilling methods------------------------------- 3612 // helper routines and methods for detecting cisc-spilling instructions 3613 //-------------------------cisc_spill_merge------------------------------------ 3614 int MatchNode::cisc_spill_merge(int left_spillable, int right_spillable) { 3615 int cisc_spillable = Maybe_cisc_spillable; 3616 3617 // Combine results of left and right checks 3618 if( (left_spillable == Maybe_cisc_spillable) && (right_spillable == Maybe_cisc_spillable) ) { 3619 // neither side is spillable, nor prevents cisc spilling 3620 cisc_spillable = Maybe_cisc_spillable; 3621 } 3622 else if( (left_spillable == Maybe_cisc_spillable) && (right_spillable > Maybe_cisc_spillable) ) { 3623 // right side is spillable 3624 cisc_spillable = right_spillable; 3625 } 3626 else if( (right_spillable == Maybe_cisc_spillable) && (left_spillable > Maybe_cisc_spillable) ) { 3627 // left side is spillable 3628 cisc_spillable = left_spillable; 3629 } 3630 else if( (left_spillable == Not_cisc_spillable) || (right_spillable == Not_cisc_spillable) ) { 3631 // left or right prevents cisc spilling this instruction 3632 cisc_spillable = Not_cisc_spillable; 3633 } 3634 else { 3635 // Only allow one to spill 3636 cisc_spillable = Not_cisc_spillable; 3637 } 3638 3639 return cisc_spillable; 3640 } 3641 3642 //-------------------------root_ops_match-------------------------------------- 3643 bool static root_ops_match(FormDict &globals, const char *op1, const char *op2) { 3644 // Base Case: check that the current operands/operations match 3645 assert( op1, "Must have op's name"); 3646 assert( op2, "Must have op's name"); 3647 const Form *form1 = globals[op1]; 3648 const Form *form2 = globals[op2]; 3649 3650 return (form1 == form2); 3651 } 3652 3653 //-------------------------cisc_spill_match_node------------------------------- 3654 // Recursively check two MatchRules for legal conversion via cisc-spilling 3655 int MatchNode::cisc_spill_match(FormDict& globals, RegisterForm* registers, MatchNode* mRule2, const char* &operand, const char* ®_type) { 3656 int cisc_spillable = Maybe_cisc_spillable; 3657 int left_spillable = Maybe_cisc_spillable; 3658 int right_spillable = Maybe_cisc_spillable; 3659 3660 // Check that each has same number of operands at this level 3661 if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) 3662 return Not_cisc_spillable; 3663 3664 // Base Case: check that the current operands/operations match 3665 // or are CISC spillable 3666 assert( _opType, "Must have _opType"); 3667 assert( mRule2->_opType, "Must have _opType"); 3668 const Form *form = globals[_opType]; 3669 const Form *form2 = globals[mRule2->_opType]; 3670 if( form == form2 ) { 3671 cisc_spillable = Maybe_cisc_spillable; 3672 } else { 3673 const InstructForm *form2_inst = form2 ? form2->is_instruction() : nullptr; 3674 const char *name_left = mRule2->_lChild ? mRule2->_lChild->_opType : nullptr; 3675 const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : nullptr; 3676 DataType data_type = Form::none; 3677 if (form->is_operand()) { 3678 // Make sure the loadX matches the type of the reg 3679 data_type = form->ideal_to_Reg_type(form->is_operand()->ideal_type(globals)); 3680 } 3681 // Detect reg vs (loadX memory) 3682 if( form->is_cisc_reg(globals) 3683 && form2_inst 3684 && data_type != Form::none 3685 && (is_load_from_memory(mRule2->_opType) == data_type) // reg vs. (load memory) 3686 && (name_left != nullptr) // NOT (load) 3687 && (name_right == nullptr) ) { // NOT (load memory foo) 3688 const Form *form2_left = globals[name_left]; 3689 if( form2_left && form2_left->is_cisc_mem(globals) ) { 3690 cisc_spillable = Is_cisc_spillable; 3691 operand = _name; 3692 reg_type = _result; 3693 return Is_cisc_spillable; 3694 } else { 3695 cisc_spillable = Not_cisc_spillable; 3696 } 3697 } 3698 // Detect reg vs memory 3699 else if (form->is_cisc_reg(globals) && form2 != nullptr && form2->is_cisc_mem(globals)) { 3700 cisc_spillable = Is_cisc_spillable; 3701 operand = _name; 3702 reg_type = _result; 3703 return Is_cisc_spillable; 3704 } else { 3705 cisc_spillable = Not_cisc_spillable; 3706 } 3707 } 3708 3709 // If cisc is still possible, check rest of tree 3710 if( cisc_spillable == Maybe_cisc_spillable ) { 3711 // Check that each has same number of operands at this level 3712 if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable; 3713 3714 // Check left operands 3715 if( (_lChild == nullptr) && (mRule2->_lChild == nullptr) ) { 3716 left_spillable = Maybe_cisc_spillable; 3717 } else if (_lChild != nullptr) { 3718 left_spillable = _lChild->cisc_spill_match(globals, registers, mRule2->_lChild, operand, reg_type); 3719 } 3720 3721 // Check right operands 3722 if( (_rChild == nullptr) && (mRule2->_rChild == nullptr) ) { 3723 right_spillable = Maybe_cisc_spillable; 3724 } else if (_rChild != nullptr) { 3725 right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type); 3726 } 3727 3728 // Combine results of left and right checks 3729 cisc_spillable = cisc_spill_merge(left_spillable, right_spillable); 3730 } 3731 3732 return cisc_spillable; 3733 } 3734 3735 //---------------------------cisc_spill_match_rule------------------------------ 3736 // Recursively check two MatchRules for legal conversion via cisc-spilling 3737 // This method handles the root of Match tree, 3738 // general recursive checks done in MatchNode 3739 int MatchRule::matchrule_cisc_spill_match(FormDict& globals, RegisterForm* registers, 3740 MatchRule* mRule2, const char* &operand, 3741 const char* ®_type) { 3742 int cisc_spillable = Maybe_cisc_spillable; 3743 int left_spillable = Maybe_cisc_spillable; 3744 int right_spillable = Maybe_cisc_spillable; 3745 3746 // Check that each sets a result 3747 if( !(sets_result() && mRule2->sets_result()) ) return Not_cisc_spillable; 3748 // Check that each has same number of operands at this level 3749 if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable; 3750 3751 // Check left operands: at root, must be target of 'Set' 3752 if( (_lChild == nullptr) || (mRule2->_lChild == nullptr) ) { 3753 left_spillable = Not_cisc_spillable; 3754 } else { 3755 // Do not support cisc-spilling instruction's target location 3756 if( root_ops_match(globals, _lChild->_opType, mRule2->_lChild->_opType) ) { 3757 left_spillable = Maybe_cisc_spillable; 3758 } else { 3759 left_spillable = Not_cisc_spillable; 3760 } 3761 } 3762 3763 // Check right operands: recursive walk to identify reg->mem operand 3764 if (_rChild == nullptr) { 3765 if (mRule2->_rChild == nullptr) { 3766 right_spillable = Maybe_cisc_spillable; 3767 } else { 3768 assert(0, "_rChild should not be null"); 3769 } 3770 } else { 3771 right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type); 3772 } 3773 3774 // Combine results of left and right checks 3775 cisc_spillable = cisc_spill_merge(left_spillable, right_spillable); 3776 3777 return cisc_spillable; 3778 } 3779 3780 //----------------------------- equivalent ------------------------------------ 3781 // Recursively check to see if two match rules are equivalent. 3782 // This rule handles the root. 3783 bool MatchRule::equivalent(FormDict &globals, MatchNode *mRule2) { 3784 // Check that each sets a result 3785 if (sets_result() != mRule2->sets_result()) { 3786 return false; 3787 } 3788 3789 // Check that the current operands/operations match 3790 assert( _opType, "Must have _opType"); 3791 assert( mRule2->_opType, "Must have _opType"); 3792 const Form *form = globals[_opType]; 3793 const Form *form2 = globals[mRule2->_opType]; 3794 if( form != form2 ) { 3795 return false; 3796 } 3797 3798 if (_lChild ) { 3799 if( !_lChild->equivalent(globals, mRule2->_lChild) ) 3800 return false; 3801 } else if (mRule2->_lChild) { 3802 return false; // I have null left child, mRule2 has non-null left child. 3803 } 3804 3805 if (_rChild ) { 3806 if( !_rChild->equivalent(globals, mRule2->_rChild) ) 3807 return false; 3808 } else if (mRule2->_rChild) { 3809 return false; // I have null right child, mRule2 has non-null right child. 3810 } 3811 3812 // We've made it through the gauntlet. 3813 return true; 3814 } 3815 3816 //----------------------------- equivalent ------------------------------------ 3817 // Recursively check to see if two match rules are equivalent. 3818 // This rule handles the operands. 3819 bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) { 3820 if( !mNode2 ) 3821 return false; 3822 3823 // Check that the current operands/operations match 3824 assert( _opType, "Must have _opType"); 3825 assert( mNode2->_opType, "Must have _opType"); 3826 const Form *form = globals[_opType]; 3827 const Form *form2 = globals[mNode2->_opType]; 3828 if( form != form2 ) { 3829 return false; 3830 } 3831 3832 // Check that their children also match 3833 if (_lChild ) { 3834 if( !_lChild->equivalent(globals, mNode2->_lChild) ) 3835 return false; 3836 } else if (mNode2->_lChild) { 3837 return false; // I have null left child, mNode2 has non-null left child. 3838 } 3839 3840 if (_rChild ) { 3841 if( !_rChild->equivalent(globals, mNode2->_rChild) ) 3842 return false; 3843 } else if (mNode2->_rChild) { 3844 return false; // I have null right child, mNode2 has non-null right child. 3845 } 3846 3847 // We've made it through the gauntlet. 3848 return true; 3849 } 3850 3851 //-------------------------- count_commutative_op ------------------------------- 3852 // Recursively check for commutative operations with subtree operands 3853 // which could be swapped. 3854 void MatchNode::count_commutative_op(int& count) { 3855 static const char *commut_op_list[] = { 3856 "AddI","AddL","AddF","AddD", 3857 "AndI","AndL", 3858 "MaxI","MinI","MaxF","MinF","MaxD","MinD", 3859 "MulI","MulL","MulF","MulD", 3860 "OrI","OrL", 3861 "XorI","XorL" 3862 }; 3863 3864 static const char *commut_vector_op_list[] = { 3865 "AddVB", "AddVS", "AddVI", "AddVL", "AddVF", "AddVD", 3866 "MulVB", "MulVS", "MulVI", "MulVL", "MulVF", "MulVD", 3867 "AndV", "OrV", "XorV", 3868 "MaxV", "MinV" 3869 }; 3870 3871 if (_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild)) { 3872 // Don't swap if right operand is an immediate constant. 3873 bool is_const = false; 3874 if (_rChild->_lChild == nullptr && _rChild->_rChild == nullptr) { 3875 FormDict &globals = _AD.globalNames(); 3876 const Form *form = globals[_rChild->_opType]; 3877 if (form) { 3878 OperandForm *oper = form->is_operand(); 3879 if (oper && oper->interface_type(globals) == Form::constant_interface) 3880 is_const = true; 3881 } 3882 } 3883 3884 if (!is_const) { 3885 int scalar_cnt = sizeof(commut_op_list)/sizeof(char*); 3886 int vector_cnt = sizeof(commut_vector_op_list)/sizeof(char*); 3887 bool matched = false; 3888 3889 // Check the commutative vector op first. It's noncommutative if 3890 // the current node is a masked vector op, since a mask value 3891 // is added to the original vector node's input list and the original 3892 // first two inputs are packed into one BinaryNode. So don't swap 3893 // if one of the operands is a BinaryNode. 3894 for (int i = 0; i < vector_cnt; i++) { 3895 if (strcmp(_opType, commut_vector_op_list[i]) == 0) { 3896 if (strcmp(_lChild->_opType, "Binary") != 0 && 3897 strcmp(_rChild->_opType, "Binary") != 0) { 3898 count++; 3899 _commutative_id = count; // id should be > 0 3900 } 3901 matched = true; 3902 break; 3903 } 3904 } 3905 3906 // Then check the scalar op if the current op is not in 3907 // the commut_vector_op_list. 3908 if (!matched) { 3909 for (int i = 0; i < scalar_cnt; i++) { 3910 if (strcmp(_opType, commut_op_list[i]) == 0) { 3911 count++; 3912 _commutative_id = count; // id should be > 0 3913 break; 3914 } 3915 } 3916 } 3917 } 3918 } 3919 if (_lChild) 3920 _lChild->count_commutative_op(count); 3921 if (_rChild) 3922 _rChild->count_commutative_op(count); 3923 } 3924 3925 //-------------------------- swap_commutative_op ------------------------------ 3926 // Recursively swap specified commutative operation with subtree operands. 3927 void MatchNode::swap_commutative_op(bool atroot, int id) { 3928 if( _commutative_id == id ) { // id should be > 0 3929 assert(_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild ), 3930 "not swappable operation"); 3931 MatchNode* tmp = _lChild; 3932 _lChild = _rChild; 3933 _rChild = tmp; 3934 // Don't exit here since we need to build internalop. 3935 } 3936 3937 bool is_set = ( strcmp(_opType, "Set") == 0 ); 3938 if( _lChild ) 3939 _lChild->swap_commutative_op(is_set, id); 3940 if( _rChild ) 3941 _rChild->swap_commutative_op(is_set, id); 3942 3943 // If not the root, reduce this subtree to an internal operand 3944 if( !atroot && (_lChild || _rChild) ) { 3945 build_internalop(); 3946 } 3947 } 3948 3949 //-------------------------- swap_commutative_op ------------------------------ 3950 // Recursively swap specified commutative operation with subtree operands. 3951 void MatchRule::matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt) { 3952 assert(match_rules_cnt < 100," too many match rule clones"); 3953 // Clone 3954 MatchRule* clone = new MatchRule(_AD, this); 3955 // Swap operands of commutative operation 3956 ((MatchNode*)clone)->swap_commutative_op(true, count); 3957 const size_t buf_size = strlen(instr_ident) + 4; 3958 char* buf = (char*) AdlAllocateHeap(buf_size); 3959 snprintf_checked(buf, buf_size, "%s_%d", instr_ident, match_rules_cnt++); 3960 clone->_result = buf; 3961 3962 clone->_next = this->_next; 3963 this-> _next = clone; 3964 if( (--count) > 0 ) { 3965 this-> matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt); 3966 clone->matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt); 3967 } 3968 } 3969 3970 //------------------------------MatchRule-------------------------------------- 3971 MatchRule::MatchRule(ArchDesc &ad) 3972 : MatchNode(ad), _depth(0), _construct(nullptr), _numchilds(0) { 3973 _next = nullptr; 3974 } 3975 3976 MatchRule::MatchRule(ArchDesc &ad, MatchRule* mRule) 3977 : MatchNode(ad, *mRule, 0), _depth(mRule->_depth), 3978 _construct(mRule->_construct), _numchilds(mRule->_numchilds) { 3979 _next = nullptr; 3980 } 3981 3982 MatchRule::MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char *cnstr, 3983 int numleaves) 3984 : MatchNode(ad,*mroot), _depth(depth), _construct(cnstr), 3985 _numchilds(0) { 3986 _next = nullptr; 3987 mroot->_lChild = nullptr; 3988 mroot->_rChild = nullptr; 3989 delete mroot; 3990 _numleaves = numleaves; 3991 _numchilds = (_lChild ? 1 : 0) + (_rChild ? 1 : 0); 3992 } 3993 MatchRule::~MatchRule() { 3994 } 3995 3996 // Recursive call collecting info on top-level operands, not transitive. 3997 // Implementation does not modify state of internal structures. 3998 void MatchRule::append_components(FormDict& locals, ComponentList& components, bool def_flag) const { 3999 assert (_name != nullptr, "MatchNode::build_components encountered empty node\n"); 4000 4001 MatchNode::append_components(locals, components, 4002 false /* not necessarily a def */); 4003 } 4004 4005 // Recursive call on all operands' match rules in my match rule. 4006 // Implementation does not modify state of internal structures since they 4007 // can be shared. 4008 // The MatchNode that is called first treats its 4009 bool MatchRule::base_operand(uint &position0, FormDict &globals, 4010 const char *&result, const char * &name, 4011 const char * &opType)const{ 4012 uint position = position0; 4013 4014 return (MatchNode::base_operand( position, globals, result, name, opType)); 4015 } 4016 4017 4018 bool MatchRule::is_base_register(FormDict &globals) const { 4019 uint position = 1; 4020 const char *result = nullptr; 4021 const char *name = nullptr; 4022 const char *opType = nullptr; 4023 if (!base_operand(position, globals, result, name, opType)) { 4024 position = 0; 4025 if( base_operand(position, globals, result, name, opType) && 4026 (strcmp(opType,"RegI")==0 || 4027 strcmp(opType,"RegP")==0 || 4028 strcmp(opType,"RegN")==0 || 4029 strcmp(opType,"RegL")==0 || 4030 strcmp(opType,"RegF")==0 || 4031 strcmp(opType,"RegD")==0 || 4032 strcmp(opType,"RegVectMask")==0 || 4033 strcmp(opType,"VecA")==0 || 4034 strcmp(opType,"VecS")==0 || 4035 strcmp(opType,"VecD")==0 || 4036 strcmp(opType,"VecX")==0 || 4037 strcmp(opType,"VecY")==0 || 4038 strcmp(opType,"VecZ")==0 || 4039 strcmp(opType,"Reg" )==0) ) { 4040 return 1; 4041 } 4042 } 4043 return 0; 4044 } 4045 4046 Form::DataType MatchRule::is_base_constant(FormDict &globals) const { 4047 uint position = 1; 4048 const char *result = nullptr; 4049 const char *name = nullptr; 4050 const char *opType = nullptr; 4051 if (!base_operand(position, globals, result, name, opType)) { 4052 position = 0; 4053 if (base_operand(position, globals, result, name, opType)) { 4054 return ideal_to_const_type(opType); 4055 } 4056 } 4057 return Form::none; 4058 } 4059 4060 bool MatchRule::is_chain_rule(FormDict &globals) const { 4061 4062 // Check for chain rule, and do not generate a match list for it 4063 if ((_lChild == nullptr) && (_rChild == nullptr) ) { 4064 const Form *form = globals[_opType]; 4065 // If this is ideal, then it is a base match, not a chain rule. 4066 if ( form && form->is_operand() && (!form->ideal_only())) { 4067 return true; 4068 } 4069 } 4070 // Check for "Set" form of chain rule, and do not generate a match list 4071 if (_rChild) { 4072 const char *rch = _rChild->_opType; 4073 const Form *form = globals[rch]; 4074 if ((!strcmp(_opType,"Set") && 4075 ((form) && form->is_operand()))) { 4076 return true; 4077 } 4078 } 4079 return false; 4080 } 4081 4082 int MatchRule::is_ideal_copy() const { 4083 if (is_chain_rule(_AD.globalNames()) && 4084 _lChild && strncmp(_lChild->_opType, "stackSlot", 9) == 0) { 4085 return 1; 4086 } 4087 return 0; 4088 } 4089 4090 int MatchRule::is_expensive() const { 4091 if( _rChild ) { 4092 const char *opType = _rChild->_opType; 4093 if( strcmp(opType,"AtanD")==0 || 4094 strcmp(opType,"DivD")==0 || 4095 strcmp(opType,"DivF")==0 || 4096 strcmp(opType,"DivI")==0 || 4097 strcmp(opType,"Log10D")==0 || 4098 strcmp(opType,"ModD")==0 || 4099 strcmp(opType,"ModF")==0 || 4100 strcmp(opType,"ModI")==0 || 4101 strcmp(opType,"SqrtD")==0 || 4102 strcmp(opType,"SqrtF")==0 || 4103 strcmp(opType,"TanD")==0 || 4104 strcmp(opType,"ConvD2F")==0 || 4105 strcmp(opType,"ConvD2I")==0 || 4106 strcmp(opType,"ConvD2L")==0 || 4107 strcmp(opType,"ConvF2D")==0 || 4108 strcmp(opType,"ConvF2I")==0 || 4109 strcmp(opType,"ConvF2L")==0 || 4110 strcmp(opType,"ConvI2D")==0 || 4111 strcmp(opType,"ConvI2F")==0 || 4112 strcmp(opType,"ConvI2L")==0 || 4113 strcmp(opType,"ConvL2D")==0 || 4114 strcmp(opType,"ConvL2F")==0 || 4115 strcmp(opType,"ConvL2I")==0 || 4116 strcmp(opType,"DecodeN")==0 || 4117 strcmp(opType,"EncodeP")==0 || 4118 strcmp(opType,"EncodePKlass")==0 || 4119 strcmp(opType,"DecodeNKlass")==0 || 4120 strcmp(opType,"FmaD") == 0 || 4121 strcmp(opType,"FmaF") == 0 || 4122 strcmp(opType,"RoundDouble")==0 || 4123 strcmp(opType,"RoundDoubleMode")==0 || 4124 strcmp(opType,"RoundFloat")==0 || 4125 strcmp(opType,"ReverseBytesI")==0 || 4126 strcmp(opType,"ReverseBytesL")==0 || 4127 strcmp(opType,"ReverseBytesUS")==0 || 4128 strcmp(opType,"ReverseBytesS")==0 || 4129 strcmp(opType,"PopulateIndex")==0 || 4130 strcmp(opType,"AddReductionVI")==0 || 4131 strcmp(opType,"AddReductionVL")==0 || 4132 strcmp(opType,"AddReductionVF")==0 || 4133 strcmp(opType,"AddReductionVD")==0 || 4134 strcmp(opType,"MulReductionVI")==0 || 4135 strcmp(opType,"MulReductionVL")==0 || 4136 strcmp(opType,"MulReductionVF")==0 || 4137 strcmp(opType,"MulReductionVD")==0 || 4138 strcmp(opType,"MinReductionV")==0 || 4139 strcmp(opType,"MaxReductionV")==0 || 4140 strcmp(opType,"AndReductionV")==0 || 4141 strcmp(opType,"OrReductionV")==0 || 4142 strcmp(opType,"XorReductionV")==0 || 4143 strcmp(opType,"MaskAll")==0 || 4144 0 /* 0 to line up columns nicely */ ) { 4145 return 1; 4146 } 4147 } 4148 return 0; 4149 } 4150 4151 bool MatchRule::is_ideal_if() const { 4152 if( !_opType ) return false; 4153 return 4154 !strcmp(_opType,"If" ) || 4155 !strcmp(_opType,"CountedLoopEnd"); 4156 } 4157 4158 bool MatchRule::is_ideal_fastlock() const { 4159 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) { 4160 return (strcmp(_rChild->_opType,"FastLock") == 0); 4161 } 4162 return false; 4163 } 4164 4165 bool MatchRule::is_ideal_membar() const { 4166 if( !_opType ) return false; 4167 return 4168 !strcmp(_opType,"MemBarAcquire") || 4169 !strcmp(_opType,"MemBarRelease") || 4170 !strcmp(_opType,"MemBarAcquireLock") || 4171 !strcmp(_opType,"MemBarReleaseLock") || 4172 !strcmp(_opType,"LoadFence" ) || 4173 !strcmp(_opType,"StoreFence") || 4174 !strcmp(_opType,"StoreStoreFence") || 4175 !strcmp(_opType,"MemBarVolatile") || 4176 !strcmp(_opType,"MemBarCPUOrder") || 4177 !strcmp(_opType,"MemBarStoreStore") || 4178 !strcmp(_opType,"OnSpinWait"); 4179 } 4180 4181 bool MatchRule::is_ideal_loadPC() const { 4182 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) { 4183 return (strcmp(_rChild->_opType,"LoadPC") == 0); 4184 } 4185 return false; 4186 } 4187 4188 bool MatchRule::is_ideal_box() const { 4189 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) { 4190 return (strcmp(_rChild->_opType,"Box") == 0); 4191 } 4192 return false; 4193 } 4194 4195 bool MatchRule::is_ideal_goto() const { 4196 bool ideal_goto = false; 4197 4198 if( _opType && (strcmp(_opType,"Goto") == 0) ) { 4199 ideal_goto = true; 4200 } 4201 return ideal_goto; 4202 } 4203 4204 bool MatchRule::is_ideal_jump() const { 4205 if( _opType ) { 4206 if( !strcmp(_opType,"Jump") ) 4207 return true; 4208 } 4209 return false; 4210 } 4211 4212 bool MatchRule::is_ideal_bool() const { 4213 if( _opType ) { 4214 if( !strcmp(_opType,"Bool") ) 4215 return true; 4216 } 4217 return false; 4218 } 4219 4220 4221 Form::DataType MatchRule::is_ideal_load() const { 4222 Form::DataType ideal_load = Form::none; 4223 4224 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) { 4225 const char *opType = _rChild->_opType; 4226 ideal_load = is_load_from_memory(opType); 4227 } 4228 4229 return ideal_load; 4230 } 4231 4232 bool MatchRule::is_vector() const { 4233 static const char *vector_list[] = { 4234 "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD", 4235 "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD", 4236 "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD", 4237 "DivVF","DivVD", 4238 "AbsVB","AbsVS","AbsVI","AbsVL","AbsVF","AbsVD", 4239 "NegVF","NegVD","NegVI","NegVL", 4240 "SqrtVD","SqrtVF", 4241 "AndV" ,"XorV" ,"OrV", 4242 "MaxV", "MinV", 4243 "CompressV", "ExpandV", "CompressM", "CompressBitsV", "ExpandBitsV", 4244 "AddReductionVI", "AddReductionVL", 4245 "AddReductionVF", "AddReductionVD", 4246 "MulReductionVI", "MulReductionVL", 4247 "MulReductionVF", "MulReductionVD", 4248 "MaxReductionV", "MinReductionV", 4249 "AndReductionV", "OrReductionV", "XorReductionV", 4250 "MulAddVS2VI", "MacroLogicV", 4251 "LShiftCntV","RShiftCntV", 4252 "LShiftVB","LShiftVS","LShiftVI","LShiftVL", 4253 "RShiftVB","RShiftVS","RShiftVI","RShiftVL", 4254 "URShiftVB","URShiftVS","URShiftVI","URShiftVL", 4255 "Replicate","ReverseV","ReverseBytesV", 4256 "RoundDoubleModeV","RotateLeftV" , "RotateRightV", "LoadVector","StoreVector", 4257 "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked", 4258 "VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert", 4259 "VectorRearrange","VectorLoadShuffle", "VectorLoadConst", 4260 "VectorCastB2X", "VectorCastS2X", "VectorCastI2X", 4261 "VectorCastL2X", "VectorCastF2X", "VectorCastD2X", "VectorCastF2HF", "VectorCastHF2F", 4262 "VectorUCastB2X", "VectorUCastS2X", "VectorUCastI2X", 4263 "VectorMaskWrapper","VectorMaskCmp","VectorReinterpret","LoadVectorMasked","StoreVectorMasked", 4264 "FmaVD","FmaVF","PopCountVI","PopCountVL","PopulateIndex","VectorLongToMask", 4265 "CountLeadingZerosV", "CountTrailingZerosV", "SignumVF", "SignumVD", 4266 // Next are vector mask ops. 4267 "MaskAll", "AndVMask", "OrVMask", "XorVMask", "VectorMaskCast", 4268 "RoundVF", "RoundVD", 4269 // Next are not supported currently. 4270 "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D", 4271 "ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD" 4272 }; 4273 int cnt = sizeof(vector_list)/sizeof(char*); 4274 if (_rChild) { 4275 const char *opType = _rChild->_opType; 4276 for (int i=0; i<cnt; i++) 4277 if (strcmp(opType,vector_list[i]) == 0) 4278 return true; 4279 } 4280 return false; 4281 } 4282 4283 4284 bool MatchRule::skip_antidep_check() const { 4285 // Some loads operate on what is effectively immutable memory so we 4286 // should skip the anti dep computations. For some of these nodes 4287 // the rewritable field keeps the anti dep logic from triggering but 4288 // for certain kinds of LoadKlass it does not since they are 4289 // actually reading memory which could be rewritten by the runtime, 4290 // though never by generated code. This disables it uniformly for 4291 // the nodes that behave like this: LoadKlass, LoadNKlass and 4292 // LoadRange. 4293 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) { 4294 const char *opType = _rChild->_opType; 4295 if (strcmp("LoadKlass", opType) == 0 || 4296 strcmp("LoadNKlass", opType) == 0 || 4297 strcmp("LoadRange", opType) == 0) { 4298 return true; 4299 } 4300 } 4301 4302 return false; 4303 } 4304 4305 4306 Form::DataType MatchRule::is_ideal_store() const { 4307 Form::DataType ideal_store = Form::none; 4308 4309 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) { 4310 const char *opType = _rChild->_opType; 4311 ideal_store = is_store_to_memory(opType); 4312 } 4313 4314 return ideal_store; 4315 } 4316 4317 4318 void MatchRule::dump() { 4319 output(stderr); 4320 } 4321 4322 // Write just one line. 4323 void MatchRule::output_short(FILE *fp) { 4324 fprintf(fp,"MatchRule: ( %s",_name); 4325 if (_lChild) _lChild->output(fp); 4326 if (_rChild) _rChild->output(fp); 4327 fprintf(fp," )"); 4328 } 4329 4330 void MatchRule::output(FILE *fp) { 4331 output_short(fp); 4332 fprintf(fp,"\n nesting depth = %d\n", _depth); 4333 if (_result) fprintf(fp," Result Type = %s", _result); 4334 fprintf(fp,"\n"); 4335 } 4336 4337 //------------------------------Attribute-------------------------------------- 4338 Attribute::Attribute(char *id, char* val, int type) 4339 : _ident(id), _val(val), _atype(type) { 4340 } 4341 Attribute::~Attribute() { 4342 } 4343 4344 int Attribute::int_val(ArchDesc &ad) { 4345 // Make sure it is an integer constant: 4346 int result = 0; 4347 if (!_val || !ADLParser::is_int_token(_val, result)) { 4348 ad.syntax_err(0, "Attribute %s must have an integer value: %s", 4349 _ident, _val ? _val : ""); 4350 } 4351 return result; 4352 } 4353 4354 void Attribute::dump() { 4355 output(stderr); 4356 } // Debug printer 4357 4358 // Write to output files 4359 void Attribute::output(FILE *fp) { 4360 fprintf(fp,"Attribute: %s %s\n", (_ident?_ident:""), (_val?_val:"")); 4361 } 4362 4363 //------------------------------FormatRule---------------------------------- 4364 FormatRule::FormatRule(char *temp) 4365 : _temp(temp) { 4366 } 4367 FormatRule::~FormatRule() { 4368 } 4369 4370 void FormatRule::dump() { 4371 output(stderr); 4372 } 4373 4374 // Write to output files 4375 void FormatRule::output(FILE *fp) { 4376 fprintf(fp,"\nFormat Rule: \n%s", (_temp?_temp:"")); 4377 fprintf(fp,"\n"); 4378 }