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