Bug Summary

File:jdk/src/hotspot/share/adlc/archDesc.cpp
Warning:line 612, column 11
Although the value stored to 'cur' is used in the enclosing expression, the value is never actually read from 'cur'

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 archDesc.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/archDesc.cpp
1//
2// Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4//
5// This code is free software; you can redistribute it and/or modify it
6// under the terms of the GNU General Public License version 2 only, as
7// published by the Free Software Foundation.
8//
9// This code is distributed in the hope that it will be useful, but WITHOUT
10// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12// version 2 for more details (a copy is included in the LICENSE file that
13// accompanied this code).
14//
15// You should have received a copy of the GNU General Public License version
16// 2 along with this work; if not, write to the Free Software Foundation,
17// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18//
19// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20// or visit www.oracle.com if you need additional information or have any
21// questions.
22//
23//
24
25
26// archDesc.cpp - Internal format for architecture definition
27#include "adlc.hpp"
28
29static FILE *errfile = stderrstderr;
30
31//--------------------------- utility functions -----------------------------
32inline char toUpper(char lower) {
33 return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
34}
35char *toUpper(const char *str) {
36 char *upper = new char[strlen(str)+1];
37 char *result = upper;
38 const char *end = str + strlen(str);
39 for (; str < end; ++str, ++upper) {
40 *upper = toUpper(*str);
41 }
42 *upper = '\0';
43 return result;
44}
45
46//---------------------------ChainList Methods-------------------------------
47ChainList::ChainList() {
48}
49
50void ChainList::insert(const char *name, const char *cost, const char *rule) {
51 _name.addName(name);
52 _cost.addName(cost);
53 _rule.addName(rule);
54}
55
56bool ChainList::search(const char *name) {
57 return _name.search(name);
58}
59
60void ChainList::reset() {
61 _name.reset();
62 _cost.reset();
63 _rule.reset();
64}
65
66bool ChainList::iter(const char * &name, const char * &cost, const char * &rule) {
67 bool notDone = false;
68 const char *n = _name.iter();
69 const char *c = _cost.iter();
70 const char *r = _rule.iter();
71
72 if (n && c && r) {
73 notDone = true;
74 name = n;
75 cost = c;
76 rule = r;
77 }
78
79 return notDone;
80}
81
82void ChainList::dump() {
83 output(stderrstderr);
84}
85
86void ChainList::output(FILE *fp) {
87 fprintf(fp, "\nChain Rules: output resets iterator\n");
88 const char *cost = NULL__null;
89 const char *name = NULL__null;
90 const char *rule = NULL__null;
91 bool chains_exist = false;
92 for(reset(); (iter(name,cost,rule)) == true; ) {
93 fprintf(fp, "Chain to <%s> at cost #%s using %s_rule\n",name, cost ? cost : "0", rule);
94 // // Check for transitive chain rules
95 // Form *form = (Form *)_globalNames[rule];
96 // if (form->is_instruction()) {
97 // // chain_rule(fp, indent, name, cost, rule);
98 // chain_rule(fp, indent, name, cost, rule);
99 // }
100 }
101 reset();
102 if( ! chains_exist ) {
103 fprintf(fp, "No entries in this ChainList\n");
104 }
105}
106
107
108//---------------------------MatchList Methods-------------------------------
109bool MatchList::search(const char *opc, const char *res, const char *lch,
110 const char *rch, Predicate *pr) {
111 bool tmp = false;
112 if ((res == _resultStr) || (res && _resultStr && !strcmp(res, _resultStr))) {
113 if ((lch == _lchild) || (lch && _lchild && !strcmp(lch, _lchild))) {
114 if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
115 char * predStr = get_pred();
116 char * prStr = pr?pr->_pred:NULL__null;
117 if (ADLParser::equivalent_expressions(prStr, predStr)) {
118 return true;
119 }
120 }
121 }
122 }
123 if (_next) {
124 tmp = _next->search(opc, res, lch, rch, pr);
125 }
126 return tmp;
127}
128
129
130void MatchList::dump() {
131 output(stderrstderr);
132}
133
134void MatchList::output(FILE *fp) {
135 fprintf(fp, "\nMatchList output is Unimplemented();\n");
136}
137
138
139//---------------------------ArchDesc Constructor and Destructor-------------
140
141ArchDesc::ArchDesc()
142 : _globalNames(cmpstr,hashstr, Form::arena),
143 _globalDefs(cmpstr,hashstr, Form::arena),
144 _preproc_table(cmpstr,hashstr, Form::arena),
145 _idealIndex(cmpstr,hashstr, Form::arena),
146 _internalOps(cmpstr,hashstr, Form::arena),
147 _internalMatch(cmpstr,hashstr, Form::arena),
148 _chainRules(cmpstr,hashstr, Form::arena),
149 _cisc_spill_operand(NULL__null),
150 _needs_deep_clone_jvms(false) {
151
152 // Initialize the opcode to MatchList table with NULLs
153 for( int i=0; i<_last_opcode; ++i ) {
154 _mlistab[i] = NULL__null;
155 }
156
157 // Set-up the global tables
158 initKeywords(_globalNames); // Initialize the Name Table with keywords
159
160 // Prime user-defined types with predefined types: Set, RegI, RegF, ...
161 initBaseOpTypes();
162
163 // Initialize flags & counters
164 _TotalLines = 0;
165 _no_output = 0;
166 _quiet_mode = 0;
167 _disable_warnings = 0;
168 _dfa_debug = 0;
169 _dfa_small = 0;
170 _adl_debug = 0;
171 _adlocation_debug = 0;
172 _internalOpCounter = 0;
173 _cisc_spill_debug = false;
174 _short_branch_debug = false;
175
176 // Initialize match rule flags
177 for (int i = 0; i < _last_opcode; i++) {
178 _has_match_rule[i] = false;
179 }
180
181 // Error/Warning Counts
182 _syntax_errs = 0;
183 _semantic_errs = 0;
184 _warnings = 0;
185 _internal_errs = 0;
186
187 // Initialize I/O Files
188 _ADL_file._name = NULL__null; _ADL_file._fp = NULL__null;
189 // Machine dependent output files
190 _DFA_file._name = NULL__null; _DFA_file._fp = NULL__null;
191 _HPP_file._name = NULL__null; _HPP_file._fp = NULL__null;
192 _CPP_file._name = NULL__null; _CPP_file._fp = NULL__null;
193 _bug_file._name = "bugs.out"; _bug_file._fp = NULL__null;
194
195 // Initialize Register & Pipeline Form Pointers
196 _register = NULL__null;
197 _encode = NULL__null;
198 _pipeline = NULL__null;
199 _frame = NULL__null;
200}
201
202ArchDesc::~ArchDesc() {
203 // Clean-up and quit
204
205}
206
207//---------------------------ArchDesc methods: Public ----------------------
208// Store forms according to type
209void ArchDesc::addForm(PreHeaderForm *ptr) { _pre_header.addForm(ptr); };
210void ArchDesc::addForm(HeaderForm *ptr) { _header.addForm(ptr); };
211void ArchDesc::addForm(SourceForm *ptr) { _source.addForm(ptr); };
212void ArchDesc::addForm(EncodeForm *ptr) { _encode = ptr; };
213void ArchDesc::addForm(InstructForm *ptr) { _instructions.addForm(ptr); };
214void ArchDesc::addForm(MachNodeForm *ptr) { _machnodes.addForm(ptr); };
215void ArchDesc::addForm(OperandForm *ptr) { _operands.addForm(ptr); };
216void ArchDesc::addForm(OpClassForm *ptr) { _opclass.addForm(ptr); };
217void ArchDesc::addForm(AttributeForm *ptr) { _attributes.addForm(ptr); };
218void ArchDesc::addForm(RegisterForm *ptr) { _register = ptr; };
219void ArchDesc::addForm(FrameForm *ptr) { _frame = ptr; };
220void ArchDesc::addForm(PipelineForm *ptr) { _pipeline = ptr; };
221
222// Build MatchList array and construct MatchLists
223void ArchDesc::generateMatchLists() {
224 // Call inspection routines to populate array
225 inspectOperands();
226 inspectInstructions();
227}
228
229// Build MatchList structures for operands
230void ArchDesc::inspectOperands() {
231
232 // Iterate through all operands
233 _operands.reset();
234 OperandForm *op;
235 for( ; (op = (OperandForm*)_operands.iter()) != NULL__null;) {
236 // Construct list of top-level operands (components)
237 op->build_components();
238
239 // Ensure that match field is defined.
240 if ( op->_matrule == NULL__null ) continue;
241
242 // Type check match rules
243 check_optype(op->_matrule);
244
245 // Construct chain rules
246 build_chain_rule(op);
247
248 MatchRule *mrule = op->_matrule;
249 Predicate *pred = op->_predicate;
250
251 // Grab the machine type of the operand
252 const char *rootOp = op->_ident;
253 mrule->_machType = rootOp;
254
255 // Check for special cases
256 if (strcmp(rootOp,"Universe")==0) continue;
257 if (strcmp(rootOp,"label")==0) continue;
258 // !!!!! !!!!!
259 assert( strcmp(rootOp,"sReg") != 0, "Disable untyped 'sReg'"){ if (!(strcmp(rootOp,"sReg") != 0)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 259, "Disable untyped 'sReg'"); abort(); }}
;
260 if (strcmp(rootOp,"sRegI")==0) continue;
261 if (strcmp(rootOp,"sRegP")==0) continue;
262 if (strcmp(rootOp,"sRegF")==0) continue;
263 if (strcmp(rootOp,"sRegD")==0) continue;
264 if (strcmp(rootOp,"sRegL")==0) continue;
265
266 // Cost for this match
267 const char *costStr = op->cost();
268 const char *defaultCost =
269 ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
270 const char *cost = costStr? costStr : defaultCost;
271
272 // Find result type for match.
273 const char *result = op->reduce_result();
274
275 // Construct a MatchList for this entry.
276 // Iterate over the list to enumerate all match cases for operands with multiple match rules.
277 for (; mrule != NULL__null; mrule = mrule->_next) {
278 mrule->_machType = rootOp;
279 buildMatchList(mrule, result, rootOp, pred, cost);
280 }
281 }
282}
283
284// Build MatchList structures for instructions
285void ArchDesc::inspectInstructions() {
286
287 // Iterate through all instructions
288 _instructions.reset();
289 InstructForm *instr;
290 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL__null; ) {
291 // Construct list of top-level operands (components)
292 instr->build_components();
293
294 // Ensure that match field is defined.
295 if ( instr->_matrule == NULL__null ) continue;
296
297 MatchRule &mrule = *instr->_matrule;
298 Predicate *pred = instr->build_predicate();
299
300 // Grab the machine type of the operand
301 const char *rootOp = instr->_ident;
302 mrule._machType = rootOp;
303
304 // Cost for this match
305 const char *costStr = instr->cost();
306 const char *defaultCost =
307 ((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
308 const char *cost = costStr? costStr : defaultCost;
309
310 // Find result type for match
311 const char *result = instr->reduce_result();
312
313 if (( instr->is_ideal_branch() && instr->label_position() == -1) ||
314 (!instr->is_ideal_branch() && instr->label_position() != -1)) {
315 syntax_err(instr->_linenum, "%s: Only branches to a label are supported\n", rootOp);
316 }
317
318 Attribute *attr = instr->_attribs;
319 while (attr != NULL__null) {
320 if (strcmp(attr->_ident,"ins_short_branch") == 0 &&
321 attr->int_val(*this) != 0) {
322 if (!instr->is_ideal_branch() || instr->label_position() == -1) {
323 syntax_err(instr->_linenum, "%s: Only short branch to a label is supported\n", rootOp);
324 }
325 instr->set_short_branch(true);
326 } else if (strcmp(attr->_ident,"ins_alignment") == 0 &&
327 attr->int_val(*this) != 0) {
328 instr->set_alignment(attr->int_val(*this));
329 }
330 attr = (Attribute *)attr->_next;
331 }
332
333 if (!instr->is_short_branch()) {
334 buildMatchList(instr->_matrule, result, mrule._machType, pred, cost);
335 }
336 }
337}
338
339static int setsResult(MatchRule &mrule) {
340 if (strcmp(mrule._name,"Set") == 0) return 1;
341 return 0;
342}
343
344const char *ArchDesc::getMatchListIndex(MatchRule &mrule) {
345 if (setsResult(mrule)) {
346 // right child
347 return mrule._rChild->_opType;
348 } else {
349 // first entry
350 return mrule._opType;
351 }
352}
353
354
355//------------------------------result of reduction----------------------------
356
357
358//------------------------------left reduction---------------------------------
359// Return the left reduction associated with an internal name
360const char *ArchDesc::reduceLeft(char *internalName) {
361 const char *left = NULL__null;
362 MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
363 if (mnode->_lChild) {
364 mnode = mnode->_lChild;
365 left = mnode->_internalop ? mnode->_internalop : mnode->_opType;
366 }
367 return left;
368}
369
370
371//------------------------------right reduction--------------------------------
372const char *ArchDesc::reduceRight(char *internalName) {
373 const char *right = NULL__null;
374 MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
375 if (mnode->_rChild) {
376 mnode = mnode->_rChild;
377 right = mnode->_internalop ? mnode->_internalop : mnode->_opType;
378 }
379 return right;
380}
381
382
383//------------------------------check_optype-----------------------------------
384void ArchDesc::check_optype(MatchRule *mrule) {
385 MatchRule *rule = mrule;
386
387 // !!!!!
388 // // Cycle through the list of match rules
389 // while(mrule) {
390 // // Check for a filled in type field
391 // if (mrule->_opType == NULL) {
392 // const Form *form = operands[_result];
393 // OpClassForm *opcForm = form ? form->is_opclass() : NULL;
394 // assert(opcForm != NULL, "Match Rule contains invalid operand name.");
395 // }
396 // char *opType = opcForm->_ident;
397 // }
398}
399
400//------------------------------add_chain_rule_entry--------------------------
401void ArchDesc::add_chain_rule_entry(const char *src, const char *cost,
402 const char *result) {
403 // Look-up the operation in chain rule table
404 ChainList *lst = (ChainList *)_chainRules[src];
405 if (lst == NULL__null) {
406 lst = new ChainList();
407 _chainRules.Insert(src, lst);
408 }
409 if (!lst->search(result)) {
410 if (cost == NULL__null) {
411 cost = ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
412 }
413 lst->insert(result, cost, result);
414 }
415}
416
417//------------------------------build_chain_rule-------------------------------
418void ArchDesc::build_chain_rule(OperandForm *oper) {
419 MatchRule *rule;
420
421 // Check for chain rules here
422 // If this is only a chain rule
423 if ((oper->_matrule) && (oper->_matrule->_lChild == NULL__null) &&
424 (oper->_matrule->_rChild == NULL__null)) {
425
426 {
427 const Form *form = _globalNames[oper->_matrule->_opType];
428 if ((form) && form->is_operand() &&
429 (form->ideal_only() == false)) {
430 add_chain_rule_entry(oper->_matrule->_opType, oper->cost(), oper->_ident);
431 }
432 }
433 // Check for additional chain rules
434 if (oper->_matrule->_next) {
435 rule = oper->_matrule;
436 do {
437 rule = rule->_next;
438 // Any extra match rules after the first must be chain rules
439 const Form *form = _globalNames[rule->_opType];
440 if ((form) && form->is_operand() &&
441 (form->ideal_only() == false)) {
442 add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
443 }
444 } while(rule->_next != NULL__null);
445 }
446 }
447 else if ((oper->_matrule) && (oper->_matrule->_next)) {
448 // Regardles of whether the first matchrule is a chain rule, check the list
449 rule = oper->_matrule;
450 do {
451 rule = rule->_next;
452 // Any extra match rules after the first must be chain rules
453 const Form *form = _globalNames[rule->_opType];
454 if ((form) && form->is_operand() &&
455 (form->ideal_only() == false)) {
456 assert( oper->cost(), "This case expects NULL cost, not default cost"){ if (!(oper->cost())) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 456, "This case expects NULL cost, not default cost"); abort
(); }}
;
457 add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
458 }
459 } while(rule->_next != NULL__null);
460 }
461
462}
463
464//------------------------------buildMatchList---------------------------------
465// operands and instructions provide the result
466void ArchDesc::buildMatchList(MatchRule *mrule, const char *resultStr,
467 const char *rootOp, Predicate *pred,
468 const char *cost) {
469 const char *leftstr, *rightstr;
470 MatchNode *mnode;
471
472 leftstr = rightstr = NULL__null;
473 // Check for chain rule, and do not generate a match list for it
474 if ( mrule->is_chain_rule(_globalNames) ) {
475 return;
476 }
477
478 // Identify index position among ideal operands
479 intptr_t index = _last_opcode;
480 const char *indexStr = getMatchListIndex(*mrule);
481 index = (intptr_t)_idealIndex[indexStr];
482 if (index == 0) {
483 fprintf(stderrstderr, "Ideal node missing: %s\n", indexStr);
484 assert(index != 0, "Failed lookup of ideal node\n"){ if (!(index != 0)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 484, "Failed lookup of ideal node\n"); abort(); }}
;
485 }
486
487 // Check that this will be placed appropriately in the DFA
488 if (index >= _last_opcode) {
489 fprintf(stderrstderr, "Invalid match rule %s <-- ( %s )\n",
490 resultStr ? resultStr : " ",
491 rootOp ? rootOp : " ");
492 assert(index < _last_opcode, "Matching item not in ideal graph\n"){ if (!(index < _last_opcode)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 492, "Matching item not in ideal graph\n"); abort(); }}
;
493 return;
494 }
495
496
497 // Walk the MatchRule, generating MatchList entries for each level
498 // of the rule (each nesting of parentheses)
499 // Check for "Set"
500 if (!strcmp(mrule->_opType, "Set")) {
501 mnode = mrule->_rChild;
502 buildMList(mnode, rootOp, resultStr, pred, cost);
503 return;
504 }
505 // Build MatchLists for children
506 // Check each child for an internal operand name, and use that name
507 // for the parent's matchlist entry if it exists
508 mnode = mrule->_lChild;
509 if (mnode) {
510 buildMList(mnode, NULL__null, NULL__null, NULL__null, NULL__null);
511 leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
512 }
513 mnode = mrule->_rChild;
514 if (mnode) {
515 buildMList(mnode, NULL__null, NULL__null, NULL__null, NULL__null);
516 rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
517 }
518 // Search for an identical matchlist entry already on the list
519 if ((_mlistab[index] == NULL__null) ||
520 (_mlistab[index] &&
521 !_mlistab[index]->search(rootOp, resultStr, leftstr, rightstr, pred))) {
522 // Place this match rule at front of list
523 MatchList *mList =
524 new MatchList(_mlistab[index], pred, cost,
525 rootOp, resultStr, leftstr, rightstr);
526 _mlistab[index] = mList;
527 }
528}
529
530// Recursive call for construction of match lists
531void ArchDesc::buildMList(MatchNode *node, const char *rootOp,
532 const char *resultOp, Predicate *pred,
533 const char *cost) {
534 const char *leftstr, *rightstr;
535 const char *resultop;
536 const char *opcode;
537 MatchNode *mnode;
538 Form *form;
539
540 leftstr = rightstr = NULL__null;
541 // Do not process leaves of the Match Tree if they are not ideal
542 if ((node) && (node->_lChild == NULL__null) && (node->_rChild == NULL__null) &&
543 ((form = (Form *)_globalNames[node->_opType]) != NULL__null) &&
544 (!form->ideal_only())) {
545 return;
546 }
547
548 // Identify index position among ideal operands
549 intptr_t index = _last_opcode;
550 const char *indexStr = node ? node->_opType : (char *) " ";
551 index = (intptr_t)_idealIndex[indexStr];
552 if (index == 0) {
553 fprintf(stderrstderr, "error: operand \"%s\" not found\n", indexStr);
554 assert(0, "fatal error"){ if (!(0)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 554, "fatal error"); abort(); }}
;
555 }
556
557 if (node == NULL__null) {
558 fprintf(stderrstderr, "error: node is NULL\n");
559 assert(0, "fatal error"){ if (!(0)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 559, "fatal error"); abort(); }}
;
560 }
561 // Build MatchLists for children
562 // Check each child for an internal operand name, and use that name
563 // for the parent's matchlist entry if it exists
564 mnode = node->_lChild;
565 if (mnode) {
566 buildMList(mnode, NULL__null, NULL__null, NULL__null, NULL__null);
567 leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
568 }
569 mnode = node->_rChild;
570 if (mnode) {
571 buildMList(mnode, NULL__null, NULL__null, NULL__null, NULL__null);
572 rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
573 }
574 // Grab the string for the opcode of this list entry
575 if (rootOp == NULL__null) {
576 opcode = (node->_internalop) ? node->_internalop : node->_opType;
577 } else {
578 opcode = rootOp;
579 }
580 // Grab the string for the result of this list entry
581 if (resultOp == NULL__null) {
582 resultop = (node->_internalop) ? node->_internalop : node->_opType;
583 }
584 else resultop = resultOp;
585 // Search for an identical matchlist entry already on the list
586 if ((_mlistab[index] == NULL__null) || (_mlistab[index] &&
587 !_mlistab[index]->search(opcode, resultop, leftstr, rightstr, pred))) {
588 // Place this match rule at front of list
589 MatchList *mList =
590 new MatchList(_mlistab[index],pred,cost,
591 opcode, resultop, leftstr, rightstr);
592 _mlistab[index] = mList;
593 }
594}
595
596// Count number of OperandForms defined
597int ArchDesc::operandFormCount() {
598 // Only interested in ones with non-NULL match rule
599 int count = 0; _operands.reset();
600 OperandForm *cur;
601 for( ; (cur = (OperandForm*)_operands.iter()) != NULL__null; ) {
602 if (cur->_matrule != NULL__null) ++count;
603 };
604 return count;
605}
606
607// Count number of OpClassForms defined
608int ArchDesc::opclassFormCount() {
609 // Only interested in ones with non-NULL match rule
610 int count = 0; _operands.reset();
611 OpClassForm *cur;
612 for( ; (cur = (OpClassForm*)_opclass.iter()) != NULL__null; ) {
Although the value stored to 'cur' is used in the enclosing expression, the value is never actually read from 'cur'
613 ++count;
614 };
615 return count;
616}
617
618// Count number of InstructForms defined
619int ArchDesc::instructFormCount() {
620 // Only interested in ones with non-NULL match rule
621 int count = 0; _instructions.reset();
622 InstructForm *cur;
623 for( ; (cur = (InstructForm*)_instructions.iter()) != NULL__null; ) {
624 if (cur->_matrule != NULL__null) ++count;
625 };
626 return count;
627}
628
629
630//------------------------------get_preproc_def--------------------------------
631// Return the textual binding for a given CPP flag name.
632// Return NULL if there is no binding, or it has been #undef-ed.
633char* ArchDesc::get_preproc_def(const char* flag) {
634 // In case of syntax errors, flag may take the value NULL.
635 SourceForm* deff = NULL__null;
636 if (flag != NULL__null)
637 deff = (SourceForm*) _preproc_table[flag];
638 return (deff == NULL__null) ? NULL__null : deff->_code;
639}
640
641
642//------------------------------set_preproc_def--------------------------------
643// Change or create a textual binding for a given CPP flag name.
644// Giving NULL means the flag name is to be #undef-ed.
645// In any case, _preproc_list collects all names either #defined or #undef-ed.
646void ArchDesc::set_preproc_def(const char* flag, const char* def) {
647 SourceForm* deff = (SourceForm*) _preproc_table[flag];
648 if (deff == NULL__null) {
649 deff = new SourceForm(NULL__null);
650 _preproc_table.Insert(flag, deff);
651 _preproc_list.addName(flag); // this supports iteration
652 }
653 deff->_code = (char*) def;
654}
655
656
657bool ArchDesc::verify() {
658
659 if (_register)
660 assert( _register->verify(), "Register declarations failed verification"){ if (!(_register->verify())) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 660, "Register declarations failed verification"); abort();
}}
;
661 if (!_quiet_mode)
662 fprintf(stderrstderr,"\n");
663 // fprintf(stderr,"---------------------------- Verify Operands ---------------\n");
664 // _operands.verify();
665 // fprintf(stderr,"\n");
666 // fprintf(stderr,"---------------------------- Verify Operand Classes --------\n");
667 // _opclass.verify();
668 // fprintf(stderr,"\n");
669 // fprintf(stderr,"---------------------------- Verify Attributes ------------\n");
670 // _attributes.verify();
671 // fprintf(stderr,"\n");
672 if (!_quiet_mode)
673 fprintf(stderrstderr,"---------------------------- Verify Instructions ----------------------------\n");
674 _instructions.verify();
675 if (!_quiet_mode)
676 fprintf(stderrstderr,"\n");
677 // if ( _encode ) {
678 // fprintf(stderr,"---------------------------- Verify Encodings --------------\n");
679 // _encode->verify();
680 // }
681
682 //if (_pipeline) _pipeline->verify();
683
684 return true;
685}
686
687
688void ArchDesc::dump() {
689 _pre_header.dump();
690 _header.dump();
691 _source.dump();
692 if (_register) _register->dump();
693 fprintf(stderrstderr,"\n");
694 fprintf(stderrstderr,"------------------ Dump Operands ---------------------\n");
695 _operands.dump();
696 fprintf(stderrstderr,"\n");
697 fprintf(stderrstderr,"------------------ Dump Operand Classes --------------\n");
698 _opclass.dump();
699 fprintf(stderrstderr,"\n");
700 fprintf(stderrstderr,"------------------ Dump Attributes ------------------\n");
701 _attributes.dump();
702 fprintf(stderrstderr,"\n");
703 fprintf(stderrstderr,"------------------ Dump Instructions -----------------\n");
704 _instructions.dump();
705 if ( _encode ) {
706 fprintf(stderrstderr,"------------------ Dump Encodings --------------------\n");
707 _encode->dump();
708 }
709 if (_pipeline) _pipeline->dump();
710}
711
712
713//------------------------------init_keywords----------------------------------
714// Load the kewords into the global name table
715void ArchDesc::initKeywords(FormDict& names) {
716 // Insert keyword strings into Global Name Table. Keywords have a NULL value
717 // field for quick easy identification when checking identifiers.
718 names.Insert("instruct", NULL__null);
719 names.Insert("operand", NULL__null);
720 names.Insert("attribute", NULL__null);
721 names.Insert("source", NULL__null);
722 names.Insert("register", NULL__null);
723 names.Insert("pipeline", NULL__null);
724 names.Insert("constraint", NULL__null);
725 names.Insert("predicate", NULL__null);
726 names.Insert("encode", NULL__null);
727 names.Insert("enc_class", NULL__null);
728 names.Insert("interface", NULL__null);
729 names.Insert("opcode", NULL__null);
730 names.Insert("ins_encode", NULL__null);
731 names.Insert("match", NULL__null);
732 names.Insert("effect", NULL__null);
733 names.Insert("expand", NULL__null);
734 names.Insert("rewrite", NULL__null);
735 names.Insert("reg_def", NULL__null);
736 names.Insert("reg_class", NULL__null);
737 names.Insert("alloc_class", NULL__null);
738 names.Insert("resource", NULL__null);
739 names.Insert("pipe_class", NULL__null);
740 names.Insert("pipe_desc", NULL__null);
741}
742
743
744//------------------------------internal_err----------------------------------
745// Issue a parser error message, and skip to the end of the current line
746void ArchDesc::internal_err(const char *fmt, ...) {
747 va_list args;
748
749 va_start(args, fmt)__builtin_va_start(args, fmt);
750 _internal_errs += emit_msg(0, INTERNAL_ERR3, 0, fmt, args);
751 va_end(args)__builtin_va_end(args);
752
753 _no_output = 1;
754}
755
756//------------------------------syntax_err----------------------------------
757// Issue a parser error message, and skip to the end of the current line
758void ArchDesc::syntax_err(int lineno, const char *fmt, ...) {
759 va_list args;
760
761 va_start(args, fmt)__builtin_va_start(args, fmt);
762 _internal_errs += emit_msg(0, SYNERR1, lineno, fmt, args);
763 va_end(args)__builtin_va_end(args);
764
765 _no_output = 1;
766}
767
768//------------------------------emit_msg---------------------------------------
769// Emit a user message, typically a warning or error
770int ArchDesc::emit_msg(int quiet, int flag, int line, const char *fmt,
771 va_list args) {
772 static int last_lineno = -1;
773 int i;
774 const char *pref;
775
776 switch(flag) {
777 case 0: pref = "Warning: "; break;
778 case 1: pref = "Syntax Error: "; break;
779 case 2: pref = "Semantic Error: "; break;
780 case 3: pref = "Internal Error: "; break;
781 default: assert(0, ""){ if (!(0)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 781, ""); abort(); }}
; break;
782 }
783
784 if (line == last_lineno) return 0;
785 last_lineno = line;
786
787 if (!quiet) { /* no output if in quiet mode */
788 i = fprintf(errfile, "%s(%d) ", _ADL_file._name, line);
789 while (i++ <= 15) fputc(' ', errfile);
790 fprintf(errfile, "%-8s:", pref);
791 vfprintf(errfile, fmt, args);
792 fprintf(errfile, "\n");
793 fflush(errfile);
794 }
795 return 1;
796}
797
798
799// ---------------------------------------------------------------------------
800//--------Utilities to build mappings for machine registers ------------------
801// ---------------------------------------------------------------------------
802
803// Construct the name of the register mask.
804static const char *getRegMask(const char *reg_class_name) {
805 if( reg_class_name == NULL__null ) return "RegMask::Empty";
806
807 if (strcmp(reg_class_name,"Universe")==0) {
808 return "RegMask::Empty";
809 } else if (strcmp(reg_class_name,"stack_slots")==0) {
810 return "(Compile::current()->FIRST_STACK_mask())";
811 } else if (strcmp(reg_class_name, "dynamic")==0) {
812 return "*_opnds[0]->in_RegMask(0)";
813 } else {
814 char *rc_name = toUpper(reg_class_name);
815 const char *mask = "_mask";
816 int length = (int)strlen(rc_name) + (int)strlen(mask) + 5;
817 char *regMask = new char[length];
818 sprintf(regMask,"%s%s()", rc_name, mask);
819 delete[] rc_name;
820 return regMask;
821 }
822}
823
824// Convert a register class name to its register mask.
825const char *ArchDesc::reg_class_to_reg_mask(const char *rc_name) {
826 const char *reg_mask = "RegMask::Empty";
827
828 if( _register ) {
829 RegClass *reg_class = _register->getRegClass(rc_name);
830 if (reg_class == NULL__null) {
831 syntax_err(0, "Use of an undefined register class %s", rc_name);
832 return reg_mask;
833 }
834
835 // Construct the name of the register mask.
836 reg_mask = getRegMask(rc_name);
837 }
838
839 return reg_mask;
840}
841
842
843// Obtain the name of the RegMask for an OperandForm
844const char *ArchDesc::reg_mask(OperandForm &opForm) {
845 const char *regMask = "RegMask::Empty";
846
847 // Check constraints on result's register class
848 const char *result_class = opForm.constrained_reg_class();
849 if (result_class == NULL__null) {
850 opForm.dump();
851 syntax_err(opForm._linenum,
852 "Use of an undefined result class for operand: %s",
853 opForm._ident);
854 abort();
855 }
856
857 regMask = reg_class_to_reg_mask( result_class );
858
859 return regMask;
860}
861
862// Obtain the name of the RegMask for an InstructForm
863const char *ArchDesc::reg_mask(InstructForm &inForm) {
864 const char *result = inForm.reduce_result();
865
866 if (result == NULL__null) {
867 syntax_err(inForm._linenum,
868 "Did not find result operand or RegMask"
869 " for this instruction: %s",
870 inForm._ident);
871 abort();
872 }
873
874 // Instructions producing 'Universe' use RegMask::Empty
875 if (strcmp(result,"Universe") == 0) {
876 return "RegMask::Empty";
877 }
878
879 // Lookup this result operand and get its register class
880 Form *form = (Form*)_globalNames[result];
881 if (form == NULL__null) {
882 syntax_err(inForm._linenum,
883 "Did not find result operand for result: %s", result);
884 abort();
885 }
886 OperandForm *oper = form->is_operand();
887 if (oper == NULL__null) {
888 syntax_err(inForm._linenum, "Form is not an OperandForm:");
889 form->dump();
890 abort();
891 }
892 return reg_mask( *oper );
893}
894
895
896// Obtain the STACK_OR_reg_mask name for an OperandForm
897char *ArchDesc::stack_or_reg_mask(OperandForm &opForm) {
898 // name of cisc_spillable version
899 const char *reg_mask_name = reg_mask(opForm);
900
901 if (reg_mask_name == NULL__null) {
902 syntax_err(opForm._linenum,
903 "Did not find reg_mask for opForm: %s",
904 opForm._ident);
905 abort();
906 }
907
908 const char *stack_or = "STACK_OR_";
909 int length = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
910 char *result = new char[length];
911 sprintf(result,"%s%s", stack_or, reg_mask_name);
912
913 return result;
914}
915
916// Record that the register class must generate a stack_or_reg_mask
917void ArchDesc::set_stack_or_reg(const char *reg_class_name) {
918 if( _register ) {
919 RegClass *reg_class = _register->getRegClass(reg_class_name);
920 reg_class->set_stack_version(true);
921 }
922}
923
924
925// Return the type signature for the ideal operation
926const char *ArchDesc::getIdealType(const char *idealOp) {
927 // Find last character in idealOp, it specifies the type
928 char last_char = 0;
929 const char *ptr = idealOp;
930 for (; *ptr != '\0'; ++ptr) {
931 last_char = *ptr;
932 }
933
934 // Match Vector types.
935 if (strncmp(idealOp, "Vec",3)==0) {
936 switch(last_char) {
937 case 'A': return "TypeVect::VECTA";
938 case 'S': return "TypeVect::VECTS";
939 case 'D': return "TypeVect::VECTD";
940 case 'X': return "TypeVect::VECTX";
941 case 'Y': return "TypeVect::VECTY";
942 case 'Z': return "TypeVect::VECTZ";
943 default:
944 internal_err("Vector type %s with unrecognized type\n",idealOp);
945 }
946 }
947
948 if (strncmp(idealOp, "RegVectMask", 8) == 0) {
949 return "TypeVect::VECTMASK";
950 }
951
952 // !!!!!
953 switch(last_char) {
954 case 'I': return "TypeInt::INT";
955 case 'P': return "TypePtr::BOTTOM";
956 case 'N': return "TypeNarrowOop::BOTTOM";
957 case 'F': return "Type::FLOAT";
958 case 'D': return "Type::DOUBLE";
959 case 'L': return "TypeLong::LONG";
960 case 's': return "TypeInt::CC /*flags*/";
961 default:
962 return NULL__null;
963 // !!!!!
964 // internal_err("Ideal type %s with unrecognized type\n",idealOp);
965 break;
966 }
967
968 return NULL__null;
969}
970
971
972
973OperandForm *ArchDesc::constructOperand(const char *ident,
974 bool ideal_only) {
975 OperandForm *opForm = new OperandForm(ident, ideal_only);
976 _globalNames.Insert(ident, opForm);
977 addForm(opForm);
978
979 return opForm;
980}
981
982
983// Import predefined base types: Set = 1, RegI, RegP, ...
984void ArchDesc::initBaseOpTypes() {
985 // Create OperandForm and assign type for each opcode.
986 for (int i = 1; i < _last_machine_leaf; ++i) {
987 char *ident = (char *)NodeClassNames[i];
988 constructOperand(ident, true);
989 }
990 // Create InstructForm and assign type for each ideal instruction.
991 for (int j = _last_machine_leaf+1; j < _last_opcode; ++j) {
992 char *ident = (char *)NodeClassNames[j];
993 if (!strcmp(ident, "ConI") || !strcmp(ident, "ConP") ||
994 !strcmp(ident, "ConN") || !strcmp(ident, "ConNKlass") ||
995 !strcmp(ident, "ConF") || !strcmp(ident, "ConD") ||
996 !strcmp(ident, "ConL") || !strcmp(ident, "Con" ) ||
997 !strcmp(ident, "Bool")) {
998 constructOperand(ident, true);
999 } else {
1000 InstructForm *insForm = new InstructForm(ident, true);
1001 // insForm->_opcode = nextUserOpType(ident);
1002 _globalNames.Insert(ident, insForm);
1003 addForm(insForm);
1004 }
1005 }
1006
1007 { OperandForm *opForm;
1008 // Create operand type "Universe" for return instructions.
1009 const char *ident = "Universe";
1010 opForm = constructOperand(ident, false);
1011
1012 // Create operand type "label" for branch targets
1013 ident = "label";
1014 opForm = constructOperand(ident, false);
1015
1016 // !!!!! Update - when adding a new sReg/stackSlot type
1017 // Create operand types "sReg[IPFDL]" for stack slot registers
1018 opForm = constructOperand("sRegI", false);
1019 opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1020 opForm = constructOperand("sRegP", false);
1021 opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1022 opForm = constructOperand("sRegF", false);
1023 opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1024 opForm = constructOperand("sRegD", false);
1025 opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1026 opForm = constructOperand("sRegL", false);
1027 opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1028
1029 // Create operand type "method" for call targets
1030 ident = "method";
1031 opForm = constructOperand(ident, false);
1032 }
1033
1034 // Create Effect Forms for each of the legal effects
1035 // USE, DEF, USE_DEF, KILL, USE_KILL
1036 {
1037 const char *ident = "USE";
1038 Effect *eForm = new Effect(ident);
1039 _globalNames.Insert(ident, eForm);
1040 ident = "DEF";
1041 eForm = new Effect(ident);
1042 _globalNames.Insert(ident, eForm);
1043 ident = "USE_DEF";
1044 eForm = new Effect(ident);
1045 _globalNames.Insert(ident, eForm);
1046 ident = "KILL";
1047 eForm = new Effect(ident);
1048 _globalNames.Insert(ident, eForm);
1049 ident = "USE_KILL";
1050 eForm = new Effect(ident);
1051 _globalNames.Insert(ident, eForm);
1052 ident = "TEMP";
1053 eForm = new Effect(ident);
1054 _globalNames.Insert(ident, eForm);
1055 ident = "TEMP_DEF";
1056 eForm = new Effect(ident);
1057 _globalNames.Insert(ident, eForm);
1058 ident = "CALL";
1059 eForm = new Effect(ident);
1060 _globalNames.Insert(ident, eForm);
1061 }
1062
1063 //
1064 // Build mapping from ideal names to ideal indices
1065 int idealIndex = 0;
1066 for (idealIndex = 1; idealIndex < _last_machine_leaf; ++idealIndex) {
1067 const char *idealName = NodeClassNames[idealIndex];
1068 _idealIndex.Insert((void*) idealName, (void*) (intptr_t) idealIndex);
1069 }
1070 for (idealIndex = _last_machine_leaf+1;
1071 idealIndex < _last_opcode; ++idealIndex) {
1072 const char *idealName = NodeClassNames[idealIndex];
1073 _idealIndex.Insert((void*) idealName, (void*) (intptr_t) idealIndex);
1074 }
1075
1076}
1077
1078
1079//---------------------------addSUNcopyright-------------------------------
1080// output SUN copyright info
1081void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
1082 size_t count = fwrite(legal, 1, size, fp);
1083 assert(count == (size_t) size, "copyright info truncated"){ if (!(count == (size_t) size)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/archDesc.cpp"
, 1083, "copyright info truncated"); abort(); }}
;
1084 fprintf(fp,"\n");
1085 fprintf(fp,"// Machine Generated File. Do Not Edit!\n");
1086 fprintf(fp,"\n");
1087}
1088
1089
1090//---------------------------addIncludeGuardStart--------------------------
1091// output the start of an include guard.
1092void ArchDesc::addIncludeGuardStart(ADLFILE &adlfile, const char* guardString) {
1093 // Build #include lines
1094 fprintf(adlfile._fp, "\n");
1095 fprintf(adlfile._fp, "#ifndef %s\n", guardString);
1096 fprintf(adlfile._fp, "#define %s\n", guardString);
1097 fprintf(adlfile._fp, "\n");
1098
1099}
1100
1101//---------------------------addIncludeGuardEnd--------------------------
1102// output the end of an include guard.
1103void ArchDesc::addIncludeGuardEnd(ADLFILE &adlfile, const char* guardString) {
1104 // Build #include lines
1105 fprintf(adlfile._fp, "\n");
1106 fprintf(adlfile._fp, "#endif // %s\n", guardString);
1107
1108}
1109
1110//---------------------------addInclude--------------------------
1111// output the #include line for this file.
1112void ArchDesc::addInclude(ADLFILE &adlfile, const char* fileName) {
1113 fprintf(adlfile._fp, "#include \"%s\"\n", fileName);
1114
1115}
1116
1117void ArchDesc::addInclude(ADLFILE &adlfile, const char* includeDir, const char* fileName) {
1118 fprintf(adlfile._fp, "#include \"%s/%s\"\n", includeDir, fileName);
1119
1120}
1121
1122//---------------------------addPreprocessorChecks-----------------------------
1123// Output C preprocessor code to verify the backend compilation environment.
1124// The idea is to force code produced by "adlc -DHS64" to be compiled by a
1125// command of the form "CC ... -DHS64 ...", so that any #ifdefs in the source
1126// blocks select C code that is consistent with adlc's selections of AD code.
1127void ArchDesc::addPreprocessorChecks(FILE *fp) {
1128 const char* flag;
1129 _preproc_list.reset();
1130 if (_preproc_list.count() > 0 && !_preproc_list.current_is_signal()) {
1131 fprintf(fp, "// Check consistency of C++ compilation with ADLC options:\n");
1132 }
1133 for (_preproc_list.reset(); (flag = _preproc_list.iter()) != NULL__null; ) {
1134 if (_preproc_list.current_is_signal()) break;
1135 char* def = get_preproc_def(flag);
1136 fprintf(fp, "// Check adlc ");
1137 if (def)
1138 fprintf(fp, "-D%s=%s\n", flag, def);
1139 else fprintf(fp, "-U%s\n", flag);
1140 fprintf(fp, "#%s %s\n",
1141 def ? "ifndef" : "ifdef", flag);
1142 fprintf(fp, "# error \"%s %s be defined\"\n",
1143 flag, def ? "must" : "must not");
1144 fprintf(fp, "#endif // %s\n", flag);
1145 }
1146}
1147
1148
1149// Convert operand name into enum name
1150const char *ArchDesc::machOperEnum(const char *opName) {
1151 return ArchDesc::getMachOperEnum(opName);
1152}
1153
1154// Convert operand name into enum name
1155const char *ArchDesc::getMachOperEnum(const char *opName) {
1156 return (opName ? toUpper(opName) : opName);
1157}
1158
1159//---------------------------buildMustCloneMap-----------------------------
1160// Flag cases when machine needs cloned values or instructions
1161void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
1162 // Build external declarations for mappings
1163 fprintf(fp_hpp, "// Mapping from machine-independent opcode to boolean\n");
1164 fprintf(fp_hpp, "// Flag cases where machine needs cloned values or instructions\n");
1165 fprintf(fp_hpp, "extern const char must_clone[];\n");
1166 fprintf(fp_hpp, "\n");
1167
1168 // Build mapping from ideal names to ideal indices
1169 fprintf(fp_cpp, "\n");
1170 fprintf(fp_cpp, "// Mapping from machine-independent opcode to boolean\n");
1171 fprintf(fp_cpp, "const char must_clone[] = {\n");
1172 for (int idealIndex = 0; idealIndex < _last_opcode; ++idealIndex) {
1173 int must_clone = 0;
1174 const char *idealName = NodeClassNames[idealIndex];
1175 // Previously selected constants for cloning
1176 // !!!!!
1177 // These are the current machine-dependent clones
1178 if ( strcmp(idealName,"CmpI") == 0
1179 || strcmp(idealName,"CmpU") == 0
1180 || strcmp(idealName,"CmpP") == 0
1181 || strcmp(idealName,"CmpN") == 0
1182 || strcmp(idealName,"CmpL") == 0
1183 || strcmp(idealName,"CmpUL") == 0
1184 || strcmp(idealName,"CmpD") == 0
1185 || strcmp(idealName,"CmpF") == 0
1186 || strcmp(idealName,"FastLock") == 0
1187 || strcmp(idealName,"FastUnlock") == 0
1188 || strcmp(idealName,"OverflowAddI") == 0
1189 || strcmp(idealName,"OverflowAddL") == 0
1190 || strcmp(idealName,"OverflowSubI") == 0
1191 || strcmp(idealName,"OverflowSubL") == 0
1192 || strcmp(idealName,"OverflowMulI") == 0
1193 || strcmp(idealName,"OverflowMulL") == 0
1194 || strcmp(idealName,"Bool") == 0
1195 || strcmp(idealName,"Binary") == 0 ) {
1196 // Removed ConI from the must_clone list. CPUs that cannot use
1197 // large constants as immediates manifest the constant as an
1198 // instruction. The must_clone flag prevents the constant from
1199 // floating up out of loops.
1200 must_clone = 1;
1201 }
1202 fprintf(fp_cpp, " %d%s // %s: %d\n", must_clone,
1203 (idealIndex != (_last_opcode - 1)) ? "," : " // no trailing comma",
1204 idealName, idealIndex);
1205 }
1206 // Finish defining table
1207 fprintf(fp_cpp, "};\n");
1208}