Bug Summary

File:jdk/src/hotspot/share/adlc/formsopt.cpp
Warning:line 813, column 15
Value stored to 'inst_operand' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name formsopt.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D LINUX -D ASSERT -D AMD64 -I /home/daniel/Projects/java/jdk/src/hotspot/share -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -Wno-unused -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formsopt.cpp
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============================
29int RegisterForm::_reg_ctr = 0;
30
31//------------------------------RegisterForm-----------------------------------
32// Constructor
33RegisterForm::RegisterForm()
34 : _regDef(cmpstr,hashstr, Form::arena),
35 _regClass(cmpstr,hashstr, Form::arena),
36 _allocClass(cmpstr,hashstr, Form::arena) {
37}
38RegisterForm::~RegisterForm() {
39}
40
41// record a new register definition
42void 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
50template <typename T>
51T* 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.
59template RegClass* RegisterForm::addRegClass<RegClass>(const char* className);
60template CodeSnippetRegClass* RegisterForm::addRegClass<CodeSnippetRegClass>(const char* className);
61template ConditionalRegClass* RegisterForm::addRegClass<ConditionalRegClass>(const char* className);
62
63// record a new register class
64AllocClass *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.
73void 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.
85void 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
95void RegisterForm::reset_RegDefs() {
96 _current_ac = NULL__null;
97 _aclasses.reset();
98}
99
100RegDef *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'
122RegDef *RegisterForm::getRegDef(const char *regName) {
123 RegDef *regDef = (RegDef*)_regDef[regName];
124 return regDef;
125}
126
127// return the register class with name 'className'
128RegClass *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
135bool 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
165int 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
178void RegisterForm::dump() { // Debug printer
179 output(stderrstderr);
180}
181
182void 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
202RegDef::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}
212RegDef::~RegDef() { // Destructor
213}
214
215void RegDef::set_register_num(uint32unsigned int register_num) {
216 _register_num = register_num;
217}
218
219// Bit pattern used for generating machine code
220const char* RegDef::register_encode() const {
221 return _register_encode;
222}
223
224// Register number used in machine-independent code
225uint32unsigned int RegDef::register_num() const {
226 return _register_num;
227}
228
229void RegDef::dump() {
230 output(stderrstderr);
231}
232
233void 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
242RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) {
243}
244
245RegClass::~RegClass() {
246}
247
248// record a register in this class
249void RegClass::addReg(RegDef *regDef) {
250 _regDefs.addName(regDef->_regname);
251 _regDef.Insert((void*)regDef->_regname, regDef);
252}
253
254// Number of registers in class
255uintunsigned int RegClass::size() const {
256 return _regDef.Size();
257}
258
259const RegDef *RegClass::get_RegDef(const char *rd_name) const {
260 return (const RegDef*)_regDef[rd_name];
261}
262
263void RegClass::reset() {
264 _regDefs.reset();
265}
266
267const char *RegClass::rd_name_iter() {
268 return _regDefs.iter();
269}
270
271RegDef *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
277const 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.
293int 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
311void RegClass::dump() {
312 output(stderrstderr);
313}
314
315void 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
324void 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
336void 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---------------------------
359CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(NULL__null) {
360}
361
362CodeSnippetRegClass::~CodeSnippetRegClass() {
363 delete _code_snippet;
364}
365
366void 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---------------------------
374ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(NULL__null) {
375}
376
377ConditionalRegClass::~ConditionalRegClass() {
378 delete _condition_code;
379}
380
381void 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-------------------------------------
411AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
412}
413
414// record a register in this class
415void 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
423void AllocClass::dump() {
424 output(stderrstderr);
425}
426
427void 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--------------------------------------
438FrameForm::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
450FrameForm::~FrameForm() {
451}
452
453void FrameForm::dump() {
454 output(stderrstderr);
455}
456
457void FrameForm::output(FILE *fp) { // Write info to output files
458 fprintf(fp,"\nFrame:\n");
459}
460
461//==============================Scheduling=====================================
462//------------------------------PipelineForm-----------------------------------
463PipelineForm::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}
484PipelineForm::~PipelineForm() {
485}
486
487void PipelineForm::dump() {
488 output(stderrstderr);
489}
490
491void 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-----------------------------------
544ResourceForm::ResourceForm(unsigned resmask)
545: _resmask(resmask) {
546}
547ResourceForm::~ResourceForm() {
548}
549
550ResourceForm *ResourceForm::is_resource() const {
551 return (ResourceForm *)(this);
552}
553
554void ResourceForm::dump() {
555 output(stderrstderr);
556}
557
558void ResourceForm::output(FILE *fp) { // Write info to output files
559 fprintf(fp, "resource: 0x%08x;\n", mask());
560}
561
562
563//------------------------------PipeClassOperandForm----------------------------------
564
565void PipeClassOperandForm::dump() {
566 output(stderrstderr);
567}
568
569void 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
585void PipeClassResourceForm::dump() {
586 output(stderrstderr);
587}
588
589void 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----------------------------------
596PipeClassForm::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
610PipeClassForm::~PipeClassForm() {
611}
612
613PipeClassForm *PipeClassForm::is_pipeclass() const {
614 return (PipeClassForm *)(this);
615}
616
617void PipeClassForm::dump() {
618 output(stderrstderr);
619}
620
621void 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==========================
636int Peephole::_peephole_counter = 0;
637//------------------------------Peephole---------------------------------------
638Peephole::Peephole() : _match(NULL__null), _constraint(NULL__null), _replace(NULL__null), _next(NULL__null) {
639 _peephole_number = _peephole_counter++;
640}
641Peephole::~Peephole() {
642}
643
644// Append a peephole rule with the same root instruction
645void 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
654void 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
659void 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
667void 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
675void Peephole::dump() {
676 output(stderrstderr);
677}
678
679void 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--------------------------------------
689PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
690}
691PeepMatch::~PeepMatch() {
692}
693
694
695// Insert info into the match-rule
696void 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
707int PeepMatch::max_position() {
708 return _max_position;
709}
710
711const char *PeepMatch::instruction_name(int position) {
712 return _instrs.name(position);
713}
714
715// Iterate through all info on matched instructions
716void PeepMatch::reset() {
717 _parent.reset();
718 _position.reset();
719 _instrs.reset();
720 _input.reset();
721}
722
723void 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.
731bool PeepMatch::is_placeholder() {
732 return _instrs.current_is_signal();
733}
734
735
736void PeepMatch::dump() {
737 output(stderrstderr);
738}
739
740void PeepMatch::output(FILE *fp) { // Write info to output files
741 fprintf(fp,"PeepMatch:\n");
742}
743
744//------------------------------PeepConstraint---------------------------------
745PeepConstraint::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) {}
749PeepConstraint::~PeepConstraint() {
750}
751
752// Check if constraints use instruction at position
753bool 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
764void 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
773PeepConstraint *PeepConstraint::next() {
774 return _next;
775}
776
777
778void PeepConstraint::dump() {
779 output(stderrstderr);
780}
781
782void PeepConstraint::output(FILE *fp) { // Write info to output files
783 fprintf(fp,"PeepConstraint:\n");
784}
785
786//------------------------------PeepReplace------------------------------------
787PeepReplace::PeepReplace(char *rule) : _rule(rule) {
788}
789PeepReplace::~PeepReplace() {
790}
791
792// Add contents of peepreplace
793void PeepReplace::add_instruction(char *root) {
794 _instruction.addName(root);
795 _operand_inst_num.add_signal();
796 _operand_op_name.add_signal();
797}
798void 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
805void PeepReplace::reset() {
806 _instruction.reset();
807 _operand_inst_num.reset();
808 _operand_op_name.reset();
809}
810void 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();
Value stored to 'inst_operand' during its initialization is never read
814}
815void PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {
816 const char* inst = _instruction.iter();
817 inst_num = (int) (intptr_t) _operand_inst_num.iter();
818 inst_operand = _operand_op_name.iter();
819}
820
821
822
823void PeepReplace::dump() {
824 output(stderrstderr);
825}
826
827void PeepReplace::output(FILE *fp) { // Write info to output files
828 fprintf(fp,"PeepReplace:\n");
829}