Bug Summary

File:jdk/src/hotspot/share/adlc/formssel.cpp
Warning:line 3672, column 7
Value stored to 'cisc_spillable' 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 formssel.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/formssel.cpp
1/*
2 * Copyright (c) 1998, 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// FORMS.CPP - Definitions for ADL Parser Forms Classes
26#include "adlc.hpp"
27
28//==============================Instructions===================================
29//------------------------------InstructForm-----------------------------------
30InstructForm::InstructForm(const char *id, bool ideal_only)
31 : _ident(id), _ideal_only(ideal_only),
32 _localNames(cmpstr, hashstr, Form::arena),
33 _effects(cmpstr, hashstr, Form::arena),
34 _is_mach_constant(false),
35 _needs_constant_base(false),
36 _has_call(false)
37{
38 _ftype = Form::INS;
39
40 _matrule = NULL__null;
41 _insencode = NULL__null;
42 _constant = NULL__null;
43 _is_postalloc_expand = false;
44 _opcode = NULL__null;
45 _size = NULL__null;
46 _attribs = NULL__null;
47 _predicate = NULL__null;
48 _exprule = NULL__null;
49 _rewrule = NULL__null;
50 _format = NULL__null;
51 _peephole = NULL__null;
52 _ins_pipe = NULL__null;
53 _uniq_idx = NULL__null;
54 _num_uniq = 0;
55 _cisc_spill_operand = Not_cisc_spillable;// Which operand may cisc-spill
56 _cisc_spill_alternate = NULL__null; // possible cisc replacement
57 _cisc_reg_mask_name = NULL__null;
58 _is_cisc_alternate = false;
59 _is_short_branch = false;
60 _short_branch_form = NULL__null;
61 _alignment = 1;
62}
63
64InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule)
65 : _ident(id), _ideal_only(false),
66 _localNames(instr->_localNames),
67 _effects(instr->_effects),
68 _is_mach_constant(false),
69 _needs_constant_base(false),
70 _has_call(false)
71{
72 _ftype = Form::INS;
73
74 _matrule = rule;
75 _insencode = instr->_insencode;
76 _constant = instr->_constant;
77 _is_postalloc_expand = instr->_is_postalloc_expand;
78 _opcode = instr->_opcode;
79 _size = instr->_size;
80 _attribs = instr->_attribs;
81 _predicate = instr->_predicate;
82 _exprule = instr->_exprule;
83 _rewrule = instr->_rewrule;
84 _format = instr->_format;
85 _peephole = instr->_peephole;
86 _ins_pipe = instr->_ins_pipe;
87 _uniq_idx = instr->_uniq_idx;
88 _num_uniq = instr->_num_uniq;
89 _cisc_spill_operand = Not_cisc_spillable; // Which operand may cisc-spill
90 _cisc_spill_alternate = NULL__null; // possible cisc replacement
91 _cisc_reg_mask_name = NULL__null;
92 _is_cisc_alternate = false;
93 _is_short_branch = false;
94 _short_branch_form = NULL__null;
95 _alignment = 1;
96 // Copy parameters
97 const char *name;
98 instr->_parameters.reset();
99 for (; (name = instr->_parameters.iter()) != NULL__null;)
100 _parameters.addName(name);
101}
102
103InstructForm::~InstructForm() {
104}
105
106InstructForm *InstructForm::is_instruction() const {
107 return (InstructForm*)this;
108}
109
110bool InstructForm::ideal_only() const {
111 return _ideal_only;
112}
113
114bool InstructForm::sets_result() const {
115 return (_matrule != NULL__null && _matrule->sets_result());
116}
117
118bool InstructForm::needs_projections() {
119 _components.reset();
120 for( Component *comp; (comp = _components.iter()) != NULL__null; ) {
121 if (comp->isa(Component::KILL)) {
122 return true;
123 }
124 }
125 return false;
126}
127
128
129bool InstructForm::has_temps() {
130 if (_matrule) {
131 // Examine each component to see if it is a TEMP
132 _components.reset();
133 // Skip the first component, if already handled as (SET dst (...))
134 Component *comp = NULL__null;
135 if (sets_result()) comp = _components.iter();
136 while ((comp = _components.iter()) != NULL__null) {
137 if (comp->isa(Component::TEMP)) {
138 return true;
139 }
140 }
141 }
142
143 return false;
144}
145
146uintunsigned int InstructForm::num_defs_or_kills() {
147 uintunsigned int defs_or_kills = 0;
148
149 _components.reset();
150 for( Component *comp; (comp = _components.iter()) != NULL__null; ) {
151 if( comp->isa(Component::DEF) || comp->isa(Component::KILL) ) {
152 ++defs_or_kills;
153 }
154 }
155
156 return defs_or_kills;
157}
158
159// This instruction has an expand rule?
160bool InstructForm::expands() const {
161 return ( _exprule != NULL__null );
162}
163
164// This instruction has a late expand rule?
165bool InstructForm::postalloc_expands() const {
166 return _is_postalloc_expand;
167}
168
169// This instruction has a peephole rule?
170Peephole *InstructForm::peepholes() const {
171 return _peephole;
172}
173
174// This instruction has a peephole rule?
175void InstructForm::append_peephole(Peephole *peephole) {
176 if( _peephole == NULL__null ) {
177 _peephole = peephole;
178 } else {
179 _peephole->append_peephole(peephole);
180 }
181}
182
183
184// ideal opcode enumeration
185const char *InstructForm::ideal_Opcode( FormDict &globalNames ) const {
186 if( !_matrule ) return "Node"; // Something weird
187 // Chain rules do not really have ideal Opcodes; use their source
188 // operand ideal Opcode instead.
189 if( is_simple_chain_rule(globalNames) ) {
190 const char *src = _matrule->_rChild->_opType;
191 OperandForm *src_op = globalNames[src]->is_operand();
192 assert( src_op, "Not operand class of chain rule" ){ if (!(src_op)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 192, "Not operand class of chain rule"); abort(); }}
;
193 if( !src_op->_matrule ) return "Node";
194 return src_op->_matrule->_opType;
195 }
196 // Operand chain rules do not really have ideal Opcodes
197 if( _matrule->is_chain_rule(globalNames) )
198 return "Node";
199 return strcmp(_matrule->_opType,"Set")
200 ? _matrule->_opType
201 : _matrule->_rChild->_opType;
202}
203
204// Recursive check on all operands' match rules in my match rule
205bool InstructForm::is_pinned(FormDict &globals) {
206 if ( ! _matrule) return false;
207
208 int index = 0;
209 if (_matrule->find_type("Goto", index)) return true;
210 if (_matrule->find_type("If", index)) return true;
211 if (_matrule->find_type("CountedLoopEnd",index)) return true;
212 if (_matrule->find_type("Return", index)) return true;
213 if (_matrule->find_type("Rethrow", index)) return true;
214 if (_matrule->find_type("TailCall", index)) return true;
215 if (_matrule->find_type("TailJump", index)) return true;
216 if (_matrule->find_type("Halt", index)) return true;
217 if (_matrule->find_type("Jump", index)) return true;
218
219 return is_parm(globals);
220}
221
222// Recursive check on all operands' match rules in my match rule
223bool InstructForm::is_projection(FormDict &globals) {
224 if ( ! _matrule) return false;
225
226 int index = 0;
227 if (_matrule->find_type("Goto", index)) return true;
228 if (_matrule->find_type("Return", index)) return true;
229 if (_matrule->find_type("Rethrow", index)) return true;
230 if (_matrule->find_type("TailCall",index)) return true;
231 if (_matrule->find_type("TailJump",index)) return true;
232 if (_matrule->find_type("Halt", index)) return true;
233
234 return false;
235}
236
237// Recursive check on all operands' match rules in my match rule
238bool InstructForm::is_parm(FormDict &globals) {
239 if ( ! _matrule) return false;
240
241 int index = 0;
242 if (_matrule->find_type("Parm",index)) return true;
243
244 return false;
245}
246
247bool InstructForm::is_ideal_negD() const {
248 return (_matrule && _matrule->_rChild && strcmp(_matrule->_rChild->_opType, "NegD") == 0);
249}
250
251// Return 'true' if this instruction matches an ideal 'Copy*' node
252int InstructForm::is_ideal_copy() const {
253 return _matrule ? _matrule->is_ideal_copy() : 0;
254}
255
256// Return 'true' if this instruction is too complex to rematerialize.
257int InstructForm::is_expensive() const {
258 // We can prove it is cheap if it has an empty encoding.
259 // This helps with platform-specific nops like ThreadLocal and RoundFloat.
260 if (is_empty_encoding())
261 return 0;
262
263 if (is_tls_instruction())
264 return 1;
265
266 if (_matrule == NULL__null) return 0;
267
268 return _matrule->is_expensive();
269}
270
271// Has an empty encoding if _size is a constant zero or there
272// are no ins_encode tokens.
273int InstructForm::is_empty_encoding() const {
274 if (_insencode != NULL__null) {
275 _insencode->reset();
276 if (_insencode->encode_class_iter() == NULL__null) {
277 return 1;
278 }
279 }
280 if (_size != NULL__null && strcmp(_size, "0") == 0) {
281 return 1;
282 }
283 return 0;
284}
285
286int InstructForm::is_tls_instruction() const {
287 if (_ident != NULL__null &&
288 ( ! strcmp( _ident,"tlsLoadP") ||
289 ! strncmp(_ident,"tlsLoadP_",9)) ) {
290 return 1;
291 }
292
293 if (_matrule != NULL__null && _insencode != NULL__null) {
294 const char* opType = _matrule->_opType;
295 if (strcmp(opType, "Set")==0)
296 opType = _matrule->_rChild->_opType;
297 if (strcmp(opType,"ThreadLocal")==0) {
298 fprintf(stderrstderr, "Warning: ThreadLocal instruction %s should be named 'tlsLoadP_*'\n",
299 (_ident == NULL__null ? "NULL" : _ident));
300 return 1;
301 }
302 }
303
304 return 0;
305}
306
307
308// Return 'true' if this instruction matches an ideal 'If' node
309bool InstructForm::is_ideal_if() const {
310 if( _matrule == NULL__null ) return false;
311
312 return _matrule->is_ideal_if();
313}
314
315// Return 'true' if this instruction matches an ideal 'FastLock' node
316bool InstructForm::is_ideal_fastlock() const {
317 if( _matrule == NULL__null ) return false;
318
319 return _matrule->is_ideal_fastlock();
320}
321
322// Return 'true' if this instruction matches an ideal 'MemBarXXX' node
323bool InstructForm::is_ideal_membar() const {
324 if( _matrule == NULL__null ) return false;
325
326 return _matrule->is_ideal_membar();
327}
328
329// Return 'true' if this instruction matches an ideal 'LoadPC' node
330bool InstructForm::is_ideal_loadPC() const {
331 if( _matrule == NULL__null ) return false;
332
333 return _matrule->is_ideal_loadPC();
334}
335
336// Return 'true' if this instruction matches an ideal 'Box' node
337bool InstructForm::is_ideal_box() const {
338 if( _matrule == NULL__null ) return false;
339
340 return _matrule->is_ideal_box();
341}
342
343// Return 'true' if this instruction matches an ideal 'Goto' node
344bool InstructForm::is_ideal_goto() const {
345 if( _matrule == NULL__null ) return false;
346
347 return _matrule->is_ideal_goto();
348}
349
350// Return 'true' if this instruction matches an ideal 'Jump' node
351bool InstructForm::is_ideal_jump() const {
352 if( _matrule == NULL__null ) return false;
353
354 return _matrule->is_ideal_jump();
355}
356
357// Return 'true' if instruction matches ideal 'If' | 'Goto' | 'CountedLoopEnd'
358bool InstructForm::is_ideal_branch() const {
359 if( _matrule == NULL__null ) return false;
360
361 return _matrule->is_ideal_if() || _matrule->is_ideal_goto();
362}
363
364
365// Return 'true' if this instruction matches an ideal 'Return' node
366bool InstructForm::is_ideal_return() const {
367 if( _matrule == NULL__null ) return false;
368
369 // Check MatchRule to see if the first entry is the ideal "Return" node
370 int index = 0;
371 if (_matrule->find_type("Return",index)) return true;
372 if (_matrule->find_type("Rethrow",index)) return true;
373 if (_matrule->find_type("TailCall",index)) return true;
374 if (_matrule->find_type("TailJump",index)) return true;
375
376 return false;
377}
378
379// Return 'true' if this instruction matches an ideal 'Halt' node
380bool InstructForm::is_ideal_halt() const {
381 int index = 0;
382 return _matrule && _matrule->find_type("Halt",index);
383}
384
385// Return 'true' if this instruction matches an ideal 'SafePoint' node
386bool InstructForm::is_ideal_safepoint() const {
387 int index = 0;
388 return _matrule && _matrule->find_type("SafePoint",index);
389}
390
391// Return 'true' if this instruction matches an ideal 'Nop' node
392bool InstructForm::is_ideal_nop() const {
393 return _ident && _ident[0] == 'N' && _ident[1] == 'o' && _ident[2] == 'p' && _ident[3] == '_';
394}
395
396bool InstructForm::is_ideal_control() const {
397 if ( ! _matrule) return false;
398
399 return is_ideal_return() || is_ideal_branch() || _matrule->is_ideal_jump() || is_ideal_halt();
400}
401
402// Return 'true' if this instruction matches an ideal 'Call' node
403Form::CallType InstructForm::is_ideal_call() const {
404 if( _matrule == NULL__null ) return Form::invalid_type;
405
406 // Check MatchRule to see if the first entry is the ideal "Call" node
407 int idx = 0;
408 if(_matrule->find_type("CallStaticJava",idx)) return Form::JAVA_STATIC;
409 idx = 0;
410 if(_matrule->find_type("Lock",idx)) return Form::JAVA_STATIC;
411 idx = 0;
412 if(_matrule->find_type("Unlock",idx)) return Form::JAVA_STATIC;
413 idx = 0;
414 if(_matrule->find_type("CallDynamicJava",idx)) return Form::JAVA_DYNAMIC;
415 idx = 0;
416 if(_matrule->find_type("CallRuntime",idx)) return Form::JAVA_RUNTIME;
417 idx = 0;
418 if(_matrule->find_type("CallLeaf",idx)) return Form::JAVA_LEAF;
419 idx = 0;
420 if(_matrule->find_type("CallLeafNoFP",idx)) return Form::JAVA_LEAF;
421 idx = 0;
422 if(_matrule->find_type("CallLeafVector",idx)) return Form::JAVA_LEAF;
423 idx = 0;
424 if(_matrule->find_type("CallNative",idx)) return Form::JAVA_NATIVE;
425 idx = 0;
426
427 return Form::invalid_type;
428}
429
430// Return 'true' if this instruction matches an ideal 'Load?' node
431Form::DataType InstructForm::is_ideal_load() const {
432 if( _matrule == NULL__null ) return Form::none;
433
434 return _matrule->is_ideal_load();
435}
436
437// Return 'true' if this instruction matches an ideal 'LoadKlass' node
438bool InstructForm::skip_antidep_check() const {
439 if( _matrule == NULL__null ) return false;
440
441 return _matrule->skip_antidep_check();
442}
443
444// Return 'true' if this instruction matches an ideal 'Load?' node
445Form::DataType InstructForm::is_ideal_store() const {
446 if( _matrule == NULL__null ) return Form::none;
447
448 return _matrule->is_ideal_store();
449}
450
451// Return 'true' if this instruction matches an ideal vector node
452bool InstructForm::is_vector() const {
453 if( _matrule == NULL__null ) return false;
454
455 return _matrule->is_vector();
456}
457
458
459// Return the input register that must match the output register
460// If this is not required, return 0
461uintunsigned int InstructForm::two_address(FormDict &globals) {
462 uintunsigned int matching_input = 0;
463 if(_components.count() == 0) return 0;
464
465 _components.reset();
466 Component *comp = _components.iter();
467 // Check if there is a DEF
468 if( comp->isa(Component::DEF) ) {
469 // Check that this is a register
470 const char *def_type = comp->_type;
471 const Form *form = globals[def_type];
472 OperandForm *op = form->is_operand();
473 if( op ) {
474 if( op->constrained_reg_class() != NULL__null &&
475 op->interface_type(globals) == Form::register_interface ) {
476 // Remember the local name for equality test later
477 const char *def_name = comp->_name;
478 // Check if a component has the same name and is a USE
479 do {
480 if( comp->isa(Component::USE) && strcmp(comp->_name,def_name)==0 ) {
481 return operand_position_format(def_name);
482 }
483 } while( (comp = _components.iter()) != NULL__null);
484 }
485 }
486 }
487
488 return 0;
489}
490
491
492// when chaining a constant to an instruction, returns 'true' and sets opType
493Form::DataType InstructForm::is_chain_of_constant(FormDict &globals) {
494 const char *dummy = NULL__null;
495 const char *dummy2 = NULL__null;
496 return is_chain_of_constant(globals, dummy, dummy2);
497}
498Form::DataType InstructForm::is_chain_of_constant(FormDict &globals,
499 const char * &opTypeParam) {
500 const char *result = NULL__null;
501
502 return is_chain_of_constant(globals, opTypeParam, result);
503}
504
505Form::DataType InstructForm::is_chain_of_constant(FormDict &globals,
506 const char * &opTypeParam, const char * &resultParam) {
507 Form::DataType data_type = Form::none;
508 if ( ! _matrule) return data_type;
509
510 // !!!!!
511 // The source of the chain rule is 'position = 1'
512 uintunsigned int position = 1;
513 const char *result = NULL__null;
514 const char *name = NULL__null;
515 const char *opType = NULL__null;
516 // Here base_operand is looking for an ideal type to be returned (opType).
517 if ( _matrule->is_chain_rule(globals)
518 && _matrule->base_operand(position, globals, result, name, opType) ) {
519 data_type = ideal_to_const_type(opType);
520
521 // if it isn't an ideal constant type, just return
522 if ( data_type == Form::none ) return data_type;
523
524 // Ideal constant types also adjust the opType parameter.
525 resultParam = result;
526 opTypeParam = opType;
527 return data_type;
528 }
529
530 return data_type;
531}
532
533// Check if a simple chain rule
534bool InstructForm::is_simple_chain_rule(FormDict &globals) const {
535 if( _matrule && _matrule->sets_result()
536 && _matrule->_rChild->_lChild == NULL__null
537 && globals[_matrule->_rChild->_opType]
538 && globals[_matrule->_rChild->_opType]->is_opclass() ) {
539 return true;
540 }
541 return false;
542}
543
544// check for structural rematerialization
545bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) {
546 bool rematerialize = false;
547
548 Form::DataType data_type = is_chain_of_constant(globals);
549 if( data_type != Form::none )
550 rematerialize = true;
551
552 // Constants
553 if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) )
554 rematerialize = true;
555
556 // Pseudo-constants (values easily available to the runtime)
557 if (is_empty_encoding() && is_tls_instruction())
558 rematerialize = true;
559
560 // 1-input, 1-output, such as copies or increments.
561 if( _components.count() == 2 &&
562 _components[0]->is(Component::DEF) &&
563 _components[1]->isa(Component::USE) )
564 rematerialize = true;
565
566 // Check for an ideal 'Load?' and eliminate rematerialize option
567 if ( is_ideal_load() != Form::none || // Ideal load? Do not rematerialize
568 is_ideal_copy() != Form::none || // Ideal copy? Do not rematerialize
569 is_expensive() != Form::none) { // Expensive? Do not rematerialize
570 rematerialize = false;
571 }
572
573 // Always rematerialize the flags. They are more expensive to save &
574 // restore than to recompute (and possibly spill the compare's inputs).
575 if( _components.count() >= 1 ) {
576 Component *c = _components[0];
577 const Form *form = globals[c->_type];
578 OperandForm *opform = form->is_operand();
579 if( opform ) {
580 // Avoid the special stack_slots register classes
581 const char *rc_name = opform->constrained_reg_class();
582 if( rc_name ) {
583 if( strcmp(rc_name,"stack_slots") ) {
584 // Check for ideal_type of RegFlags
585 const char *type = opform->ideal_type( globals, registers );
586 if( (type != NULL__null) && !strcmp(type, "RegFlags") )
587 rematerialize = true;
588 } else
589 rematerialize = false; // Do not rematerialize things target stk
590 }
591 }
592 }
593
594 return rematerialize;
595}
596
597// loads from memory, so must check for anti-dependence
598bool InstructForm::needs_anti_dependence_check(FormDict &globals) const {
599 if ( skip_antidep_check() ) return false;
600
601 // Machine independent loads must be checked for anti-dependences
602 if( is_ideal_load() != Form::none ) return true;
603
604 // !!!!! !!!!! !!!!!
605 // TEMPORARY
606 // if( is_simple_chain_rule(globals) ) return false;
607
608 // String.(compareTo/equals/indexOf) and Arrays.equals use many memorys edges,
609 // but writes none
610 if( _matrule && _matrule->_rChild &&
611 ( strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
612 strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
613 strcmp(_matrule->_rChild->_opType,"StrIndexOf" )==0 ||
614 strcmp(_matrule->_rChild->_opType,"StrIndexOfChar" )==0 ||
615 strcmp(_matrule->_rChild->_opType,"HasNegatives" )==0 ||
616 strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ))
617 return true;
618
619 // Check if instruction has a USE of a memory operand class, but no defs
620 bool USE_of_memory = false;
621 bool DEF_of_memory = false;
622 Component *comp = NULL__null;
623 ComponentList &components = (ComponentList &)_components;
624
625 components.reset();
626 while( (comp = components.iter()) != NULL__null ) {
627 const Form *form = globals[comp->_type];
628 if( !form ) continue;
629 OpClassForm *op = form->is_opclass();
630 if( !op ) continue;
631 if( form->interface_type(globals) == Form::memory_interface ) {
632 if( comp->isa(Component::USE) ) USE_of_memory = true;
633 if( comp->isa(Component::DEF) ) {
634 OperandForm *oper = form->is_operand();
635 if( oper && oper->is_user_name_for_sReg() ) {
636 // Stack slots are unaliased memory handled by allocator
637 oper = oper; // debug stopping point !!!!!
638 } else {
639 DEF_of_memory = true;
640 }
641 }
642 }
643 }
644 return (USE_of_memory && !DEF_of_memory);
645}
646
647
648int InstructForm::memory_operand(FormDict &globals) const {
649 // Machine independent loads must be checked for anti-dependences
650 // Check if instruction has a USE of a memory operand class, or a def.
651 int USE_of_memory = 0;
652 int DEF_of_memory = 0;
653 const char* last_memory_DEF = NULL__null; // to test DEF/USE pairing in asserts
654 const char* last_memory_USE = NULL__null;
655 Component *unique = NULL__null;
656 Component *comp = NULL__null;
657 ComponentList &components = (ComponentList &)_components;
658
659 components.reset();
660 while( (comp = components.iter()) != NULL__null ) {
661 const Form *form = globals[comp->_type];
662 if( !form ) continue;
663 OpClassForm *op = form->is_opclass();
664 if( !op ) continue;
665 if( op->stack_slots_only(globals) ) continue;
666 if( form->interface_type(globals) == Form::memory_interface ) {
667 if( comp->isa(Component::DEF) ) {
668 last_memory_DEF = comp->_name;
669 DEF_of_memory++;
670 unique = comp;
671 } else if( comp->isa(Component::USE) ) {
672 if( last_memory_DEF != NULL__null ) {
673 assert(0 == strcmp(last_memory_DEF, comp->_name), "every memory DEF is followed by a USE of the same name"){ if (!(0 == strcmp(last_memory_DEF, comp->_name))) { fprintf
(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 673, "every memory DEF is followed by a USE of the same name"
); abort(); }}
;
674 last_memory_DEF = NULL__null;
675 }
676 // Handles same memory being used multiple times in the case of BMI1 instructions.
677 if (last_memory_USE != NULL__null) {
678 if (strcmp(comp->_name, last_memory_USE) != 0) {
679 USE_of_memory++;
680 }
681 } else {
682 USE_of_memory++;
683 }
684 last_memory_USE = comp->_name;
685
686 if (DEF_of_memory == 0) // defs take precedence
687 unique = comp;
688 } else {
689 assert(last_memory_DEF == NULL, "unpaired memory DEF"){ if (!(last_memory_DEF == __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 689, "unpaired memory DEF"); abort(); }}
;
690 }
691 }
692 }
693 assert(last_memory_DEF == NULL, "unpaired memory DEF"){ if (!(last_memory_DEF == __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 693, "unpaired memory DEF"); abort(); }}
;
694 assert(USE_of_memory >= DEF_of_memory, "unpaired memory DEF"){ if (!(USE_of_memory >= DEF_of_memory)) { fprintf(stderr,
"assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 694, "unpaired memory DEF"); abort(); }}
;
695 USE_of_memory -= DEF_of_memory; // treat paired DEF/USE as one occurrence
696 if( (USE_of_memory + DEF_of_memory) > 0 ) {
697 if( is_simple_chain_rule(globals) ) {
698 //fprintf(stderr, "Warning: chain rule is not really a memory user.\n");
699 //((InstructForm*)this)->dump();
700 // Preceding code prints nothing on sparc and these insns on intel:
701 // leaP8 leaP32 leaPIdxOff leaPIdxScale leaPIdxScaleOff leaP8 leaP32
702 // leaPIdxOff leaPIdxScale leaPIdxScaleOff
703 return NO_MEMORY_OPERAND;
704 }
705
706 if( DEF_of_memory == 1 ) {
707 assert(unique != NULL, ""){ if (!(unique != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 707, ""); abort(); }}
;
708 if( USE_of_memory == 0 ) {
709 // unique def, no uses
710 } else {
711 // // unique def, some uses
712 // // must return bottom unless all uses match def
713 // unique = NULL;
714#ifdef S390
715 // This case is important for move instructions on s390x.
716 // On other platforms (e.g. x86), all uses always match the def.
717 unique = NULL__null;
718#endif
719 }
720 } else if( DEF_of_memory > 0 ) {
721 // multiple defs, don't care about uses
722 unique = NULL__null;
723 } else if( USE_of_memory == 1) {
724 // unique use, no defs
725 assert(unique != NULL, ""){ if (!(unique != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 725, ""); abort(); }}
;
726 } else if( USE_of_memory > 0 ) {
727 // multiple uses, no defs
728 unique = NULL__null;
729 } else {
730 assert(false, "bad case analysis"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 730, "bad case analysis"); abort(); }}
;
731 }
732 // process the unique DEF or USE, if there is one
733 if( unique == NULL__null ) {
734 return MANY_MEMORY_OPERANDS;
735 } else {
736 int pos = components.operand_position(unique->_name);
737 if( unique->isa(Component::DEF) ) {
738 pos += 1; // get corresponding USE from DEF
739 }
740 assert(pos >= 1, "I was just looking at it!"){ if (!(pos >= 1)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 740, "I was just looking at it!"); abort(); }}
;
741 return pos;
742 }
743 }
744
745 // missed the memory op??
746 if( true ) { // %%% should not be necessary
747 if( is_ideal_store() != Form::none ) {
748 fprintf(stderrstderr, "Warning: cannot find memory opnd in instr.\n");
749 ((InstructForm*)this)->dump();
750 // pretend it has multiple defs and uses
751 return MANY_MEMORY_OPERANDS;
752 }
753 if( is_ideal_load() != Form::none ) {
754 fprintf(stderrstderr, "Warning: cannot find memory opnd in instr.\n");
755 ((InstructForm*)this)->dump();
756 // pretend it has multiple uses and no defs
757 return MANY_MEMORY_OPERANDS;
758 }
759 }
760
761 return NO_MEMORY_OPERAND;
762}
763
764// This instruction captures the machine-independent bottom_type
765// Expected use is for pointer vs oop determination for LoadP
766bool InstructForm::captures_bottom_type(FormDict &globals) const {
767 if (_matrule && _matrule->_rChild &&
768 (!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type
769 !strcmp(_matrule->_rChild->_opType,"CastDD") ||
770 !strcmp(_matrule->_rChild->_opType,"CastFF") ||
771 !strcmp(_matrule->_rChild->_opType,"CastII") ||
772 !strcmp(_matrule->_rChild->_opType,"CastLL") ||
773 !strcmp(_matrule->_rChild->_opType,"CastVV") ||
774 !strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
775 !strcmp(_matrule->_rChild->_opType,"DecodeN") ||
776 !strcmp(_matrule->_rChild->_opType,"EncodeP") ||
777 !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
778 !strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
779 !strcmp(_matrule->_rChild->_opType,"LoadN") ||
780 !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
781 !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
782 !strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||
783 !strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||
784 !strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
785 !strcmp(_matrule->_rChild->_opType,"RotateLeft") ||
786 !strcmp(_matrule->_rChild->_opType,"RotateRight") ||
787#if INCLUDE_SHENANDOAHGC1
788 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") ||
789 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") ||
790#endif
791 !strcmp(_matrule->_rChild->_opType,"StrInflatedCopy") ||
792 !strcmp(_matrule->_rChild->_opType,"VectorCmpMasked")||
793 !strcmp(_matrule->_rChild->_opType,"VectorMaskGen")||
794 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") ||
795 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true;
796 else if ( is_ideal_load() == Form::idealP ) return true;
797 else if ( is_ideal_store() != Form::none ) return true;
798
799 if (needs_base_oop_edge(globals)) return true;
800
801 if (is_vector()) return true;
802 if (is_mach_constant()) return true;
803
804 return false;
805}
806
807
808// Access instr_cost attribute or return NULL.
809const char* InstructForm::cost() {
810 for (Attribute* cur = _attribs; cur != NULL__null; cur = (Attribute*)cur->_next) {
811 if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
812 return cur->_val;
813 }
814 }
815 return NULL__null;
816}
817
818// Return count of top-level operands.
819uintunsigned int InstructForm::num_opnds() {
820 int num_opnds = _components.num_operands();
821
822 // Need special handling for matching some ideal nodes
823 // i.e. Matching a return node
824 /*
825 if( _matrule ) {
826 if( strcmp(_matrule->_opType,"Return" )==0 ||
827 strcmp(_matrule->_opType,"Halt" )==0 )
828 return 3;
829 }
830 */
831 return num_opnds;
832}
833
834const char* InstructForm::opnd_ident(int idx) {
835 return _components.at(idx)->_name;
836}
837
838const char* InstructForm::unique_opnd_ident(uintunsigned int idx) {
839 uintunsigned int i;
840 for (i = 1; i < num_opnds(); ++i) {
841 if (unique_opnds_idx(i) == idx) {
842 break;
843 }
844 }
845 return (_components.at(i) != NULL__null) ? _components.at(i)->_name : "";
846}
847
848// Return count of unmatched operands.
849uintunsigned int InstructForm::num_post_match_opnds() {
850 uintunsigned int num_post_match_opnds = _components.count();
851 uintunsigned int num_match_opnds = _components.match_count();
852 num_post_match_opnds = num_post_match_opnds - num_match_opnds;
853
854 return num_post_match_opnds;
855}
856
857// Return the number of leaves below this complex operand
858uintunsigned int InstructForm::num_consts(FormDict &globals) const {
859 if ( ! _matrule) return 0;
860
861 // This is a recursive invocation on all operands in the matchrule
862 return _matrule->num_consts(globals);
863}
864
865// Constants in match rule with specified type
866uintunsigned int InstructForm::num_consts(FormDict &globals, Form::DataType type) const {
867 if ( ! _matrule) return 0;
868
869 // This is a recursive invocation on all operands in the matchrule
870 return _matrule->num_consts(globals, type);
871}
872
873
874// Return the register class associated with 'leaf'.
875const char *InstructForm::out_reg_class(FormDict &globals) {
876 assert( false, "InstructForm::out_reg_class(FormDict &globals); Not Implemented"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 876, "InstructForm::out_reg_class(FormDict &globals); Not Implemented"
); abort(); }}
;
877
878 return NULL__null;
879}
880
881
882
883// Lookup the starting position of inputs we are interested in wrt. ideal nodes
884uintunsigned int InstructForm::oper_input_base(FormDict &globals) {
885 if( !_matrule ) return 1; // Skip control for most nodes
886
887 // Need special handling for matching some ideal nodes
888 // i.e. Matching a return node
889 if( strcmp(_matrule->_opType,"Return" )==0 ||
890 strcmp(_matrule->_opType,"Rethrow" )==0 ||
891 strcmp(_matrule->_opType,"TailCall" )==0 ||
892 strcmp(_matrule->_opType,"TailJump" )==0 ||
893 strcmp(_matrule->_opType,"SafePoint" )==0 ||
894 strcmp(_matrule->_opType,"Halt" )==0 )
895 return AdlcVMDeps::Parms; // Skip the machine-state edges
896
897 if( _matrule->_rChild &&
898 ( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||
899 strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
900 strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
901 strcmp(_matrule->_rChild->_opType,"StrInflatedCopy" )==0 ||
902 strcmp(_matrule->_rChild->_opType,"StrCompressedCopy" )==0 ||
903 strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
904 strcmp(_matrule->_rChild->_opType,"StrIndexOfChar")==0 ||
905 strcmp(_matrule->_rChild->_opType,"HasNegatives")==0 ||
906 strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
907 // String.(compareTo/equals/indexOf) and Arrays.equals
908 // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
909 // take 1 control and 1 memory edges.
910 // Also String.(compressedCopy/inflatedCopy).
911 return 2;
912 }
913
914 // Check for handling of 'Memory' input/edge in the ideal world.
915 // The AD file writer is shielded from knowledge of these edges.
916 int base = 1; // Skip control
917 base += _matrule->needs_ideal_memory_edge(globals);
918
919 // Also skip the base-oop value for uses of derived oops.
920 // The AD file writer is shielded from knowledge of these edges.
921 base += needs_base_oop_edge(globals);
922
923 return base;
924}
925
926// This function determines the order of the MachOper in _opnds[]
927// by writing the operand names into the _components list.
928//
929// Implementation does not modify state of internal structures
930void InstructForm::build_components() {
931 // Add top-level operands to the components
932 if (_matrule) _matrule->append_components(_localNames, _components);
933
934 // Add parameters that "do not appear in match rule".
935 bool has_temp = false;
936 const char *name;
937 const char *kill_name = NULL__null;
938 for (_parameters.reset(); (name = _parameters.iter()) != NULL__null;) {
939 OpClassForm *opForm = _localNames[name]->is_opclass();
940 assert(opForm != NULL, "sanity"){ if (!(opForm != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 940, "sanity"); abort(); }}
;
941
942 Effect* e = NULL__null;
943 {
944 const Form* form = _effects[name];
945 e = form ? form->is_effect() : NULL__null;
946 }
947
948 if (e != NULL__null) {
949 has_temp |= e->is(Component::TEMP);
950
951 // KILLs must be declared after any TEMPs because TEMPs are real
952 // uses so their operand numbering must directly follow the real
953 // inputs from the match rule. Fixing the numbering seems
954 // complex so simply enforce the restriction during parse.
955 if (kill_name != NULL__null &&
956 e->isa(Component::TEMP) && !e->isa(Component::DEF)) {
957 OpClassForm* kill = _localNames[kill_name]->is_opclass();
958 assert(kill != NULL, "sanity"){ if (!(kill != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 958, "sanity"); abort(); }}
;
959 globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n",
960 _ident, kill->_ident, kill_name);
961 } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) {
962 kill_name = name;
963 }
964 }
965
966 const Component *component = _components.search(name);
967 if ( component == NULL__null ) {
968 if (e) {
969 _components.insert(name, opForm->_ident, e->_use_def, false);
970 component = _components.search(name);
971 if (component->isa(Component::USE) && !component->isa(Component::TEMP) && _matrule) {
972 const Form *form = globalAD->globalNames()[component->_type];
973 assert( form, "component type must be a defined form"){ if (!(form)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 973, "component type must be a defined form"); abort(); }}
;
974 OperandForm *op = form->is_operand();
975 if (op->_interface && op->_interface->is_RegInterface()) {
976 globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n",
977 _ident, opForm->_ident, name);
978 }
979 }
980 } else {
981 // This would be a nice warning but it triggers in a few places in a benign way
982 // if (_matrule != NULL && !expands()) {
983 // globalAD->syntax_err(_linenum, "%s: %s %s not mentioned in effect or match rule\n",
984 // _ident, opForm->_ident, name);
985 // }
986 _components.insert(name, opForm->_ident, Component::INVALID, false);
987 }
988 }
989 else if (e) {
990 // Component was found in the list
991 // Check if there is a new effect that requires an extra component.
992 // This happens when adding 'USE' to a component that is not yet one.
993 if ((!component->isa( Component::USE) && ((e->_use_def & Component::USE) != 0))) {
994 if (component->isa(Component::USE) && _matrule) {
995 const Form *form = globalAD->globalNames()[component->_type];
996 assert( form, "component type must be a defined form"){ if (!(form)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 996, "component type must be a defined form"); abort(); }}
;
997 OperandForm *op = form->is_operand();
998 if (op->_interface && op->_interface->is_RegInterface()) {
999 globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n",
1000 _ident, opForm->_ident, name);
1001 }
1002 }
1003 _components.insert(name, opForm->_ident, e->_use_def, false);
1004 } else {
1005 Component *comp = (Component*)component;
1006 comp->promote_use_def_info(e->_use_def);
1007 }
1008 // Component positions are zero based.
1009 int pos = _components.operand_position(name);
1010 assert( ! (component->isa(Component::DEF) && (pos >= 1)),{ if (!(! (component->isa(Component::DEF) && (pos >=
1)))) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1011, "Component::DEF can only occur in the first position"
); abort(); }}
1011 "Component::DEF can only occur in the first position"){ if (!(! (component->isa(Component::DEF) && (pos >=
1)))) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1011, "Component::DEF can only occur in the first position"
); abort(); }}
;
1012 }
1013 }
1014
1015 // Resolving the interactions between expand rules and TEMPs would
1016 // be complex so simply disallow it.
1017 if (_matrule == NULL__null && has_temp) {
1018 globalAD->syntax_err(_linenum, "%s: TEMPs without match rule isn't supported\n", _ident);
1019 }
1020
1021 return;
1022}
1023
1024// Return zero-based position in component list; -1 if not in list.
1025int InstructForm::operand_position(const char *name, int usedef) {
1026 return unique_opnds_idx(_components.operand_position(name, usedef, this));
1027}
1028
1029int InstructForm::operand_position_format(const char *name) {
1030 return unique_opnds_idx(_components.operand_position_format(name, this));
1031}
1032
1033// Return zero-based position in component list; -1 if not in list.
1034int InstructForm::label_position() {
1035 return unique_opnds_idx(_components.label_position());
1036}
1037
1038int InstructForm::method_position() {
1039 return unique_opnds_idx(_components.method_position());
1040}
1041
1042// Return number of relocation entries needed for this instruction.
1043uintunsigned int InstructForm::reloc(FormDict &globals) {
1044 uintunsigned int reloc_entries = 0;
1045 // Check for "Call" nodes
1046 if ( is_ideal_call() ) ++reloc_entries;
1047 if ( is_ideal_return() ) ++reloc_entries;
1048 if ( is_ideal_safepoint() ) ++reloc_entries;
1049
1050
1051 // Check if operands MAYBE oop pointers, by checking for ConP elements
1052 // Proceed through the leaves of the match-tree and check for ConPs
1053 if ( _matrule != NULL__null ) {
1054 uintunsigned int position = 0;
1055 const char *result = NULL__null;
1056 const char *name = NULL__null;
1057 const char *opType = NULL__null;
1058 while (_matrule->base_operand(position, globals, result, name, opType)) {
1059 if ( strcmp(opType,"ConP") == 0 ) {
1060 ++reloc_entries;
1061 }
1062 ++position;
1063 }
1064 }
1065
1066 // Above is only a conservative estimate
1067 // because it did not check contents of operand classes.
1068 // !!!!! !!!!!
1069 // Add 1 to reloc info for each operand class in the component list.
1070 Component *comp;
1071 _components.reset();
1072 while ( (comp = _components.iter()) != NULL__null ) {
1073 const Form *form = globals[comp->_type];
1074 assert( form, "Did not find component's type in global names"){ if (!(form)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1074, "Did not find component's type in global names"); abort
(); }}
;
1075 const OpClassForm *opc = form->is_opclass();
1076 const OperandForm *oper = form->is_operand();
1077 if ( opc && (oper == NULL__null) ) {
1078 ++reloc_entries;
1079 } else if ( oper ) {
1080 // floats and doubles loaded out of method's constant pool require reloc info
1081 Form::DataType type = oper->is_base_constant(globals);
1082 if ( (type == Form::idealF) || (type == Form::idealD) ) {
1083 ++reloc_entries;
1084 }
1085 }
1086 }
1087
1088 // Float and Double constants may come from the CodeBuffer table
1089 // and require relocatable addresses for access
1090 // !!!!!
1091 // Check for any component being an immediate float or double.
1092 Form::DataType data_type = is_chain_of_constant(globals);
1093 if( data_type==idealD || data_type==idealF ) {
1094 reloc_entries++;
1095 }
1096
1097 return reloc_entries;
1098}
1099
1100// Utility function defined in archDesc.cpp
1101extern bool is_def(int usedef);
1102
1103// Return the result of reducing an instruction
1104const char *InstructForm::reduce_result() {
1105 const char* result = "Universe"; // default
1106 _components.reset();
1107 Component *comp = _components.iter();
1108 if (comp != NULL__null && comp->isa(Component::DEF)) {
1109 result = comp->_type;
1110 // Override this if the rule is a store operation:
1111 if (_matrule && _matrule->_rChild &&
1112 is_store_to_memory(_matrule->_rChild->_opType))
1113 result = "Universe";
1114 }
1115 return result;
1116}
1117
1118// Return the name of the operand on the right hand side of the binary match
1119// Return NULL if there is no right hand side
1120const char *InstructForm::reduce_right(FormDict &globals) const {
1121 if( _matrule == NULL__null ) return NULL__null;
1122 return _matrule->reduce_right(globals);
1123}
1124
1125// Similar for left
1126const char *InstructForm::reduce_left(FormDict &globals) const {
1127 if( _matrule == NULL__null ) return NULL__null;
1128 return _matrule->reduce_left(globals);
1129}
1130
1131
1132// Base class for this instruction, MachNode except for calls
1133const char *InstructForm::mach_base_class(FormDict &globals) const {
1134 if( is_ideal_call() == Form::JAVA_STATIC ) {
1135 return "MachCallStaticJavaNode";
1136 }
1137 else if( is_ideal_call() == Form::JAVA_DYNAMIC ) {
1138 return "MachCallDynamicJavaNode";
1139 }
1140 else if( is_ideal_call() == Form::JAVA_RUNTIME ) {
1141 return "MachCallRuntimeNode";
1142 }
1143 else if( is_ideal_call() == Form::JAVA_LEAF ) {
1144 return "MachCallLeafNode";
1145 }
1146 else if( is_ideal_call() == Form::JAVA_NATIVE ) {
1147 return "MachCallNativeNode";
1148 }
1149 else if (is_ideal_return()) {
1150 return "MachReturnNode";
1151 }
1152 else if (is_ideal_halt()) {
1153 return "MachHaltNode";
1154 }
1155 else if (is_ideal_safepoint()) {
1156 return "MachSafePointNode";
1157 }
1158 else if (is_ideal_if()) {
1159 return "MachIfNode";
1160 }
1161 else if (is_ideal_goto()) {
1162 return "MachGotoNode";
1163 }
1164 else if (is_ideal_fastlock()) {
1165 return "MachFastLockNode";
1166 }
1167 else if (is_ideal_nop()) {
1168 return "MachNopNode";
1169 }
1170 else if( is_ideal_membar()) {
1171 return "MachMemBarNode";
1172 }
1173 else if (is_ideal_jump()) {
1174 return "MachJumpNode";
1175 }
1176 else if (is_mach_constant()) {
1177 return "MachConstantNode";
1178 }
1179 else if (captures_bottom_type(globals)) {
1180 return "MachTypeNode";
1181 } else {
1182 return "MachNode";
1183 }
1184 assert( false, "ShouldNotReachHere()"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1184, "ShouldNotReachHere()"); abort(); }}
;
1185 return NULL__null;
1186}
1187
1188// Compare the instruction predicates for textual equality
1189bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {
1190 const Predicate *pred1 = instr1->_predicate;
1191 const Predicate *pred2 = instr2->_predicate;
1192 if( pred1 == NULL__null && pred2 == NULL__null ) {
1193 // no predicates means they are identical
1194 return true;
1195 }
1196 if( pred1 != NULL__null && pred2 != NULL__null ) {
1197 // compare the predicates
1198 if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) {
1199 return true;
1200 }
1201 }
1202
1203 return false;
1204}
1205
1206// Check if this instruction can cisc-spill to 'alternate'
1207bool InstructForm::cisc_spills_to(ArchDesc &AD, InstructForm *instr) {
1208 assert( _matrule != NULL && instr->_matrule != NULL, "must have match rules"){ if (!(_matrule != __null && instr->_matrule != __null
)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1208, "must have match rules"); abort(); }}
;
1209 // Do not replace if a cisc-version has been found.
1210 if( cisc_spill_operand() != Not_cisc_spillable ) return false;
1211
1212 int cisc_spill_operand = Maybe_cisc_spillable;
1213 char *result = NULL__null;
1214 char *result2 = NULL__null;
1215 const char *op_name = NULL__null;
1216 const char *reg_type = NULL__null;
1217 FormDict &globals = AD.globalNames();
1218 cisc_spill_operand = _matrule->matchrule_cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);
1219 if( (cisc_spill_operand != Not_cisc_spillable) && (op_name != NULL__null) && equivalent_predicates(this, instr) ) {
1220 cisc_spill_operand = operand_position(op_name, Component::USE);
1221 int def_oper = operand_position(op_name, Component::DEF);
1222 if( def_oper == NameList::Not_in_list && instr->num_opnds() == num_opnds()) {
1223 // Do not support cisc-spilling for destination operands and
1224 // make sure they have the same number of operands.
1225 _cisc_spill_alternate = instr;
1226 instr->set_cisc_alternate(true);
1227 if( AD._cisc_spill_debug ) {
1228 fprintf(stderrstderr, "Instruction %s cisc-spills-to %s\n", _ident, instr->_ident);
1229 fprintf(stderrstderr, " using operand %s %s at index %d\n", reg_type, op_name, cisc_spill_operand);
1230 }
1231 // Record that a stack-version of the reg_mask is needed
1232 // !!!!!
1233 OperandForm *oper = (OperandForm*)(globals[reg_type]->is_operand());
1234 assert( oper != NULL, "cisc-spilling non operand"){ if (!(oper != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1234, "cisc-spilling non operand"); abort(); }}
;
1235 const char *reg_class_name = oper->constrained_reg_class();
1236 AD.set_stack_or_reg(reg_class_name);
1237 const char *reg_mask_name = AD.reg_mask(*oper);
1238 set_cisc_reg_mask_name(reg_mask_name);
1239 const char *stack_or_reg_mask_name = AD.stack_or_reg_mask(*oper);
1240 } else {
1241 cisc_spill_operand = Not_cisc_spillable;
1242 }
1243 } else {
1244 cisc_spill_operand = Not_cisc_spillable;
1245 }
1246
1247 set_cisc_spill_operand(cisc_spill_operand);
1248 return (cisc_spill_operand != Not_cisc_spillable);
1249}
1250
1251// Check to see if this instruction can be replaced with the short branch
1252// instruction `short-branch'
1253bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch) {
1254 if (_matrule != NULL__null &&
1255 this != short_branch && // Don't match myself
1256 !is_short_branch() && // Don't match another short branch variant
1257 reduce_result() != NULL__null &&
1258 strstr(_ident, "restoreMask") == NULL__null && // Don't match side effects
1259 strcmp(reduce_result(), short_branch->reduce_result()) == 0 &&
1260 _matrule->equivalent(AD.globalNames(), short_branch->_matrule)) {
1261 // The instructions are equivalent.
1262
1263 // Now verify that both instructions have the same parameters and
1264 // the same effects. Both branch forms should have the same inputs
1265 // and resulting projections to correctly replace a long branch node
1266 // with corresponding short branch node during code generation.
1267
1268 bool different = false;
1269 if (short_branch->_components.count() != _components.count()) {
1270 different = true;
1271 } else if (_components.count() > 0) {
1272 short_branch->_components.reset();
1273 _components.reset();
1274 Component *comp;
1275 while ((comp = _components.iter()) != NULL__null) {
1276 Component *short_comp = short_branch->_components.iter();
1277 if (short_comp == NULL__null ||
1278 short_comp->_type != comp->_type ||
1279 short_comp->_usedef != comp->_usedef) {
1280 different = true;
1281 break;
1282 }
1283 }
1284 if (short_branch->_components.iter() != NULL__null)
1285 different = true;
1286 }
1287 if (different) {
1288 globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);
1289 }
1290 if (AD._adl_debug > 1 || AD._short_branch_debug) {
1291 fprintf(stderrstderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);
1292 }
1293 _short_branch_form = short_branch;
1294 return true;
1295 }
1296 return false;
1297}
1298
1299
1300// --------------------------- FILE *output_routines
1301//
1302// Generate the format call for the replacement variable
1303void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
1304 // Handle special constant table variables.
1305 if (strcmp(rep_var, "constanttablebase") == 0) {
1306 fprintf(fp, "char reg[128]; ra->dump_register(in(mach_constant_base_node_input()), reg);\n");
1307 fprintf(fp, " st->print(\"%%s\", reg);\n");
1308 return;
1309 }
1310 if (strcmp(rep_var, "constantoffset") == 0) {
1311 fprintf(fp, "st->print(\"#%%d\", constant_offset_unchecked());\n");
1312 return;
1313 }
1314 if (strcmp(rep_var, "constantaddress") == 0) {
1315 fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset_unchecked());\n");
1316 return;
1317 }
1318
1319 // Find replacement variable's type
1320 const Form *form = _localNames[rep_var];
1321 if (form == NULL__null) {
1322 globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.",
1323 rep_var, _ident);
1324 return;
1325 }
1326 OpClassForm *opc = form->is_opclass();
1327 assert( opc, "replacement variable was not found in local names"){ if (!(opc)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1327, "replacement variable was not found in local names");
abort(); }}
;
1328 // Lookup the index position of the replacement variable
1329 int idx = operand_position_format(rep_var);
1330 if ( idx == -1 ) {
1331 globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n",
1332 rep_var, _ident);
1333 assert(strcmp(opc->_ident, "label") == 0, "Unimplemented"){ if (!(strcmp(opc->_ident, "label") == 0)) { fprintf(stderr
, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1333, "Unimplemented"); abort(); }}
;
1334 return;
1335 }
1336
1337 if (is_noninput_operand(idx)) {
1338 // This component isn't in the input array. Print out the static
1339 // name of the register.
1340 OperandForm* oper = form->is_operand();
1341 if (oper != NULL__null && oper->is_bound_register()) {
1342 const RegDef* first = oper->get_RegClass()->find_first_elem();
1343 fprintf(fp, " st->print_raw(\"%s\");\n", first->_regname);
1344 } else {
1345 globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var);
1346 }
1347 } else {
1348 // Output the format call for this operand
1349 fprintf(fp,"opnd_array(%d)->",idx);
1350 if (idx == 0)
1351 fprintf(fp,"int_format(ra, this, st); // %s\n", rep_var);
1352 else
1353 fprintf(fp,"ext_format(ra, this,idx%d, st); // %s\n", idx, rep_var );
1354 }
1355}
1356
1357// Seach through operands to determine parameters unique positions.
1358void InstructForm::set_unique_opnds() {
1359 uintunsigned int* uniq_idx = NULL__null;
1360 uintunsigned int nopnds = num_opnds();
1361 uintunsigned int num_uniq = nopnds;
1362 uintunsigned int i;
1363 _uniq_idx_length = 0;
1364 if (nopnds > 0) {
1365 // Allocate index array. Worst case we're mapping from each
1366 // component back to an index and any DEF always goes at 0 so the
1367 // length of the array has to be the number of components + 1.
1368 _uniq_idx_length = _components.count() + 1;
1369 uniq_idx = (uintunsigned int*) AllocateHeap(sizeof(uintunsigned int) * _uniq_idx_length);
1370 for (i = 0; i < _uniq_idx_length; i++) {
1371 uniq_idx[i] = i;
1372 }
1373 }
1374 // Do it only if there is a match rule and no expand rule. With an
1375 // expand rule it is done by creating new mach node in Expand()
1376 // method.
1377 if (nopnds > 0 && _matrule != NULL__null && _exprule == NULL__null) {
1378 const char *name;
1379 uintunsigned int count;
1380 bool has_dupl_use = false;
1381
1382 _parameters.reset();
1383 while ((name = _parameters.iter()) != NULL__null) {
1384 count = 0;
1385 uintunsigned int position = 0;
1386 uintunsigned int uniq_position = 0;
1387 _components.reset();
1388 Component *comp = NULL__null;
1389 if (sets_result()) {
1390 comp = _components.iter();
1391 position++;
1392 }
1393 // The next code is copied from the method operand_position().
1394 for (; (comp = _components.iter()) != NULL__null; ++position) {
1395 // When the first component is not a DEF,
1396 // leave space for the result operand!
1397 if (position==0 && (!comp->isa(Component::DEF))) {
1398 ++position;
1399 }
1400 if (strcmp(name, comp->_name) == 0) {
1401 if (++count > 1) {
1402 assert(position < _uniq_idx_length, "out of bounds"){ if (!(position < _uniq_idx_length)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1402, "out of bounds"); abort(); }}
;
1403 uniq_idx[position] = uniq_position;
1404 has_dupl_use = true;
1405 } else {
1406 uniq_position = position;
1407 }
1408 }
1409 if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {
1410 ++position;
1411 if (position != 1)
1412 --position; // only use two slots for the 1st USE_DEF
1413 }
1414 }
1415 }
1416 if (has_dupl_use) {
1417 for (i = 1; i < nopnds; i++) {
1418 if (i != uniq_idx[i]) {
1419 break;
1420 }
1421 }
1422 uintunsigned int j = i;
1423 for (; i < nopnds; i++) {
1424 if (i == uniq_idx[i]) {
1425 uniq_idx[i] = j++;
1426 }
1427 }
1428 num_uniq = j;
1429 }
1430 }
1431 _uniq_idx = uniq_idx;
1432 _num_uniq = num_uniq;
1433}
1434
1435// Generate index values needed for determining the operand position
1436void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix, const char *receiver) {
1437 uintunsigned int idx = 0; // position of operand in match rule
1438 int cur_num_opnds = num_opnds();
1439
1440 // Compute the index into vector of operand pointers:
1441 // idx0=0 is used to indicate that info comes from this same node, not from input edge.
1442 // idx1 starts at oper_input_base()
1443 if ( cur_num_opnds >= 1 ) {
1444 fprintf(fp," // Start at oper_input_base() and count operands\n");
1445 fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));
1446 fprintf(fp," unsigned %sidx1 = %d;", prefix, oper_input_base(globals));
1447 fprintf(fp," \t// %s\n", unique_opnd_ident(1));
1448
1449 // Generate starting points for other unique operands if they exist
1450 for ( idx = 2; idx < num_unique_opnds(); ++idx ) {
1451 if( *receiver == 0 ) {
1452 fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();",
1453 prefix, idx, prefix, idx-1, idx-1 );
1454 } else {
1455 fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();",
1456 prefix, idx, prefix, idx-1, receiver, idx-1 );
1457 }
1458 fprintf(fp," \t// %s\n", unique_opnd_ident(idx));
1459 }
1460 }
1461 if( *receiver != 0 ) {
1462 // This value is used by generate_peepreplace when copying a node.
1463 // Don't emit it in other cases since it can hide bugs with the
1464 // use invalid idx's.
1465 fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);
1466 }
1467
1468}
1469
1470// ---------------------------
1471bool InstructForm::verify() {
1472 // !!!!! !!!!!
1473 // Check that a "label" operand occurs last in the operand list, if present
1474 return true;
1475}
1476
1477void InstructForm::dump() {
1478 output(stderrstderr);
1479}
1480
1481void InstructForm::output(FILE *fp) {
1482 fprintf(fp,"\nInstruction: %s\n", (_ident?_ident:""));
1483 if (_matrule) _matrule->output(fp);
1484 if (_insencode) _insencode->output(fp);
1485 if (_constant) _constant->output(fp);
1486 if (_opcode) _opcode->output(fp);
1487 if (_attribs) _attribs->output(fp);
1488 if (_predicate) _predicate->output(fp);
1489 if (_effects.Size()) {
1490 fprintf(fp,"Effects\n");
1491 _effects.dump();
1492 }
1493 if (_exprule) _exprule->output(fp);
1494 if (_rewrule) _rewrule->output(fp);
1495 if (_format) _format->output(fp);
1496 if (_peephole) _peephole->output(fp);
1497}
1498
1499void MachNodeForm::dump() {
1500 output(stderrstderr);
1501}
1502
1503void MachNodeForm::output(FILE *fp) {
1504 fprintf(fp,"\nMachNode: %s\n", (_ident?_ident:""));
1505}
1506
1507//------------------------------build_predicate--------------------------------
1508// Build instruction predicates. If the user uses the same operand name
1509// twice, we need to check that the operands are pointer-eequivalent in
1510// the DFA during the labeling process.
1511Predicate *InstructForm::build_predicate() {
1512 const int buflen = 1024;
1513 char buf[buflen], *s=buf;
1514 Dict names(cmpstr,hashstr,Form::arena); // Map Names to counts
1515
1516 MatchNode *mnode =
1517 strcmp(_matrule->_opType, "Set") ? _matrule : _matrule->_rChild;
1518 if (mnode != NULL__null) mnode->count_instr_names(names);
1519
1520 uintunsigned int first = 1;
1521 // Start with the predicate supplied in the .ad file.
1522 if (_predicate) {
1523 if (first) first = 0;
1524 strcpy(s, "("); s += strlen(s);
1525 strncpy(s, _predicate->_pred, buflen - strlen(s) - 1);
1526 s += strlen(s);
1527 strcpy(s, ")"); s += strlen(s);
1528 }
1529 for( DictI i(&names); i.test(); ++i ) {
1530 uintptr_t cnt = (uintptr_t)i._value;
1531 if( cnt > 1 ) { // Need a predicate at all?
1532 int path_bitmask = 0;
1533 assert( cnt == 2, "Unimplemented" ){ if (!(cnt == 2)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1533, "Unimplemented"); abort(); }}
;
1534 // Handle many pairs
1535 if( first ) first=0;
1536 else { // All tests must pass, so use '&&'
1537 strcpy(s," && ");
1538 s += strlen(s);
1539 }
1540 // Add predicate to working buffer
1541 sprintf(s,"/*%s*/(",(char*)i._key);
1542 s += strlen(s);
1543 mnode->build_instr_pred(s,(char*)i._key, 0, path_bitmask, 0);
1544 s += strlen(s);
1545 strcpy(s," == "); s += strlen(s);
1546 mnode->build_instr_pred(s,(char*)i._key, 1, path_bitmask, 0);
1547 s += strlen(s);
1548 strcpy(s,")"); s += strlen(s);
1549 }
1550 }
1551 if( s == buf ) s = NULL__null;
1552 else {
1553 assert( strlen(buf) < sizeof(buf), "String buffer overflow" ){ if (!(strlen(buf) < sizeof(buf))) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1553, "String buffer overflow"); abort(); }}
;
1554 s = strdup(buf);
1555 }
1556 return new Predicate(s);
1557}
1558
1559//------------------------------EncodeForm-------------------------------------
1560// Constructor
1561EncodeForm::EncodeForm()
1562 : _encClass(cmpstr,hashstr, Form::arena) {
1563}
1564EncodeForm::~EncodeForm() {
1565}
1566
1567// record a new register class
1568EncClass *EncodeForm::add_EncClass(const char *className) {
1569 EncClass *encClass = new EncClass(className);
1570 _eclasses.addName(className);
1571 _encClass.Insert(className,encClass);
1572 return encClass;
1573}
1574
1575// Lookup the function body for an encoding class
1576EncClass *EncodeForm::encClass(const char *className) {
1577 assert( className != NULL, "Must provide a defined encoding name"){ if (!(className != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1577, "Must provide a defined encoding name"); abort(); }}
;
1578
1579 EncClass *encClass = (EncClass*)_encClass[className];
1580 return encClass;
1581}
1582
1583// Lookup the function body for an encoding class
1584const char *EncodeForm::encClassBody(const char *className) {
1585 if( className == NULL__null ) return NULL__null;
1586
1587 EncClass *encClass = (EncClass*)_encClass[className];
1588 assert( encClass != NULL, "Encode Class is missing."){ if (!(encClass != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1588, "Encode Class is missing."); abort(); }}
;
1589 encClass->_code.reset();
1590 const char *code = (const char*)encClass->_code.iter();
1591 assert( code != NULL, "Found an empty encode class body."){ if (!(code != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1591, "Found an empty encode class body."); abort(); }}
;
1592
1593 return code;
1594}
1595
1596// Lookup the function body for an encoding class
1597const char *EncodeForm::encClassPrototype(const char *className) {
1598 assert( className != NULL, "Encode class name must be non NULL."){ if (!(className != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1598, "Encode class name must be non NULL."); abort(); }}
;
1599
1600 return className;
1601}
1602
1603void EncodeForm::dump() { // Debug printer
1604 output(stderrstderr);
1605}
1606
1607void EncodeForm::output(FILE *fp) { // Write info to output files
1608 const char *name;
1609 fprintf(fp,"\n");
1610 fprintf(fp,"-------------------- Dump EncodeForm --------------------\n");
1611 for (_eclasses.reset(); (name = _eclasses.iter()) != NULL__null;) {
1612 ((EncClass*)_encClass[name])->output(fp);
1613 }
1614 fprintf(fp,"-------------------- end EncodeForm --------------------\n");
1615}
1616//------------------------------EncClass---------------------------------------
1617EncClass::EncClass(const char *name)
1618 : _localNames(cmpstr,hashstr, Form::arena), _name(name) {
1619}
1620EncClass::~EncClass() {
1621}
1622
1623// Add a parameter <type,name> pair
1624void EncClass::add_parameter(const char *parameter_type, const char *parameter_name) {
1625 _parameter_type.addName( parameter_type );
1626 _parameter_name.addName( parameter_name );
1627}
1628
1629// Verify operand types in parameter list
1630bool EncClass::check_parameter_types(FormDict &globals) {
1631 // !!!!!
1632 return false;
1633}
1634
1635// Add the decomposed "code" sections of an encoding's code-block
1636void EncClass::add_code(const char *code) {
1637 _code.addName(code);
1638}
1639
1640// Add the decomposed "replacement variables" of an encoding's code-block
1641void EncClass::add_rep_var(char *replacement_var) {
1642 _code.addName(NameList::_signal);
1643 _rep_vars.addName(replacement_var);
1644}
1645
1646// Lookup the function body for an encoding class
1647int EncClass::rep_var_index(const char *rep_var) {
1648 uintunsigned int position = 0;
1649 const char *name = NULL__null;
1650
1651 _parameter_name.reset();
1652 while ( (name = _parameter_name.iter()) != NULL__null ) {
1653 if ( strcmp(rep_var,name) == 0 ) return position;
1654 ++position;
1655 }
1656
1657 return -1;
1658}
1659
1660// Check after parsing
1661bool EncClass::verify() {
1662 // 1!!!!
1663 // Check that each replacement variable, '$name' in architecture description
1664 // is actually a local variable for this encode class, or a reserved name
1665 // "primary, secondary, tertiary"
1666 return true;
1667}
1668
1669void EncClass::dump() {
1670 output(stderrstderr);
1671}
1672
1673// Write info to output files
1674void EncClass::output(FILE *fp) {
1675 fprintf(fp,"EncClass: %s", (_name ? _name : ""));
1676
1677 // Output the parameter list
1678 _parameter_type.reset();
1679 _parameter_name.reset();
1680 const char *type = _parameter_type.iter();
1681 const char *name = _parameter_name.iter();
1682 fprintf(fp, " ( ");
1683 for ( ; (type != NULL__null) && (name != NULL__null);
1684 (type = _parameter_type.iter()), (name = _parameter_name.iter()) ) {
1685 fprintf(fp, " %s %s,", type, name);
1686 }
1687 fprintf(fp, " ) ");
1688
1689 // Output the code block
1690 _code.reset();
1691 _rep_vars.reset();
1692 const char *code;
1693 while ( (code = _code.iter()) != NULL__null ) {
1694 if ( _code.is_signal(code) ) {
1695 // A replacement variable
1696 const char *rep_var = _rep_vars.iter();
1697 fprintf(fp,"($%s)", rep_var);
1698 } else {
1699 // A section of code
1700 fprintf(fp,"%s", code);
1701 }
1702 }
1703
1704}
1705
1706//------------------------------Opcode-----------------------------------------
1707Opcode::Opcode(char *primary, char *secondary, char *tertiary)
1708 : _primary(primary), _secondary(secondary), _tertiary(tertiary) {
1709}
1710
1711Opcode::~Opcode() {
1712}
1713
1714Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
1715 if( strcmp(param,"primary") == 0 ) {
1716 return Opcode::PRIMARY;
1717 }
1718 else if( strcmp(param,"secondary") == 0 ) {
1719 return Opcode::SECONDARY;
1720 }
1721 else if( strcmp(param,"tertiary") == 0 ) {
1722 return Opcode::TERTIARY;
1723 }
1724 return Opcode::NOT_AN_OPCODE;
1725}
1726
1727bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
1728 // Default values previously provided by MachNode::primary()...
1729 const char *description = NULL__null;
1730 const char *value = NULL__null;
1731 // Check if user provided any opcode definitions
1732 // Update 'value' if user provided a definition in the instruction
1733 switch (desired_opcode) {
1734 case PRIMARY:
1735 description = "primary()";
1736 if( _primary != NULL__null) { value = _primary; }
1737 break;
1738 case SECONDARY:
1739 description = "secondary()";
1740 if( _secondary != NULL__null ) { value = _secondary; }
1741 break;
1742 case TERTIARY:
1743 description = "tertiary()";
1744 if( _tertiary != NULL__null ) { value = _tertiary; }
1745 break;
1746 default:
1747 assert( false, "ShouldNotReachHere();"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1747, "ShouldNotReachHere();"); abort(); }}
;
1748 break;
1749 }
1750
1751 if (value != NULL__null) {
1752 fprintf(fp, "(%s /*%s*/)", value, description);
1753 }
1754 return value != NULL__null;
1755}
1756
1757void Opcode::dump() {
1758 output(stderrstderr);
1759}
1760
1761// Write info to output files
1762void Opcode::output(FILE *fp) {
1763 if (_primary != NULL__null) fprintf(fp,"Primary opcode: %s\n", _primary);
1764 if (_secondary != NULL__null) fprintf(fp,"Secondary opcode: %s\n", _secondary);
1765 if (_tertiary != NULL__null) fprintf(fp,"Tertiary opcode: %s\n", _tertiary);
1766}
1767
1768//------------------------------InsEncode--------------------------------------
1769InsEncode::InsEncode() {
1770}
1771InsEncode::~InsEncode() {
1772}
1773
1774// Add "encode class name" and its parameters
1775NameAndList *InsEncode::add_encode(char *encoding) {
1776 assert( encoding != NULL, "Must provide name for encoding"){ if (!(encoding != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1776, "Must provide name for encoding"); abort(); }}
;
1777
1778 // add_parameter(NameList::_signal);
1779 NameAndList *encode = new NameAndList(encoding);
1780 _encoding.addName((char*)encode);
1781
1782 return encode;
1783}
1784
1785// Access the list of encodings
1786void InsEncode::reset() {
1787 _encoding.reset();
1788 // _parameter.reset();
1789}
1790const char* InsEncode::encode_class_iter() {
1791 NameAndList *encode_class = (NameAndList*)_encoding.iter();
1792 return ( encode_class != NULL__null ? encode_class->name() : NULL__null );
1793}
1794// Obtain parameter name from zero based index
1795const char *InsEncode::rep_var_name(InstructForm &inst, uintunsigned int param_no) {
1796 NameAndList *params = (NameAndList*)_encoding.current();
1797 assert( params != NULL, "Internal Error"){ if (!(params != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1797, "Internal Error"); abort(); }}
;
1798 const char *param = (*params)[param_no];
1799
1800 // Remove '$' if parser placed it there.
1801 return ( param != NULL__null && *param == '$') ? (param+1) : param;
1802}
1803
1804void InsEncode::dump() {
1805 output(stderrstderr);
1806}
1807
1808// Write info to output files
1809void InsEncode::output(FILE *fp) {
1810 NameAndList *encoding = NULL__null;
1811 const char *parameter = NULL__null;
1812
1813 fprintf(fp,"InsEncode: ");
1814 _encoding.reset();
1815
1816 while ( (encoding = (NameAndList*)_encoding.iter()) != 0 ) {
1817 // Output the encoding being used
1818 fprintf(fp,"%s(", encoding->name() );
1819
1820 // Output its parameter list, if any
1821 bool first_param = true;
1822 encoding->reset();
1823 while ( (parameter = encoding->iter()) != 0 ) {
1824 // Output the ',' between parameters
1825 if ( ! first_param ) fprintf(fp,", ");
1826 first_param = false;
1827 // Output the parameter
1828 fprintf(fp,"%s", parameter);
1829 } // done with parameters
1830 fprintf(fp,") ");
1831 } // done with encodings
1832
1833 fprintf(fp,"\n");
1834}
1835
1836//------------------------------Effect-----------------------------------------
1837static int effect_lookup(const char *name) {
1838 if (!strcmp(name, "USE")) return Component::USE;
1839 if (!strcmp(name, "DEF")) return Component::DEF;
1840 if (!strcmp(name, "USE_DEF")) return Component::USE_DEF;
1841 if (!strcmp(name, "KILL")) return Component::KILL;
1842 if (!strcmp(name, "USE_KILL")) return Component::USE_KILL;
1843 if (!strcmp(name, "TEMP")) return Component::TEMP;
1844 if (!strcmp(name, "TEMP_DEF")) return Component::TEMP_DEF;
1845 if (!strcmp(name, "INVALID")) return Component::INVALID;
1846 if (!strcmp(name, "CALL")) return Component::CALL;
1847 assert(false,"Invalid effect name specified\n"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1847, "Invalid effect name specified\n"); abort(); }}
;
1848 return Component::INVALID;
1849}
1850
1851const char *Component::getUsedefName() {
1852 switch (_usedef) {
1853 case Component::INVALID: return "INVALID"; break;
1854 case Component::USE: return "USE"; break;
1855 case Component::USE_DEF: return "USE_DEF"; break;
1856 case Component::USE_KILL: return "USE_KILL"; break;
1857 case Component::KILL: return "KILL"; break;
1858 case Component::TEMP: return "TEMP"; break;
1859 case Component::TEMP_DEF: return "TEMP_DEF"; break;
1860 case Component::DEF: return "DEF"; break;
1861 case Component::CALL: return "CALL"; break;
1862 default: assert(false, "unknown effect"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1862, "unknown effect"); abort(); }}
;
1863 }
1864 return "Undefined Use/Def info";
1865}
1866
1867Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) {
1868 _ftype = Form::EFF;
1869}
1870
1871Effect::~Effect() {
1872}
1873
1874// Dynamic type check
1875Effect *Effect::is_effect() const {
1876 return (Effect*)this;
1877}
1878
1879
1880// True if this component is equal to the parameter.
1881bool Effect::is(int use_def_kill_enum) const {
1882 return (_use_def == use_def_kill_enum ? true : false);
1883}
1884// True if this component is used/def'd/kill'd as the parameter suggests.
1885bool Effect::isa(int use_def_kill_enum) const {
1886 return (_use_def & use_def_kill_enum) == use_def_kill_enum;
1887}
1888
1889void Effect::dump() {
1890 output(stderrstderr);
1891}
1892
1893void Effect::output(FILE *fp) { // Write info to output files
1894 fprintf(fp,"Effect: %s\n", (_name?_name:""));
1895}
1896
1897//------------------------------ExpandRule-------------------------------------
1898ExpandRule::ExpandRule() : _expand_instrs(),
1899 _newopconst(cmpstr, hashstr, Form::arena) {
1900 _ftype = Form::EXP;
1901}
1902
1903ExpandRule::~ExpandRule() { // Destructor
1904}
1905
1906void ExpandRule::add_instruction(NameAndList *instruction_name_and_operand_list) {
1907 _expand_instrs.addName((char*)instruction_name_and_operand_list);
1908}
1909
1910void ExpandRule::reset_instructions() {
1911 _expand_instrs.reset();
1912}
1913
1914NameAndList* ExpandRule::iter_instructions() {
1915 return (NameAndList*)_expand_instrs.iter();
1916}
1917
1918
1919void ExpandRule::dump() {
1920 output(stderrstderr);
1921}
1922
1923void ExpandRule::output(FILE *fp) { // Write info to output files
1924 NameAndList *expand_instr = NULL__null;
1925 const char *opid = NULL__null;
1926
1927 fprintf(fp,"\nExpand Rule:\n");
1928
1929 // Iterate over the instructions 'node' expands into
1930 for(reset_instructions(); (expand_instr = iter_instructions()) != NULL__null; ) {
1931 fprintf(fp,"%s(", expand_instr->name());
1932
1933 // iterate over the operand list
1934 for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL__null; ) {
1935 fprintf(fp,"%s ", opid);
1936 }
1937 fprintf(fp,");\n");
1938 }
1939}
1940
1941//------------------------------RewriteRule------------------------------------
1942RewriteRule::RewriteRule(char* params, char* block)
1943 : _tempParams(params), _tempBlock(block) { }; // Constructor
1944RewriteRule::~RewriteRule() { // Destructor
1945}
1946
1947void RewriteRule::dump() {
1948 output(stderrstderr);
1949}
1950
1951void RewriteRule::output(FILE *fp) { // Write info to output files
1952 fprintf(fp,"\nRewrite Rule:\n%s\n%s\n",
1953 (_tempParams?_tempParams:""),
1954 (_tempBlock?_tempBlock:""));
1955}
1956
1957
1958//==============================MachNodes======================================
1959//------------------------------MachNodeForm-----------------------------------
1960MachNodeForm::MachNodeForm(char *id)
1961 : _ident(id) {
1962}
1963
1964MachNodeForm::~MachNodeForm() {
1965}
1966
1967MachNodeForm *MachNodeForm::is_machnode() const {
1968 return (MachNodeForm*)this;
1969}
1970
1971//==============================Operand Classes================================
1972//------------------------------OpClassForm------------------------------------
1973OpClassForm::OpClassForm(const char* id) : _ident(id) {
1974 _ftype = Form::OPCLASS;
1975}
1976
1977OpClassForm::~OpClassForm() {
1978}
1979
1980bool OpClassForm::ideal_only() const { return 0; }
1981
1982OpClassForm *OpClassForm::is_opclass() const {
1983 return (OpClassForm*)this;
1984}
1985
1986Form::InterfaceType OpClassForm::interface_type(FormDict &globals) const {
1987 if( _oplst.count() == 0 ) return Form::no_interface;
1988
1989 // Check that my operands have the same interface type
1990 Form::InterfaceType interface;
1991 bool first = true;
1992 NameList &op_list = (NameList &)_oplst;
1993 op_list.reset();
1994 const char *op_name;
1995 while( (op_name = op_list.iter()) != NULL__null ) {
1996 const Form *form = globals[op_name];
1997 OperandForm *operand = form->is_operand();
1998 assert( operand, "Entry in operand class that is not an operand"){ if (!(operand)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 1998, "Entry in operand class that is not an operand"); abort
(); }}
;
1999 if( first ) {
2000 first = false;
2001 interface = operand->interface_type(globals);
2002 } else {
2003 interface = (interface == operand->interface_type(globals) ? interface : Form::no_interface);
2004 }
2005 }
2006 return interface;
2007}
2008
2009bool OpClassForm::stack_slots_only(FormDict &globals) const {
2010 if( _oplst.count() == 0 ) return false; // how?
2011
2012 NameList &op_list = (NameList &)_oplst;
2013 op_list.reset();
2014 const char *op_name;
2015 while( (op_name = op_list.iter()) != NULL__null ) {
2016 const Form *form = globals[op_name];
2017 OperandForm *operand = form->is_operand();
2018 assert( operand, "Entry in operand class that is not an operand"){ if (!(operand)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2018, "Entry in operand class that is not an operand"); abort
(); }}
;
2019 if( !operand->stack_slots_only(globals) ) return false;
2020 }
2021 return true;
2022}
2023
2024
2025void OpClassForm::dump() {
2026 output(stderrstderr);
2027}
2028
2029void OpClassForm::output(FILE *fp) {
2030 const char *name;
2031 fprintf(fp,"\nOperand Class: %s\n", (_ident?_ident:""));
2032 fprintf(fp,"\nCount = %d\n", _oplst.count());
2033 for(_oplst.reset(); (name = _oplst.iter()) != NULL__null;) {
2034 fprintf(fp,"%s, ",name);
2035 }
2036 fprintf(fp,"\n");
2037}
2038
2039
2040//==============================Operands=======================================
2041//------------------------------OperandForm------------------------------------
2042OperandForm::OperandForm(const char* id)
2043 : OpClassForm(id), _ideal_only(false),
2044 _localNames(cmpstr, hashstr, Form::arena) {
2045 _ftype = Form::OPER;
2046
2047 _matrule = NULL__null;
2048 _interface = NULL__null;
2049 _attribs = NULL__null;
2050 _predicate = NULL__null;
2051 _constraint= NULL__null;
2052 _construct = NULL__null;
2053 _format = NULL__null;
2054}
2055OperandForm::OperandForm(const char* id, bool ideal_only)
2056 : OpClassForm(id), _ideal_only(ideal_only),
2057 _localNames(cmpstr, hashstr, Form::arena) {
2058 _ftype = Form::OPER;
2059
2060 _matrule = NULL__null;
2061 _interface = NULL__null;
2062 _attribs = NULL__null;
2063 _predicate = NULL__null;
2064 _constraint= NULL__null;
2065 _construct = NULL__null;
2066 _format = NULL__null;
2067}
2068OperandForm::~OperandForm() {
2069}
2070
2071
2072OperandForm *OperandForm::is_operand() const {
2073 return (OperandForm*)this;
2074}
2075
2076bool OperandForm::ideal_only() const {
2077 return _ideal_only;
2078}
2079
2080Form::InterfaceType OperandForm::interface_type(FormDict &globals) const {
2081 if( _interface == NULL__null ) return Form::no_interface;
2082
2083 return _interface->interface_type(globals);
2084}
2085
2086
2087bool OperandForm::stack_slots_only(FormDict &globals) const {
2088 if( _constraint == NULL__null ) return false;
2089 return _constraint->stack_slots_only();
2090}
2091
2092
2093// Access op_cost attribute or return NULL.
2094const char* OperandForm::cost() {
2095 for (Attribute* cur = _attribs; cur != NULL__null; cur = (Attribute*)cur->_next) {
2096 if( strcmp(cur->_ident,AttributeForm::_op_cost) == 0 ) {
2097 return cur->_val;
2098 }
2099 }
2100 return NULL__null;
2101}
2102
2103// Return the number of leaves below this complex operand
2104uintunsigned int OperandForm::num_leaves() const {
2105 if ( ! _matrule) return 0;
2106
2107 int num_leaves = _matrule->_numleaves;
2108 return num_leaves;
2109}
2110
2111// Return the number of constants contained within this complex operand
2112uintunsigned int OperandForm::num_consts(FormDict &globals) const {
2113 if ( ! _matrule) return 0;
2114
2115 // This is a recursive invocation on all operands in the matchrule
2116 return _matrule->num_consts(globals);
2117}
2118
2119// Return the number of constants in match rule with specified type
2120uintunsigned int OperandForm::num_consts(FormDict &globals, Form::DataType type) const {
2121 if ( ! _matrule) return 0;
2122
2123 // This is a recursive invocation on all operands in the matchrule
2124 return _matrule->num_consts(globals, type);
2125}
2126
2127// Return the number of pointer constants contained within this complex operand
2128uintunsigned int OperandForm::num_const_ptrs(FormDict &globals) const {
2129 if ( ! _matrule) return 0;
2130
2131 // This is a recursive invocation on all operands in the matchrule
2132 return _matrule->num_const_ptrs(globals);
2133}
2134
2135uintunsigned int OperandForm::num_edges(FormDict &globals) const {
2136 uintunsigned int edges = 0;
2137 uintunsigned int leaves = num_leaves();
2138 uintunsigned int consts = num_consts(globals);
2139
2140 // If we are matching a constant directly, there are no leaves.
2141 edges = ( leaves > consts ) ? leaves - consts : 0;
2142
2143 // !!!!!
2144 // Special case operands that do not have a corresponding ideal node.
2145 if( (edges == 0) && (consts == 0) ) {
2146 if( constrained_reg_class() != NULL__null ) {
2147 edges = 1;
2148 } else {
2149 if( _matrule
2150 && (_matrule->_lChild == NULL__null) && (_matrule->_rChild == NULL__null) ) {
2151 const Form *form = globals[_matrule->_opType];
2152 OperandForm *oper = form ? form->is_operand() : NULL__null;
2153 if( oper ) {
2154 return oper->num_edges(globals);
2155 }
2156 }
2157 }
2158 }
2159
2160 return edges;
2161}
2162
2163
2164// Check if this operand is usable for cisc-spilling
2165bool OperandForm::is_cisc_reg(FormDict &globals) const {
2166 const char *ideal = ideal_type(globals);
2167 bool is_cisc_reg = (ideal && (ideal_to_Reg_type(ideal) != none));
2168 return is_cisc_reg;
2169}
2170
2171bool OpClassForm::is_cisc_mem(FormDict &globals) const {
2172 Form::InterfaceType my_interface = interface_type(globals);
2173 return (my_interface == memory_interface);
2174}
2175
2176
2177// node matches ideal 'Bool'
2178bool OperandForm::is_ideal_bool() const {
2179 if( _matrule == NULL__null ) return false;
2180
2181 return _matrule->is_ideal_bool();
2182}
2183
2184// Require user's name for an sRegX to be stackSlotX
2185Form::DataType OperandForm::is_user_name_for_sReg() const {
2186 DataType data_type = none;
2187 if( _ident != NULL__null ) {
2188 if( strcmp(_ident,"stackSlotI") == 0 ) data_type = Form::idealI;
2189 else if( strcmp(_ident,"stackSlotP") == 0 ) data_type = Form::idealP;
2190 else if( strcmp(_ident,"stackSlotD") == 0 ) data_type = Form::idealD;
2191 else if( strcmp(_ident,"stackSlotF") == 0 ) data_type = Form::idealF;
2192 else if( strcmp(_ident,"stackSlotL") == 0 ) data_type = Form::idealL;
2193 }
2194 assert((data_type == none) || (_matrule == NULL), "No match-rule for stackSlotX"){ if (!((data_type == none) || (_matrule == __null))) { fprintf
(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2194, "No match-rule for stackSlotX"); abort(); }}
;
2195
2196 return data_type;
2197}
2198
2199
2200// Return ideal type, if there is a single ideal type for this operand
2201const char *OperandForm::ideal_type(FormDict &globals, RegisterForm *registers) const {
2202 const char *type = NULL__null;
2203 if (ideal_only()) type = _ident;
2204 else if( _matrule == NULL__null ) {
2205 // Check for condition code register
2206 const char *rc_name = constrained_reg_class();
2207 // !!!!!
2208 if (rc_name == NULL__null) return NULL__null;
2209 // !!!!! !!!!!
2210 // Check constraints on result's register class
2211 if( registers ) {
2212 RegClass *reg_class = registers->getRegClass(rc_name);
2213 assert( reg_class != NULL, "Register class is not defined"){ if (!(reg_class != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2213, "Register class is not defined"); abort(); }}
;
2214
2215 // Check for ideal type of entries in register class, all are the same type
2216 reg_class->reset();
2217 RegDef *reg_def = reg_class->RegDef_iter();
2218 assert( reg_def != NULL, "No entries in register class"){ if (!(reg_def != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2218, "No entries in register class"); abort(); }}
;
2219 assert( reg_def->_idealtype != NULL, "Did not define ideal type for register"){ if (!(reg_def->_idealtype != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2219, "Did not define ideal type for register"); abort(); }
}
;
2220 // Return substring that names the register's ideal type
2221 type = reg_def->_idealtype + 3;
2222 assert( *(reg_def->_idealtype + 0) == 'O', "Expect Op_ prefix"){ if (!(*(reg_def->_idealtype + 0) == 'O')) { fprintf(stderr
, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2222, "Expect Op_ prefix"); abort(); }}
;
2223 assert( *(reg_def->_idealtype + 1) == 'p', "Expect Op_ prefix"){ if (!(*(reg_def->_idealtype + 1) == 'p')) { fprintf(stderr
, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2223, "Expect Op_ prefix"); abort(); }}
;
2224 assert( *(reg_def->_idealtype + 2) == '_', "Expect Op_ prefix"){ if (!(*(reg_def->_idealtype + 2) == '_')) { fprintf(stderr
, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2224, "Expect Op_ prefix"); abort(); }}
;
2225 }
2226 }
2227 else if( _matrule->_lChild == NULL__null && _matrule->_rChild == NULL__null ) {
2228 // This operand matches a single type, at the top level.
2229 // Check for ideal type
2230 type = _matrule->_opType;
2231 if( strcmp(type,"Bool") == 0 )
2232 return "Bool";
2233 // transitive lookup
2234 const Form *frm = globals[type];
2235 OperandForm *op = frm->is_operand();
2236 type = op->ideal_type(globals, registers);
2237 }
2238 return type;
2239}
2240
2241
2242// If there is a single ideal type for this interface field, return it.
2243const char *OperandForm::interface_ideal_type(FormDict &globals,
2244 const char *field) const {
2245 const char *ideal_type = NULL__null;
2246 const char *value = NULL__null;
2247
2248 // Check if "field" is valid for this operand's interface
2249 if ( ! is_interface_field(field, value) ) return ideal_type;
2250
2251 // !!!!! !!!!! !!!!!
2252 // If a valid field has a constant value, identify "ConI" or "ConP" or ...
2253
2254 // Else, lookup type of field's replacement variable
2255
2256 return ideal_type;
2257}
2258
2259
2260RegClass* OperandForm::get_RegClass() const {
2261 if (_interface && !_interface->is_RegInterface()) return NULL__null;
2262 return globalAD->get_registers()->getRegClass(constrained_reg_class());
2263}
2264
2265
2266bool OperandForm::is_bound_register() const {
2267 RegClass* reg_class = get_RegClass();
2268 if (reg_class == NULL__null) {
2269 return false;
2270 }
2271
2272 const char* name = ideal_type(globalAD->globalNames());
2273 if (name == NULL__null) {
2274 return false;
2275 }
2276
2277 uintunsigned int size = 0;
2278 if (strcmp(name, "RegFlags") == 0) size = 1;
2279 if (strcmp(name, "RegI") == 0) size = 1;
2280 if (strcmp(name, "RegF") == 0) size = 1;
2281 if (strcmp(name, "RegD") == 0) size = 2;
2282 if (strcmp(name, "RegL") == 0) size = 2;
2283 if (strcmp(name, "RegN") == 0) size = 1;
2284 if (strcmp(name, "RegVectMask") == 0) size = globalAD->get_preproc_def("AARCH64") ? 1 : 2;
2285 if (strcmp(name, "VecX") == 0) size = 4;
2286 if (strcmp(name, "VecY") == 0) size = 8;
2287 if (strcmp(name, "VecZ") == 0) size = 16;
2288 if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
2289 if (size == 0) {
2290 return false;
2291 }
2292 return size == reg_class->size();
2293}
2294
2295
2296// Check if this is a valid field for this operand,
2297// Return 'true' if valid, and set the value to the string the user provided.
2298bool OperandForm::is_interface_field(const char *field,
2299 const char * &value) const {
2300 return false;
2301}
2302
2303
2304// Return register class name if a constraint specifies the register class.
2305const char *OperandForm::constrained_reg_class() const {
2306 const char *reg_class = NULL__null;
2307 if ( _constraint ) {
2308 // !!!!!
2309 Constraint *constraint = _constraint;
2310 if ( strcmp(_constraint->_func,"ALLOC_IN_RC") == 0 ) {
2311 reg_class = _constraint->_arg;
2312 }
2313 }
2314
2315 return reg_class;
2316}
2317
2318
2319// Return the register class associated with 'leaf'.
2320const char *OperandForm::in_reg_class(uintunsigned int leaf, FormDict &globals) {
2321 const char *reg_class = NULL__null; // "RegMask::Empty";
2322
2323 if((_matrule == NULL__null) || (_matrule->is_chain_rule(globals))) {
2324 reg_class = constrained_reg_class();
2325 return reg_class;
2326 }
2327 const char *result = NULL__null;
2328 const char *name = NULL__null;
2329 const char *type = NULL__null;
2330 // iterate through all base operands
2331 // until we reach the register that corresponds to "leaf"
2332 // This function is not looking for an ideal type. It needs the first
2333 // level user type associated with the leaf.
2334 for(uintunsigned int idx = 0;_matrule->base_operand(idx,globals,result,name,type);++idx) {
2335 const Form *form = (_localNames[name] ? _localNames[name] : globals[result]);
2336 OperandForm *oper = form ? form->is_operand() : NULL__null;
2337 if( oper ) {
2338 reg_class = oper->constrained_reg_class();
2339 if( reg_class ) {
2340 reg_class = reg_class;
2341 } else {
2342 // ShouldNotReachHere();
2343 }
2344 } else {
2345 // ShouldNotReachHere();
2346 }
2347
2348 // Increment our target leaf position if current leaf is not a candidate.
2349 if( reg_class == NULL__null) ++leaf;
2350 // Exit the loop with the value of reg_class when at the correct index
2351 if( idx == leaf ) break;
2352 // May iterate through all base operands if reg_class for 'leaf' is NULL
2353 }
2354 return reg_class;
2355}
2356
2357
2358// Recursive call to construct list of top-level operands.
2359// Implementation does not modify state of internal structures
2360void OperandForm::build_components() {
2361 if (_matrule) _matrule->append_components(_localNames, _components);
2362
2363 // Add parameters that "do not appear in match rule".
2364 const char *name;
2365 for (_parameters.reset(); (name = _parameters.iter()) != NULL__null;) {
2366 OpClassForm *opForm = _localNames[name]->is_opclass();
2367 assert(opForm != NULL, "sanity"){ if (!(opForm != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2367, "sanity"); abort(); }}
;
2368
2369 if ( _components.operand_position(name) == -1 ) {
2370 _components.insert(name, opForm->_ident, Component::INVALID, false);
2371 }
2372 }
2373
2374 return;
2375}
2376
2377int OperandForm::operand_position(const char *name, int usedef) {
2378 return _components.operand_position(name, usedef, this);
2379}
2380
2381
2382// Return zero-based position in component list, only counting constants;
2383// Return -1 if not in list.
2384int OperandForm::constant_position(FormDict &globals, const Component *last) {
2385 // Iterate through components and count constants preceding 'constant'
2386 int position = 0;
2387 Component *comp;
2388 _components.reset();
2389 while( (comp = _components.iter()) != NULL__null && (comp != last) ) {
2390 // Special case for operands that take a single user-defined operand
2391 // Skip the initial definition in the component list.
2392 if( strcmp(comp->_name,this->_ident) == 0 ) continue;
2393
2394 const char *type = comp->_type;
2395 // Lookup operand form for replacement variable's type
2396 const Form *form = globals[type];
2397 assert( form != NULL, "Component's type not found"){ if (!(form != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2397, "Component's type not found"); abort(); }}
;
2398 OperandForm *oper = form ? form->is_operand() : NULL__null;
2399 if( oper ) {
2400 if( oper->_matrule->is_base_constant(globals) != Form::none ) {
2401 ++position;
2402 }
2403 }
2404 }
2405
2406 // Check for being passed a component that was not in the list
2407 if( comp != last ) position = -1;
2408
2409 return position;
2410}
2411// Provide position of constant by "name"
2412int OperandForm::constant_position(FormDict &globals, const char *name) {
2413 const Component *comp = _components.search(name);
2414 int idx = constant_position( globals, comp );
2415
2416 return idx;
2417}
2418
2419
2420// Return zero-based position in component list, only counting constants;
2421// Return -1 if not in list.
2422int OperandForm::register_position(FormDict &globals, const char *reg_name) {
2423 // Iterate through components and count registers preceding 'last'
2424 uintunsigned int position = 0;
2425 Component *comp;
2426 _components.reset();
2427 while( (comp = _components.iter()) != NULL__null
2428 && (strcmp(comp->_name,reg_name) != 0) ) {
2429 // Special case for operands that take a single user-defined operand
2430 // Skip the initial definition in the component list.
2431 if( strcmp(comp->_name,this->_ident) == 0 ) continue;
2432
2433 const char *type = comp->_type;
2434 // Lookup operand form for component's type
2435 const Form *form = globals[type];
2436 assert( form != NULL, "Component's type not found"){ if (!(form != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2436, "Component's type not found"); abort(); }}
;
2437 OperandForm *oper = form ? form->is_operand() : NULL__null;
2438 if( oper ) {
2439 if( oper->_matrule->is_base_register(globals) ) {
2440 ++position;
2441 }
2442 }
2443 }
2444
2445 return position;
2446}
2447
2448
2449const char *OperandForm::reduce_result() const {
2450 return _ident;
2451}
2452// Return the name of the operand on the right hand side of the binary match
2453// Return NULL if there is no right hand side
2454const char *OperandForm::reduce_right(FormDict &globals) const {
2455 return ( _matrule ? _matrule->reduce_right(globals) : NULL__null );
2456}
2457
2458// Similar for left
2459const char *OperandForm::reduce_left(FormDict &globals) const {
2460 return ( _matrule ? _matrule->reduce_left(globals) : NULL__null );
2461}
2462
2463
2464// --------------------------- FILE *output_routines
2465//
2466// Output code for disp_is_oop, if true.
2467void OperandForm::disp_is_oop(FILE *fp, FormDict &globals) {
2468 // Check it is a memory interface with a non-user-constant disp field
2469 if ( this->_interface == NULL__null ) return;
2470 MemInterface *mem_interface = this->_interface->is_MemInterface();
2471 if ( mem_interface == NULL__null ) return;
2472 const char *disp = mem_interface->_disp;
2473 if ( *disp != '$' ) return;
2474
2475 // Lookup replacement variable in operand's component list
2476 const char *rep_var = disp + 1;
2477 const Component *comp = this->_components.search(rep_var);
2478 assert( comp != NULL, "Replacement variable not found in components"){ if (!(comp != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2478, "Replacement variable not found in components"); abort
(); }}
;
2479 // Lookup operand form for replacement variable's type
2480 const char *type = comp->_type;
2481 Form *form = (Form*)globals[type];
2482 assert( form != NULL, "Replacement variable's type not found"){ if (!(form != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2482, "Replacement variable's type not found"); abort(); }}
;
2483 OperandForm *op = form->is_operand();
2484 assert( op, "Memory Interface 'disp' can only emit an operand form"){ if (!(op)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2484, "Memory Interface 'disp' can only emit an operand form"
); abort(); }}
;
2485 // Check if this is a ConP, which may require relocation
2486 if ( op->is_base_constant(globals) == Form::idealP ) {
2487 // Find the constant's index: _c0, _c1, _c2, ... , _cN
2488 uintunsigned int idx = op->constant_position( globals, rep_var);
2489 fprintf(fp," virtual relocInfo::relocType disp_reloc() const {");
2490 fprintf(fp, " return _c%d->reloc();", idx);
2491 fprintf(fp, " }\n");
2492 }
2493}
2494
2495// Generate code for internal and external format methods
2496//
2497// internal access to reg# node->_idx
2498// access to subsumed constant _c0, _c1,
2499void OperandForm::int_format(FILE *fp, FormDict &globals, uintunsigned int index) {
2500 Form::DataType dtype;
2501 if (_matrule && (_matrule->is_base_register(globals) ||
2502 strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
2503 // !!!!! !!!!!
2504 fprintf(fp," { char reg_str[128];\n");
2505 fprintf(fp," ra->dump_register(node,reg_str);\n");
2506 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
2507 fprintf(fp," }\n");
2508 } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
2509 format_constant( fp, index, dtype );
2510 } else if (ideal_to_sReg_type(_ident) != Form::none) {
2511 // Special format for Stack Slot Register
2512 fprintf(fp," { char reg_str[128];\n");
2513 fprintf(fp," ra->dump_register(node,reg_str);\n");
2514 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
2515 fprintf(fp," }\n");
2516 } else {
2517 fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident);
2518 fflush(fp);
2519 fprintf(stderrstderr,"No format defined for %s\n", _ident);
2520 dump();
2521 assert( false,"Internal error:\n output_internal_operand() attempting to output other than a Register or Constant"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2521, "Internal error:\n output_internal_operand() attempting to output other than a Register or Constant"
); abort(); }}
;
2522 }
2523}
2524
2525// Similar to "int_format" but for cases where data is external to operand
2526// external access to reg# node->in(idx)->_idx,
2527void OperandForm::ext_format(FILE *fp, FormDict &globals, uintunsigned int index) {
2528 Form::DataType dtype;
2529 if (_matrule && (_matrule->is_base_register(globals) ||
2530 strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
2531 fprintf(fp," { char reg_str[128];\n");
2532 fprintf(fp," ra->dump_register(node->in(idx");
2533 if ( index != 0 ) fprintf(fp, "+%d",index);
2534 fprintf(fp, "),reg_str);\n");
2535 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
2536 fprintf(fp," }\n");
2537 } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
2538 format_constant( fp, index, dtype );
2539 } else if (ideal_to_sReg_type(_ident) != Form::none) {
2540 // Special format for Stack Slot Register
2541 fprintf(fp," { char reg_str[128];\n");
2542 fprintf(fp," ra->dump_register(node->in(idx");
2543 if ( index != 0 ) fprintf(fp, "+%d",index);
2544 fprintf(fp, "),reg_str);\n");
2545 fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
2546 fprintf(fp," }\n");
2547 } else {
2548 fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident);
2549 assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2549, "Internal error:\n output_external_operand() attempting to output other than a Register or Constant"
); abort(); }}
;
2550 }
2551}
2552
2553void OperandForm::format_constant(FILE *fp, uintunsigned int const_index, uintunsigned int const_type) {
2554 switch(const_type) {
2555 case Form::idealI: fprintf(fp," st->print(\"#%%d\", _c%d);\n", const_index); break;
2556 case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
2557 case Form::idealNKlass:
2558 case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
2559 case Form::idealL: fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break;
2560 case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break;
2561 case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break;
2562 default:
2563 assert( false, "ShouldNotReachHere()"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2563, "ShouldNotReachHere()"); abort(); }}
;
2564 }
2565}
2566
2567// Return the operand form corresponding to the given index, else NULL.
2568OperandForm *OperandForm::constant_operand(FormDict &globals,
2569 uintunsigned int index) {
2570 // !!!!!
2571 // Check behavior on complex operands
2572 uintunsigned int n_consts = num_consts(globals);
2573 if( n_consts > 0 ) {
2574 uintunsigned int i = 0;
2575 const char *type;
2576 Component *comp;
2577 _components.reset();
2578 if ((comp = _components.iter()) == NULL__null) {
2579 assert(n_consts == 1, "Bad component list detected.\n"){ if (!(n_consts == 1)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2579, "Bad component list detected.\n"); abort(); }}
;
2580 // Current operand is THE operand
2581 if ( index == 0 ) {
2582 return this;
2583 }
2584 } // end if NULL
2585 else {
2586 // Skip the first component, it can not be a DEF of a constant
2587 do {
2588 type = comp->base_type(globals);
2589 // Check that "type" is a 'ConI', 'ConP', ...
2590 if ( ideal_to_const_type(type) != Form::none ) {
2591 // When at correct component, get corresponding Operand
2592 if ( index == 0 ) {
2593 return globals[comp->_type]->is_operand();
2594 }
2595 // Decrement number of constants to go
2596 --index;
2597 }
2598 } while((comp = _components.iter()) != NULL__null);
2599 }
2600 }
2601
2602 // Did not find a constant for this index.
2603 return NULL__null;
2604}
2605
2606// If this operand has a single ideal type, return its type
2607Form::DataType OperandForm::simple_type(FormDict &globals) const {
2608 const char *type_name = ideal_type(globals);
2609 Form::DataType type = type_name ? ideal_to_const_type( type_name )
2610 : Form::none;
2611 return type;
2612}
2613
2614Form::DataType OperandForm::is_base_constant(FormDict &globals) const {
2615 if ( _matrule == NULL__null ) return Form::none;
2616
2617 return _matrule->is_base_constant(globals);
2618}
2619
2620// "true" if this operand is a simple type that is swallowed
2621bool OperandForm::swallowed(FormDict &globals) const {
2622 Form::DataType type = simple_type(globals);
2623 if( type != Form::none ) {
2624 return true;
2625 }
2626
2627 return false;
2628}
2629
2630// Output code to access the value of the index'th constant
2631void OperandForm::access_constant(FILE *fp, FormDict &globals,
2632 uintunsigned int const_index) {
2633 OperandForm *oper = constant_operand(globals, const_index);
2634 assert( oper, "Index exceeds number of constants in operand"){ if (!(oper)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2634, "Index exceeds number of constants in operand"); abort
(); }}
;
2635 Form::DataType dtype = oper->is_base_constant(globals);
2636
2637 switch(dtype) {
2638 case idealI: fprintf(fp,"_c%d", const_index); break;
2639 case idealP: fprintf(fp,"_c%d->get_con()",const_index); break;
2640 case idealL: fprintf(fp,"_c%d", const_index); break;
2641 case idealF: fprintf(fp,"_c%d", const_index); break;
2642 case idealD: fprintf(fp,"_c%d", const_index); break;
2643 default:
2644 assert( false, "ShouldNotReachHere()"){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2644, "ShouldNotReachHere()"); abort(); }}
;
2645 }
2646}
2647
2648
2649void OperandForm::dump() {
2650 output(stderrstderr);
2651}
2652
2653void OperandForm::output(FILE *fp) {
2654 fprintf(fp,"\nOperand: %s\n", (_ident?_ident:""));
2655 if (_matrule) _matrule->dump();
2656 if (_interface) _interface->dump();
2657 if (_attribs) _attribs->dump();
2658 if (_predicate) _predicate->dump();
2659 if (_constraint) _constraint->dump();
2660 if (_construct) _construct->dump();
2661 if (_format) _format->dump();
2662}
2663
2664//------------------------------Constraint-------------------------------------
2665Constraint::Constraint(const char *func, const char *arg)
2666 : _func(func), _arg(arg) {
2667}
2668Constraint::~Constraint() { /* not owner of char* */
2669}
2670
2671bool Constraint::stack_slots_only() const {
2672 return strcmp(_func, "ALLOC_IN_RC") == 0
2673 && strcmp(_arg, "stack_slots") == 0;
2674}
2675
2676void Constraint::dump() {
2677 output(stderrstderr);
2678}
2679
2680void Constraint::output(FILE *fp) { // Write info to output files
2681 assert((_func != NULL && _arg != NULL),"missing constraint function or arg"){ if (!((_func != __null && _arg != __null))) { fprintf
(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2681, "missing constraint function or arg"); abort(); }}
;
2682 fprintf(fp,"Constraint: %s ( %s )\n", _func, _arg);
2683}
2684
2685//------------------------------Predicate--------------------------------------
2686Predicate::Predicate(char *pr)
2687 : _pred(pr) {
2688}
2689Predicate::~Predicate() {
2690}
2691
2692void Predicate::dump() {
2693 output(stderrstderr);
2694}
2695
2696void Predicate::output(FILE *fp) {
2697 fprintf(fp,"Predicate"); // Write to output files
2698}
2699//------------------------------Interface--------------------------------------
2700Interface::Interface(const char *name) : _name(name) {
2701}
2702Interface::~Interface() {
2703}
2704
2705Form::InterfaceType Interface::interface_type(FormDict &globals) const {
2706 Interface *thsi = (Interface*)this;
2707 if ( thsi->is_RegInterface() ) return Form::register_interface;
2708 if ( thsi->is_MemInterface() ) return Form::memory_interface;
2709 if ( thsi->is_ConstInterface() ) return Form::constant_interface;
2710 if ( thsi->is_CondInterface() ) return Form::conditional_interface;
2711
2712 return Form::no_interface;
2713}
2714
2715RegInterface *Interface::is_RegInterface() {
2716 if ( strcmp(_name,"REG_INTER") != 0 )
2717 return NULL__null;
2718 return (RegInterface*)this;
2719}
2720MemInterface *Interface::is_MemInterface() {
2721 if ( strcmp(_name,"MEMORY_INTER") != 0 ) return NULL__null;
2722 return (MemInterface*)this;
2723}
2724ConstInterface *Interface::is_ConstInterface() {
2725 if ( strcmp(_name,"CONST_INTER") != 0 ) return NULL__null;
2726 return (ConstInterface*)this;
2727}
2728CondInterface *Interface::is_CondInterface() {
2729 if ( strcmp(_name,"COND_INTER") != 0 ) return NULL__null;
2730 return (CondInterface*)this;
2731}
2732
2733
2734void Interface::dump() {
2735 output(stderrstderr);
2736}
2737
2738// Write info to output files
2739void Interface::output(FILE *fp) {
2740 fprintf(fp,"Interface: %s\n", (_name ? _name : "") );
2741}
2742
2743//------------------------------RegInterface-----------------------------------
2744RegInterface::RegInterface() : Interface("REG_INTER") {
2745}
2746RegInterface::~RegInterface() {
2747}
2748
2749void RegInterface::dump() {
2750 output(stderrstderr);
2751}
2752
2753// Write info to output files
2754void RegInterface::output(FILE *fp) {
2755 Interface::output(fp);
2756}
2757
2758//------------------------------ConstInterface---------------------------------
2759ConstInterface::ConstInterface() : Interface("CONST_INTER") {
2760}
2761ConstInterface::~ConstInterface() {
2762}
2763
2764void ConstInterface::dump() {
2765 output(stderrstderr);
2766}
2767
2768// Write info to output files
2769void ConstInterface::output(FILE *fp) {
2770 Interface::output(fp);
2771}
2772
2773//------------------------------MemInterface-----------------------------------
2774MemInterface::MemInterface(char *base, char *index, char *scale, char *disp)
2775 : Interface("MEMORY_INTER"), _base(base), _index(index), _scale(scale), _disp(disp) {
2776}
2777MemInterface::~MemInterface() {
2778 // not owner of any character arrays
2779}
2780
2781void MemInterface::dump() {
2782 output(stderrstderr);
2783}
2784
2785// Write info to output files
2786void MemInterface::output(FILE *fp) {
2787 Interface::output(fp);
2788 if ( _base != NULL__null ) fprintf(fp," base == %s\n", _base);
2789 if ( _index != NULL__null ) fprintf(fp," index == %s\n", _index);
2790 if ( _scale != NULL__null ) fprintf(fp," scale == %s\n", _scale);
2791 if ( _disp != NULL__null ) fprintf(fp," disp == %s\n", _disp);
2792 // fprintf(fp,"\n");
2793}
2794
2795//------------------------------CondInterface----------------------------------
2796CondInterface::CondInterface(const char* equal, const char* equal_format,
2797 const char* not_equal, const char* not_equal_format,
2798 const char* less, const char* less_format,
2799 const char* greater_equal, const char* greater_equal_format,
2800 const char* less_equal, const char* less_equal_format,
2801 const char* greater, const char* greater_format,
2802 const char* overflow, const char* overflow_format,
2803 const char* no_overflow, const char* no_overflow_format)
2804 : Interface("COND_INTER"),
2805 _equal(equal), _equal_format(equal_format),
2806 _not_equal(not_equal), _not_equal_format(not_equal_format),
2807 _less(less), _less_format(less_format),
2808 _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
2809 _less_equal(less_equal), _less_equal_format(less_equal_format),
2810 _greater(greater), _greater_format(greater_format),
2811 _overflow(overflow), _overflow_format(overflow_format),
2812 _no_overflow(no_overflow), _no_overflow_format(no_overflow_format) {
2813}
2814CondInterface::~CondInterface() {
2815 // not owner of any character arrays
2816}
2817
2818void CondInterface::dump() {
2819 output(stderrstderr);
2820}
2821
2822// Write info to output files
2823void CondInterface::output(FILE *fp) {
2824 Interface::output(fp);
2825 if ( _equal != NULL__null ) fprintf(fp," equal == %s\n", _equal);
2826 if ( _not_equal != NULL__null ) fprintf(fp," not_equal == %s\n", _not_equal);
2827 if ( _less != NULL__null ) fprintf(fp," less == %s\n", _less);
2828 if ( _greater_equal != NULL__null ) fprintf(fp," greater_equal == %s\n", _greater_equal);
2829 if ( _less_equal != NULL__null ) fprintf(fp," less_equal == %s\n", _less_equal);
2830 if ( _greater != NULL__null ) fprintf(fp," greater == %s\n", _greater);
2831 if ( _overflow != NULL__null ) fprintf(fp," overflow == %s\n", _overflow);
2832 if ( _no_overflow != NULL__null ) fprintf(fp," no_overflow == %s\n", _no_overflow);
2833 // fprintf(fp,"\n");
2834}
2835
2836//------------------------------ConstructRule----------------------------------
2837ConstructRule::ConstructRule(char *cnstr)
2838 : _construct(cnstr) {
2839}
2840ConstructRule::~ConstructRule() {
2841}
2842
2843void ConstructRule::dump() {
2844 output(stderrstderr);
2845}
2846
2847void ConstructRule::output(FILE *fp) {
2848 fprintf(fp,"\nConstruct Rule\n"); // Write to output files
2849}
2850
2851
2852//==============================Shared Forms===================================
2853//------------------------------AttributeForm----------------------------------
2854int AttributeForm::_insId = 0; // start counter at 0
2855int AttributeForm::_opId = 0; // start counter at 0
2856const char* AttributeForm::_ins_cost = "ins_cost"; // required name
2857const char* AttributeForm::_op_cost = "op_cost"; // required name
2858
2859AttributeForm::AttributeForm(char *attr, int type, char *attrdef)
2860 : Form(Form::ATTR), _attrname(attr), _atype(type), _attrdef(attrdef) {
2861 if (type==OP_ATTR1) {
2862 id = ++_opId;
2863 }
2864 else if (type==INS_ATTR0) {
2865 id = ++_insId;
2866 }
2867 else assert( false,""){ if (!(false)) { fprintf(stderr, "assert fails %s %d: %s\n",
"/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2867, ""); abort(); }}
;
2868}
2869AttributeForm::~AttributeForm() {
2870}
2871
2872// Dynamic type check
2873AttributeForm *AttributeForm::is_attribute() const {
2874 return (AttributeForm*)this;
2875}
2876
2877
2878// inlined // int AttributeForm::type() { return id;}
2879
2880void AttributeForm::dump() {
2881 output(stderrstderr);
2882}
2883
2884void AttributeForm::output(FILE *fp) {
2885 if( _attrname && _attrdef ) {
2886 fprintf(fp,"\n// AttributeForm \nstatic const int %s = %s;\n",
2887 _attrname, _attrdef);
2888 }
2889 else {
2890 fprintf(fp,"\n// AttributeForm missing name %s or definition %s\n",
2891 (_attrname?_attrname:""), (_attrdef?_attrdef:"") );
2892 }
2893}
2894
2895//------------------------------Component--------------------------------------
2896Component::Component(const char *name, const char *type, int usedef)
2897 : _name(name), _type(type), _usedef(usedef) {
2898 _ftype = Form::COMP;
2899}
2900Component::~Component() {
2901}
2902
2903// True if this component is equal to the parameter.
2904bool Component::is(int use_def_kill_enum) const {
2905 return (_usedef == use_def_kill_enum ? true : false);
2906}
2907// True if this component is used/def'd/kill'd as the parameter suggests.
2908bool Component::isa(int use_def_kill_enum) const {
2909 return (_usedef & use_def_kill_enum) == use_def_kill_enum;
2910}
2911
2912// Extend this component with additional use/def/kill behavior
2913int Component::promote_use_def_info(int new_use_def) {
2914 _usedef |= new_use_def;
2915
2916 return _usedef;
2917}
2918
2919// Check the base type of this component, if it has one
2920const char *Component::base_type(FormDict &globals) {
2921 const Form *frm = globals[_type];
2922 if (frm == NULL__null) return NULL__null;
2923 OperandForm *op = frm->is_operand();
2924 if (op == NULL__null) return NULL__null;
2925 if (op->ideal_only()) return op->_ident;
2926 return (char *)op->ideal_type(globals);
2927}
2928
2929void Component::dump() {
2930 output(stderrstderr);
2931}
2932
2933void Component::output(FILE *fp) {
2934 fprintf(fp,"Component:"); // Write to output files
2935 fprintf(fp, " name = %s", _name);
2936 fprintf(fp, ", type = %s", _type);
2937 assert(_usedef != 0, "unknown effect"){ if (!(_usedef != 0)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 2937, "unknown effect"); abort(); }}
;
2938 fprintf(fp, ", use/def = %s\n", getUsedefName());
2939}
2940
2941
2942//------------------------------ComponentList---------------------------------
2943ComponentList::ComponentList() : NameList(), _matchcnt(0) {
2944}
2945ComponentList::~ComponentList() {
2946 // // This list may not own its elements if copied via assignment
2947 // Component *component;
2948 // for (reset(); (component = iter()) != NULL;) {
2949 // delete component;
2950 // }
2951}
2952
2953void ComponentList::insert(Component *component, bool mflag) {
2954 NameList::addName((char *)component);
2955 if(mflag) _matchcnt++;
2956}
2957void ComponentList::insert(const char *name, const char *opType, int usedef,
2958 bool mflag) {
2959 Component * component = new Component(name, opType, usedef);
2960 insert(component, mflag);
2961}
2962Component *ComponentList::current() { return (Component*)NameList::current(); }
2963Component *ComponentList::iter() { return (Component*)NameList::iter(); }
2964Component *ComponentList::match_iter() {
2965 if(_iter < _matchcnt) return (Component*)NameList::iter();
2966 return NULL__null;
2967}
2968Component *ComponentList::post_match_iter() {
2969 Component *comp = iter();
2970 // At end of list?
2971 if ( comp == NULL__null ) {
2972 return comp;
2973 }
2974 // In post-match components?
2975 if (_iter > match_count()-1) {
2976 return comp;
2977 }
2978
2979 return post_match_iter();
2980}
2981
2982void ComponentList::reset() { NameList::reset(); }
2983int ComponentList::count() { return NameList::count(); }
2984
2985Component *ComponentList::operator[](int position) {
2986 // Shortcut complete iteration if there are not enough entries
2987 if (position >= count()) return NULL__null;
2988
2989 int index = 0;
2990 Component *component = NULL__null;
2991 for (reset(); (component = iter()) != NULL__null;) {
2992 if (index == position) {
2993 return component;
2994 }
2995 ++index;
2996 }
2997
2998 return NULL__null;
2999}
3000
3001const Component *ComponentList::search(const char *name) {
3002 PreserveIter pi(this);
3003 reset();
3004 for( Component *comp = NULL__null; ((comp = iter()) != NULL__null); ) {
3005 if( strcmp(comp->_name,name) == 0 ) return comp;
3006 }
3007
3008 return NULL__null;
3009}
3010
3011// Return number of USEs + number of DEFs
3012// When there are no components, or the first component is a USE,
3013// then we add '1' to hold a space for the 'result' operand.
3014int ComponentList::num_operands() {
3015 PreserveIter pi(this);
3016 uintunsigned int count = 1; // result operand
3017 uintunsigned int position = 0;
3018
3019 Component *component = NULL__null;
3020 for( reset(); (component = iter()) != NULL__null; ++position ) {
3021 if( component->isa(Component::USE) ||
3022 ( position == 0 && (! component->isa(Component::DEF))) ) {
3023 ++count;
3024 }
3025 }
3026
3027 return count;
3028}
3029
3030// Return zero-based position of operand 'name' in list; -1 if not in list.
3031// if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ...
3032int ComponentList::operand_position(const char *name, int usedef, Form *fm) {
3033 PreserveIter pi(this);
3034 int position = 0;
3035 int num_opnds = num_operands();
3036 Component *component;
3037 Component* preceding_non_use = NULL__null;
3038 Component* first_def = NULL__null;
3039 for (reset(); (component = iter()) != NULL__null; ++position) {
3040 // When the first component is not a DEF,
3041 // leave space for the result operand!
3042 if ( position==0 && (! component->isa(Component::DEF)) ) {
3043 ++position;
3044 ++num_opnds;
3045 }
3046 if (strcmp(name, component->_name)==0 && (component->isa(usedef))) {
3047 // When the first entry in the component list is a DEF and a USE
3048 // Treat them as being separate, a DEF first, then a USE
3049 if( position==0
3050 && usedef==Component::USE && component->isa(Component::DEF) ) {
3051 assert(position+1 < num_opnds, "advertised index in bounds"){ if (!(position+1 < num_opnds)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3051, "advertised index in bounds"); abort(); }}
;
3052 return position+1;
3053 } else {
3054 if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) {
3055 fprintf(stderrstderr, "the name '%s(%s)' should not precede the name '%s(%s)'",
3056 preceding_non_use->_name, preceding_non_use->getUsedefName(),
3057 name, component->getUsedefName());
3058 if (fm && fm->is_instruction()) fprintf(stderrstderr, "in form '%s'", fm->is_instruction()->_ident);
3059 if (fm && fm->is_operand()) fprintf(stderrstderr, "in form '%s'", fm->is_operand()->_ident);
3060 fprintf(stderrstderr, "\n");
3061 }
3062 if( position >= num_opnds ) {
3063 fprintf(stderrstderr, "the name '%s' is too late in its name list", name);
3064 if (fm && fm->is_instruction()) fprintf(stderrstderr, "in form '%s'", fm->is_instruction()->_ident);
3065 if (fm && fm->is_operand()) fprintf(stderrstderr, "in form '%s'", fm->is_operand()->_ident);
3066 fprintf(stderrstderr, "\n");
3067 }
3068 assert(position < num_opnds, "advertised index in bounds"){ if (!(position < num_opnds)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3068, "advertised index in bounds"); abort(); }}
;
3069 return position;
3070 }
3071 }
3072 if( component->isa(Component::DEF)
3073 && component->isa(Component::USE) ) {
3074 ++position;
3075 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF
3076 }
3077 if( component->isa(Component::DEF) && !first_def ) {
3078 first_def = component;
3079 }
3080 if( !component->isa(Component::USE) && component != first_def ) {
3081 preceding_non_use = component;
3082 } else if( preceding_non_use && !strcmp(component->_name, preceding_non_use->_name) ) {
3083 preceding_non_use = NULL__null;
3084 }
3085 }
3086 return Not_in_list;
3087}
3088
3089// Find position for this name, regardless of use/def information
3090int ComponentList::operand_position(const char *name) {
3091 PreserveIter pi(this);
3092 int position = 0;
3093 Component *component;
3094 for (reset(); (component = iter()) != NULL__null; ++position) {
3095 // When the first component is not a DEF,
3096 // leave space for the result operand!
3097 if ( position==0 && (! component->isa(Component::DEF)) ) {
3098 ++position;
3099 }
3100 if (strcmp(name, component->_name)==0) {
3101 return position;
3102 }
3103 if( component->isa(Component::DEF)
3104 && component->isa(Component::USE) ) {
3105 ++position;
3106 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF
3107 }
3108 }
3109 return Not_in_list;
3110}
3111
3112int ComponentList::operand_position_format(const char *name, Form *fm) {
3113 PreserveIter pi(this);
3114 int first_position = operand_position(name);
3115 int use_position = operand_position(name, Component::USE, fm);
3116
3117 return ((first_position < use_position) ? use_position : first_position);
3118}
3119
3120int ComponentList::label_position() {
3121 PreserveIter pi(this);
3122 int position = 0;
3123 reset();
3124 for( Component *comp; (comp = iter()) != NULL__null; ++position) {
3125 // When the first component is not a DEF,
3126 // leave space for the result operand!
3127 if ( position==0 && (! comp->isa(Component::DEF)) ) {
3128 ++position;
3129 }
3130 if (strcmp(comp->_type, "label")==0) {
3131 return position;
3132 }
3133 if( comp->isa(Component::DEF)
3134 && comp->isa(Component::USE) ) {
3135 ++position;
3136 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF
3137 }
3138 }
3139
3140 return -1;
3141}
3142
3143int ComponentList::method_position() {
3144 PreserveIter pi(this);
3145 int position = 0;
3146 reset();
3147 for( Component *comp; (comp = iter()) != NULL__null; ++position) {
3148 // When the first component is not a DEF,
3149 // leave space for the result operand!
3150 if ( position==0 && (! comp->isa(Component::DEF)) ) {
3151 ++position;
3152 }
3153 if (strcmp(comp->_type, "method")==0) {
3154 return position;
3155 }
3156 if( comp->isa(Component::DEF)
3157 && comp->isa(Component::USE) ) {
3158 ++position;
3159 if( position != 1 ) --position; // only use two slots for the 1st USE_DEF
3160 }
3161 }
3162
3163 return -1;
3164}
3165
3166void ComponentList::dump() { output(stderrstderr); }
3167
3168void ComponentList::output(FILE *fp) {
3169 PreserveIter pi(this);
3170 fprintf(fp, "\n");
3171 Component *component;
3172 for (reset(); (component = iter()) != NULL__null;) {
3173 component->output(fp);
3174 }
3175 fprintf(fp, "\n");
3176}
3177
3178//------------------------------MatchNode--------------------------------------
3179MatchNode::MatchNode(ArchDesc &ad, const char *result, const char *mexpr,
3180 const char *opType, MatchNode *lChild, MatchNode *rChild)
3181 : _AD(ad), _result(result), _name(mexpr), _opType(opType),
3182 _lChild(lChild), _rChild(rChild), _internalop(0), _numleaves(0),
3183 _commutative_id(0) {
3184 _numleaves = (lChild ? lChild->_numleaves : 0)
3185 + (rChild ? rChild->_numleaves : 0);
3186}
3187
3188MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode)
3189 : _AD(ad), _result(mnode._result), _name(mnode._name),
3190 _opType(mnode._opType), _lChild(mnode._lChild), _rChild(mnode._rChild),
3191 _internalop(0), _numleaves(mnode._numleaves),
3192 _commutative_id(mnode._commutative_id) {
3193}
3194
3195MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode, int clone)
3196 : _AD(ad), _result(mnode._result), _name(mnode._name),
3197 _opType(mnode._opType),
3198 _internalop(0), _numleaves(mnode._numleaves),
3199 _commutative_id(mnode._commutative_id) {
3200 if (mnode._lChild) {
3201 _lChild = new MatchNode(ad, *mnode._lChild, clone);
3202 } else {
3203 _lChild = NULL__null;
3204 }
3205 if (mnode._rChild) {
3206 _rChild = new MatchNode(ad, *mnode._rChild, clone);
3207 } else {
3208 _rChild = NULL__null;
3209 }
3210}
3211
3212MatchNode::~MatchNode() {
3213 // // This node may not own its children if copied via assignment
3214 // if( _lChild ) delete _lChild;
3215 // if( _rChild ) delete _rChild;
3216}
3217
3218bool MatchNode::find_type(const char *type, int &position) const {
3219 if ( (_lChild != NULL__null) && (_lChild->find_type(type, position)) ) return true;
3220 if ( (_rChild != NULL__null) && (_rChild->find_type(type, position)) ) return true;
3221
3222 if (strcmp(type,_opType)==0) {
3223 return true;
3224 } else {
3225 ++position;
3226 }
3227 return false;
3228}
3229
3230// Recursive call collecting info on top-level operands, not transitive.
3231// Implementation does not modify state of internal structures.
3232void MatchNode::append_components(FormDict& locals, ComponentList& components,
3233 bool def_flag) const {
3234 int usedef = def_flag ? Component::DEF : Component::USE;
3235 FormDict &globals = _AD.globalNames();
3236
3237 assert (_name != NULL, "MatchNode::build_components encountered empty node\n"){ if (!(_name != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3237, "MatchNode::build_components encountered empty node\n"
); abort(); }}
;
3238 // Base case
3239 if (_lChild==NULL__null && _rChild==NULL__null) {
3240 // If _opType is not an operation, do not build a component for it #####
3241 const Form *f = globals[_opType];
3242 if( f != NULL__null ) {
3243 // Add non-ideals that are operands, operand-classes,
3244 if( ! f->ideal_only()
3245 && (f->is_opclass() || f->is_operand()) ) {
3246 components.insert(_name, _opType, usedef, true);
3247 }
3248 }
3249 return;
3250 }
3251 // Promote results of "Set" to DEF
3252 bool tmpdef_flag = (!strcmp(_opType, "Set")) ? true : false;
3253 if (_lChild) _lChild->append_components(locals, components, tmpdef_flag);
3254 tmpdef_flag = false; // only applies to component immediately following 'Set'
3255 if (_rChild) _rChild->append_components(locals, components, tmpdef_flag);
3256}
3257
3258// Find the n'th base-operand in the match node,
3259// recursively investigates match rules of user-defined operands.
3260//
3261// Implementation does not modify state of internal structures since they
3262// can be shared.
3263bool MatchNode::base_operand(uintunsigned int &position, FormDict &globals,
3264 const char * &result, const char * &name,
3265 const char * &opType) const {
3266 assert (_name != NULL, "MatchNode::base_operand encountered empty node\n"){ if (!(_name != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3266, "MatchNode::base_operand encountered empty node\n"); abort
(); }}
;
3267 // Base case
3268 if (_lChild==NULL__null && _rChild==NULL__null) {
3269 // Check for special case: "Universe", "label"
3270 if (strcmp(_opType,"Universe") == 0 || strcmp(_opType,"label")==0 ) {
3271 if (position == 0) {
3272 result = _result;
3273 name = _name;
3274 opType = _opType;
3275 return 1;
3276 } else {
3277 -- position;
3278 return 0;
3279 }
3280 }
3281
3282 const Form *form = globals[_opType];
3283 MatchNode *matchNode = NULL__null;
3284 // Check for user-defined type
3285 if (form) {
3286 // User operand or instruction?
3287 OperandForm *opForm = form->is_operand();
3288 InstructForm *inForm = form->is_instruction();
3289 if ( opForm ) {
3290 matchNode = (MatchNode*)opForm->_matrule;
3291 } else if ( inForm ) {
3292 matchNode = (MatchNode*)inForm->_matrule;
3293 }
3294 }
3295 // if this is user-defined, recurse on match rule
3296 // User-defined operand and instruction forms have a match-rule.
3297 if (matchNode) {
3298 return (matchNode->base_operand(position,globals,result,name,opType));
3299 } else {
3300 // Either not a form, or a system-defined form (no match rule).
3301 if (position==0) {
3302 result = _result;
3303 name = _name;
3304 opType = _opType;
3305 return 1;
3306 } else {
3307 --position;
3308 return 0;
3309 }
3310 }
3311
3312 } else {
3313 // Examine the left child and right child as well
3314 if (_lChild) {
3315 if (_lChild->base_operand(position, globals, result, name, opType))
3316 return 1;
3317 }
3318
3319 if (_rChild) {
3320 if (_rChild->base_operand(position, globals, result, name, opType))
3321 return 1;
3322 }
3323 }
3324
3325 return 0;
3326}
3327
3328// Recursive call on all operands' match rules in my match rule.
3329uintunsigned int MatchNode::num_consts(FormDict &globals) const {
3330 uintunsigned int index = 0;
3331 uintunsigned int num_consts = 0;
3332 const char *result;
3333 const char *name;
3334 const char *opType;
3335
3336 for (uintunsigned int position = index;
3337 base_operand(position,globals,result,name,opType); position = index) {
3338 ++index;
3339 if( ideal_to_const_type(opType) ) num_consts++;
3340 }
3341
3342 return num_consts;
3343}
3344
3345// Recursive call on all operands' match rules in my match rule.
3346// Constants in match rule subtree with specified type
3347uintunsigned int MatchNode::num_consts(FormDict &globals, Form::DataType type) const {
3348 uintunsigned int index = 0;
3349 uintunsigned int num_consts = 0;
3350 const char *result;
3351 const char *name;
3352 const char *opType;
3353
3354 for (uintunsigned int position = index;
3355 base_operand(position,globals,result,name,opType); position = index) {
3356 ++index;
3357 if( ideal_to_const_type(opType) == type ) num_consts++;
3358 }
3359
3360 return num_consts;
3361}
3362
3363// Recursive call on all operands' match rules in my match rule.
3364uintunsigned int MatchNode::num_const_ptrs(FormDict &globals) const {
3365 return num_consts( globals, Form::idealP );
3366}
3367
3368bool MatchNode::sets_result() const {
3369 return ( (strcmp(_name,"Set") == 0) ? true : false );
3370}
3371
3372const char *MatchNode::reduce_right(FormDict &globals) const {
3373 // If there is no right reduction, return NULL.
3374 const char *rightStr = NULL__null;
3375
3376 // If we are a "Set", start from the right child.
3377 const MatchNode *const mnode = sets_result() ?
3378 (const MatchNode *)this->_rChild :
3379 (const MatchNode *)this;
3380
3381 // If our right child exists, it is the right reduction
3382 if ( mnode->_rChild ) {
3383 rightStr = mnode->_rChild->_internalop ? mnode->_rChild->_internalop
3384 : mnode->_rChild->_opType;
3385 }
3386 // Else, May be simple chain rule: (Set dst operand_form), rightStr=NULL;
3387 return rightStr;
3388}
3389
3390const char *MatchNode::reduce_left(FormDict &globals) const {
3391 // If there is no left reduction, return NULL.
3392 const char *leftStr = NULL__null;
3393
3394 // If we are a "Set", start from the right child.
3395 const MatchNode *const mnode = sets_result() ?
3396 (const MatchNode *)this->_rChild :
3397 (const MatchNode *)this;
3398
3399 // If our left child exists, it is the left reduction
3400 if ( mnode->_lChild ) {
3401 leftStr = mnode->_lChild->_internalop ? mnode->_lChild->_internalop
3402 : mnode->_lChild->_opType;
3403 } else {
3404 // May be simple chain rule: (Set dst operand_form_source)
3405 if ( sets_result() ) {
3406 OperandForm *oper = globals[mnode->_opType]->is_operand();
3407 if( oper ) {
3408 leftStr = mnode->_opType;
3409 }
3410 }
3411 }
3412 return leftStr;
3413}
3414
3415//------------------------------count_instr_names------------------------------
3416// Count occurrences of operands names in the leaves of the instruction
3417// match rule.
3418void MatchNode::count_instr_names( Dict &names ) {
3419 if( _lChild ) _lChild->count_instr_names(names);
3420 if( _rChild ) _rChild->count_instr_names(names);
3421 if( !_lChild && !_rChild ) {
3422 uintptr_t cnt = (uintptr_t)names[_name];
3423 cnt++; // One more name found
3424 names.Insert(_name,(void*)cnt);
3425 }
3426}
3427
3428//------------------------------build_instr_pred-------------------------------
3429// Build a path to 'name' in buf. Actually only build if cnt is zero, so we
3430// can skip some leading instances of 'name'.
3431int MatchNode::build_instr_pred( char *buf, const char *name, int cnt, int path_bitmask, int level) {
3432 if( _lChild ) {
3433 cnt = _lChild->build_instr_pred(buf, name, cnt, path_bitmask, level+1);
3434 if( cnt < 0 ) {
3435 return cnt; // Found it, all done
3436 }
3437 }
3438 if( _rChild ) {
3439 path_bitmask |= 1 << level;
3440 cnt = _rChild->build_instr_pred( buf, name, cnt, path_bitmask, level+1);
3441 if( cnt < 0 ) {
3442 return cnt; // Found it, all done
3443 }
3444 }
3445 if( !_lChild && !_rChild ) { // Found a leaf
3446 // Wrong name? Give up...
3447 if( strcmp(name,_name) ) return cnt;
3448 if( !cnt ) {
3449 for(int i = 0; i < level; i++) {
3450 int kid = path_bitmask & (1 << i);
3451 if (0 == kid) {
3452 strcpy( buf, "_kids[0]->" );
3453 } else {
3454 strcpy( buf, "_kids[1]->" );
3455 }
3456 buf += 10;
3457 }
3458 strcpy( buf, "_leaf" );
3459 }
3460 return cnt-1;
3461 }
3462 return cnt;
3463}
3464
3465
3466//------------------------------build_internalop-------------------------------
3467// Build string representation of subtree
3468void MatchNode::build_internalop( ) {
3469 char *iop, *subtree;
3470 const char *lstr, *rstr;
3471 // Build string representation of subtree
3472 // Operation lchildType rchildType
3473 int len = (int)strlen(_opType) + 4;
3474 lstr = (_lChild) ? ((_lChild->_internalop) ?
3475 _lChild->_internalop : _lChild->_opType) : "";
3476 rstr = (_rChild) ? ((_rChild->_internalop) ?
3477 _rChild->_internalop : _rChild->_opType) : "";
3478 len += (int)strlen(lstr) + (int)strlen(rstr);
3479 subtree = (char *)AllocateHeap(len);
3480 sprintf(subtree,"_%s_%s_%s", _opType, lstr, rstr);
3481 // Hash the subtree string in _internalOps; if a name exists, use it
3482 iop = (char *)_AD._internalOps[subtree];
3483 // Else create a unique name, and add it to the hash table
3484 if (iop == NULL__null) {
3485 iop = subtree;
3486 _AD._internalOps.Insert(subtree, iop);
3487 _AD._internalOpNames.addName(iop);
3488 _AD._internalMatch.Insert(iop, this);
3489 }
3490 // Add the internal operand name to the MatchNode
3491 _internalop = iop;
3492 _result = iop;
3493}
3494
3495
3496void MatchNode::dump() {
3497 output(stderrstderr);
3498}
3499
3500void MatchNode::output(FILE *fp) {
3501 if (_lChild==0 && _rChild==0) {
3502 fprintf(fp," %s",_name); // operand
3503 }
3504 else {
3505 fprintf(fp," (%s ",_name); // " (opcodeName "
3506 if(_lChild) _lChild->output(fp); // left operand
3507 if(_rChild) _rChild->output(fp); // right operand
3508 fprintf(fp,")"); // ")"
3509 }
3510}
3511
3512int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3513 static const char *needs_ideal_memory_list[] = {
3514 "StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,
3515 "StoreB","StoreC","Store" ,"StoreFP",
3516 "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,
3517 "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
3518 "StoreVector", "LoadVector", "LoadVectorMasked", "StoreVectorMasked",
3519 "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked",
3520 "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
3521 "LoadPLocked",
3522 "StorePConditional", "StoreIConditional", "StoreLConditional",
3523 "CompareAndSwapB", "CompareAndSwapS", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
3524 "WeakCompareAndSwapB", "WeakCompareAndSwapS", "WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN",
3525 "CompareAndExchangeB", "CompareAndExchangeS", "CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN",
3526#if INCLUDE_SHENANDOAHGC1
3527 "ShenandoahCompareAndSwapN", "ShenandoahCompareAndSwapP", "ShenandoahWeakCompareAndSwapP", "ShenandoahWeakCompareAndSwapN", "ShenandoahCompareAndExchangeP", "ShenandoahCompareAndExchangeN",
3528#endif
3529 "StoreCM",
3530 "GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
3531 "GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
3532 "ClearArray"
3533 };
3534 int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3535 if( strcmp(_opType,"PrefetchAllocation")==0 )
3536 return 1;
3537 if( strcmp(_opType,"CacheWB")==0 )
3538 return 1;
3539 if( strcmp(_opType,"CacheWBPreSync")==0 )
3540 return 1;
3541 if( strcmp(_opType,"CacheWBPostSync")==0 )
3542 return 1;
3543 if( _lChild ) {
3544 const char *opType = _lChild->_opType;
3545 for( int i=0; i<cnt; i++ )
3546 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3547 return 1;
3548 if( _lChild->needs_ideal_memory_edge(globals) )
3549 return 1;
3550 }
3551 if( _rChild ) {
3552 const char *opType = _rChild->_opType;
3553 for( int i=0; i<cnt; i++ )
3554 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3555 return 1;
3556 if( _rChild->needs_ideal_memory_edge(globals) )
3557 return 1;
3558 }
3559
3560 return 0;
3561}
3562
3563// TRUE if defines a derived oop, and so needs a base oop edge present
3564// post-matching.
3565int MatchNode::needs_base_oop_edge() const {
3566 if( !strcmp(_opType,"AddP") ) return 1;
3567 if( strcmp(_opType,"Set") ) return 0;
3568 return !strcmp(_rChild->_opType,"AddP");
3569}
3570
3571int InstructForm::needs_base_oop_edge(FormDict &globals) const {
3572 if( is_simple_chain_rule(globals) ) {
3573 const char *src = _matrule->_rChild->_opType;
3574 OperandForm *src_op = globals[src]->is_operand();
3575 assert( src_op, "Not operand class of chain rule" ){ if (!(src_op)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3575, "Not operand class of chain rule"); abort(); }}
;
3576 return src_op->_matrule ? src_op->_matrule->needs_base_oop_edge() : 0;
3577 } // Else check instruction
3578
3579 return _matrule ? _matrule->needs_base_oop_edge() : 0;
3580}
3581
3582
3583//-------------------------cisc spilling methods-------------------------------
3584// helper routines and methods for detecting cisc-spilling instructions
3585//-------------------------cisc_spill_merge------------------------------------
3586int MatchNode::cisc_spill_merge(int left_spillable, int right_spillable) {
3587 int cisc_spillable = Maybe_cisc_spillable;
3588
3589 // Combine results of left and right checks
3590 if( (left_spillable == Maybe_cisc_spillable) && (right_spillable == Maybe_cisc_spillable) ) {
3591 // neither side is spillable, nor prevents cisc spilling
3592 cisc_spillable = Maybe_cisc_spillable;
3593 }
3594 else if( (left_spillable == Maybe_cisc_spillable) && (right_spillable > Maybe_cisc_spillable) ) {
3595 // right side is spillable
3596 cisc_spillable = right_spillable;
3597 }
3598 else if( (right_spillable == Maybe_cisc_spillable) && (left_spillable > Maybe_cisc_spillable) ) {
3599 // left side is spillable
3600 cisc_spillable = left_spillable;
3601 }
3602 else if( (left_spillable == Not_cisc_spillable) || (right_spillable == Not_cisc_spillable) ) {
3603 // left or right prevents cisc spilling this instruction
3604 cisc_spillable = Not_cisc_spillable;
3605 }
3606 else {
3607 // Only allow one to spill
3608 cisc_spillable = Not_cisc_spillable;
3609 }
3610
3611 return cisc_spillable;
3612}
3613
3614//-------------------------root_ops_match--------------------------------------
3615bool static root_ops_match(FormDict &globals, const char *op1, const char *op2) {
3616 // Base Case: check that the current operands/operations match
3617 assert( op1, "Must have op's name"){ if (!(op1)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3617, "Must have op's name"); abort(); }}
;
3618 assert( op2, "Must have op's name"){ if (!(op2)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3618, "Must have op's name"); abort(); }}
;
3619 const Form *form1 = globals[op1];
3620 const Form *form2 = globals[op2];
3621
3622 return (form1 == form2);
3623}
3624
3625//-------------------------cisc_spill_match_node-------------------------------
3626// Recursively check two MatchRules for legal conversion via cisc-spilling
3627int MatchNode::cisc_spill_match(FormDict& globals, RegisterForm* registers, MatchNode* mRule2, const char* &operand, const char* &reg_type) {
3628 int cisc_spillable = Maybe_cisc_spillable;
3629 int left_spillable = Maybe_cisc_spillable;
3630 int right_spillable = Maybe_cisc_spillable;
3631
3632 // Check that each has same number of operands at this level
3633 if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) )
3634 return Not_cisc_spillable;
3635
3636 // Base Case: check that the current operands/operations match
3637 // or are CISC spillable
3638 assert( _opType, "Must have _opType"){ if (!(_opType)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3638, "Must have _opType"); abort(); }}
;
3639 assert( mRule2->_opType, "Must have _opType"){ if (!(mRule2->_opType)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3639, "Must have _opType"); abort(); }}
;
3640 const Form *form = globals[_opType];
3641 const Form *form2 = globals[mRule2->_opType];
3642 if( form == form2 ) {
3643 cisc_spillable = Maybe_cisc_spillable;
3644 } else {
3645 const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL__null;
3646 const char *name_left = mRule2->_lChild ? mRule2->_lChild->_opType : NULL__null;
3647 const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL__null;
3648 DataType data_type = Form::none;
3649 if (form->is_operand()) {
3650 // Make sure the loadX matches the type of the reg
3651 data_type = form->ideal_to_Reg_type(form->is_operand()->ideal_type(globals));
3652 }
3653 // Detect reg vs (loadX memory)
3654 if( form->is_cisc_reg(globals)
3655 && form2_inst
3656 && data_type != Form::none
3657 && (is_load_from_memory(mRule2->_opType) == data_type) // reg vs. (load memory)
3658 && (name_left != NULL__null) // NOT (load)
3659 && (name_right == NULL__null) ) { // NOT (load memory foo)
3660 const Form *form2_left = globals[name_left];
3661 if( form2_left && form2_left->is_cisc_mem(globals) ) {
3662 cisc_spillable = Is_cisc_spillable;
3663 operand = _name;
3664 reg_type = _result;
3665 return Is_cisc_spillable;
3666 } else {
3667 cisc_spillable = Not_cisc_spillable;
3668 }
3669 }
3670 // Detect reg vs memory
3671 else if (form->is_cisc_reg(globals) && form2 != NULL__null && form2->is_cisc_mem(globals)) {
3672 cisc_spillable = Is_cisc_spillable;
Value stored to 'cisc_spillable' is never read
3673 operand = _name;
3674 reg_type = _result;
3675 return Is_cisc_spillable;
3676 } else {
3677 cisc_spillable = Not_cisc_spillable;
3678 }
3679 }
3680
3681 // If cisc is still possible, check rest of tree
3682 if( cisc_spillable == Maybe_cisc_spillable ) {
3683 // Check that each has same number of operands at this level
3684 if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable;
3685
3686 // Check left operands
3687 if( (_lChild == NULL__null) && (mRule2->_lChild == NULL__null) ) {
3688 left_spillable = Maybe_cisc_spillable;
3689 } else if (_lChild != NULL__null) {
3690 left_spillable = _lChild->cisc_spill_match(globals, registers, mRule2->_lChild, operand, reg_type);
3691 }
3692
3693 // Check right operands
3694 if( (_rChild == NULL__null) && (mRule2->_rChild == NULL__null) ) {
3695 right_spillable = Maybe_cisc_spillable;
3696 } else if (_rChild != NULL__null) {
3697 right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type);
3698 }
3699
3700 // Combine results of left and right checks
3701 cisc_spillable = cisc_spill_merge(left_spillable, right_spillable);
3702 }
3703
3704 return cisc_spillable;
3705}
3706
3707//---------------------------cisc_spill_match_rule------------------------------
3708// Recursively check two MatchRules for legal conversion via cisc-spilling
3709// This method handles the root of Match tree,
3710// general recursive checks done in MatchNode
3711int MatchRule::matchrule_cisc_spill_match(FormDict& globals, RegisterForm* registers,
3712 MatchRule* mRule2, const char* &operand,
3713 const char* &reg_type) {
3714 int cisc_spillable = Maybe_cisc_spillable;
3715 int left_spillable = Maybe_cisc_spillable;
3716 int right_spillable = Maybe_cisc_spillable;
3717
3718 // Check that each sets a result
3719 if( !(sets_result() && mRule2->sets_result()) ) return Not_cisc_spillable;
3720 // Check that each has same number of operands at this level
3721 if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable;
3722
3723 // Check left operands: at root, must be target of 'Set'
3724 if( (_lChild == NULL__null) || (mRule2->_lChild == NULL__null) ) {
3725 left_spillable = Not_cisc_spillable;
3726 } else {
3727 // Do not support cisc-spilling instruction's target location
3728 if( root_ops_match(globals, _lChild->_opType, mRule2->_lChild->_opType) ) {
3729 left_spillable = Maybe_cisc_spillable;
3730 } else {
3731 left_spillable = Not_cisc_spillable;
3732 }
3733 }
3734
3735 // Check right operands: recursive walk to identify reg->mem operand
3736 if (_rChild == NULL__null) {
3737 if (mRule2->_rChild == NULL__null) {
3738 right_spillable = Maybe_cisc_spillable;
3739 } else {
3740 assert(0, "_rChild should not be NULL"){ if (!(0)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3740, "_rChild should not be NULL"); abort(); }}
;
3741 }
3742 } else {
3743 right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type);
3744 }
3745
3746 // Combine results of left and right checks
3747 cisc_spillable = cisc_spill_merge(left_spillable, right_spillable);
3748
3749 return cisc_spillable;
3750}
3751
3752//----------------------------- equivalent ------------------------------------
3753// Recursively check to see if two match rules are equivalent.
3754// This rule handles the root.
3755bool MatchRule::equivalent(FormDict &globals, MatchNode *mRule2) {
3756 // Check that each sets a result
3757 if (sets_result() != mRule2->sets_result()) {
3758 return false;
3759 }
3760
3761 // Check that the current operands/operations match
3762 assert( _opType, "Must have _opType"){ if (!(_opType)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3762, "Must have _opType"); abort(); }}
;
3763 assert( mRule2->_opType, "Must have _opType"){ if (!(mRule2->_opType)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3763, "Must have _opType"); abort(); }}
;
3764 const Form *form = globals[_opType];
3765 const Form *form2 = globals[mRule2->_opType];
3766 if( form != form2 ) {
3767 return false;
3768 }
3769
3770 if (_lChild ) {
3771 if( !_lChild->equivalent(globals, mRule2->_lChild) )
3772 return false;
3773 } else if (mRule2->_lChild) {
3774 return false; // I have NULL left child, mRule2 has non-NULL left child.
3775 }
3776
3777 if (_rChild ) {
3778 if( !_rChild->equivalent(globals, mRule2->_rChild) )
3779 return false;
3780 } else if (mRule2->_rChild) {
3781 return false; // I have NULL right child, mRule2 has non-NULL right child.
3782 }
3783
3784 // We've made it through the gauntlet.
3785 return true;
3786}
3787
3788//----------------------------- equivalent ------------------------------------
3789// Recursively check to see if two match rules are equivalent.
3790// This rule handles the operands.
3791bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) {
3792 if( !mNode2 )
3793 return false;
3794
3795 // Check that the current operands/operations match
3796 assert( _opType, "Must have _opType"){ if (!(_opType)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3796, "Must have _opType"); abort(); }}
;
3797 assert( mNode2->_opType, "Must have _opType"){ if (!(mNode2->_opType)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3797, "Must have _opType"); abort(); }}
;
3798 const Form *form = globals[_opType];
3799 const Form *form2 = globals[mNode2->_opType];
3800 if( form != form2 ) {
3801 return false;
3802 }
3803
3804 // Check that their children also match
3805 if (_lChild ) {
3806 if( !_lChild->equivalent(globals, mNode2->_lChild) )
3807 return false;
3808 } else if (mNode2->_lChild) {
3809 return false; // I have NULL left child, mNode2 has non-NULL left child.
3810 }
3811
3812 if (_rChild ) {
3813 if( !_rChild->equivalent(globals, mNode2->_rChild) )
3814 return false;
3815 } else if (mNode2->_rChild) {
3816 return false; // I have NULL right child, mNode2 has non-NULL right child.
3817 }
3818
3819 // We've made it through the gauntlet.
3820 return true;
3821}
3822
3823//-------------------------- count_commutative_op -------------------------------
3824// Recursively check for commutative operations with subtree operands
3825// which could be swapped.
3826void MatchNode::count_commutative_op(int& count) {
3827 static const char *commut_op_list[] = {
3828 "AddI","AddL","AddF","AddD",
3829 "AndI","AndL",
3830 "MaxI","MinI","MaxF","MinF","MaxD","MinD",
3831 "MulI","MulL","MulF","MulD",
3832 "OrI","OrL",
3833 "XorI","XorL"
3834 };
3835
3836 static const char *commut_vector_op_list[] = {
3837 "AddVB", "AddVS", "AddVI", "AddVL", "AddVF", "AddVD",
3838 "MulVB", "MulVS", "MulVI", "MulVL", "MulVF", "MulVD",
3839 "AndV", "OrV", "XorV",
3840 "MaxV", "MinV"
3841 };
3842
3843 if (_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild)) {
3844 // Don't swap if right operand is an immediate constant.
3845 bool is_const = false;
3846 if (_rChild->_lChild == NULL__null && _rChild->_rChild == NULL__null) {
3847 FormDict &globals = _AD.globalNames();
3848 const Form *form = globals[_rChild->_opType];
3849 if (form) {
3850 OperandForm *oper = form->is_operand();
3851 if (oper && oper->interface_type(globals) == Form::constant_interface)
3852 is_const = true;
3853 }
3854 }
3855
3856 if (!is_const) {
3857 int scalar_cnt = sizeof(commut_op_list)/sizeof(char*);
3858 int vector_cnt = sizeof(commut_vector_op_list)/sizeof(char*);
3859 bool matched = false;
3860
3861 // Check the commutative vector op first. It's noncommutative if
3862 // the current node is a masked vector op, since a mask value
3863 // is added to the original vector node's input list and the original
3864 // first two inputs are packed into one BinaryNode. So don't swap
3865 // if one of the operands is a BinaryNode.
3866 for (int i = 0; i < vector_cnt; i++) {
3867 if (strcmp(_opType, commut_vector_op_list[i]) == 0) {
3868 if (strcmp(_lChild->_opType, "Binary") != 0 &&
3869 strcmp(_rChild->_opType, "Binary") != 0) {
3870 count++;
3871 _commutative_id = count; // id should be > 0
3872 }
3873 matched = true;
3874 break;
3875 }
3876 }
3877
3878 // Then check the scalar op if the current op is not in
3879 // the commut_vector_op_list.
3880 if (!matched) {
3881 for (int i = 0; i < scalar_cnt; i++) {
3882 if (strcmp(_opType, commut_op_list[i]) == 0) {
3883 count++;
3884 _commutative_id = count; // id should be > 0
3885 break;
3886 }
3887 }
3888 }
3889 }
3890 }
3891 if (_lChild)
3892 _lChild->count_commutative_op(count);
3893 if (_rChild)
3894 _rChild->count_commutative_op(count);
3895}
3896
3897//-------------------------- swap_commutative_op ------------------------------
3898// Recursively swap specified commutative operation with subtree operands.
3899void MatchNode::swap_commutative_op(bool atroot, int id) {
3900 if( _commutative_id == id ) { // id should be > 0
3901 assert(_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild ),{ if (!(_lChild && _rChild && (_lChild->_lChild
|| _rChild->_lChild ))) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3902, "not swappable operation"); abort(); }}
3902 "not swappable operation"){ if (!(_lChild && _rChild && (_lChild->_lChild
|| _rChild->_lChild ))) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3902, "not swappable operation"); abort(); }}
;
3903 MatchNode* tmp = _lChild;
3904 _lChild = _rChild;
3905 _rChild = tmp;
3906 // Don't exit here since we need to build internalop.
3907 }
3908
3909 bool is_set = ( strcmp(_opType, "Set") == 0 );
3910 if( _lChild )
3911 _lChild->swap_commutative_op(is_set, id);
3912 if( _rChild )
3913 _rChild->swap_commutative_op(is_set, id);
3914
3915 // If not the root, reduce this subtree to an internal operand
3916 if( !atroot && (_lChild || _rChild) ) {
3917 build_internalop();
3918 }
3919}
3920
3921//-------------------------- swap_commutative_op ------------------------------
3922// Recursively swap specified commutative operation with subtree operands.
3923void MatchRule::matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt) {
3924 assert(match_rules_cnt < 100," too many match rule clones"){ if (!(match_rules_cnt < 100)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3924, " too many match rule clones"); abort(); }}
;
3925 // Clone
3926 MatchRule* clone = new MatchRule(_AD, this);
3927 // Swap operands of commutative operation
3928 ((MatchNode*)clone)->swap_commutative_op(true, count);
3929 char* buf = (char*) AllocateHeap(strlen(instr_ident) + 4);
3930 sprintf(buf, "%s_%d", instr_ident, match_rules_cnt++);
3931 clone->_result = buf;
3932
3933 clone->_next = this->_next;
3934 this-> _next = clone;
3935 if( (--count) > 0 ) {
3936 this-> matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
3937 clone->matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
3938 }
3939}
3940
3941//------------------------------MatchRule--------------------------------------
3942MatchRule::MatchRule(ArchDesc &ad)
3943 : MatchNode(ad), _depth(0), _construct(NULL__null), _numchilds(0) {
3944 _next = NULL__null;
3945}
3946
3947MatchRule::MatchRule(ArchDesc &ad, MatchRule* mRule)
3948 : MatchNode(ad, *mRule, 0), _depth(mRule->_depth),
3949 _construct(mRule->_construct), _numchilds(mRule->_numchilds) {
3950 _next = NULL__null;
3951}
3952
3953MatchRule::MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char *cnstr,
3954 int numleaves)
3955 : MatchNode(ad,*mroot), _depth(depth), _construct(cnstr),
3956 _numchilds(0) {
3957 _next = NULL__null;
3958 mroot->_lChild = NULL__null;
3959 mroot->_rChild = NULL__null;
3960 delete mroot;
3961 _numleaves = numleaves;
3962 _numchilds = (_lChild ? 1 : 0) + (_rChild ? 1 : 0);
3963}
3964MatchRule::~MatchRule() {
3965}
3966
3967// Recursive call collecting info on top-level operands, not transitive.
3968// Implementation does not modify state of internal structures.
3969void MatchRule::append_components(FormDict& locals, ComponentList& components, bool def_flag) const {
3970 assert (_name != NULL, "MatchNode::build_components encountered empty node\n"){ if (!(_name != __null)) { fprintf(stderr, "assert fails %s %d: %s\n"
, "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/formssel.cpp"
, 3970, "MatchNode::build_components encountered empty node\n"
); abort(); }}
;
3971
3972 MatchNode::append_components(locals, components,
3973 false /* not necessarily a def */);
3974}
3975
3976// Recursive call on all operands' match rules in my match rule.
3977// Implementation does not modify state of internal structures since they
3978// can be shared.
3979// The MatchNode that is called first treats its
3980bool MatchRule::base_operand(uintunsigned int &position0, FormDict &globals,
3981 const char *&result, const char * &name,
3982 const char * &opType)const{
3983 uintunsigned int position = position0;
3984
3985 return (MatchNode::base_operand( position, globals, result, name, opType));
3986}
3987
3988
3989bool MatchRule::is_base_register(FormDict &globals) const {
3990 uintunsigned int position = 1;
3991 const char *result = NULL__null;
3992 const char *name = NULL__null;
3993 const char *opType = NULL__null;
3994 if (!base_operand(position, globals, result, name, opType)) {
3995 position = 0;
3996 if( base_operand(position, globals, result, name, opType) &&
3997 (strcmp(opType,"RegI")==0 ||
3998 strcmp(opType,"RegP")==0 ||
3999 strcmp(opType,"RegN")==0 ||
4000 strcmp(opType,"RegL")==0 ||
4001 strcmp(opType,"RegF")==0 ||
4002 strcmp(opType,"RegD")==0 ||
4003 strcmp(opType,"RegVectMask")==0 ||
4004 strcmp(opType,"VecA")==0 ||
4005 strcmp(opType,"VecS")==0 ||
4006 strcmp(opType,"VecD")==0 ||
4007 strcmp(opType,"VecX")==0 ||
4008 strcmp(opType,"VecY")==0 ||
4009 strcmp(opType,"VecZ")==0 ||
4010 strcmp(opType,"Reg" )==0) ) {
4011 return 1;
4012 }
4013 }
4014 return 0;
4015}
4016
4017Form::DataType MatchRule::is_base_constant(FormDict &globals) const {
4018 uintunsigned int position = 1;
4019 const char *result = NULL__null;
4020 const char *name = NULL__null;
4021 const char *opType = NULL__null;
4022 if (!base_operand(position, globals, result, name, opType)) {
4023 position = 0;
4024 if (base_operand(position, globals, result, name, opType)) {
4025 return ideal_to_const_type(opType);
4026 }
4027 }
4028 return Form::none;
4029}
4030
4031bool MatchRule::is_chain_rule(FormDict &globals) const {
4032
4033 // Check for chain rule, and do not generate a match list for it
4034 if ((_lChild == NULL__null) && (_rChild == NULL__null) ) {
4035 const Form *form = globals[_opType];
4036 // If this is ideal, then it is a base match, not a chain rule.
4037 if ( form && form->is_operand() && (!form->ideal_only())) {
4038 return true;
4039 }
4040 }
4041 // Check for "Set" form of chain rule, and do not generate a match list
4042 if (_rChild) {
4043 const char *rch = _rChild->_opType;
4044 const Form *form = globals[rch];
4045 if ((!strcmp(_opType,"Set") &&
4046 ((form) && form->is_operand()))) {
4047 return true;
4048 }
4049 }
4050 return false;
4051}
4052
4053int MatchRule::is_ideal_copy() const {
4054 if (is_chain_rule(_AD.globalNames()) &&
4055 _lChild && strncmp(_lChild->_opType, "stackSlot", 9) == 0) {
4056 return 1;
4057 }
4058 return 0;
4059}
4060
4061int MatchRule::is_expensive() const {
4062 if( _rChild ) {
4063 const char *opType = _rChild->_opType;
4064 if( strcmp(opType,"AtanD")==0 ||
4065 strcmp(opType,"DivD")==0 ||
4066 strcmp(opType,"DivF")==0 ||
4067 strcmp(opType,"DivI")==0 ||
4068 strcmp(opType,"Log10D")==0 ||
4069 strcmp(opType,"ModD")==0 ||
4070 strcmp(opType,"ModF")==0 ||
4071 strcmp(opType,"ModI")==0 ||
4072 strcmp(opType,"SqrtD")==0 ||
4073 strcmp(opType,"SqrtF")==0 ||
4074 strcmp(opType,"TanD")==0 ||
4075 strcmp(opType,"ConvD2F")==0 ||
4076 strcmp(opType,"ConvD2I")==0 ||
4077 strcmp(opType,"ConvD2L")==0 ||
4078 strcmp(opType,"ConvF2D")==0 ||
4079 strcmp(opType,"ConvF2I")==0 ||
4080 strcmp(opType,"ConvF2L")==0 ||
4081 strcmp(opType,"ConvI2D")==0 ||
4082 strcmp(opType,"ConvI2F")==0 ||
4083 strcmp(opType,"ConvI2L")==0 ||
4084 strcmp(opType,"ConvL2D")==0 ||
4085 strcmp(opType,"ConvL2F")==0 ||
4086 strcmp(opType,"ConvL2I")==0 ||
4087 strcmp(opType,"DecodeN")==0 ||
4088 strcmp(opType,"EncodeP")==0 ||
4089 strcmp(opType,"EncodePKlass")==0 ||
4090 strcmp(opType,"DecodeNKlass")==0 ||
4091 strcmp(opType,"FmaD") == 0 ||
4092 strcmp(opType,"FmaF") == 0 ||
4093 strcmp(opType,"RoundDouble")==0 ||
4094 strcmp(opType,"RoundDoubleMode")==0 ||
4095 strcmp(opType,"RoundFloat")==0 ||
4096 strcmp(opType,"ReverseBytesI")==0 ||
4097 strcmp(opType,"ReverseBytesL")==0 ||
4098 strcmp(opType,"ReverseBytesUS")==0 ||
4099 strcmp(opType,"ReverseBytesS")==0 ||
4100 strcmp(opType,"ReplicateB")==0 ||
4101 strcmp(opType,"ReplicateS")==0 ||
4102 strcmp(opType,"ReplicateI")==0 ||
4103 strcmp(opType,"ReplicateL")==0 ||
4104 strcmp(opType,"ReplicateF")==0 ||
4105 strcmp(opType,"ReplicateD")==0 ||
4106 strcmp(opType,"AddReductionVI")==0 ||
4107 strcmp(opType,"AddReductionVL")==0 ||
4108 strcmp(opType,"AddReductionVF")==0 ||
4109 strcmp(opType,"AddReductionVD")==0 ||
4110 strcmp(opType,"MulReductionVI")==0 ||
4111 strcmp(opType,"MulReductionVL")==0 ||
4112 strcmp(opType,"MulReductionVF")==0 ||
4113 strcmp(opType,"MulReductionVD")==0 ||
4114 strcmp(opType,"MinReductionV")==0 ||
4115 strcmp(opType,"MaxReductionV")==0 ||
4116 strcmp(opType,"AndReductionV")==0 ||
4117 strcmp(opType,"OrReductionV")==0 ||
4118 strcmp(opType,"XorReductionV")==0 ||
4119 strcmp(opType,"MaskAll")==0 ||
4120 0 /* 0 to line up columns nicely */ )
4121 return 1;
4122 }
4123 return 0;
4124}
4125
4126bool MatchRule::is_ideal_if() const {
4127 if( !_opType ) return false;
4128 return
4129 !strcmp(_opType,"If" ) ||
4130 !strcmp(_opType,"CountedLoopEnd");
4131}
4132
4133bool MatchRule::is_ideal_fastlock() const {
4134 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
4135 return (strcmp(_rChild->_opType,"FastLock") == 0);
4136 }
4137 return false;
4138}
4139
4140bool MatchRule::is_ideal_membar() const {
4141 if( !_opType ) return false;
4142 return
4143 !strcmp(_opType,"MemBarAcquire") ||
4144 !strcmp(_opType,"MemBarRelease") ||
4145 !strcmp(_opType,"MemBarAcquireLock") ||
4146 !strcmp(_opType,"MemBarReleaseLock") ||
4147 !strcmp(_opType,"LoadFence" ) ||
4148 !strcmp(_opType,"StoreFence") ||
4149 !strcmp(_opType,"StoreStoreFence") ||
4150 !strcmp(_opType,"MemBarVolatile") ||
4151 !strcmp(_opType,"MemBarCPUOrder") ||
4152 !strcmp(_opType,"MemBarStoreStore") ||
4153 !strcmp(_opType,"OnSpinWait");
4154}
4155
4156bool MatchRule::is_ideal_loadPC() const {
4157 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
4158 return (strcmp(_rChild->_opType,"LoadPC") == 0);
4159 }
4160 return false;
4161}
4162
4163bool MatchRule::is_ideal_box() const {
4164 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
4165 return (strcmp(_rChild->_opType,"Box") == 0);
4166 }
4167 return false;
4168}
4169
4170bool MatchRule::is_ideal_goto() const {
4171 bool ideal_goto = false;
4172
4173 if( _opType && (strcmp(_opType,"Goto") == 0) ) {
4174 ideal_goto = true;
4175 }
4176 return ideal_goto;
4177}
4178
4179bool MatchRule::is_ideal_jump() const {
4180 if( _opType ) {
4181 if( !strcmp(_opType,"Jump") )
4182 return true;
4183 }
4184 return false;
4185}
4186
4187bool MatchRule::is_ideal_bool() const {
4188 if( _opType ) {
4189 if( !strcmp(_opType,"Bool") )
4190 return true;
4191 }
4192 return false;
4193}
4194
4195
4196Form::DataType MatchRule::is_ideal_load() const {
4197 Form::DataType ideal_load = Form::none;
4198
4199 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
4200 const char *opType = _rChild->_opType;
4201 ideal_load = is_load_from_memory(opType);
4202 }
4203
4204 return ideal_load;
4205}
4206
4207bool MatchRule::is_vector() const {
4208 static const char *vector_list[] = {
4209 "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",
4210 "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
4211 "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD",
4212 "CMoveVD", "CMoveVF",
4213 "DivVF","DivVD",
4214 "AbsVB","AbsVS","AbsVI","AbsVL","AbsVF","AbsVD",
4215 "NegVF","NegVD","NegVI",
4216 "SqrtVD","SqrtVF",
4217 "AndV" ,"XorV" ,"OrV",
4218 "MaxV", "MinV",
4219 "AddReductionVI", "AddReductionVL",
4220 "AddReductionVF", "AddReductionVD",
4221 "MulReductionVI", "MulReductionVL",
4222 "MulReductionVF", "MulReductionVD",
4223 "MaxReductionV", "MinReductionV",
4224 "AndReductionV", "OrReductionV", "XorReductionV",
4225 "MulAddVS2VI", "MacroLogicV",
4226 "LShiftCntV","RShiftCntV",
4227 "LShiftVB","LShiftVS","LShiftVI","LShiftVL",
4228 "RShiftVB","RShiftVS","RShiftVI","RShiftVL",
4229 "URShiftVB","URShiftVS","URShiftVI","URShiftVL",
4230 "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD",
4231 "RoundDoubleModeV","RotateLeftV" , "RotateRightV", "LoadVector","StoreVector",
4232 "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked",
4233 "VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert",
4234 "VectorRearrange","VectorLoadShuffle", "VectorLoadConst",
4235 "VectorCastB2X", "VectorCastS2X", "VectorCastI2X",
4236 "VectorCastL2X", "VectorCastF2X", "VectorCastD2X",
4237 "VectorMaskWrapper","VectorMaskCmp","VectorReinterpret","LoadVectorMasked","StoreVectorMasked",
4238 "FmaVD","FmaVF","PopCountVI","VectorLongToMask",
4239 // Next are vector mask ops.
4240 "MaskAll", "AndVMask", "OrVMask", "XorVMask", "VectorMaskCast",
4241 // Next are not supported currently.
4242 "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",
4243 "ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD"
4244 };
4245 int cnt = sizeof(vector_list)/sizeof(char*);
4246 if (_rChild) {
4247 const char *opType = _rChild->_opType;
4248 for (int i=0; i<cnt; i++)
4249 if (strcmp(opType,vector_list[i]) == 0)
4250 return true;
4251 }
4252 return false;
4253}
4254
4255
4256bool MatchRule::skip_antidep_check() const {
4257 // Some loads operate on what is effectively immutable memory so we
4258 // should skip the anti dep computations. For some of these nodes
4259 // the rewritable field keeps the anti dep logic from triggering but
4260 // for certain kinds of LoadKlass it does not since they are
4261 // actually reading memory which could be rewritten by the runtime,
4262 // though never by generated code. This disables it uniformly for
4263 // the nodes that behave like this: LoadKlass, LoadNKlass and
4264 // LoadRange.
4265 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
4266 const char *opType = _rChild->_opType;
4267 if (strcmp("LoadKlass", opType) == 0 ||
4268 strcmp("LoadNKlass", opType) == 0 ||
4269 strcmp("LoadRange", opType) == 0) {
4270 return true;
4271 }
4272 }
4273
4274 return false;
4275}
4276
4277
4278Form::DataType MatchRule::is_ideal_store() const {
4279 Form::DataType ideal_store = Form::none;
4280
4281 if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
4282 const char *opType = _rChild->_opType;
4283 ideal_store = is_store_to_memory(opType);
4284 }
4285
4286 return ideal_store;
4287}
4288
4289
4290void MatchRule::dump() {
4291 output(stderrstderr);
4292}
4293
4294// Write just one line.
4295void MatchRule::output_short(FILE *fp) {
4296 fprintf(fp,"MatchRule: ( %s",_name);
4297 if (_lChild) _lChild->output(fp);
4298 if (_rChild) _rChild->output(fp);
4299 fprintf(fp," )");
4300}
4301
4302void MatchRule::output(FILE *fp) {
4303 output_short(fp);
4304 fprintf(fp,"\n nesting depth = %d\n", _depth);
4305 if (_result) fprintf(fp," Result Type = %s", _result);
4306 fprintf(fp,"\n");
4307}
4308
4309//------------------------------Attribute--------------------------------------
4310Attribute::Attribute(char *id, char* val, int type)
4311 : _ident(id), _val(val), _atype(type) {
4312}
4313Attribute::~Attribute() {
4314}
4315
4316int Attribute::int_val(ArchDesc &ad) {
4317 // Make sure it is an integer constant:
4318 int result = 0;
4319 if (!_val || !ADLParser::is_int_token(_val, result)) {
4320 ad.syntax_err(0, "Attribute %s must have an integer value: %s",
4321 _ident, _val ? _val : "");
4322 }
4323 return result;
4324}
4325
4326void Attribute::dump() {
4327 output(stderrstderr);
4328} // Debug printer
4329
4330// Write to output files
4331void Attribute::output(FILE *fp) {
4332 fprintf(fp,"Attribute: %s %s\n", (_ident?_ident:""), (_val?_val:""));
4333}
4334
4335//------------------------------FormatRule----------------------------------
4336FormatRule::FormatRule(char *temp)
4337 : _temp(temp) {
4338}
4339FormatRule::~FormatRule() {
4340}
4341
4342void FormatRule::dump() {
4343 output(stderrstderr);
4344}
4345
4346// Write to output files
4347void FormatRule::output(FILE *fp) {
4348 fprintf(fp,"\nFormat Rule: \n%s", (_temp?_temp:""));
4349 fprintf(fp,"\n");
4350}