Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/adlc/formsopt.hpp
32285 views
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
*/
24
25
#ifndef SHARE_VM_ADLC_FORMSOPT_HPP
26
#define SHARE_VM_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_VM_ADLC_FORMSOPT_HPP
678
679