src/share/vm/adlc/formsopt.hpp

Wed, 31 Jan 2018 19:24:57 -0500

author
dbuck
date
Wed, 31 Jan 2018 19:24:57 -0500
changeset 9289
427b2fb1944f
parent 7853
a1642365d69f
child 7994
04ff2f6cd0eb
permissions
-rw-r--r--

8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed

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

mercurial