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