Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/c1/c1_LinearScan.hpp
40931 views
1
/*
2
* Copyright (c) 2005, 2021, 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_C1_C1_LINEARSCAN_HPP
26
#define SHARE_C1_C1_LINEARSCAN_HPP
27
28
#include "c1/c1_FpuStackSim.hpp"
29
#include "c1/c1_FrameMap.hpp"
30
#include "c1/c1_IR.hpp"
31
#include "c1/c1_Instruction.hpp"
32
#include "c1/c1_LIR.hpp"
33
#include "c1/c1_LIRGenerator.hpp"
34
#include "compiler/oopMap.hpp"
35
#include "utilities/align.hpp"
36
#include "utilities/macros.hpp"
37
38
class FpuStackAllocator;
39
class IRScopeDebugInfo;
40
class Interval;
41
class IntervalWalker;
42
class LIRGenerator;
43
class LinearScan;
44
class MoveResolver;
45
class Range;
46
47
typedef GrowableArray<Interval*> IntervalArray;
48
typedef GrowableArray<Interval*> IntervalList;
49
typedef GrowableArray<IntervalList*> IntervalsList;
50
typedef GrowableArray<ScopeValue*> ScopeValueArray;
51
typedef GrowableArray<LIR_OpList*> LIR_OpListStack;
52
53
enum IntervalUseKind {
54
// priority of use kinds must be ascending
55
noUse = 0,
56
loopEndMarker = 1,
57
shouldHaveRegister = 2,
58
mustHaveRegister = 3,
59
60
firstValidKind = 1,
61
lastValidKind = 3
62
};
63
64
enum IntervalKind {
65
fixedKind = 0, // interval pre-colored by LIR_Generator
66
anyKind = 1, // no register/memory allocated by LIR_Generator
67
nofKinds,
68
firstKind = fixedKind
69
};
70
71
72
// during linear scan an interval is in one of four states in
73
enum IntervalState {
74
unhandledState = 0, // unhandled state (not processed yet)
75
activeState = 1, // life and is in a physical register
76
inactiveState = 2, // in a life time hole and is in a physical register
77
handledState = 3, // spilled or not life again
78
invalidState = -1
79
};
80
81
82
enum IntervalSpillState {
83
noDefinitionFound, // starting state of calculation: no definition found yet
84
oneDefinitionFound, // one definition has already been found.
85
// Note: two consecutive definitions are treated as one (e.g. consecutive move and add because of two-operand LIR form)
86
// the position of this definition is stored in _definition_pos
87
oneMoveInserted, // one spill move has already been inserted.
88
storeAtDefinition, // the interval should be stored immediately after its definition because otherwise
89
// there would be multiple redundant stores
90
startInMemory, // the interval starts in memory (e.g. method parameter), so a store is never necessary
91
noOptimization // the interval has more then one definition (e.g. resulting from phi moves), so stores to memory are not optimized
92
};
93
94
95
#define for_each_interval_kind(kind) \
96
for (IntervalKind kind = firstKind; kind < nofKinds; kind = (IntervalKind)(kind + 1))
97
98
#define for_each_visitor_mode(mode) \
99
for (LIR_OpVisitState::OprMode mode = LIR_OpVisitState::firstMode; mode < LIR_OpVisitState::numModes; mode = (LIR_OpVisitState::OprMode)(mode + 1))
100
101
102
class LinearScan : public CompilationResourceObj {
103
// declare classes used by LinearScan as friends because they
104
// need a wide variety of functions declared here
105
//
106
// Only the small interface to the rest of the compiler is public
107
friend class Interval;
108
friend class IntervalWalker;
109
friend class LinearScanWalker;
110
friend class FpuStackAllocator;
111
friend class MoveResolver;
112
friend class LinearScanStatistic;
113
friend class LinearScanTimers;
114
friend class RegisterVerifier;
115
116
public:
117
enum {
118
any_reg = -1,
119
nof_cpu_regs = pd_nof_cpu_regs_linearscan,
120
nof_fpu_regs = pd_nof_fpu_regs_linearscan,
121
nof_xmm_regs = pd_nof_xmm_regs_linearscan,
122
nof_regs = nof_cpu_regs + nof_fpu_regs + nof_xmm_regs
123
};
124
125
private:
126
Compilation* _compilation;
127
IR* _ir;
128
LIRGenerator* _gen;
129
FrameMap* _frame_map;
130
131
BlockList _cached_blocks; // cached list with all blocks in linear-scan order (only correct if original list keeps unchanged)
132
int _num_virtual_regs; // number of virtual registers (without new registers introduced because of splitting intervals)
133
bool _has_fpu_registers; // true if this method uses any floating point registers (and so fpu stack allocation is necessary)
134
int _num_calls; // total number of calls in this method
135
int _max_spills; // number of stack slots used for intervals allocated to memory
136
int _unused_spill_slot; // unused spill slot for a single-word value because of alignment of a double-word value
137
138
IntervalList _intervals; // mapping from register number to interval
139
IntervalList* _new_intervals_from_allocation; // list with all intervals created during allocation when an existing interval is split
140
IntervalArray* _sorted_intervals; // intervals sorted by Interval::from()
141
bool _needs_full_resort; // set to true if an Interval::from() is changed and _sorted_intervals must be resorted
142
143
LIR_OpArray _lir_ops; // mapping from LIR_Op id to LIR_Op node
144
BlockBeginArray _block_of_op; // mapping from LIR_Op id to the BlockBegin containing this instruction
145
ResourceBitMap _has_info; // bit set for each LIR_Op id that has a CodeEmitInfo
146
ResourceBitMap _has_call; // bit set for each LIR_Op id that destroys all caller save registers
147
BitMap2D _interval_in_loop; // bit set for each virtual register that is contained in each loop
148
149
// cached debug info to prevent multiple creation of same object
150
// TODO: cached scope values for registers could be static
151
ScopeValueArray _scope_value_cache;
152
153
static ConstantOopWriteValue* _oop_null_scope_value;
154
static ConstantIntValue* _int_m1_scope_value;
155
static ConstantIntValue* _int_0_scope_value;
156
static ConstantIntValue* _int_1_scope_value;
157
static ConstantIntValue* _int_2_scope_value;
158
159
// accessors
160
IR* ir() const { return _ir; }
161
Compilation* compilation() const { return _compilation; }
162
LIRGenerator* gen() const { return _gen; }
163
FrameMap* frame_map() const { return _frame_map; }
164
165
// unified bailout support
166
void bailout(const char* msg) const { compilation()->bailout(msg); }
167
bool bailed_out() const { return compilation()->bailed_out(); }
168
169
// access to block list (sorted in linear scan order)
170
int block_count() const { assert(_cached_blocks.length() == ir()->linear_scan_order()->length(), "invalid cached block list"); return _cached_blocks.length(); }
171
BlockBegin* block_at(int idx) const { assert(_cached_blocks.at(idx) == ir()->linear_scan_order()->at(idx), "invalid cached block list"); return _cached_blocks.at(idx); }
172
173
int num_virtual_regs() const { return _num_virtual_regs; }
174
// size of live_in and live_out sets of BasicBlocks (BitMap needs rounded size for iteration)
175
int live_set_size() const { return align_up(_num_virtual_regs, BitsPerWord); }
176
bool has_fpu_registers() const { return _has_fpu_registers; }
177
int num_loops() const { return ir()->num_loops(); }
178
bool is_interval_in_loop(int interval, int loop) const { return _interval_in_loop.at(interval, loop); }
179
180
// handling of fpu stack allocation (platform dependent, needed for debug information generation)
181
#ifdef IA32
182
FpuStackAllocator* _fpu_stack_allocator;
183
bool use_fpu_stack_allocation() const { return UseSSE < 2 && has_fpu_registers(); }
184
#else
185
bool use_fpu_stack_allocation() const { return false; }
186
#endif
187
188
189
// access to interval list
190
int interval_count() const { return _intervals.length(); }
191
Interval* interval_at(int reg_num) const { return _intervals.at(reg_num); }
192
193
// access to LIR_Ops and Blocks indexed by op_id
194
int max_lir_op_id() const { assert(_lir_ops.length() > 0, "no operations"); return (_lir_ops.length() - 1) << 1; }
195
LIR_Op* lir_op_with_id(int op_id) const { assert(op_id >= 0 && op_id <= max_lir_op_id() && op_id % 2 == 0, "op_id out of range or not even"); return _lir_ops.at(op_id >> 1); }
196
BlockBegin* block_of_op_with_id(int op_id) const { assert(_block_of_op.length() > 0 && op_id >= 0 && op_id <= max_lir_op_id() + 1, "op_id out of range"); return _block_of_op.at(op_id >> 1); }
197
198
bool is_block_begin(int op_id) { return op_id == 0 || block_of_op_with_id(op_id) != block_of_op_with_id(op_id - 1); }
199
200
bool has_call(int op_id) { assert(op_id % 2 == 0, "must be even"); return _has_call.at(op_id >> 1); }
201
bool has_info(int op_id) { assert(op_id % 2 == 0, "must be even"); return _has_info.at(op_id >> 1); }
202
203
204
// functions for converting LIR-Operands to register numbers
205
static bool is_valid_reg_num(int reg_num) { return reg_num >= 0; }
206
static int reg_num(LIR_Opr opr);
207
static int reg_numHi(LIR_Opr opr);
208
209
// functions for classification of intervals
210
static bool is_precolored_interval(const Interval* i);
211
static bool is_virtual_interval(const Interval* i);
212
213
static bool is_precolored_cpu_interval(const Interval* i);
214
static bool is_virtual_cpu_interval(const Interval* i);
215
static bool is_precolored_fpu_interval(const Interval* i);
216
static bool is_virtual_fpu_interval(const Interval* i);
217
218
static bool is_in_fpu_register(const Interval* i);
219
static bool is_oop_interval(const Interval* i);
220
221
222
// General helper functions
223
int allocate_spill_slot(bool double_word);
224
void assign_spill_slot(Interval* it);
225
void propagate_spill_slots();
226
227
Interval* create_interval(int reg_num);
228
void append_interval(Interval* it);
229
void copy_register_flags(Interval* from, Interval* to);
230
231
// platform dependent functions
232
static bool is_processed_reg_num(int reg_num);
233
static int num_physical_regs(BasicType type);
234
static bool requires_adjacent_regs(BasicType type);
235
static bool is_caller_save(int assigned_reg);
236
237
// spill move optimization: eliminate moves from register to stack if
238
// stack slot is known to be correct
239
void change_spill_definition_pos(Interval* interval, int def_pos);
240
void change_spill_state(Interval* interval, int spill_pos);
241
static bool must_store_at_definition(const Interval* i);
242
void eliminate_spill_moves();
243
244
// Phase 1: number all instructions in all blocks
245
void number_instructions();
246
247
// Phase 2: compute local live sets separately for each block
248
// (sets live_gen and live_kill for each block)
249
//
250
// helper methods used by compute_local_live_sets()
251
void set_live_gen_kill(Value value, LIR_Op* op, BitMap& live_gen, BitMap& live_kill);
252
253
void compute_local_live_sets();
254
255
// Phase 3: perform a backward dataflow analysis to compute global live sets
256
// (sets live_in and live_out for each block)
257
void compute_global_live_sets();
258
259
260
// Phase 4: build intervals
261
// (fills the list _intervals)
262
//
263
// helper methods used by build_intervals()
264
void add_use (Value value, int from, int to, IntervalUseKind use_kind);
265
266
void add_def (LIR_Opr opr, int def_pos, IntervalUseKind use_kind);
267
void add_use (LIR_Opr opr, int from, int to, IntervalUseKind use_kind);
268
void add_temp(LIR_Opr opr, int temp_pos, IntervalUseKind use_kind);
269
270
void add_def (int reg_num, int def_pos, IntervalUseKind use_kind, BasicType type);
271
void add_use (int reg_num, int from, int to, IntervalUseKind use_kind, BasicType type);
272
void add_temp(int reg_num, int temp_pos, IntervalUseKind use_kind, BasicType type);
273
274
// Add platform dependent kills for particular LIR ops. Can be used
275
// to add platform dependent behaviour for some operations.
276
void pd_add_temps(LIR_Op* op);
277
278
IntervalUseKind use_kind_of_output_operand(LIR_Op* op, LIR_Opr opr);
279
IntervalUseKind use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr);
280
void handle_method_arguments(LIR_Op* op);
281
void handle_doubleword_moves(LIR_Op* op);
282
void add_register_hints(LIR_Op* op);
283
284
void build_intervals();
285
286
287
// Phase 5: actual register allocation
288
// (Uses LinearScanWalker)
289
//
290
// helper functions for building a sorted list of intervals
291
NOT_PRODUCT(bool is_sorted(IntervalArray* intervals);)
292
static int interval_cmp(Interval** a, Interval** b);
293
void add_to_list(Interval** first, Interval** prev, Interval* interval);
294
void create_unhandled_lists(Interval** list1, Interval** list2, bool (is_list1)(const Interval* i), bool (is_list2)(const Interval* i));
295
296
void sort_intervals_before_allocation();
297
void sort_intervals_after_allocation();
298
void allocate_registers();
299
300
301
// Phase 6: resolve data flow
302
// (insert moves at edges between blocks if intervals have been split)
303
//
304
// helper functions for resolve_data_flow()
305
Interval* split_child_at_op_id(Interval* interval, int op_id, LIR_OpVisitState::OprMode mode);
306
Interval* interval_at_block_begin(BlockBegin* block, int reg_num);
307
Interval* interval_at_block_end(BlockBegin* block, int reg_num);
308
Interval* interval_at_op_id(int reg_num, int op_id);
309
void resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver);
310
void resolve_find_insert_pos(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver);
311
void resolve_data_flow();
312
313
void resolve_exception_entry(BlockBegin* block, int reg_num, MoveResolver &move_resolver);
314
void resolve_exception_entry(BlockBegin* block, MoveResolver &move_resolver);
315
void resolve_exception_edge(XHandler* handler, int throwing_op_id, int reg_num, Phi* phi, MoveResolver &move_resolver);
316
void resolve_exception_edge(XHandler* handler, int throwing_op_id, MoveResolver &move_resolver);
317
void resolve_exception_handlers();
318
319
// Phase 7: assign register numbers back to LIR
320
// (includes computation of debug information and oop maps)
321
//
322
// helper functions for assign_reg_num()
323
VMReg vm_reg_for_interval(Interval* interval);
324
VMReg vm_reg_for_operand(LIR_Opr opr);
325
326
static LIR_Opr operand_for_interval(Interval* interval);
327
static LIR_Opr calc_operand_for_interval(const Interval* interval);
328
LIR_Opr canonical_spill_opr(Interval* interval);
329
330
LIR_Opr color_lir_opr(LIR_Opr opr, int id, LIR_OpVisitState::OprMode);
331
332
// methods used for oop map computation
333
IntervalWalker* init_compute_oop_maps();
334
OopMap* compute_oop_map(IntervalWalker* iw, LIR_Op* op, CodeEmitInfo* info, bool is_call_site);
335
void compute_oop_map(IntervalWalker* iw, const LIR_OpVisitState &visitor, LIR_Op* op);
336
337
// methods used for debug information computation
338
void init_compute_debug_info();
339
340
MonitorValue* location_for_monitor_index(int monitor_index);
341
LocationValue* location_for_name(int name, Location::Type loc_type);
342
void set_oop(OopMap* map, VMReg name) {
343
if (map->legal_vm_reg_name(name)) {
344
map->set_oop(name);
345
} else {
346
bailout("illegal oopMap register name");
347
}
348
}
349
350
int append_scope_value_for_constant(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
351
int append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
352
int append_scope_value(int op_id, Value value, GrowableArray<ScopeValue*>* scope_values);
353
354
IRScopeDebugInfo* compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state);
355
void compute_debug_info(CodeEmitInfo* info, int op_id);
356
357
void assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw);
358
void assign_reg_num();
359
360
361
// Phase 8: fpu stack allocation
362
// (Used only on x86 when fpu operands are present)
363
void allocate_fpu_stack();
364
365
366
// helper functions for printing state
367
#ifndef PRODUCT
368
static void print_bitmap(BitMap& bitmap);
369
void print_intervals(const char* label);
370
void print_lir(int level, const char* label, bool hir_valid = true);
371
static void print_reg_num(int reg_num) { print_reg_num(tty, reg_num); }
372
static void print_reg_num(outputStream* out, int reg_num);
373
static LIR_Opr get_operand(int reg_num);
374
#endif
375
376
#ifdef ASSERT
377
// verification functions for allocation
378
// (check that all intervals have a correct register and that no registers are overwritten)
379
void verify();
380
void verify_intervals();
381
void verify_no_oops_in_fixed_intervals();
382
void verify_constants();
383
void verify_registers();
384
#endif
385
386
public:
387
// creation
388
LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map);
389
390
// main entry function: perform linear scan register allocation
391
void do_linear_scan();
392
393
// accessors used by Compilation
394
int max_spills() const { return _max_spills; }
395
int num_calls() const { assert(_num_calls >= 0, "not set"); return _num_calls; }
396
397
#ifndef PRODUCT
398
// entry functions for printing
399
static void print_statistics();
400
static void print_timers(double total);
401
402
// Used for debugging
403
Interval* find_interval_at(int reg_num) const;
404
#endif
405
};
406
407
408
// Helper class for ordering moves that are inserted at the same position in the LIR
409
// When moves between registers are inserted, it is important that the moves are
410
// ordered such that no register is overwritten. So moves from register to stack
411
// are processed prior to moves from stack to register. When moves have circular
412
// dependencies, a temporary stack slot is used to break the circle.
413
// The same logic is used in the LinearScanWalker and in LinearScan during resolve_data_flow
414
// and therefore factored out in a separate class
415
class MoveResolver: public StackObj {
416
private:
417
LinearScan* _allocator;
418
419
LIR_List* _insert_list;
420
int _insert_idx;
421
LIR_InsertionBuffer _insertion_buffer; // buffer where moves are inserted
422
423
IntervalList _mapping_from;
424
LIR_OprList _mapping_from_opr;
425
IntervalList _mapping_to;
426
bool _multiple_reads_allowed;
427
int _register_blocked[LinearScan::nof_regs];
428
429
int register_blocked(int reg) { assert(reg >= 0 && reg < LinearScan::nof_regs, "out of bounds"); return _register_blocked[reg]; }
430
void set_register_blocked(int reg, int direction) { assert(reg >= 0 && reg < LinearScan::nof_regs, "out of bounds"); assert(direction == 1 || direction == -1, "out of bounds"); _register_blocked[reg] += direction; }
431
432
void block_registers(Interval* it);
433
void unblock_registers(Interval* it);
434
bool save_to_process_move(Interval* from, Interval* to);
435
436
void create_insertion_buffer(LIR_List* list);
437
void append_insertion_buffer();
438
void insert_move(Interval* from_interval, Interval* to_interval);
439
void insert_move(LIR_Opr from_opr, Interval* to_interval);
440
LIR_Opr get_virtual_register(Interval* interval);
441
442
DEBUG_ONLY(void verify_before_resolve();)
443
void resolve_mappings();
444
public:
445
MoveResolver(LinearScan* allocator);
446
447
DEBUG_ONLY(void check_empty();)
448
void set_multiple_reads_allowed() { _multiple_reads_allowed = true; }
449
void set_insert_position(LIR_List* insert_list, int insert_idx);
450
void move_insert_position(LIR_List* insert_list, int insert_idx);
451
void add_mapping(Interval* from, Interval* to);
452
void add_mapping(LIR_Opr from, Interval* to);
453
void resolve_and_append_moves();
454
455
LinearScan* allocator() { return _allocator; }
456
bool has_mappings() { return _mapping_from.length() > 0; }
457
};
458
459
460
class Range : public CompilationResourceObj {
461
friend class Interval;
462
463
private:
464
static Range* _end; // sentinel (from == to == max_jint)
465
466
int _from; // from (inclusive)
467
int _to; // to (exclusive)
468
Range* _next; // linear list of Ranges
469
470
// used only by class Interval, so hide them
471
bool intersects(Range* r) const { return intersects_at(r) != -1; }
472
int intersects_at(Range* r) const;
473
474
public:
475
Range(int from, int to, Range* next);
476
477
static void initialize(Arena* arena);
478
static Range* end() { return _end; }
479
480
int from() const { return _from; }
481
int to() const { return _to; }
482
Range* next() const { return _next; }
483
void set_from(int from) { _from = from; }
484
void set_to(int to) { _to = to; }
485
void set_next(Range* next) { _next = next; }
486
487
// for testing
488
void print(outputStream* out = tty) const PRODUCT_RETURN;
489
};
490
491
492
// Interval is an ordered list of disjoint ranges.
493
494
// For pre-colored double word LIR_Oprs, one interval is created for
495
// the low word register and one is created for the hi word register.
496
// On Intel for FPU double registers only one interval is created. At
497
// all times assigned_reg contains the reg. number of the physical
498
// register.
499
500
// For LIR_Opr in virtual registers a single interval can represent
501
// single and double word values. When a physical register is
502
// assigned to the interval, assigned_reg contains the
503
// phys. reg. number and for double word values assigned_regHi the
504
// phys. reg. number of the hi word if there is any. For spilled
505
// intervals assigned_reg contains the stack index. assigned_regHi is
506
// always -1.
507
508
class Interval : public CompilationResourceObj {
509
private:
510
static Interval* _end; // sentinel (interval with only range Range::end())
511
512
int _reg_num;
513
BasicType _type; // valid only for virtual registers
514
Range* _first; // sorted list of Ranges
515
intStack _use_pos_and_kinds; // sorted list of use-positions and their according use-kinds
516
517
Range* _current; // interval iteration: the current Range
518
Interval* _next; // interval iteration: sorted list of Intervals (ends with sentinel)
519
IntervalState _state; // interval iteration: to which set belongs this interval
520
521
522
int _assigned_reg;
523
int _assigned_regHi;
524
525
int _cached_to; // cached value: to of last range (-1: not cached)
526
LIR_Opr _cached_opr;
527
VMReg _cached_vm_reg;
528
529
Interval* _split_parent; // the original interval where this interval is derived from
530
IntervalList* _split_children; // list of all intervals that are split off from this interval (only available for split parents)
531
Interval* _current_split_child; // the current split child that has been active or inactive last (always stored in split parents)
532
533
int _canonical_spill_slot; // the stack slot where all split parts of this interval are spilled to (always stored in split parents)
534
bool _insert_move_when_activated; // true if move is inserted between _current_split_child and this interval when interval gets active the first time
535
IntervalSpillState _spill_state; // for spill move optimization
536
int _spill_definition_pos; // position where the interval is defined (if defined only once)
537
Interval* _register_hint; // this interval should be in the same register as the hint interval
538
539
int calc_to();
540
Interval* new_split_child();
541
public:
542
Interval(int reg_num);
543
544
static void initialize(Arena* arena);
545
static Interval* end() { return _end; }
546
547
// accessors
548
int reg_num() const { return _reg_num; }
549
void set_reg_num(int r) { assert(_reg_num == -1, "cannot change reg_num"); _reg_num = r; }
550
BasicType type() const { assert(_reg_num == -1 || _reg_num >= LIR_OprDesc::vreg_base, "cannot access type for fixed interval"); return _type; }
551
void set_type(BasicType type) { assert(_reg_num < LIR_OprDesc::vreg_base || _type == T_ILLEGAL || _type == type, "overwriting existing type"); _type = type; }
552
553
Range* first() const { return _first; }
554
int from() const { return _first->from(); }
555
int to() { if (_cached_to == -1) _cached_to = calc_to(); assert(_cached_to == calc_to(), "invalid cached value"); return _cached_to; }
556
557
#ifndef PRODUCT
558
int num_use_positions() const { return _use_pos_and_kinds.length() / 2; }
559
#endif
560
561
Interval* next() const { return _next; }
562
Interval** next_addr() { return &_next; }
563
void set_next(Interval* next) { _next = next; }
564
565
int assigned_reg() const { return _assigned_reg; }
566
int assigned_regHi() const { return _assigned_regHi; }
567
void assign_reg(int reg) { _assigned_reg = reg; _assigned_regHi = LinearScan::any_reg; }
568
void assign_reg(int reg,int regHi) { _assigned_reg = reg; _assigned_regHi = regHi; }
569
570
Interval* register_hint(bool search_split_child = true) const; // calculation needed
571
void set_register_hint(Interval* i) { _register_hint = i; }
572
573
int state() const { return _state; }
574
void set_state(IntervalState s) { _state = s; }
575
576
// access to split parent and split children
577
bool is_split_parent() const { return _split_parent == this; }
578
bool is_split_child() const { return _split_parent != this; }
579
Interval* split_parent() const { assert(_split_parent->is_split_parent(), "must be"); return _split_parent; }
580
Interval* split_child_at_op_id(int op_id, LIR_OpVisitState::OprMode mode);
581
Interval* split_child_before_op_id(int op_id);
582
DEBUG_ONLY(void check_split_children();)
583
584
// information stored in split parent, but available for all children
585
int canonical_spill_slot() const { return split_parent()->_canonical_spill_slot; }
586
void set_canonical_spill_slot(int slot) { assert(split_parent()->_canonical_spill_slot == -1, "overwriting existing value"); split_parent()->_canonical_spill_slot = slot; }
587
Interval* current_split_child() const { return split_parent()->_current_split_child; }
588
void make_current_split_child() { split_parent()->_current_split_child = this; }
589
590
bool insert_move_when_activated() const { return _insert_move_when_activated; }
591
void set_insert_move_when_activated(bool b) { _insert_move_when_activated = b; }
592
593
// for spill optimization
594
IntervalSpillState spill_state() const { return split_parent()->_spill_state; }
595
int spill_definition_pos() const { return split_parent()->_spill_definition_pos; }
596
void set_spill_state(IntervalSpillState state) { assert(state >= spill_state(), "state cannot decrease"); split_parent()->_spill_state = state; }
597
void set_spill_definition_pos(int pos) { assert(spill_definition_pos() == -1, "cannot set the position twice"); split_parent()->_spill_definition_pos = pos; }
598
// returns true if this interval has a shadow copy on the stack that is always correct
599
bool always_in_memory() const { return split_parent()->_spill_state == storeAtDefinition || split_parent()->_spill_state == startInMemory; }
600
601
// caching of values that take time to compute and are used multiple times
602
LIR_Opr cached_opr() const { return _cached_opr; }
603
VMReg cached_vm_reg() const { return _cached_vm_reg; }
604
void set_cached_opr(LIR_Opr opr) { _cached_opr = opr; }
605
void set_cached_vm_reg(VMReg reg) { _cached_vm_reg = reg; }
606
607
// access to use positions
608
int first_usage(IntervalUseKind min_use_kind) const; // id of the first operation requiring this interval in a register
609
int next_usage(IntervalUseKind min_use_kind, int from) const; // id of next usage seen from the given position
610
int next_usage_exact(IntervalUseKind exact_use_kind, int from) const;
611
int previous_usage(IntervalUseKind min_use_kind, int from) const;
612
613
// manipulating intervals
614
void add_use_pos(int pos, IntervalUseKind use_kind);
615
void add_range(int from, int to);
616
Interval* split(int split_pos);
617
Interval* split_from_start(int split_pos);
618
void remove_first_use_pos() { _use_pos_and_kinds.trunc_to(_use_pos_and_kinds.length() - 2); }
619
620
// test intersection
621
bool covers(int op_id, LIR_OpVisitState::OprMode mode) const;
622
bool has_hole_between(int from, int to);
623
bool intersects(Interval* i) const { return _first->intersects(i->_first); }
624
bool intersects_any_children_of(Interval* i) const;
625
int intersects_at(Interval* i) const { return _first->intersects_at(i->_first); }
626
627
// range iteration
628
void rewind_range() { _current = _first; }
629
void next_range() { assert(this != _end, "not allowed on sentinel"); _current = _current->next(); }
630
int current_from() const { return _current->from(); }
631
int current_to() const { return _current->to(); }
632
bool current_at_end() const { return _current == Range::end(); }
633
bool current_intersects(Interval* it) { return _current->intersects(it->_current); };
634
int current_intersects_at(Interval* it) { return _current->intersects_at(it->_current); };
635
636
// printing
637
#ifndef PRODUCT
638
void print() const { print_on(tty); }
639
void print_on(outputStream* out) const {
640
print_on(out, false);
641
}
642
// Special version for compatibility with C1 Visualizer.
643
void print_on(outputStream* out, bool is_cfg_printer) const;
644
645
// Used for debugging
646
void print_parent() const;
647
void print_children() const;
648
#endif
649
650
};
651
652
653
class IntervalWalker : public CompilationResourceObj {
654
protected:
655
Compilation* _compilation;
656
LinearScan* _allocator;
657
658
Interval* _unhandled_first[nofKinds]; // sorted list of intervals, not life before the current position
659
Interval* _active_first [nofKinds]; // sorted list of intervals, life at the current position
660
Interval* _inactive_first [nofKinds]; // sorted list of intervals, intervals in a life time hole at the current position
661
662
Interval* _current; // the current interval coming from unhandled list
663
int _current_position; // the current position (intercept point through the intervals)
664
IntervalKind _current_kind; // and whether it is fixed_kind or any_kind.
665
666
667
Compilation* compilation() const { return _compilation; }
668
LinearScan* allocator() const { return _allocator; }
669
670
// unified bailout support
671
void bailout(const char* msg) const { compilation()->bailout(msg); }
672
bool bailed_out() const { return compilation()->bailed_out(); }
673
674
void check_bounds(IntervalKind kind) { assert(kind >= fixedKind && kind <= anyKind, "invalid interval_kind"); }
675
676
Interval** unhandled_first_addr(IntervalKind kind) { check_bounds(kind); return &_unhandled_first[kind]; }
677
Interval** active_first_addr(IntervalKind kind) { check_bounds(kind); return &_active_first[kind]; }
678
Interval** inactive_first_addr(IntervalKind kind) { check_bounds(kind); return &_inactive_first[kind]; }
679
680
void append_sorted(Interval** first, Interval* interval);
681
void append_to_unhandled(Interval** list, Interval* interval);
682
683
bool remove_from_list(Interval** list, Interval* i);
684
void remove_from_list(Interval* i);
685
686
void next_interval();
687
Interval* current() const { return _current; }
688
IntervalKind current_kind() const { return _current_kind; }
689
690
void walk_to(IntervalState state, int from);
691
692
// activate_current() is called when an unhandled interval becomes active (in current(), current_kind()).
693
// Return false if current() should not be moved the the active interval list.
694
// It is safe to append current to any interval list but the unhandled list.
695
virtual bool activate_current() { return true; }
696
697
// This method is called whenever an interval moves from one interval list to another to print some
698
// information about it and its state change if TraceLinearScanLevel is set appropriately.
699
DEBUG_ONLY(void interval_moved(Interval* interval, IntervalKind kind, IntervalState from, IntervalState to);)
700
701
public:
702
IntervalWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first);
703
704
Interval* unhandled_first(IntervalKind kind) { check_bounds(kind); return _unhandled_first[kind]; }
705
Interval* active_first(IntervalKind kind) { check_bounds(kind); return _active_first[kind]; }
706
Interval* inactive_first(IntervalKind kind) { check_bounds(kind); return _inactive_first[kind]; }
707
708
// active contains the intervals that are live after the lir_op
709
void walk_to(int lir_op_id);
710
// active contains the intervals that are live before the lir_op
711
void walk_before(int lir_op_id) { walk_to(lir_op_id-1); }
712
// walk through all intervals
713
void walk() { walk_to(max_jint); }
714
715
int current_position() { return _current_position; }
716
};
717
718
719
// The actual linear scan register allocator
720
class LinearScanWalker : public IntervalWalker {
721
enum {
722
any_reg = LinearScan::any_reg
723
};
724
725
private:
726
int _first_reg; // the reg. number of the first phys. register
727
int _last_reg; // the reg. nmber of the last phys. register
728
int _num_phys_regs; // required by current interval
729
bool _adjacent_regs; // have lo/hi words of phys. regs be adjacent
730
731
int _use_pos[LinearScan::nof_regs];
732
int _block_pos[LinearScan::nof_regs];
733
IntervalList* _spill_intervals[LinearScan::nof_regs];
734
735
MoveResolver _move_resolver; // for ordering spill moves
736
737
// accessors mapped to same functions in class LinearScan
738
int block_count() const { return allocator()->block_count(); }
739
BlockBegin* block_at(int idx) const { return allocator()->block_at(idx); }
740
BlockBegin* block_of_op_with_id(int op_id) const { return allocator()->block_of_op_with_id(op_id); }
741
742
void init_use_lists(bool only_process_use_pos);
743
void exclude_from_use(int reg);
744
void exclude_from_use(Interval* i);
745
void set_use_pos(int reg, Interval* i, int use_pos, bool only_process_use_pos);
746
void set_use_pos(Interval* i, int use_pos, bool only_process_use_pos);
747
void set_block_pos(int reg, Interval* i, int block_pos);
748
void set_block_pos(Interval* i, int block_pos);
749
750
void free_exclude_active_fixed();
751
void free_exclude_active_any();
752
void free_collect_inactive_fixed(Interval* cur);
753
void free_collect_inactive_any(Interval* cur);
754
void spill_exclude_active_fixed();
755
void spill_block_inactive_fixed(Interval* cur);
756
void spill_collect_active_any();
757
void spill_collect_inactive_any(Interval* cur);
758
759
void insert_move(int op_id, Interval* src_it, Interval* dst_it);
760
int find_optimal_split_pos(BlockBegin* min_block, BlockBegin* max_block, int max_split_pos);
761
int find_optimal_split_pos(Interval* it, int min_split_pos, int max_split_pos, bool do_loop_optimization);
762
void split_before_usage(Interval* it, int min_split_pos, int max_split_pos);
763
void split_for_spilling(Interval* it);
764
void split_stack_interval(Interval* it);
765
void split_when_partial_register_available(Interval* it, int register_available_until);
766
void split_and_spill_interval(Interval* it);
767
768
int find_free_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split);
769
int find_free_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split);
770
bool alloc_free_reg(Interval* cur);
771
772
int find_locked_reg(int reg_needed_until, int interval_to, int ignore_reg, bool* need_split);
773
int find_locked_double_reg(int reg_needed_until, int interval_to, bool* need_split);
774
void split_and_spill_intersecting_intervals(int reg, int regHi);
775
void alloc_locked_reg(Interval* cur);
776
777
bool no_allocation_possible(Interval* cur);
778
void init_vars_for_alloc(Interval* cur);
779
bool pd_init_regs_for_alloc(Interval* cur);
780
781
void combine_spilled_intervals(Interval* cur);
782
bool is_move(LIR_Op* op, Interval* from, Interval* to);
783
784
bool activate_current();
785
786
public:
787
LinearScanWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first);
788
789
// must be called when all intervals are allocated
790
void finish_allocation() { _move_resolver.resolve_and_append_moves(); }
791
};
792
793
794
795
/*
796
When a block has more than one predecessor, and all predecessors end with
797
the same sequence of move-instructions, than this moves can be placed once
798
at the beginning of the block instead of multiple times in the predecessors.
799
800
Similarly, when a block has more than one successor, then equal sequences of
801
moves at the beginning of the successors can be placed once at the end of
802
the block. But because the moves must be inserted before all branch
803
instructions, this works only when there is exactly one conditional branch
804
at the end of the block (because the moves must be inserted before all
805
branches, but after all compares).
806
807
This optimization affects all kind of moves (reg->reg, reg->stack and
808
stack->reg). Because this optimization works best when a block contains only
809
few moves, it has a huge impact on the number of blocks that are totally
810
empty.
811
*/
812
class EdgeMoveOptimizer : public StackObj {
813
private:
814
// the class maintains a list with all lir-instruction-list of the
815
// successors (predecessors) and the current index into the lir-lists
816
LIR_OpListStack _edge_instructions;
817
intStack _edge_instructions_idx;
818
819
void init_instructions();
820
void append_instructions(LIR_OpList* instructions, int instructions_idx);
821
LIR_Op* instruction_at(int edge);
822
void remove_cur_instruction(int edge, bool decrement_index);
823
824
bool operations_different(LIR_Op* op1, LIR_Op* op2);
825
826
void optimize_moves_at_block_end(BlockBegin* cur);
827
void optimize_moves_at_block_begin(BlockBegin* cur);
828
829
EdgeMoveOptimizer();
830
831
public:
832
static void optimize(BlockList* code);
833
};
834
835
836
837
class ControlFlowOptimizer : public StackObj {
838
private:
839
BlockList _original_preds;
840
841
enum {
842
ShortLoopSize = 5
843
};
844
void reorder_short_loop(BlockList* code, BlockBegin* header_block, int header_idx);
845
void reorder_short_loops(BlockList* code);
846
847
bool can_delete_block(BlockBegin* cur);
848
void substitute_branch_target(BlockBegin* cur, BlockBegin* target_from, BlockBegin* target_to);
849
void delete_empty_blocks(BlockList* code);
850
851
void delete_unnecessary_jumps(BlockList* code);
852
void delete_jumps_to_return(BlockList* code);
853
854
DEBUG_ONLY(void verify(BlockList* code);)
855
856
ControlFlowOptimizer();
857
public:
858
static void optimize(BlockList* code);
859
};
860
861
862
#ifndef PRODUCT
863
864
// Helper class for collecting statistics of LinearScan
865
class LinearScanStatistic : public StackObj {
866
public:
867
enum Counter {
868
// general counters
869
counter_method,
870
counter_fpu_method,
871
counter_loop_method,
872
counter_exception_method,
873
counter_loop,
874
counter_block,
875
counter_loop_block,
876
counter_exception_block,
877
counter_interval,
878
counter_fixed_interval,
879
counter_range,
880
counter_fixed_range,
881
counter_use_pos,
882
counter_fixed_use_pos,
883
counter_spill_slots,
884
blank_line_1,
885
886
// counter for classes of lir instructions
887
counter_instruction,
888
counter_label,
889
counter_entry,
890
counter_return,
891
counter_call,
892
counter_move,
893
counter_cmp,
894
counter_cond_branch,
895
counter_uncond_branch,
896
counter_stub_branch,
897
counter_alu,
898
counter_alloc,
899
counter_sync,
900
counter_throw,
901
counter_unwind,
902
counter_typecheck,
903
counter_fpu_stack,
904
counter_misc_inst,
905
counter_other_inst,
906
blank_line_2,
907
908
// counter for different types of moves
909
counter_move_total,
910
counter_move_reg_reg,
911
counter_move_reg_stack,
912
counter_move_stack_reg,
913
counter_move_stack_stack,
914
counter_move_reg_mem,
915
counter_move_mem_reg,
916
counter_move_const_any,
917
918
number_of_counters,
919
invalid_counter = -1
920
};
921
922
private:
923
int _counters_sum[number_of_counters];
924
int _counters_max[number_of_counters];
925
926
void inc_counter(Counter idx, int value = 1) { _counters_sum[idx] += value; }
927
928
const char* counter_name(int counter_idx);
929
Counter base_counter(int counter_idx);
930
931
void sum_up(LinearScanStatistic &method_statistic);
932
void collect(LinearScan* allocator);
933
934
public:
935
LinearScanStatistic();
936
void print(const char* title);
937
static void compute(LinearScan* allocator, LinearScanStatistic &global_statistic);
938
};
939
940
941
// Helper class for collecting compilation time of LinearScan
942
class LinearScanTimers : public StackObj {
943
public:
944
enum Timer {
945
timer_do_nothing,
946
timer_number_instructions,
947
timer_compute_local_live_sets,
948
timer_compute_global_live_sets,
949
timer_build_intervals,
950
timer_sort_intervals_before,
951
timer_allocate_registers,
952
timer_resolve_data_flow,
953
timer_sort_intervals_after,
954
timer_eliminate_spill_moves,
955
timer_assign_reg_num,
956
timer_allocate_fpu_stack,
957
timer_optimize_lir,
958
959
number_of_timers
960
};
961
962
private:
963
elapsedTimer _timers[number_of_timers];
964
const char* timer_name(int idx);
965
966
public:
967
LinearScanTimers();
968
969
void begin_method(); // called for each method when register allocation starts
970
void end_method(LinearScan* allocator); // called for each method when register allocation completed
971
void print(double total_time); // called before termination of VM to print global summary
972
973
elapsedTimer* timer(int idx) { return &(_timers[idx]); }
974
};
975
976
977
#endif // ifndef PRODUCT
978
979
// Pick up platform-dependent implementation details
980
#include CPU_HEADER(c1_LinearScan)
981
982
#endif // SHARE_C1_C1_LINEARSCAN_HPP
983
984