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