1 /*
2 * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_OPTO_OUTPUT_HPP
26 #define SHARE_OPTO_OUTPUT_HPP
27
28 #include "code/debugInfo.hpp"
29 #include "code/exceptionHandlerTable.hpp"
30 #include "metaprogramming/enableIf.hpp"
31 #include "opto/ad.hpp"
32 #include "opto/c2_CodeStubs.hpp"
33 #include "opto/constantTable.hpp"
34 #include "opto/phase.hpp"
35 #include "runtime/vm_version.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/macros.hpp"
38
39 class AbstractCompiler;
40 class Arena;
41 class Bundle;
42 class Block;
43 class Block_Array;
44 class C2_MacroAssembler;
45 class ciMethod;
46 class Compile;
47 class MachNode;
48 class MachSafePointNode;
49 class Node;
50 class PhaseCFG;
51 #ifndef PRODUCT
52 #define DEBUG_ARG(x) , x
53 #else
54 #define DEBUG_ARG(x)
55 #endif
56
57 class BufferSizingData {
58 public:
59 int _stub;
60 int _code;
61 int _const;
62 int _reloc;
63
64 BufferSizingData() :
65 _stub(0),
66 _code(0),
67 _const(0),
68 _reloc(0)
69 { };
70 };
71
72 class PhaseOutput : public Phase {
73 private:
74 // Instruction bits passed off to the VM
75 CodeBuffer _code_buffer; // Where the code is assembled
76 int _first_block_size; // Size of unvalidated entry point code / OSR poison code
77 ExceptionHandlerTable _handler_table; // Table of native-code exception handlers
78 ImplicitExceptionTable _inc_table; // Table of implicit null checks in native code
79 C2CodeStubList _stub_list; // List of code stubs
80 OopMapSet* _oop_map_set; // Table of oop maps (one for each safepoint location)
81 BufferBlob* _scratch_buffer_blob; // For temporary code buffers.
82 relocInfo* _scratch_locs_memory; // For temporary code buffers.
83 int _scratch_const_size; // For temporary code buffers.
84 bool _in_scratch_emit_size; // true when in scratch_emit_size.
85
86 int _frame_slots; // Size of total frame in stack slots
87 CodeOffsets _code_offsets; // Offsets into the code for various interesting entries
88
89 uint _node_bundling_limit;
90 Bundle* _node_bundling_base; // Information for instruction bundling
91
92 // For deopt
93 int _orig_pc_slot;
94 int _orig_pc_slot_offset_in_bytes;
95
96 // For GC barriers
97 int _gc_barrier_save_slots;
98 int _gc_barrier_save_slots_offset_in_bytes;
99
100 ConstantTable _constant_table; // The constant table for this compilation unit.
101
102 BufferSizingData _buf_sizes;
103 Block* _block;
104 uint _index;
105
106 void perform_mach_node_analysis();
107 void pd_perform_mach_node_analysis();
108
109 public:
110 PhaseOutput();
111 ~PhaseOutput();
112
113 // Convert Nodes to instruction bits and pass off to the VM
114 void Output();
115 bool need_stack_bang(int frame_size_in_bytes) const;
116 bool need_register_stack_bang() const;
117 void compute_loop_first_inst_sizes();
118
119 void install_code(ciMethod* target,
120 int entry_bci,
121 AbstractCompiler* compiler,
122 bool has_unsafe_access,
123 bool has_wide_vectors);
124
125 void install_stub(const char* stub_name);
126
127 // Constant table
128 ConstantTable& constant_table() { return _constant_table; }
129
130 // Code stubs list
131 void add_stub(C2CodeStub* stub) { _stub_list.add_stub(stub); }
132
133 // Code emission iterator
134 Block* block() { return _block; }
135 int index() { return _index; }
136
137 // The architecture description provides short branch variants for some long
138 // branch instructions. Replace eligible long branches with short branches.
139 void shorten_branches(uint* blk_starts);
140 // If "objs" contains an ObjectValue whose id is "id", returns it, else null.
141 static ObjectValue* sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id);
142 static void set_sv_for_object_node(GrowableArray<ScopeValue*> *objs, ObjectValue* sv);
143 void FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
144 GrowableArray<ScopeValue*> *array,
145 GrowableArray<ScopeValue*> *objs );
146
147 void Process_OopMap_Node(MachNode *mach, int current_offset);
148
149 // Initialize code buffer
150 void estimate_buffer_size(int& const_req);
151 CodeBuffer* init_buffer();
152
153 // Write out basic block data to code buffer
154 void fill_buffer(C2_MacroAssembler* masm, uint* blk_starts);
155
156 // Compute the information for the exception tables
157 void FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels);
158
159 // Perform instruction scheduling and bundling over the sequence of
160 // instructions in backwards order.
161 void ScheduleAndBundle();
162
163 void install();
164
165 // Instruction bits passed off to the VM
166 CodeBuffer* code_buffer() { return &_code_buffer; }
167 int first_block_size() { return _first_block_size; }
168 void set_frame_complete(int off) { if (!in_scratch_emit_size()) { _code_offsets.set_value(CodeOffsets::Frame_Complete, off); } }
169 ExceptionHandlerTable* handler_table() { return &_handler_table; }
170 ImplicitExceptionTable* inc_table() { return &_inc_table; }
171 OopMapSet* oop_map_set() { return _oop_map_set; }
172
173 // Scratch buffer
174 BufferBlob* scratch_buffer_blob() { return _scratch_buffer_blob; }
175 void init_scratch_buffer_blob(int const_size);
176 void clear_scratch_buffer_blob();
177 void set_scratch_buffer_blob(BufferBlob* b) { _scratch_buffer_blob = b; }
178 relocInfo* scratch_locs_memory() { return _scratch_locs_memory; }
179 void set_scratch_locs_memory(relocInfo* b) { _scratch_locs_memory = b; }
180 int scratch_buffer_code_size() { return (address)scratch_locs_memory() - _scratch_buffer_blob->content_begin(); }
181
182 // emit to scratch blob, report resulting size
183 uint scratch_emit_size(const Node* n);
184 void set_in_scratch_emit_size(bool x) { _in_scratch_emit_size = x; }
185 bool in_scratch_emit_size() const { return _in_scratch_emit_size; }
186
187 BufferSizingData* buffer_sizing_data() { return &_buf_sizes; }
188
189 enum ScratchBufferBlob {
190 MAX_inst_size = 2048,
191 MAX_locs_size = 128, // number of relocInfo elements
192 MAX_const_size = 128,
193 MAX_stubs_size = 128
194 };
195
196 int frame_slots() const { return _frame_slots; }
197 int frame_size_in_words() const; // frame_slots in units of the polymorphic 'words'
198 int frame_size_in_bytes() const { return _frame_slots << LogBytesPerInt; }
199
200 int bang_size_in_bytes() const;
201
202 int gc_barrier_save_slots_offset_in_bytes() { return _gc_barrier_save_slots_offset_in_bytes; }
203
204 void set_node_bundling_limit(uint n) { _node_bundling_limit = n; }
205 void set_node_bundling_base(Bundle* b) { _node_bundling_base = b; }
206
207 Bundle* node_bundling(const Node *n);
208 bool valid_bundle_info(const Node *n);
209
210 bool starts_bundle(const Node *n) const;
211 bool contains_as_owner(GrowableArray<MonitorValue*> *monarray, ObjectValue *ov) const;
212 bool contains_as_scalarized_obj(JVMState* jvms, MachSafePointNode* sfn,
213 GrowableArray<ScopeValue*>* objs,
214 ObjectValue* ov) const;
215
216 // Dump formatted assembly
217 #if defined(SUPPORT_OPTO_ASSEMBLY)
218 void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit);
219 #else
220 void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit) { return; }
221 #endif
222
223 // Build OopMaps for each GC point
224 void BuildOopMaps();
225
226 #ifndef PRODUCT
227 void print_scheduling(outputStream* output_stream);
228 void print_scheduling(); // to tty for debugging
229 static void print_statistics();
230 #endif
231 };
232
233 #endif // SHARE_OPTO_OUTPUT_HPP