1 | /* |
2 | * Copyright (c) 2007, 2017, 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 | #include "precompiled.hpp" |
25 | #include "memory/allocation.inline.hpp" |
26 | #include "opto/connode.hpp" |
27 | #include "opto/vectornode.hpp" |
28 | |
29 | //------------------------------VectorNode-------------------------------------- |
30 | |
31 | // Return the vector operator for the specified scalar operation |
32 | // and vector length. |
33 | int VectorNode::opcode(int sopc, BasicType bt) { |
34 | switch (sopc) { |
35 | case Op_AddI: |
36 | switch (bt) { |
37 | case T_BOOLEAN: |
38 | case T_BYTE: return Op_AddVB; |
39 | case T_CHAR: |
40 | case T_SHORT: return Op_AddVS; |
41 | case T_INT: return Op_AddVI; |
42 | default: ShouldNotReachHere(); return 0; |
43 | } |
44 | case Op_AddL: |
45 | assert(bt == T_LONG, "must be" ); |
46 | return Op_AddVL; |
47 | case Op_AddF: |
48 | assert(bt == T_FLOAT, "must be" ); |
49 | return Op_AddVF; |
50 | case Op_AddD: |
51 | assert(bt == T_DOUBLE, "must be" ); |
52 | return Op_AddVD; |
53 | case Op_SubI: |
54 | switch (bt) { |
55 | case T_BOOLEAN: |
56 | case T_BYTE: return Op_SubVB; |
57 | case T_CHAR: |
58 | case T_SHORT: return Op_SubVS; |
59 | case T_INT: return Op_SubVI; |
60 | default: ShouldNotReachHere(); return 0; |
61 | } |
62 | case Op_SubL: |
63 | assert(bt == T_LONG, "must be" ); |
64 | return Op_SubVL; |
65 | case Op_SubF: |
66 | assert(bt == T_FLOAT, "must be" ); |
67 | return Op_SubVF; |
68 | case Op_SubD: |
69 | assert(bt == T_DOUBLE, "must be" ); |
70 | return Op_SubVD; |
71 | case Op_MulI: |
72 | switch (bt) { |
73 | case T_BOOLEAN:return 0; |
74 | case T_BYTE: return Op_MulVB; |
75 | case T_CHAR: |
76 | case T_SHORT: return Op_MulVS; |
77 | case T_INT: return Op_MulVI; |
78 | default: ShouldNotReachHere(); return 0; |
79 | } |
80 | case Op_MulL: |
81 | assert(bt == T_LONG, "must be" ); |
82 | return Op_MulVL; |
83 | case Op_MulF: |
84 | assert(bt == T_FLOAT, "must be" ); |
85 | return Op_MulVF; |
86 | case Op_MulD: |
87 | assert(bt == T_DOUBLE, "must be" ); |
88 | return Op_MulVD; |
89 | case Op_FmaD: |
90 | assert(bt == T_DOUBLE, "must be" ); |
91 | return Op_FmaVD; |
92 | case Op_FmaF: |
93 | assert(bt == T_FLOAT, "must be" ); |
94 | return Op_FmaVF; |
95 | case Op_CMoveF: |
96 | assert(bt == T_FLOAT, "must be" ); |
97 | return Op_CMoveVF; |
98 | case Op_CMoveD: |
99 | assert(bt == T_DOUBLE, "must be" ); |
100 | return Op_CMoveVD; |
101 | case Op_DivF: |
102 | assert(bt == T_FLOAT, "must be" ); |
103 | return Op_DivVF; |
104 | case Op_DivD: |
105 | assert(bt == T_DOUBLE, "must be" ); |
106 | return Op_DivVD; |
107 | case Op_AbsI: |
108 | switch (bt) { |
109 | case T_BOOLEAN: |
110 | case T_CHAR: return 0; // abs does not make sense for unsigned |
111 | case T_BYTE: return Op_AbsVB; |
112 | case T_SHORT: return Op_AbsVS; |
113 | case T_INT: return Op_AbsVI; |
114 | default: ShouldNotReachHere(); return 0; |
115 | } |
116 | case Op_AbsL: |
117 | assert(bt == T_LONG, "must be" ); |
118 | return Op_AbsVL; |
119 | case Op_AbsF: |
120 | assert(bt == T_FLOAT, "must be" ); |
121 | return Op_AbsVF; |
122 | case Op_AbsD: |
123 | assert(bt == T_DOUBLE, "must be" ); |
124 | return Op_AbsVD; |
125 | case Op_NegF: |
126 | assert(bt == T_FLOAT, "must be" ); |
127 | return Op_NegVF; |
128 | case Op_NegD: |
129 | assert(bt == T_DOUBLE, "must be" ); |
130 | return Op_NegVD; |
131 | case Op_SqrtF: |
132 | assert(bt == T_FLOAT, "must be" ); |
133 | return Op_SqrtVF; |
134 | case Op_SqrtD: |
135 | assert(bt == T_DOUBLE, "must be" ); |
136 | return Op_SqrtVD; |
137 | case Op_PopCountI: |
138 | if (bt == T_INT) { |
139 | return Op_PopCountVI; |
140 | } |
141 | // Unimplemented for subword types since bit count changes |
142 | // depending on size of lane (and sign bit). |
143 | return 0; |
144 | case Op_LShiftI: |
145 | switch (bt) { |
146 | case T_BOOLEAN: |
147 | case T_BYTE: return Op_LShiftVB; |
148 | case T_CHAR: |
149 | case T_SHORT: return Op_LShiftVS; |
150 | case T_INT: return Op_LShiftVI; |
151 | default: ShouldNotReachHere(); return 0; |
152 | } |
153 | case Op_LShiftL: |
154 | assert(bt == T_LONG, "must be" ); |
155 | return Op_LShiftVL; |
156 | case Op_RShiftI: |
157 | switch (bt) { |
158 | case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value |
159 | case T_CHAR: return Op_URShiftVS; // char is unsigned value |
160 | case T_BYTE: return Op_RShiftVB; |
161 | case T_SHORT: return Op_RShiftVS; |
162 | case T_INT: return Op_RShiftVI; |
163 | default: ShouldNotReachHere(); return 0; |
164 | } |
165 | case Op_RShiftL: |
166 | assert(bt == T_LONG, "must be" ); |
167 | return Op_RShiftVL; |
168 | case Op_URShiftI: |
169 | switch (bt) { |
170 | case T_BOOLEAN:return Op_URShiftVB; |
171 | case T_CHAR: return Op_URShiftVS; |
172 | case T_BYTE: |
173 | case T_SHORT: return 0; // Vector logical right shift for signed short |
174 | // values produces incorrect Java result for |
175 | // negative data because java code should convert |
176 | // a short value into int value with sign |
177 | // extension before a shift. |
178 | case T_INT: return Op_URShiftVI; |
179 | default: ShouldNotReachHere(); return 0; |
180 | } |
181 | case Op_URShiftL: |
182 | assert(bt == T_LONG, "must be" ); |
183 | return Op_URShiftVL; |
184 | case Op_AndI: |
185 | case Op_AndL: |
186 | return Op_AndV; |
187 | case Op_OrI: |
188 | case Op_OrL: |
189 | return Op_OrV; |
190 | case Op_XorI: |
191 | case Op_XorL: |
192 | return Op_XorV; |
193 | case Op_MinF: |
194 | assert(bt == T_FLOAT, "must be" ); |
195 | return Op_MinV; |
196 | case Op_MinD: |
197 | assert(bt == T_DOUBLE, "must be" ); |
198 | return Op_MinV; |
199 | case Op_MaxF: |
200 | assert(bt == T_FLOAT, "must be" ); |
201 | return Op_MaxV; |
202 | case Op_MaxD: |
203 | assert(bt == T_DOUBLE, "must be" ); |
204 | return Op_MaxV; |
205 | |
206 | case Op_LoadB: |
207 | case Op_LoadUB: |
208 | case Op_LoadUS: |
209 | case Op_LoadS: |
210 | case Op_LoadI: |
211 | case Op_LoadL: |
212 | case Op_LoadF: |
213 | case Op_LoadD: |
214 | return Op_LoadVector; |
215 | |
216 | case Op_StoreB: |
217 | case Op_StoreC: |
218 | case Op_StoreI: |
219 | case Op_StoreL: |
220 | case Op_StoreF: |
221 | case Op_StoreD: |
222 | return Op_StoreVector; |
223 | case Op_MulAddS2I: |
224 | return Op_MulAddVS2VI; |
225 | |
226 | default: |
227 | return 0; // Unimplemented |
228 | } |
229 | } |
230 | |
231 | // Also used to check if the code generator |
232 | // supports the vector operation. |
233 | bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { |
234 | if (is_java_primitive(bt) && |
235 | (vlen > 1) && is_power_of_2(vlen) && |
236 | Matcher::vector_size_supported(bt, vlen)) { |
237 | int vopc = VectorNode::opcode(opc, bt); |
238 | return vopc > 0 && Matcher::match_rule_supported_vector(vopc, vlen); |
239 | } |
240 | return false; |
241 | } |
242 | |
243 | bool VectorNode::is_type_transition_short_to_int(Node* n) { |
244 | switch (n->Opcode()) { |
245 | case Op_MulAddS2I: |
246 | return true; |
247 | } |
248 | return false; |
249 | } |
250 | |
251 | bool VectorNode::is_type_transition_to_int(Node* n) { |
252 | return is_type_transition_short_to_int(n); |
253 | } |
254 | |
255 | bool VectorNode::is_muladds2i(Node* n) { |
256 | if (n->Opcode() == Op_MulAddS2I) { |
257 | return true; |
258 | } |
259 | return false; |
260 | } |
261 | |
262 | bool VectorNode::is_shift(Node* n) { |
263 | switch (n->Opcode()) { |
264 | case Op_LShiftI: |
265 | case Op_LShiftL: |
266 | case Op_RShiftI: |
267 | case Op_RShiftL: |
268 | case Op_URShiftI: |
269 | case Op_URShiftL: |
270 | return true; |
271 | default: |
272 | return false; |
273 | } |
274 | } |
275 | |
276 | // Check if input is loop invariant vector. |
277 | bool VectorNode::is_invariant_vector(Node* n) { |
278 | // Only Replicate vector nodes are loop invariant for now. |
279 | switch (n->Opcode()) { |
280 | case Op_ReplicateB: |
281 | case Op_ReplicateS: |
282 | case Op_ReplicateI: |
283 | case Op_ReplicateL: |
284 | case Op_ReplicateF: |
285 | case Op_ReplicateD: |
286 | return true; |
287 | default: |
288 | return false; |
289 | } |
290 | } |
291 | |
292 | // [Start, end) half-open range defining which operands are vectors |
293 | void VectorNode::vector_operands(Node* n, uint* start, uint* end) { |
294 | switch (n->Opcode()) { |
295 | case Op_LoadB: case Op_LoadUB: |
296 | case Op_LoadS: case Op_LoadUS: |
297 | case Op_LoadI: case Op_LoadL: |
298 | case Op_LoadF: case Op_LoadD: |
299 | case Op_LoadP: case Op_LoadN: |
300 | *start = 0; |
301 | *end = 0; // no vector operands |
302 | break; |
303 | case Op_StoreB: case Op_StoreC: |
304 | case Op_StoreI: case Op_StoreL: |
305 | case Op_StoreF: case Op_StoreD: |
306 | case Op_StoreP: case Op_StoreN: |
307 | *start = MemNode::ValueIn; |
308 | *end = MemNode::ValueIn + 1; // 1 vector operand |
309 | break; |
310 | case Op_LShiftI: case Op_LShiftL: |
311 | case Op_RShiftI: case Op_RShiftL: |
312 | case Op_URShiftI: case Op_URShiftL: |
313 | *start = 1; |
314 | *end = 2; // 1 vector operand |
315 | break; |
316 | case Op_AddI: case Op_AddL: case Op_AddF: case Op_AddD: |
317 | case Op_SubI: case Op_SubL: case Op_SubF: case Op_SubD: |
318 | case Op_MulI: case Op_MulL: case Op_MulF: case Op_MulD: |
319 | case Op_DivF: case Op_DivD: |
320 | case Op_AndI: case Op_AndL: |
321 | case Op_OrI: case Op_OrL: |
322 | case Op_XorI: case Op_XorL: |
323 | case Op_MulAddS2I: |
324 | *start = 1; |
325 | *end = 3; // 2 vector operands |
326 | break; |
327 | case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD: |
328 | *start = 2; |
329 | *end = n->req(); |
330 | break; |
331 | case Op_FmaD: |
332 | case Op_FmaF: |
333 | *start = 1; |
334 | *end = 4; // 3 vector operands |
335 | break; |
336 | default: |
337 | *start = 1; |
338 | *end = n->req(); // default is all operands |
339 | } |
340 | } |
341 | |
342 | // Return the vector version of a scalar operation node. |
343 | VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { |
344 | const TypeVect* vt = TypeVect::make(bt, vlen); |
345 | int vopc = VectorNode::opcode(opc, bt); |
346 | // This method should not be called for unimplemented vectors. |
347 | guarantee(vopc > 0, "Vector for '%s' is not implemented" , NodeClassNames[opc]); |
348 | switch (vopc) { |
349 | case Op_AddVB: return new AddVBNode(n1, n2, vt); |
350 | case Op_AddVS: return new AddVSNode(n1, n2, vt); |
351 | case Op_AddVI: return new AddVINode(n1, n2, vt); |
352 | case Op_AddVL: return new AddVLNode(n1, n2, vt); |
353 | case Op_AddVF: return new AddVFNode(n1, n2, vt); |
354 | case Op_AddVD: return new AddVDNode(n1, n2, vt); |
355 | |
356 | case Op_SubVB: return new SubVBNode(n1, n2, vt); |
357 | case Op_SubVS: return new SubVSNode(n1, n2, vt); |
358 | case Op_SubVI: return new SubVINode(n1, n2, vt); |
359 | case Op_SubVL: return new SubVLNode(n1, n2, vt); |
360 | case Op_SubVF: return new SubVFNode(n1, n2, vt); |
361 | case Op_SubVD: return new SubVDNode(n1, n2, vt); |
362 | |
363 | case Op_MulVB: return new MulVBNode(n1, n2, vt); |
364 | case Op_MulVS: return new MulVSNode(n1, n2, vt); |
365 | case Op_MulVI: return new MulVINode(n1, n2, vt); |
366 | case Op_MulVL: return new MulVLNode(n1, n2, vt); |
367 | case Op_MulVF: return new MulVFNode(n1, n2, vt); |
368 | case Op_MulVD: return new MulVDNode(n1, n2, vt); |
369 | |
370 | case Op_DivVF: return new DivVFNode(n1, n2, vt); |
371 | case Op_DivVD: return new DivVDNode(n1, n2, vt); |
372 | |
373 | case Op_AbsVB: return new AbsVBNode(n1, vt); |
374 | case Op_AbsVS: return new AbsVSNode(n1, vt); |
375 | case Op_AbsVI: return new AbsVINode(n1, vt); |
376 | case Op_AbsVL: return new AbsVLNode(n1, vt); |
377 | case Op_AbsVF: return new AbsVFNode(n1, vt); |
378 | case Op_AbsVD: return new AbsVDNode(n1, vt); |
379 | |
380 | case Op_NegVF: return new NegVFNode(n1, vt); |
381 | case Op_NegVD: return new NegVDNode(n1, vt); |
382 | |
383 | case Op_SqrtVF: return new SqrtVFNode(n1, vt); |
384 | case Op_SqrtVD: return new SqrtVDNode(n1, vt); |
385 | |
386 | case Op_PopCountVI: return new PopCountVINode(n1, vt); |
387 | |
388 | case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt); |
389 | case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt); |
390 | case Op_LShiftVI: return new LShiftVINode(n1, n2, vt); |
391 | case Op_LShiftVL: return new LShiftVLNode(n1, n2, vt); |
392 | |
393 | case Op_RShiftVB: return new RShiftVBNode(n1, n2, vt); |
394 | case Op_RShiftVS: return new RShiftVSNode(n1, n2, vt); |
395 | case Op_RShiftVI: return new RShiftVINode(n1, n2, vt); |
396 | case Op_RShiftVL: return new RShiftVLNode(n1, n2, vt); |
397 | |
398 | case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt); |
399 | case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt); |
400 | case Op_URShiftVI: return new URShiftVINode(n1, n2, vt); |
401 | case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt); |
402 | |
403 | case Op_AndV: return new AndVNode(n1, n2, vt); |
404 | case Op_OrV: return new OrVNode (n1, n2, vt); |
405 | case Op_XorV: return new XorVNode(n1, n2, vt); |
406 | |
407 | case Op_MinV: return new MinVNode(n1, n2, vt); |
408 | case Op_MaxV: return new MaxVNode(n1, n2, vt); |
409 | |
410 | case Op_MulAddVS2VI: return new MulAddVS2VINode(n1, n2, vt); |
411 | default: |
412 | fatal("Missed vector creation for '%s'" , NodeClassNames[vopc]); |
413 | return NULL; |
414 | } |
415 | } |
416 | |
417 | VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) { |
418 | const TypeVect* vt = TypeVect::make(bt, vlen); |
419 | int vopc = VectorNode::opcode(opc, bt); |
420 | // This method should not be called for unimplemented vectors. |
421 | guarantee(vopc > 0, "Vector for '%s' is not implemented" , NodeClassNames[opc]); |
422 | switch (vopc) { |
423 | case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt); |
424 | case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt); |
425 | default: |
426 | fatal("Missed vector creation for '%s'" , NodeClassNames[vopc]); |
427 | return NULL; |
428 | } |
429 | } |
430 | |
431 | // Scalar promotion |
432 | VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) { |
433 | BasicType bt = opd_t->array_element_basic_type(); |
434 | const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen) |
435 | : TypeVect::make(bt, vlen); |
436 | switch (bt) { |
437 | case T_BOOLEAN: |
438 | case T_BYTE: |
439 | return new ReplicateBNode(s, vt); |
440 | case T_CHAR: |
441 | case T_SHORT: |
442 | return new ReplicateSNode(s, vt); |
443 | case T_INT: |
444 | return new ReplicateINode(s, vt); |
445 | case T_LONG: |
446 | return new ReplicateLNode(s, vt); |
447 | case T_FLOAT: |
448 | return new ReplicateFNode(s, vt); |
449 | case T_DOUBLE: |
450 | return new ReplicateDNode(s, vt); |
451 | default: |
452 | fatal("Type '%s' is not supported for vectors" , type2name(bt)); |
453 | return NULL; |
454 | } |
455 | } |
456 | |
457 | VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) { |
458 | assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count" ); |
459 | // Match shift count type with shift vector type. |
460 | const TypeVect* vt = TypeVect::make(bt, vlen); |
461 | switch (shift->Opcode()) { |
462 | case Op_LShiftI: |
463 | case Op_LShiftL: |
464 | return new LShiftCntVNode(cnt, vt); |
465 | case Op_RShiftI: |
466 | case Op_RShiftL: |
467 | case Op_URShiftI: |
468 | case Op_URShiftL: |
469 | return new RShiftCntVNode(cnt, vt); |
470 | default: |
471 | fatal("Missed vector creation for '%s'" , NodeClassNames[shift->Opcode()]); |
472 | return NULL; |
473 | } |
474 | } |
475 | |
476 | // Return initial Pack node. Additional operands added with add_opd() calls. |
477 | PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) { |
478 | const TypeVect* vt = TypeVect::make(bt, vlen); |
479 | switch (bt) { |
480 | case T_BOOLEAN: |
481 | case T_BYTE: |
482 | return new PackBNode(s, vt); |
483 | case T_CHAR: |
484 | case T_SHORT: |
485 | return new PackSNode(s, vt); |
486 | case T_INT: |
487 | return new PackINode(s, vt); |
488 | case T_LONG: |
489 | return new PackLNode(s, vt); |
490 | case T_FLOAT: |
491 | return new PackFNode(s, vt); |
492 | case T_DOUBLE: |
493 | return new PackDNode(s, vt); |
494 | default: |
495 | fatal("Type '%s' is not supported for vectors" , type2name(bt)); |
496 | return NULL; |
497 | } |
498 | } |
499 | |
500 | // Create a binary tree form for Packs. [lo, hi) (half-open) range |
501 | PackNode* PackNode::binary_tree_pack(int lo, int hi) { |
502 | int ct = hi - lo; |
503 | assert(is_power_of_2(ct), "power of 2" ); |
504 | if (ct == 2) { |
505 | PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type()); |
506 | pk->add_opd(in(lo+1)); |
507 | return pk; |
508 | } else { |
509 | int mid = lo + ct/2; |
510 | PackNode* n1 = binary_tree_pack(lo, mid); |
511 | PackNode* n2 = binary_tree_pack(mid, hi ); |
512 | |
513 | BasicType bt = n1->vect_type()->element_basic_type(); |
514 | assert(bt == n2->vect_type()->element_basic_type(), "should be the same" ); |
515 | switch (bt) { |
516 | case T_BOOLEAN: |
517 | case T_BYTE: |
518 | return new PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); |
519 | case T_CHAR: |
520 | case T_SHORT: |
521 | return new PackINode(n1, n2, TypeVect::make(T_INT, 2)); |
522 | case T_INT: |
523 | return new PackLNode(n1, n2, TypeVect::make(T_LONG, 2)); |
524 | case T_LONG: |
525 | return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); |
526 | case T_FLOAT: |
527 | return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); |
528 | case T_DOUBLE: |
529 | return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); |
530 | default: |
531 | fatal("Type '%s' is not supported for vectors" , type2name(bt)); |
532 | return NULL; |
533 | } |
534 | } |
535 | } |
536 | |
537 | // Return the vector version of a scalar load node. |
538 | LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem, |
539 | Node* adr, const TypePtr* atyp, |
540 | uint vlen, BasicType bt, |
541 | ControlDependency control_dependency) { |
542 | const TypeVect* vt = TypeVect::make(bt, vlen); |
543 | return new LoadVectorNode(ctl, mem, adr, atyp, vt, control_dependency); |
544 | } |
545 | |
546 | // Return the vector version of a scalar store node. |
547 | StoreVectorNode* StoreVectorNode::make(int opc, Node* ctl, Node* mem, |
548 | Node* adr, const TypePtr* atyp, Node* val, |
549 | uint vlen) { |
550 | return new StoreVectorNode(ctl, mem, adr, atyp, val); |
551 | } |
552 | |
553 | // Extract a scalar element of vector. |
554 | Node* ExtractNode::(Node* v, uint position, BasicType bt) { |
555 | assert((int)position < Matcher::max_vector_size(bt), "pos in range" ); |
556 | ConINode* pos = ConINode::make((int)position); |
557 | switch (bt) { |
558 | case T_BOOLEAN: |
559 | return new ExtractUBNode(v, pos); |
560 | case T_BYTE: |
561 | return new ExtractBNode(v, pos); |
562 | case T_CHAR: |
563 | return new ExtractCNode(v, pos); |
564 | case T_SHORT: |
565 | return new ExtractSNode(v, pos); |
566 | case T_INT: |
567 | return new ExtractINode(v, pos); |
568 | case T_LONG: |
569 | return new ExtractLNode(v, pos); |
570 | case T_FLOAT: |
571 | return new ExtractFNode(v, pos); |
572 | case T_DOUBLE: |
573 | return new ExtractDNode(v, pos); |
574 | default: |
575 | fatal("Type '%s' is not supported for vectors" , type2name(bt)); |
576 | return NULL; |
577 | } |
578 | } |
579 | |
580 | int ReductionNode::opcode(int opc, BasicType bt) { |
581 | int vopc = opc; |
582 | switch (opc) { |
583 | case Op_AddI: |
584 | assert(bt == T_INT, "must be" ); |
585 | vopc = Op_AddReductionVI; |
586 | break; |
587 | case Op_AddL: |
588 | assert(bt == T_LONG, "must be" ); |
589 | vopc = Op_AddReductionVL; |
590 | break; |
591 | case Op_AddF: |
592 | assert(bt == T_FLOAT, "must be" ); |
593 | vopc = Op_AddReductionVF; |
594 | break; |
595 | case Op_AddD: |
596 | assert(bt == T_DOUBLE, "must be" ); |
597 | vopc = Op_AddReductionVD; |
598 | break; |
599 | case Op_MulI: |
600 | assert(bt == T_INT, "must be" ); |
601 | vopc = Op_MulReductionVI; |
602 | break; |
603 | case Op_MulL: |
604 | assert(bt == T_LONG, "must be" ); |
605 | vopc = Op_MulReductionVL; |
606 | break; |
607 | case Op_MulF: |
608 | assert(bt == T_FLOAT, "must be" ); |
609 | vopc = Op_MulReductionVF; |
610 | break; |
611 | case Op_MulD: |
612 | assert(bt == T_DOUBLE, "must be" ); |
613 | vopc = Op_MulReductionVD; |
614 | break; |
615 | case Op_MinF: |
616 | assert(bt == T_FLOAT, "must be" ); |
617 | vopc = Op_MinReductionV; |
618 | break; |
619 | case Op_MinD: |
620 | assert(bt == T_DOUBLE, "must be" ); |
621 | vopc = Op_MinReductionV; |
622 | break; |
623 | case Op_MaxF: |
624 | assert(bt == T_FLOAT, "must be" ); |
625 | vopc = Op_MaxReductionV; |
626 | break; |
627 | case Op_MaxD: |
628 | assert(bt == T_DOUBLE, "must be" ); |
629 | vopc = Op_MaxReductionV; |
630 | break; |
631 | // TODO: add MulL for targets that support it |
632 | default: |
633 | break; |
634 | } |
635 | return vopc; |
636 | } |
637 | |
638 | // Return the appropriate reduction node. |
639 | ReductionNode* ReductionNode::make(int opc, Node *ctrl, Node* n1, Node* n2, BasicType bt) { |
640 | |
641 | int vopc = opcode(opc, bt); |
642 | |
643 | // This method should not be called for unimplemented vectors. |
644 | guarantee(vopc != opc, "Vector for '%s' is not implemented" , NodeClassNames[opc]); |
645 | |
646 | switch (vopc) { |
647 | case Op_AddReductionVI: return new AddReductionVINode(ctrl, n1, n2); |
648 | case Op_AddReductionVL: return new AddReductionVLNode(ctrl, n1, n2); |
649 | case Op_AddReductionVF: return new AddReductionVFNode(ctrl, n1, n2); |
650 | case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2); |
651 | case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2); |
652 | case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2); |
653 | case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2); |
654 | case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2); |
655 | case Op_MinReductionV: return new MinReductionVNode(ctrl, n1, n2); |
656 | case Op_MaxReductionV: return new MaxReductionVNode(ctrl, n1, n2); |
657 | default: |
658 | fatal("Missed vector creation for '%s'" , NodeClassNames[vopc]); |
659 | return NULL; |
660 | } |
661 | } |
662 | |
663 | bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) { |
664 | if (is_java_primitive(bt) && |
665 | (vlen > 1) && is_power_of_2(vlen) && |
666 | Matcher::vector_size_supported(bt, vlen)) { |
667 | int vopc = ReductionNode::opcode(opc, bt); |
668 | return vopc != opc && Matcher::match_rule_supported(vopc); |
669 | } |
670 | return false; |
671 | } |
672 | |