File: | jdk/src/hotspot/share/adlc/formsopt.cpp |
Warning: | line 816, column 15 Value stored to 'inst' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 1998, 2012, 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 | // FORMS.CPP - Definitions for ADL Parser Forms Classes |
26 | #include "adlc.hpp" |
27 | |
28 | //==============================Register Allocation============================ |
29 | int RegisterForm::_reg_ctr = 0; |
30 | |
31 | //------------------------------RegisterForm----------------------------------- |
32 | // Constructor |
33 | RegisterForm::RegisterForm() |
34 | : _regDef(cmpstr,hashstr, Form::arena), |
35 | _regClass(cmpstr,hashstr, Form::arena), |
36 | _allocClass(cmpstr,hashstr, Form::arena) { |
37 | } |
38 | RegisterForm::~RegisterForm() { |
39 | } |
40 | |
41 | // record a new register definition |
42 | void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv, |
43 | char *idealtype, char *encoding, char* concrete) { |
44 | RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete); |
45 | _rdefs.addName(name); |
46 | _regDef.Insert(name,regDef); |
47 | } |
48 | |
49 | // record a new register class |
50 | template <typename T> |
51 | T* RegisterForm::addRegClass(const char* className) { |
52 | T* regClass = new T(className); |
53 | _rclasses.addName(className); |
54 | _regClass.Insert(className, regClass); |
55 | return regClass; |
56 | } |
57 | |
58 | // Explicit instantiation for all supported register classes. |
59 | template RegClass* RegisterForm::addRegClass<RegClass>(const char* className); |
60 | template CodeSnippetRegClass* RegisterForm::addRegClass<CodeSnippetRegClass>(const char* className); |
61 | template ConditionalRegClass* RegisterForm::addRegClass<ConditionalRegClass>(const char* className); |
62 | |
63 | // record a new register class |
64 | AllocClass *RegisterForm::addAllocClass(char *className) { |
65 | AllocClass *allocClass = new AllocClass(className); |
66 | _aclasses.addName(className); |
67 | _allocClass.Insert(className,allocClass); |
68 | return allocClass; |
69 | } |
70 | |
71 | // Called after parsing the Register block. Record the register class |
72 | // for spill-slots/regs. |
73 | void RegisterForm::addSpillRegClass() { |
74 | // Stack slots start at the next available even register number. |
75 | _reg_ctr = (_reg_ctr+7) & ~7; |
76 | const char *rc_name = "stack_slots"; |
77 | RegClass* reg_class = new RegClass(rc_name); |
78 | reg_class->set_stack_version(true); |
79 | _rclasses.addName(rc_name); |
80 | _regClass.Insert(rc_name,reg_class); |
81 | } |
82 | |
83 | // Called after parsing the Register block. Record the register class |
84 | // for operands which are overwritten after matching. |
85 | void RegisterForm::addDynamicRegClass() { |
86 | const char *rc_name = "dynamic"; |
87 | RegClass* reg_class = new RegClass(rc_name); |
88 | reg_class->set_stack_version(false); |
89 | _rclasses.addName(rc_name); |
90 | _regClass.Insert(rc_name,reg_class); |
91 | } |
92 | |
93 | // Provide iteration over all register definitions |
94 | // in the order used by the register allocator |
95 | void RegisterForm::reset_RegDefs() { |
96 | _current_ac = NULL__null; |
97 | _aclasses.reset(); |
98 | } |
99 | |
100 | RegDef *RegisterForm::iter_RegDefs() { |
101 | // Check if we need to get the next AllocClass |
102 | if ( _current_ac == NULL__null ) { |
103 | const char *ac_name = _aclasses.iter(); |
104 | if( ac_name == NULL__null ) return NULL__null; // No more allocation classes |
105 | _current_ac = (AllocClass*)_allocClass[ac_name]; |
106 | _current_ac->_regDefs.reset(); |
107 | assert( _current_ac != NULL, "Name must match an allocation class"){ if (!(_current_ac != __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 107, "Name must match an allocation class"); abort(); }}; |
108 | } |
109 | |
110 | const char *rd_name = _current_ac->_regDefs.iter(); |
111 | if( rd_name == NULL__null ) { |
112 | // At end of this allocation class, check the next |
113 | _current_ac = NULL__null; |
114 | return iter_RegDefs(); |
115 | } |
116 | RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name]; |
117 | assert( reg_def != NULL, "Name must match a register definition"){ if (!(reg_def != __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 117, "Name must match a register definition"); abort(); }}; |
118 | return reg_def; |
119 | } |
120 | |
121 | // return the register definition with name 'regName' |
122 | RegDef *RegisterForm::getRegDef(const char *regName) { |
123 | RegDef *regDef = (RegDef*)_regDef[regName]; |
124 | return regDef; |
125 | } |
126 | |
127 | // return the register class with name 'className' |
128 | RegClass *RegisterForm::getRegClass(const char *className) { |
129 | RegClass *regClass = (RegClass*)_regClass[className]; |
130 | return regClass; |
131 | } |
132 | |
133 | |
134 | // Check that register classes are compatible with chunks |
135 | bool RegisterForm::verify() { |
136 | bool valid = true; |
137 | |
138 | // Verify Register Classes |
139 | // check that each register class contains registers from one chunk |
140 | const char *rc_name = NULL__null; |
141 | _rclasses.reset(); |
142 | while ( (rc_name = _rclasses.iter()) != NULL__null ) { |
143 | // Check the chunk value for all registers in this class |
144 | RegClass *reg_class = getRegClass(rc_name); |
145 | assert( reg_class != NULL, "InternalError() no matching register class"){ if (!(reg_class != __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 145, "InternalError() no matching register class"); abort() ; }}; |
146 | } // end of RegClasses |
147 | |
148 | // Verify that every register has been placed into an allocation class |
149 | RegDef *reg_def = NULL__null; |
150 | reset_RegDefs(); |
151 | uintunsigned int num_register_zero = 0; |
152 | while ( (reg_def = iter_RegDefs()) != NULL__null ) { |
153 | if( reg_def->register_num() == 0 ) ++num_register_zero; |
154 | } |
155 | if( num_register_zero > 1 ) { |
156 | fprintf(stderrstderr, |
157 | "ERROR: More than one register has been assigned register-number 0.\n" |
158 | "Probably because a register has not been entered into an allocation class.\n"); |
159 | } |
160 | |
161 | return valid; |
162 | } |
163 | |
164 | // Compute RegMask size |
165 | int RegisterForm::RegMask_Size() { |
166 | // Need at least this many words |
167 | int words_for_regs = (_reg_ctr + 31)>>5; |
168 | // The array of Register Mask bits should be large enough to cover |
169 | // all the machine registers and all parameters that need to be passed |
170 | // on the stack (stack registers) up to some interesting limit. Methods |
171 | // that need more parameters will NOT be compiled. On Intel, the limit |
172 | // is something like 90+ parameters. |
173 | // Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls. |
174 | // Round up to the next doubleword size. |
175 | return (words_for_regs + 3 + 1) & ~1; |
176 | } |
177 | |
178 | void RegisterForm::dump() { // Debug printer |
179 | output(stderrstderr); |
180 | } |
181 | |
182 | void RegisterForm::output(FILE *fp) { // Write info to output files |
183 | const char *name; |
184 | fprintf(fp,"\n"); |
185 | fprintf(fp,"-------------------- Dump RegisterForm --------------------\n"); |
186 | for(_rdefs.reset(); (name = _rdefs.iter()) != NULL__null;) { |
187 | ((RegDef*)_regDef[name])->output(fp); |
188 | } |
189 | fprintf(fp,"\n"); |
190 | for (_rclasses.reset(); (name = _rclasses.iter()) != NULL__null;) { |
191 | ((RegClass*)_regClass[name])->output(fp); |
192 | } |
193 | fprintf(fp,"\n"); |
194 | for (_aclasses.reset(); (name = _aclasses.iter()) != NULL__null;) { |
195 | ((AllocClass*)_allocClass[name])->output(fp); |
196 | } |
197 | fprintf(fp,"-------------------- end RegisterForm --------------------\n"); |
198 | } |
199 | |
200 | //------------------------------RegDef----------------------------------------- |
201 | // Constructor |
202 | RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete) |
203 | : _regname(regname), _callconv(callconv), _c_conv(c_conv), |
204 | _idealtype(idealtype), |
205 | _register_encode(encode), |
206 | _concrete(concrete), |
207 | _register_num(0) { |
208 | |
209 | // Chunk and register mask are determined by the register number |
210 | // _register_num is set when registers are added to an allocation class |
211 | } |
212 | RegDef::~RegDef() { // Destructor |
213 | } |
214 | |
215 | void RegDef::set_register_num(uint32unsigned int register_num) { |
216 | _register_num = register_num; |
217 | } |
218 | |
219 | // Bit pattern used for generating machine code |
220 | const char* RegDef::register_encode() const { |
221 | return _register_encode; |
222 | } |
223 | |
224 | // Register number used in machine-independent code |
225 | uint32unsigned int RegDef::register_num() const { |
226 | return _register_num; |
227 | } |
228 | |
229 | void RegDef::dump() { |
230 | output(stderrstderr); |
231 | } |
232 | |
233 | void RegDef::output(FILE *fp) { // Write info to output files |
234 | fprintf(fp,"RegDef: %s (%s) encode as %s using number %d\n", |
235 | _regname, (_callconv?_callconv:""), _register_encode, _register_num); |
236 | fprintf(fp,"\n"); |
237 | } |
238 | |
239 | |
240 | //------------------------------RegClass--------------------------------------- |
241 | // Construct a register class into which registers will be inserted |
242 | RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) { |
243 | } |
244 | |
245 | RegClass::~RegClass() { |
246 | } |
247 | |
248 | // record a register in this class |
249 | void RegClass::addReg(RegDef *regDef) { |
250 | _regDefs.addName(regDef->_regname); |
251 | _regDef.Insert((void*)regDef->_regname, regDef); |
252 | } |
253 | |
254 | // Number of registers in class |
255 | uintunsigned int RegClass::size() const { |
256 | return _regDef.Size(); |
257 | } |
258 | |
259 | const RegDef *RegClass::get_RegDef(const char *rd_name) const { |
260 | return (const RegDef*)_regDef[rd_name]; |
261 | } |
262 | |
263 | void RegClass::reset() { |
264 | _regDefs.reset(); |
265 | } |
266 | |
267 | const char *RegClass::rd_name_iter() { |
268 | return _regDefs.iter(); |
269 | } |
270 | |
271 | RegDef *RegClass::RegDef_iter() { |
272 | const char *rd_name = rd_name_iter(); |
273 | RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL__null; |
274 | return reg_def; |
275 | } |
276 | |
277 | const RegDef* RegClass::find_first_elem() { |
278 | const RegDef* first = NULL__null; |
279 | const RegDef* def = NULL__null; |
280 | |
281 | reset(); |
282 | while ((def = RegDef_iter()) != NULL__null) { |
283 | if (first == NULL__null || def->register_num() < first->register_num()) { |
284 | first = def; |
285 | } |
286 | } |
287 | |
288 | assert(first != NULL, "empty mask?"){ if (!(first != __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 288, "empty mask?"); abort(); }}; |
289 | return first;; |
290 | } |
291 | |
292 | // Collect all the registers in this register-word. One bit per register. |
293 | int RegClass::regs_in_word( int wordnum, bool stack_also ) { |
294 | int word = 0; |
295 | const char *name; |
296 | for(_regDefs.reset(); (name = _regDefs.iter()) != NULL__null;) { |
297 | int rnum = ((RegDef*)_regDef[name])->register_num(); |
298 | if( (rnum >> 5) == wordnum ) |
299 | word |= (1 << (rnum & 31)); |
300 | } |
301 | if( stack_also ) { |
302 | // Now also collect stack bits |
303 | for( int i = 0; i < 32; i++ ) |
304 | if( wordnum*32+i >= RegisterForm::_reg_ctr ) |
305 | word |= (1 << i); |
306 | } |
307 | |
308 | return word; |
309 | } |
310 | |
311 | void RegClass::dump() { |
312 | output(stderrstderr); |
313 | } |
314 | |
315 | void RegClass::output(FILE *fp) { // Write info to output files |
316 | fprintf(fp,"RegClass: %s\n",_classid); |
317 | const char *name; |
318 | for(_regDefs.reset(); (name = _regDefs.iter()) != NULL__null;) { |
319 | ((RegDef*)_regDef[name])->output(fp); |
320 | } |
321 | fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid); |
322 | } |
323 | |
324 | void RegClass::declare_register_masks(FILE* fp) { |
325 | const char* prefix = ""; |
326 | const char* rc_name_to_upper = toUpper(_classid); |
327 | fprintf(fp, "extern const RegMask _%s%s_mask;\n", prefix, rc_name_to_upper); |
328 | fprintf(fp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper); |
329 | if (_stack_or_reg) { |
330 | fprintf(fp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, rc_name_to_upper); |
331 | fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper); |
332 | } |
333 | delete[] rc_name_to_upper; |
334 | } |
335 | |
336 | void RegClass::build_register_masks(FILE* fp) { |
337 | int len = RegisterForm::RegMask_Size(); |
338 | const char *prefix = ""; |
339 | const char* rc_name_to_upper = toUpper(_classid); |
340 | fprintf(fp, "const RegMask _%s%s_mask(", prefix, rc_name_to_upper); |
341 | |
342 | int i; |
343 | for(i = 0; i < len - 1; i++) { |
344 | fprintf(fp," 0x%x,", regs_in_word(i, false)); |
345 | } |
346 | fprintf(fp," 0x%x );\n", regs_in_word(i, false)); |
347 | |
348 | if (_stack_or_reg) { |
349 | fprintf(fp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, rc_name_to_upper); |
350 | for(i = 0; i < len - 1; i++) { |
351 | fprintf(fp," 0x%x,", regs_in_word(i, true)); |
352 | } |
353 | fprintf(fp," 0x%x );\n", regs_in_word(i, true)); |
354 | } |
355 | delete[] rc_name_to_upper; |
356 | } |
357 | |
358 | //------------------------------CodeSnippetRegClass--------------------------- |
359 | CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(NULL__null) { |
360 | } |
361 | |
362 | CodeSnippetRegClass::~CodeSnippetRegClass() { |
363 | delete _code_snippet; |
364 | } |
365 | |
366 | void CodeSnippetRegClass::declare_register_masks(FILE* fp) { |
367 | const char* prefix = ""; |
368 | const char* rc_name_to_upper = toUpper(_classid); |
369 | fprintf(fp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, rc_name_to_upper, _code_snippet); |
370 | delete[] rc_name_to_upper; |
371 | } |
372 | |
373 | //------------------------------ConditionalRegClass--------------------------- |
374 | ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(NULL__null) { |
375 | } |
376 | |
377 | ConditionalRegClass::~ConditionalRegClass() { |
378 | delete _condition_code; |
379 | } |
380 | |
381 | void ConditionalRegClass::declare_register_masks(FILE* fp) { |
382 | const char* prefix = ""; |
383 | const char* rc_name_to_upper = toUpper(_classid); |
384 | const char* rclass_0_to_upper = toUpper(_rclasses[0]->_classid); |
385 | const char* rclass_1_to_upper = toUpper(_rclasses[1]->_classid); |
386 | fprintf(fp, "inline const RegMask &%s%s_mask() {" |
387 | " return (%s) ?" |
388 | " %s%s_mask() :" |
389 | " %s%s_mask(); }\n", |
390 | prefix, rc_name_to_upper, |
391 | _condition_code, |
392 | prefix, rclass_0_to_upper, |
393 | prefix, rclass_1_to_upper); |
394 | if (_stack_or_reg) { |
395 | fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() {" |
396 | " return (%s) ?" |
397 | " %sSTACK_OR_%s_mask() :" |
398 | " %sSTACK_OR_%s_mask(); }\n", |
399 | prefix, rc_name_to_upper, |
400 | _condition_code, |
401 | prefix, rclass_0_to_upper, |
402 | prefix, rclass_1_to_upper); |
403 | } |
404 | delete[] rc_name_to_upper; |
405 | delete[] rclass_0_to_upper; |
406 | delete[] rclass_1_to_upper; |
407 | return; |
408 | } |
409 | |
410 | //------------------------------AllocClass------------------------------------- |
411 | AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) { |
412 | } |
413 | |
414 | // record a register in this class |
415 | void AllocClass::addReg(RegDef *regDef) { |
416 | assert( regDef != NULL, "Can not add a NULL to an allocation class"){ if (!(regDef != __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 416, "Can not add a NULL to an allocation class"); abort(); }}; |
417 | regDef->set_register_num( RegisterForm::_reg_ctr++ ); |
418 | // Add regDef to this allocation class |
419 | _regDefs.addName(regDef->_regname); |
420 | _regDef.Insert((void*)regDef->_regname, regDef); |
421 | } |
422 | |
423 | void AllocClass::dump() { |
424 | output(stderrstderr); |
425 | } |
426 | |
427 | void AllocClass::output(FILE *fp) { // Write info to output files |
428 | fprintf(fp,"AllocClass: %s \n",_classid); |
429 | const char *name; |
430 | for(_regDefs.reset(); (name = _regDefs.iter()) != NULL__null;) { |
431 | ((RegDef*)_regDef[name])->output(fp); |
432 | } |
433 | fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid); |
434 | } |
435 | |
436 | //==============================Frame Handling================================= |
437 | //------------------------------FrameForm-------------------------------------- |
438 | FrameForm::FrameForm() { |
439 | _frame_pointer = NULL__null; |
440 | _c_frame_pointer = NULL__null; |
441 | _alignment = NULL__null; |
442 | _return_addr = NULL__null; |
443 | _c_return_addr = NULL__null; |
444 | _varargs_C_out_slots_killed = NULL__null; |
445 | _return_value = NULL__null; |
446 | _c_return_value = NULL__null; |
447 | _interpreter_frame_pointer_reg = NULL__null; |
448 | } |
449 | |
450 | FrameForm::~FrameForm() { |
451 | } |
452 | |
453 | void FrameForm::dump() { |
454 | output(stderrstderr); |
455 | } |
456 | |
457 | void FrameForm::output(FILE *fp) { // Write info to output files |
458 | fprintf(fp,"\nFrame:\n"); |
459 | } |
460 | |
461 | //==============================Scheduling===================================== |
462 | //------------------------------PipelineForm----------------------------------- |
463 | PipelineForm::PipelineForm() |
464 | : _reslist () |
465 | , _resdict (cmpstr, hashstr, Form::arena) |
466 | , _classdict (cmpstr, hashstr, Form::arena) |
467 | , _rescount (0) |
468 | , _maxcycleused (0) |
469 | , _stages () |
470 | , _stagecnt (0) |
471 | , _classlist () |
472 | , _classcnt (0) |
473 | , _noplist () |
474 | , _nopcnt (0) |
475 | , _variableSizeInstrs (false) |
476 | , _branchHasDelaySlot (false) |
477 | , _maxInstrsPerBundle (0) |
478 | , _maxBundlesPerCycle (1) |
479 | , _instrUnitSize (0) |
480 | , _bundleUnitSize (0) |
481 | , _instrFetchUnitSize (0) |
482 | , _instrFetchUnits (0) { |
483 | } |
484 | PipelineForm::~PipelineForm() { |
485 | } |
486 | |
487 | void PipelineForm::dump() { |
488 | output(stderrstderr); |
489 | } |
490 | |
491 | void PipelineForm::output(FILE *fp) { // Write info to output files |
492 | const char *res; |
493 | const char *stage; |
494 | const char *cls; |
495 | const char *nop; |
496 | int count = 0; |
497 | |
498 | fprintf(fp,"\nPipeline:"); |
499 | if (_variableSizeInstrs) |
500 | if (_instrUnitSize > 0) |
501 | fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize); |
502 | else |
503 | fprintf(fp," variable-sized instructions"); |
504 | else |
505 | if (_instrUnitSize > 0) |
506 | fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize); |
507 | else if (_bundleUnitSize > 0) |
508 | fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize); |
509 | else |
510 | fprintf(fp," fixed-sized instructions"); |
511 | if (_branchHasDelaySlot) |
512 | fprintf(fp,", branch has delay slot"); |
513 | if (_maxInstrsPerBundle > 0) |
514 | fprintf(fp,", max of %d instruction%s in parallel", |
515 | _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : ""); |
516 | if (_maxBundlesPerCycle > 0) |
517 | fprintf(fp,", max of %d bundle%s in parallel", |
518 | _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : ""); |
519 | if (_instrFetchUnitSize > 0 && _instrFetchUnits) |
520 | fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize); |
521 | |
522 | fprintf(fp,"\nResource:"); |
523 | for ( _reslist.reset(); (res = _reslist.iter()) != NULL__null; ) |
524 | fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask()); |
525 | fprintf(fp,"\n"); |
526 | |
527 | fprintf(fp,"\nDescription:\n"); |
528 | for ( _stages.reset(); (stage = _stages.iter()) != NULL__null; ) |
529 | fprintf(fp," %s(%d)", stage, count++); |
530 | fprintf(fp,"\n"); |
531 | |
532 | fprintf(fp,"\nClasses:\n"); |
533 | for ( _classlist.reset(); (cls = _classlist.iter()) != NULL__null; ) |
534 | _classdict[cls]->is_pipeclass()->output(fp); |
535 | |
536 | fprintf(fp,"\nNop Instructions:"); |
537 | for ( _noplist.reset(); (nop = _noplist.iter()) != NULL__null; ) |
538 | fprintf(fp, " \"%s\"", nop); |
539 | fprintf(fp,"\n"); |
540 | } |
541 | |
542 | |
543 | //------------------------------ResourceForm----------------------------------- |
544 | ResourceForm::ResourceForm(unsigned resmask) |
545 | : _resmask(resmask) { |
546 | } |
547 | ResourceForm::~ResourceForm() { |
548 | } |
549 | |
550 | ResourceForm *ResourceForm::is_resource() const { |
551 | return (ResourceForm *)(this); |
552 | } |
553 | |
554 | void ResourceForm::dump() { |
555 | output(stderrstderr); |
556 | } |
557 | |
558 | void ResourceForm::output(FILE *fp) { // Write info to output files |
559 | fprintf(fp, "resource: 0x%08x;\n", mask()); |
560 | } |
561 | |
562 | |
563 | //------------------------------PipeClassOperandForm---------------------------------- |
564 | |
565 | void PipeClassOperandForm::dump() { |
566 | output(stderrstderr); |
567 | } |
568 | |
569 | void PipeClassOperandForm::output(FILE *fp) { // Write info to output files |
570 | fprintf(stderrstderr,"PipeClassOperandForm: %s", _stage); |
571 | fflush(stderrstderr); |
572 | if (_more_instrs > 0) |
573 | fprintf(stderrstderr,"+%d", _more_instrs); |
574 | fprintf(stderrstderr," (%s)\n", _iswrite ? "write" : "read"); |
575 | fflush(stderrstderr); |
576 | fprintf(fp,"PipeClassOperandForm: %s", _stage); |
577 | if (_more_instrs > 0) |
578 | fprintf(fp,"+%d", _more_instrs); |
579 | fprintf(fp," (%s)\n", _iswrite ? "write" : "read"); |
580 | } |
581 | |
582 | |
583 | //------------------------------PipeClassResourceForm---------------------------------- |
584 | |
585 | void PipeClassResourceForm::dump() { |
586 | output(stderrstderr); |
587 | } |
588 | |
589 | void PipeClassResourceForm::output(FILE *fp) { // Write info to output files |
590 | fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n", |
591 | _resource, _stage, _cycles); |
592 | } |
593 | |
594 | |
595 | //------------------------------PipeClassForm---------------------------------- |
596 | PipeClassForm::PipeClassForm(const char *id, int num) |
597 | : _ident(id) |
598 | , _num(num) |
599 | , _localNames(cmpstr, hashstr, Form::arena) |
600 | , _localUsage(cmpstr, hashstr, Form::arena) |
601 | , _has_fixed_latency(0) |
602 | , _fixed_latency(0) |
603 | , _instruction_count(0) |
604 | , _has_multiple_bundles(false) |
605 | , _has_branch_delay_slot(false) |
606 | , _force_serialization(false) |
607 | , _may_have_no_code(false) { |
608 | } |
609 | |
610 | PipeClassForm::~PipeClassForm() { |
611 | } |
612 | |
613 | PipeClassForm *PipeClassForm::is_pipeclass() const { |
614 | return (PipeClassForm *)(this); |
615 | } |
616 | |
617 | void PipeClassForm::dump() { |
618 | output(stderrstderr); |
619 | } |
620 | |
621 | void PipeClassForm::output(FILE *fp) { // Write info to output files |
622 | fprintf(fp,"PipeClassForm: #%03d", _num); |
623 | if (_ident) |
624 | fprintf(fp," \"%s\":", _ident); |
625 | if (_has_fixed_latency) |
626 | fprintf(fp," latency %d", _fixed_latency); |
627 | if (_force_serialization) |
628 | fprintf(fp, ", force serialization"); |
629 | if (_may_have_no_code) |
630 | fprintf(fp, ", may have no code"); |
631 | fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : ""); |
632 | } |
633 | |
634 | |
635 | //==============================Peephole Optimization========================== |
636 | int Peephole::_peephole_counter = 0; |
637 | //------------------------------Peephole--------------------------------------- |
638 | Peephole::Peephole() : _match(NULL__null), _constraint(NULL__null), _replace(NULL__null), _next(NULL__null) { |
639 | _peephole_number = _peephole_counter++; |
640 | } |
641 | Peephole::~Peephole() { |
642 | } |
643 | |
644 | // Append a peephole rule with the same root instruction |
645 | void Peephole::append_peephole(Peephole *next_peephole) { |
646 | if( _next == NULL__null ) { |
647 | _next = next_peephole; |
648 | } else { |
649 | _next->append_peephole( next_peephole ); |
650 | } |
651 | } |
652 | |
653 | // Store the components of this peephole rule |
654 | void Peephole::add_match(PeepMatch *match) { |
655 | assert( _match == NULL, "fatal()" ){ if (!(_match == __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 655, "fatal()"); abort(); }}; |
656 | _match = match; |
657 | } |
658 | |
659 | void Peephole::append_constraint(PeepConstraint *next_constraint) { |
660 | if( _constraint == NULL__null ) { |
661 | _constraint = next_constraint; |
662 | } else { |
663 | _constraint->append( next_constraint ); |
664 | } |
665 | } |
666 | |
667 | void Peephole::add_replace(PeepReplace *replace) { |
668 | assert( _replace == NULL, "fatal()" ){ if (!(_replace == __null)) { fprintf(stderr, "assert fails %s %d: %s\n" , "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp" , 668, "fatal()"); abort(); }}; |
669 | _replace = replace; |
670 | } |
671 | |
672 | // class Peephole accessor methods are in the declaration. |
673 | |
674 | |
675 | void Peephole::dump() { |
676 | output(stderrstderr); |
677 | } |
678 | |
679 | void Peephole::output(FILE *fp) { // Write info to output files |
680 | fprintf(fp,"Peephole:\n"); |
681 | if( _match != NULL__null ) _match->output(fp); |
682 | if( _constraint != NULL__null ) _constraint->output(fp); |
683 | if( _replace != NULL__null ) _replace->output(fp); |
684 | // Output the next entry |
685 | if( _next ) _next->output(fp); |
686 | } |
687 | |
688 | //------------------------------PeepMatch-------------------------------------- |
689 | PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) { |
690 | } |
691 | PeepMatch::~PeepMatch() { |
692 | } |
693 | |
694 | |
695 | // Insert info into the match-rule |
696 | void PeepMatch::add_instruction(int parent, int position, const char *name, |
697 | int input) { |
698 | if( position > _max_position ) _max_position = position; |
699 | |
700 | _parent.addName((char*) (intptr_t) parent); |
701 | _position.addName((char*) (intptr_t) position); |
702 | _instrs.addName(name); |
703 | _input.addName((char*) (intptr_t) input); |
704 | } |
705 | |
706 | // Access info about instructions in the peep-match rule |
707 | int PeepMatch::max_position() { |
708 | return _max_position; |
709 | } |
710 | |
711 | const char *PeepMatch::instruction_name(int position) { |
712 | return _instrs.name(position); |
713 | } |
714 | |
715 | // Iterate through all info on matched instructions |
716 | void PeepMatch::reset() { |
717 | _parent.reset(); |
718 | _position.reset(); |
719 | _instrs.reset(); |
720 | _input.reset(); |
721 | } |
722 | |
723 | void PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) { |
724 | parent = (int) (intptr_t) _parent.iter(); |
725 | position = (int) (intptr_t) _position.iter(); |
726 | name = _instrs.iter(); |
727 | input = (int) (intptr_t) _input.iter(); |
728 | } |
729 | |
730 | // 'true' if current position in iteration is a placeholder, not matched. |
731 | bool PeepMatch::is_placeholder() { |
732 | return _instrs.current_is_signal(); |
733 | } |
734 | |
735 | |
736 | void PeepMatch::dump() { |
737 | output(stderrstderr); |
738 | } |
739 | |
740 | void PeepMatch::output(FILE *fp) { // Write info to output files |
741 | fprintf(fp,"PeepMatch:\n"); |
742 | } |
743 | |
744 | //------------------------------PeepConstraint--------------------------------- |
745 | PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation, |
746 | int right_inst, char* right_op) |
747 | : _left_inst(left_inst), _left_op(left_op), _relation(relation), |
748 | _right_inst(right_inst), _right_op(right_op), _next(NULL__null) {} |
749 | PeepConstraint::~PeepConstraint() { |
750 | } |
751 | |
752 | // Check if constraints use instruction at position |
753 | bool PeepConstraint::constrains_instruction(int position) { |
754 | // Check local instruction constraints |
755 | if( _left_inst == position ) return true; |
756 | if( _right_inst == position ) return true; |
757 | |
758 | // Check remaining constraints in list |
759 | if( _next == NULL__null ) return false; |
760 | else return _next->constrains_instruction(position); |
761 | } |
762 | |
763 | // Add another constraint |
764 | void PeepConstraint::append(PeepConstraint *next_constraint) { |
765 | if( _next == NULL__null ) { |
766 | _next = next_constraint; |
767 | } else { |
768 | _next->append( next_constraint ); |
769 | } |
770 | } |
771 | |
772 | // Access the next constraint in the list |
773 | PeepConstraint *PeepConstraint::next() { |
774 | return _next; |
775 | } |
776 | |
777 | |
778 | void PeepConstraint::dump() { |
779 | output(stderrstderr); |
780 | } |
781 | |
782 | void PeepConstraint::output(FILE *fp) { // Write info to output files |
783 | fprintf(fp,"PeepConstraint:\n"); |
784 | } |
785 | |
786 | //------------------------------PeepReplace------------------------------------ |
787 | PeepReplace::PeepReplace(char *rule) : _rule(rule) { |
788 | } |
789 | PeepReplace::~PeepReplace() { |
790 | } |
791 | |
792 | // Add contents of peepreplace |
793 | void PeepReplace::add_instruction(char *root) { |
794 | _instruction.addName(root); |
795 | _operand_inst_num.add_signal(); |
796 | _operand_op_name.add_signal(); |
797 | } |
798 | void PeepReplace::add_operand( int inst_num, char *inst_operand ) { |
799 | _instruction.add_signal(); |
800 | _operand_inst_num.addName((char*) (intptr_t) inst_num); |
801 | _operand_op_name.addName(inst_operand); |
802 | } |
803 | |
804 | // Access contents of peepreplace |
805 | void PeepReplace::reset() { |
806 | _instruction.reset(); |
807 | _operand_inst_num.reset(); |
808 | _operand_op_name.reset(); |
809 | } |
810 | void PeepReplace::next_instruction(const char* &inst){ |
811 | inst = _instruction.iter(); |
812 | int inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
813 | const char* inst_operand = _operand_op_name.iter(); |
814 | } |
815 | void PeepReplace::next_operand(int &inst_num, const char* &inst_operand) { |
816 | const char* inst = _instruction.iter(); |
Value stored to 'inst' during its initialization is never read | |
817 | inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
818 | inst_operand = _operand_op_name.iter(); |
819 | } |
820 | |
821 | |
822 | |
823 | void PeepReplace::dump() { |
824 | output(stderrstderr); |
825 | } |
826 | |
827 | void PeepReplace::output(FILE *fp) { // Write info to output files |
828 | fprintf(fp,"PeepReplace:\n"); |
829 | } |