1 /* 2 * Copyright (c) 1998, 2019, 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 #ifndef SHARE_ADLC_FORMSOPT_HPP 26 #define SHARE_ADLC_FORMSOPT_HPP 27 28 // FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes 29 30 // Class List 31 class Form; 32 class InstructForm; 33 class OperandForm; 34 class OpClassForm; 35 class AttributeForm; 36 class RegisterForm; 37 class PipelineForm; 38 class SourceForm; 39 class EncodeForm; 40 class Component; 41 class Constraint; 42 class Predicate; 43 class MatchRule; 44 class Attribute; 45 class Effect; 46 class ExpandRule; 47 class RewriteRule; 48 class ConstructRule; 49 class FormatRule; 50 class Peephole; 51 class PeepMatch; 52 class PeepConstraint; 53 class EncClass; 54 class Interface; 55 class RegInterface; 56 class ConstInterface; 57 class MemInterface; 58 class CondInterface; 59 class Opcode; 60 class InsEncode; 61 class RegDef; 62 class RegClass; 63 class CodeSnippetRegClass; 64 class ConditionalRegClass; 65 class AllocClass; 66 class ResourceForm; 67 class PipeClassForm; 68 class PipeClassOperandForm; 69 class PipeClassResourceForm; 70 class PeepMatch; 71 class PeepConstraint; 72 class PeepReplace; 73 class MatchList; 74 75 class ArchDesc; 76 77 //==============================Register Allocation============================ 78 //------------------------------RegisterForm----------------------------------- 79 class RegisterForm : public Form { 80 private: 81 AllocClass *_current_ac; // State used by iter_RegDefs() 82 83 public: 84 // Public Data 85 NameList _rdefs; // List of register definition names 86 Dict _regDef; // map register name to RegDef* 87 88 NameList _rclasses; // List of register class names 89 Dict _regClass; // map register class name to RegClass* 90 91 NameList _aclasses; // List of allocation class names 92 Dict _allocClass; // Dictionary of allocation classes 93 94 static int _reg_ctr; // Register counter 95 static int RegMask_Size(); // Compute RegMask size 96 97 // Public Methods 98 RegisterForm(); 99 ~RegisterForm(); 100 101 void addRegDef(char *regName, char *callingConv, char *c_conv, 102 char * idealtype, char *encoding, char* concreteName); 103 template<typename T> T* addRegClass(const char* className); 104 105 AllocClass *addAllocClass(char *allocName); 106 void addSpillRegClass(); 107 108 // Provide iteration over all register definitions 109 // in the order used by the register allocator 110 void reset_RegDefs(); 111 RegDef *iter_RegDefs(); 112 RegDef *getRegDef (const char *regName); 113 114 RegClass *getRegClass(const char *className); 115 116 // Return register mask, compressed chunk and register # 117 uint reg_mask(char *register_class); 118 119 // Check that register classes are compatible with chunks 120 bool verify(); 121 122 void dump(); // Debug printer 123 void output(FILE *fp); // Write info to output files 124 }; 125 126 //------------------------------RegDef----------------------------------------- 127 class RegDef : public Form { 128 public: 129 // Public Data 130 const char *_regname; // ADLC (Opto) Register name 131 const char *_callconv; // Calling convention 132 const char *_c_conv; // Native calling convention, 'C' 133 const char *_idealtype; // Ideal Type for register save/restore 134 const char *_concrete; // concrete register name 135 136 private: 137 const char *_register_encode; // The register encoding 138 // The chunk and register mask bits define info for register allocation 139 uint32 _register_num; // Which register am I 140 141 public: 142 // Public Methods 143 RegDef(char *regname, char *callconv, char *c_conv, 144 char *idealtype, char *encoding, char *concrete); 145 ~RegDef(); // Destructor 146 147 // Interface to define/redefine the register number 148 void set_register_num(uint32 new_register_num); 149 150 // Bit pattern used for generating machine code 151 const char *register_encode() const; 152 // Register number used in machine-independent code 153 uint32 register_num() const; 154 155 void dump(); // Debug printer 156 void output(FILE *fp); // Write info to output files 157 }; 158 159 //------------------------------RegClass--------------------------------------- 160 // Generic register class. This register class is the internal representation 161 // for the following .ad file format: 162 // 163 // reg_class ptr(RAX, RBX, ...); 164 // 165 // where ptr is the name of the register class, RAX and RBX are registers. 166 // 167 // This register class allows registers to be spilled onto the stack. Spilling 168 // is allowed is field _stack_or_reg is true. 169 class RegClass : public Form { 170 public: 171 // Public Data 172 const char *_classid; // Name of class 173 NameList _regDefs; // List of registers in class 174 Dict _regDef; // Dictionary of registers in class 175 protected: 176 bool _stack_or_reg; // Allowed on any stack slot 177 178 public: 179 // Public Methods 180 RegClass(const char *classid);// Constructor 181 virtual ~RegClass(); 182 183 void addReg(RegDef *regDef); // Add a register to this class 184 185 uint size() const; // Number of registers in class 186 int regs_in_word( int wordnum, bool stack_also ); 187 188 const RegDef *get_RegDef(const char *regDef_name) const; 189 190 // Returns the lowest numbered register in the mask. 191 const RegDef* find_first_elem(); 192 193 // Iteration support 194 void reset(); // Reset the following two iterators 195 RegDef *RegDef_iter(); // which move jointly, 196 const char *rd_name_iter(); // invoking either advances both. 197 198 void dump(); // Debug printer 199 void output(FILE *fp); // Write info to output files 200 201 virtual bool has_stack_version() { 202 return _stack_or_reg; 203 } 204 virtual void set_stack_version(bool flag) { 205 _stack_or_reg = flag; 206 } 207 208 virtual void declare_register_masks(FILE* fp); 209 virtual void build_register_masks(FILE* fp); 210 }; 211 212 //------------------------------CodeSnippetRegClass---------------------------- 213 // Register class that has an user-defined C++ code snippet attached to it 214 // to determine at runtime which register class to use. This register class is 215 // the internal representation for the following .ad file format: 216 // 217 // reg_class actual_dflt_reg %{ 218 // if (VM_Version::has_vfp3_32()) { 219 // return DFLT_REG_mask(); 220 // } else { 221 // return DFLT_LOW_REG_mask(); 222 // } 223 // %} 224 // 225 // where DFLT_REG_mask() and DFLT_LOW_REG_mask() are the internal names of the 226 // masks of register classes dflt_reg and dflt_low_reg. 227 // 228 // The attached code snippet can select also between more than two register classes. 229 // This register class can be, however, used only if the register class is not 230 // cisc-spillable (i.e., the registers of this class are not allowed on the stack, 231 // which is equivalent with _stack_or_reg being false). 232 class CodeSnippetRegClass : public RegClass { 233 protected: 234 char* _code_snippet; 235 public: 236 CodeSnippetRegClass(const char* classid);// Constructor 237 ~CodeSnippetRegClass(); 238 239 void set_code_snippet(char* code) { 240 _code_snippet = code; 241 } 242 char* code_snippet() { 243 return _code_snippet; 244 } 245 void set_stack_version(bool flag) { 246 assert(false, "User defined register classes are not allowed to spill to the stack."); 247 } 248 void declare_register_masks(FILE* fp); 249 void build_register_masks(FILE* fp) { 250 // We do not need to generate register masks because we select at runtime 251 // between register masks generated for other register classes. 252 return; 253 } 254 }; 255 256 //------------------------------ConditionalRegClass---------------------------- 257 // Register class that has two register classes and a runtime condition attached 258 // to it. The condition is evaluated at runtime and either one of the register 259 // attached register classes is selected. This register class is the internal 260 // representation for the following .ad format: 261 // 262 // reg_class_dynamic actual_dflt_reg(dflt_reg, low_reg, 263 // %{ VM_Version::has_vfp3_32() }% 264 // ); 265 // 266 // This example is equivalent to the example used with the CodeSnippetRegClass 267 // register class. A ConditionalRegClass works also if a register class is cisc-spillable 268 // (i.e., _stack_or_reg is true), but if can select only between two register classes. 269 class ConditionalRegClass : public RegClass { 270 protected: 271 // reference to condition code 272 char* _condition_code; // C++ condition code to dynamically determine which register class to use. 273 274 // Example syntax (equivalent to previous example): 275 // 276 // reg_class actual_dflt_reg(dflt_reg, low_reg, 277 // %{ VM_Version::has_vfp3_32() }% 278 // ); 279 // reference to conditional register classes 280 RegClass* _rclasses[2]; // 0 is the register class selected if the condition code returns true 281 // 1 is the register class selected if the condition code returns false 282 public: 283 ConditionalRegClass(const char* classid);// Constructor 284 ~ConditionalRegClass(); 285 286 virtual void set_stack_version(bool flag) { 287 RegClass::set_stack_version(flag); 288 assert((_rclasses[0] != NULL), "Register class NULL for condition code == true"); 289 assert((_rclasses[1] != NULL), "Register class NULL for condition code == false"); 290 _rclasses[0]->set_stack_version(flag); 291 _rclasses[1]->set_stack_version(flag); 292 } 293 void declare_register_masks(FILE* fp); 294 void build_register_masks(FILE* fp) { 295 // We do not need to generate register masks because we select at runtime 296 // between register masks generated for other register classes. 297 return; 298 } 299 void set_rclass_at_index(int index, RegClass* rclass) { 300 assert((0 <= index && index < 2), "Condition code can select only between two register classes"); 301 _rclasses[index] = rclass; 302 } 303 void set_condition_code(char* code) { 304 _condition_code = code; 305 } 306 char* condition_code() { 307 return _condition_code; 308 } 309 }; 310 311 //------------------------------AllocClass------------------------------------- 312 class AllocClass : public Form { 313 private: 314 315 public: 316 // Public Data 317 char *_classid; // Name of class 318 NameList _regDefs; // List of registers in class 319 Dict _regDef; // Dictionary of registers in class 320 321 // Public Methods 322 AllocClass(char *classid); // Constructor 323 324 void addReg(RegDef *regDef); // Add a register to this class 325 uint size() {return _regDef.Size();} // Number of registers in class 326 327 void dump(); // Debug printer 328 void output(FILE *fp); // Write info to output files 329 }; 330 331 332 //==============================Frame Handling================================ 333 //------------------------------FrameForm------------------------------------- 334 class FrameForm : public Form { 335 private: 336 337 public: 338 // Public Data 339 bool _direction; // Direction of stack growth 340 char *_sync_stack_slots; 341 char *_inline_cache_reg; 342 char *_interpreter_method_oop_reg; 343 char *_interpreter_frame_pointer_reg; 344 char *_cisc_spilling_operand_name; 345 char *_frame_pointer; 346 char *_c_frame_pointer; 347 char *_alignment; 348 bool _return_addr_loc; 349 bool _c_return_addr_loc; 350 char *_return_addr; 351 char *_c_return_addr; 352 char *_in_preserve_slots; 353 char *_varargs_C_out_slots_killed; 354 char *_calling_convention; 355 char *_c_calling_convention; 356 char *_return_value; 357 char *_c_return_value; 358 359 // Public Methods 360 FrameForm(); 361 ~FrameForm(); 362 363 void dump(); // Debug printer 364 void output(FILE *fp); // Write info to output files 365 }; 366 367 368 //==============================Scheduling===================================== 369 //------------------------------PipelineForm----------------------------------- 370 class PipelineForm : public Form { 371 private: 372 373 public: 374 // Public Data 375 NameList _reslist; // List of pipeline resources 376 FormDict _resdict; // Resource Name -> ResourceForm mapping 377 int _rescount; // Number of resources (ignores OR cases) 378 int _maxcycleused; // Largest cycle used relative to beginning of instruction 379 380 NameList _stages; // List of pipeline stages on architecture 381 int _stagecnt; // Number of stages listed 382 383 NameList _classlist; // List of pipeline classes 384 FormDict _classdict; // Class Name -> PipeClassForm mapping 385 int _classcnt; // Number of classes 386 387 NameList _noplist; // List of NOP instructions 388 int _nopcnt; // Number of nop instructions 389 390 bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions 391 bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions 392 int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP 393 int _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP 394 int _instrUnitSize; // The minimum instruction unit size, in bytes 395 int _bundleUnitSize; // The bundle unit size, in bytes 396 int _instrFetchUnitSize; // The size of the I-fetch unit, in bytes [must be power of 2] 397 int _instrFetchUnits; // The number of I-fetch units processed per cycle 398 399 // Public Methods 400 PipelineForm(); 401 ~PipelineForm(); 402 403 void dump(); // Debug printer 404 void output(FILE *fp); // Write info to output files 405 }; 406 407 //------------------------------ResourceForm----------------------------------- 408 class ResourceForm : public Form { 409 public: 410 unsigned mask() const { return _resmask; }; 411 412 private: 413 // Public Data 414 unsigned _resmask; // Resource Mask (OR of resource specifier bits) 415 416 public: 417 418 // Virtual Methods 419 virtual ResourceForm *is_resource() const; 420 421 // Public Methods 422 ResourceForm(unsigned resmask); // Constructor 423 ~ResourceForm(); // Destructor 424 425 void dump(); // Debug printer 426 void output(FILE *fp); // Write info to output files 427 }; 428 429 //------------------------------PipeClassOperandForm----------------------------- 430 class PipeClassOperandForm : public Form { 431 private: 432 433 public: 434 // Public Data 435 const char *_stage; // Name of Stage 436 unsigned _iswrite; // Read or Write 437 unsigned _more_instrs; // Additional Instructions 438 439 // Public Methods 440 PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs) 441 : _stage(stage) 442 , _iswrite(iswrite) 443 , _more_instrs(more_instrs) 444 {}; 445 446 ~PipeClassOperandForm() {}; // Destructor 447 448 bool isWrite() const { return _iswrite != 0; } 449 450 void dump(); // Debug printer 451 void output(FILE *fp); // Write info to output files 452 }; 453 454 //------------------------------PipeClassResourceForm-------------------------- 455 class PipeClassResourceForm : public Form { 456 private: 457 458 public: 459 // Public Data 460 const char *_resource; // Resource 461 const char *_stage; // Stage the resource is used in 462 int _cycles; // Number of cycles the resource is used 463 464 // Public Methods 465 PipeClassResourceForm(const char *resource, const char *stage, int cycles) 466 // Constructor 467 : _resource(resource) 468 , _stage(stage) 469 , _cycles(cycles) 470 {}; 471 472 ~PipeClassResourceForm() {}; // Destructor 473 474 void dump(); // Debug printer 475 void output(FILE *fp); // Write info to output files 476 }; 477 478 //------------------------------PipeClassForm---------------------------------- 479 class PipeClassForm : public Form { 480 private: 481 482 public: 483 484 // Public Data 485 const char *_ident; // Name of class 486 int _num; // Used in name of MachNode subclass 487 NameList _parameters; // Locally defined names 488 FormDict _localNames; // Table of operands & their types 489 FormDict _localUsage; // Table of operand usage 490 FormList _resUsage; // List of resource usage 491 NameList _instructs; // List of instructions and machine nodes that use this pipeline class 492 bool _has_fixed_latency; // Always takes this number of cycles 493 int _fixed_latency; // Always takes this number of cycles 494 int _instruction_count; // Number of instructions in first bundle 495 bool _has_multiple_bundles; // Indicates if 1 or multiple bundles 496 bool _has_branch_delay_slot; // Has branch delay slot as last instruction 497 bool _force_serialization; // This node serializes relative to surrounding nodes 498 bool _may_have_no_code; // This node may generate no code based on register allocation 499 500 // Virtual Methods 501 virtual PipeClassForm *is_pipeclass() const; 502 503 // Public Methods 504 PipeClassForm(const char *id, int num); 505 // Constructor 506 ~PipeClassForm(); // Destructor 507 508 bool hasFixedLatency() { return _has_fixed_latency; } 509 int fixedLatency() { return _fixed_latency; } 510 511 void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; } 512 513 void setInstructionCount(int i) { _instruction_count = i; } 514 void setMultipleBundles(bool b) { _has_multiple_bundles = b; } 515 void setBranchDelay(bool s) { _has_branch_delay_slot = s; } 516 void setForceSerialization(bool s) { _force_serialization = s; } 517 void setMayHaveNoCode(bool s) { _may_have_no_code = s; } 518 519 int InstructionCount() const { return _instruction_count; } 520 bool hasMultipleBundles() const { return _has_multiple_bundles; } 521 bool hasBranchDelay() const { return _has_branch_delay_slot; } 522 bool forceSerialization() const { return _force_serialization; } 523 bool mayHaveNoCode() const { return _may_have_no_code; } 524 525 void dump(); // Debug printer 526 void output(FILE *fp); // Write info to output files 527 }; 528 529 530 //==============================Peephole Optimization========================== 531 //------------------------------Peephole--------------------------------------- 532 class Peephole : public Form { 533 private: 534 static int _peephole_counter;// Incremented by each peephole rule parsed 535 int _peephole_number;// Remember my order in architecture description 536 PeepMatch *_match; // Instruction pattern to match 537 PeepConstraint *_constraint; // List of additional constraints 538 PeepReplace *_replace; // Instruction pattern to substitute in 539 540 Peephole *_next; 541 542 public: 543 // Public Methods 544 Peephole(); 545 ~Peephole(); 546 547 // Append a peephole rule with the same root instruction 548 void append_peephole(Peephole *next_peephole); 549 550 // Store the components of this peephole rule 551 void add_match(PeepMatch *only_one_match); 552 void append_constraint(PeepConstraint *next_constraint); 553 void add_replace(PeepReplace *only_one_replacement); 554 555 // Access the components of this peephole rule 556 int peephole_number() { return _peephole_number; } 557 PeepMatch *match() { return _match; } 558 PeepConstraint *constraints() { return _constraint; } 559 PeepReplace *replacement() { return _replace; } 560 Peephole *next() { return _next; } 561 562 void dump(); // Debug printer 563 void output(FILE *fp); // Write info to output files 564 }; 565 566 567 class PeepMatch : public Form { 568 private: 569 char *_rule; 570 // NameList _depth; // Depth of this instruction 571 NameList _parent; 572 NameList _position; 573 NameList _instrs; // List of instructions in match rule 574 NameList _input; // input position in parent's instruction 575 int _max_position; 576 577 public: 578 // Public Methods 579 PeepMatch(char *rule); 580 ~PeepMatch(); 581 582 // Insert info into the match-rule 583 void add_instruction(int parent, int position, const char *name, int input); 584 585 // Access info about instructions in the peep-match rule 586 int max_position(); 587 const char *instruction_name(int position); 588 // Iterate through all info on matched instructions 589 void reset(); 590 void next_instruction(int &parent, int &position, const char* &name, int &input); 591 // 'true' if current position in iteration is a placeholder, not matched. 592 bool is_placeholder(); 593 594 void dump(); 595 void output(FILE *fp); 596 }; 597 598 599 class PeepConstraint : public Form { 600 private: 601 PeepConstraint *_next; // Additional constraints ANDed together 602 603 public: 604 const int _left_inst; 605 const char* _left_op; 606 const char* _relation; 607 const int _right_inst; 608 const char* _right_op; 609 610 public: 611 // Public Methods 612 PeepConstraint(int left_inst, char* left_op, char* relation, 613 int right_inst, char* right_op); 614 ~PeepConstraint(); 615 616 // Check if constraints use instruction at position 617 bool constrains_instruction(int position); 618 619 // Add another constraint 620 void append(PeepConstraint *next_peep_constraint); 621 // Access the next constraint in the list 622 PeepConstraint *next(); 623 624 void dump(); 625 void output(FILE *fp); 626 }; 627 628 629 class PeepReplace : public Form { 630 private: 631 char *_rule; 632 NameList _instruction; 633 NameList _operand_inst_num; 634 NameList _operand_op_name; 635 636 public: 637 638 // Public Methods 639 PeepReplace(char *rule); 640 ~PeepReplace(); 641 642 // Add contents of peepreplace 643 void add_instruction(char *root); 644 void add_operand( int inst_num, char *inst_operand ); 645 646 // Access contents of peepreplace 647 void reset(); 648 void next_instruction(const char * &root); 649 void next_operand(int &inst_num, const char * &inst_operand ); 650 651 // Utilities 652 void dump(); 653 void output(FILE *fp); 654 }; 655 656 657 class PeepChild : public Form { 658 public: 659 const int _inst_num; // Number of instruction (-1 if only named) 660 const char *_inst_op; // Instruction's operand, NULL if number == -1 661 const char *_inst_name; // Name of the instruction 662 663 public: 664 PeepChild(char *inst_name) 665 : _inst_num(-1), _inst_op(NULL), _inst_name(inst_name) {}; 666 PeepChild(int inst_num, char *inst_op, char *inst_name) 667 : _inst_num(inst_num), _inst_op(inst_op), _inst_name(inst_name) {}; 668 ~PeepChild(); 669 670 bool use_leaf_operand() { return _inst_num != -1; }; 671 bool generate_an_instruction() { return _inst_num == -1; } 672 673 void dump(); 674 void output(FILE *fp); 675 }; 676 677 #endif // SHARE_ADLC_FORMSOPT_HPP