Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/adlc/formsopt.hpp
41144 views
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
202
virtual bool has_stack_version() {
203
return _stack_or_reg;
204
}
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
240
void set_code_snippet(char* code) {
241
_code_snippet = code;
242
}
243
char* code_snippet() {
244
return _code_snippet;
245
}
246
void declare_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
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);
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
}
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
}
301
void set_condition_code(char* code) {
302
_condition_code = code;
303
}
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
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:
403
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
433
PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs)
434
: _stage(stage)
435
, _iswrite(iswrite)
436
, _more_instrs(more_instrs)
437
{};
438
439
~PipeClassOperandForm() {}; // Destructor
440
441
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
458
PipeClassResourceForm(const char *resource, const char *stage, int cycles)
459
// Constructor
460
: _resource(resource)
461
, _stage(stage)
462
, _cycles(cycles)
463
{};
464
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
501
bool hasFixedLatency() { return _has_fixed_latency; }
502
int fixedLatency() { return _fixed_latency; }
503
504
void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; }
505
506
void setInstructionCount(int i) { _instruction_count = i; }
507
void setMultipleBundles(bool b) { _has_multiple_bundles = b; }
508
void setBranchDelay(bool s) { _has_branch_delay_slot = s; }
509
void setForceSerialization(bool s) { _force_serialization = s; }
510
void setMayHaveNoCode(bool s) { _may_have_no_code = s; }
511
512
int InstructionCount() const { return _instruction_count; }
513
bool hasMultipleBundles() const { return _has_multiple_bundles; }
514
bool hasBranchDelay() const { return _has_branch_delay_slot; }
515
bool forceSerialization() const { return _force_serialization; }
516
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
549
int peephole_number() { return _peephole_number; }
550
PeepMatch *match() { return _match; }
551
PeepConstraint *constraints() { return _constraint; }
552
PeepReplace *replacement() { return _replace; }
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:
657
PeepChild(char *inst_name)
658
: _inst_num(-1), _inst_op(NULL), _inst_name(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
663
bool use_leaf_operand() { return _inst_num != -1; };
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
672