annotate src/share/vm/c1/c1_LinearScan.hpp @ 6862:8a5ea0a9ccc4

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