Wed, 31 Jan 2018 19:24:57 -0500
8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed
1 /*
2 * Copyright (c) 1998, 2010, 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 */
25 #ifndef SHARE_VM_ADLC_FORMSOPT_HPP
26 #define SHARE_VM_ADLC_FORMSOPT_HPP
28 // FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes
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;
75 class ArchDesc;
77 //==============================Register Allocation============================
78 //------------------------------RegisterForm-----------------------------------
79 class RegisterForm : public Form {
80 private:
81 AllocClass *_current_ac; // State used by iter_RegDefs()
83 public:
84 // Public Data
85 NameList _rdefs; // List of register definition names
86 Dict _regDef; // map register name to RegDef*
88 NameList _rclasses; // List of register class names
89 Dict _regClass; // map register class name to RegClass*
91 NameList _aclasses; // List of allocation class names
92 Dict _allocClass; // Dictionary of allocation classes
94 static int _reg_ctr; // Register counter
95 static int RegMask_Size(); // Compute RegMask size
97 // Public Methods
98 RegisterForm();
99 ~RegisterForm();
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);
105 AllocClass *addAllocClass(char *allocName);
106 void addSpillRegClass();
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);
114 RegClass *getRegClass(const char *className);
116 // Return register mask, compressed chunk and register #
117 uint reg_mask(char *register_class);
119 // Check that register classes are compatible with chunks
120 bool verify();
122 void dump(); // Debug printer
123 void output(FILE *fp); // Write info to output files
124 };
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
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
141 public:
142 // Public Methods
143 RegDef(char *regname, char *callconv, char *c_conv,
144 char *idealtype, char *encoding, char *concrete);
145 ~RegDef(); // Destructor
147 // Interface to define/redefine the register number
148 void set_register_num(uint32 new_register_num);
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;
155 void dump(); // Debug printer
156 void output(FILE *fp); // Write info to output files
157 };
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
178 public:
179 // Public Methods
180 RegClass(const char *classid);// Constructor
181 virtual ~RegClass();
183 void addReg(RegDef *regDef); // Add a register to this class
185 uint size() const; // Number of registers in class
186 int regs_in_word( int wordnum, bool stack_also );
188 const RegDef *get_RegDef(const char *regDef_name) const;
190 // Returns the lowest numbered register in the mask.
191 const RegDef* find_first_elem();
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.
198 void dump(); // Debug printer
199 void output(FILE *fp); // Write info to output files
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 }
208 virtual void declare_register_masks(FILE* fp);
209 virtual void build_register_masks(FILE* fp);
210 };
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();
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 };
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.
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();
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 };
311 //------------------------------AllocClass-------------------------------------
312 class AllocClass : public Form {
313 private:
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
321 // Public Methods
322 AllocClass(char *classid); // Constructor
324 void addReg(RegDef *regDef); // Add a register to this class
325 uint size() {return _regDef.Size();} // Number of registers in class
327 void dump(); // Debug printer
328 void output(FILE *fp); // Write info to output files
329 };
332 //==============================Frame Handling================================
333 //------------------------------FrameForm-------------------------------------
334 class FrameForm : public Form {
335 private:
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;
359 // Public Methods
360 FrameForm();
361 ~FrameForm();
363 void dump(); // Debug printer
364 void output(FILE *fp); // Write info to output files
365 };
368 //==============================Scheduling=====================================
369 //------------------------------PipelineForm-----------------------------------
370 class PipelineForm : public Form {
371 private:
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
380 NameList _stages; // List of pipeline stages on architecture
381 int _stagecnt; // Number of stages listed
383 NameList _classlist; // List of pipeline classes
384 FormDict _classdict; // Class Name -> PipeClassForm mapping
385 int _classcnt; // Number of classes
387 NameList _noplist; // List of NOP instructions
388 int _nopcnt; // Number of nop instructions
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
399 // Public Methods
400 PipelineForm();
401 ~PipelineForm();
403 void dump(); // Debug printer
404 void output(FILE *fp); // Write info to output files
405 };
407 //------------------------------ResourceForm-----------------------------------
408 class ResourceForm : public Form {
409 public:
410 unsigned mask() const { return _resmask; };
412 private:
413 // Public Data
414 unsigned _resmask; // Resource Mask (OR of resource specifier bits)
416 public:
418 // Virtual Methods
419 virtual ResourceForm *is_resource() const;
421 // Public Methods
422 ResourceForm(unsigned resmask); // Constructor
423 ~ResourceForm(); // Destructor
425 void dump(); // Debug printer
426 void output(FILE *fp); // Write info to output files
427 };
429 //------------------------------PipeClassOperandForm-----------------------------
430 class PipeClassOperandForm : public Form {
431 private:
433 public:
434 // Public Data
435 const char *_stage; // Name of Stage
436 unsigned _iswrite; // Read or Write
437 unsigned _more_instrs; // Additional Instructions
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 {};
446 ~PipeClassOperandForm() {}; // Destructor
448 bool isWrite() const { return _iswrite != 0; }
450 void dump(); // Debug printer
451 void output(FILE *fp); // Write info to output files
452 };
454 //------------------------------PipeClassResourceForm--------------------------
455 class PipeClassResourceForm : public Form {
456 private:
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
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 {};
472 ~PipeClassResourceForm() {}; // Destructor
474 void dump(); // Debug printer
475 void output(FILE *fp); // Write info to output files
476 };
478 //------------------------------PipeClassForm----------------------------------
479 class PipeClassForm : public Form {
480 private:
482 public:
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
500 // Virtual Methods
501 virtual PipeClassForm *is_pipeclass() const;
503 // Public Methods
504 PipeClassForm(const char *id, int num);
505 // Constructor
506 ~PipeClassForm(); // Destructor
508 bool hasFixedLatency() { return _has_fixed_latency; }
509 int fixedLatency() { return _fixed_latency; }
511 void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; }
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; }
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; }
525 void dump(); // Debug printer
526 void output(FILE *fp); // Write info to output files
527 };
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
540 Peephole *_next;
542 public:
543 // Public Methods
544 Peephole();
545 ~Peephole();
547 // Append a peephole rule with the same root instruction
548 void append_peephole(Peephole *next_peephole);
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);
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; }
562 void dump(); // Debug printer
563 void output(FILE *fp); // Write info to output files
564 };
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;
577 public:
578 // Public Methods
579 PeepMatch(char *rule);
580 ~PeepMatch();
582 // Insert info into the match-rule
583 void add_instruction(int parent, int position, const char *name, int input);
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();
594 void dump();
595 void output(FILE *fp);
596 };
599 class PeepConstraint : public Form {
600 private:
601 PeepConstraint *_next; // Additional constraints ANDed together
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;
610 public:
611 // Public Methods
612 PeepConstraint(int left_inst, char* left_op, char* relation,
613 int right_inst, char* right_op);
614 ~PeepConstraint();
616 // Check if constraints use instruction at position
617 bool constrains_instruction(int position);
619 // Add another constraint
620 void append(PeepConstraint *next_peep_constraint);
621 // Access the next constraint in the list
622 PeepConstraint *next();
624 void dump();
625 void output(FILE *fp);
626 };
629 class PeepReplace : public Form {
630 private:
631 char *_rule;
632 NameList _instruction;
633 NameList _operand_inst_num;
634 NameList _operand_op_name;
636 public:
638 // Public Methods
639 PeepReplace(char *rule);
640 ~PeepReplace();
642 // Add contents of peepreplace
643 void add_instruction(char *root);
644 void add_operand( int inst_num, char *inst_operand );
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 );
651 // Utilities
652 void dump();
653 void output(FILE *fp);
654 };
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
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();
670 bool use_leaf_operand() { return _inst_num != -1; };
671 bool generate_an_instruction() { return _inst_num == -1; }
673 void dump();
674 void output(FILE *fp);
675 };
677 #endif // SHARE_VM_ADLC_FORMSOPT_HPP