235 case Op_OrI: case Op_OrL:
236 case Op_XorI: case Op_XorL:
237 *start = 1;
238 *end = 3; // 2 vector operands
239 break;
240 case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD:
241 *start = 2;
242 *end = n->req();
243 break;
244 default:
245 *start = 1;
246 *end = n->req(); // default is all operands
247 }
248 }
249
250 // Return the vector version of a scalar operation node.
251 VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
252 const TypeVect* vt = TypeVect::make(bt, vlen);
253 int vopc = VectorNode::opcode(opc, bt);
254 // This method should not be called for unimplemented vectors.
255 guarantee(vopc > 0, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
256 switch (vopc) {
257 case Op_AddVB: return new AddVBNode(n1, n2, vt);
258 case Op_AddVS: return new AddVSNode(n1, n2, vt);
259 case Op_AddVI: return new AddVINode(n1, n2, vt);
260 case Op_AddVL: return new AddVLNode(n1, n2, vt);
261 case Op_AddVF: return new AddVFNode(n1, n2, vt);
262 case Op_AddVD: return new AddVDNode(n1, n2, vt);
263
264 case Op_SubVB: return new SubVBNode(n1, n2, vt);
265 case Op_SubVS: return new SubVSNode(n1, n2, vt);
266 case Op_SubVI: return new SubVINode(n1, n2, vt);
267 case Op_SubVL: return new SubVLNode(n1, n2, vt);
268 case Op_SubVF: return new SubVFNode(n1, n2, vt);
269 case Op_SubVD: return new SubVDNode(n1, n2, vt);
270
271 case Op_MulVS: return new MulVSNode(n1, n2, vt);
272 case Op_MulVI: return new MulVINode(n1, n2, vt);
273 case Op_MulVL: return new MulVLNode(n1, n2, vt);
274 case Op_MulVF: return new MulVFNode(n1, n2, vt);
275 case Op_MulVD: return new MulVDNode(n1, n2, vt);
279
280 case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt);
281 case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt);
282 case Op_LShiftVI: return new LShiftVINode(n1, n2, vt);
283 case Op_LShiftVL: return new LShiftVLNode(n1, n2, vt);
284
285 case Op_RShiftVB: return new RShiftVBNode(n1, n2, vt);
286 case Op_RShiftVS: return new RShiftVSNode(n1, n2, vt);
287 case Op_RShiftVI: return new RShiftVINode(n1, n2, vt);
288 case Op_RShiftVL: return new RShiftVLNode(n1, n2, vt);
289
290 case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt);
291 case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt);
292 case Op_URShiftVI: return new URShiftVINode(n1, n2, vt);
293 case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt);
294
295 case Op_AndV: return new AndVNode(n1, n2, vt);
296 case Op_OrV: return new OrVNode (n1, n2, vt);
297 case Op_XorV: return new XorVNode(n1, n2, vt);
298 }
299 fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
300 return NULL;
301
302 }
303
304 // Scalar promotion
305 VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) {
306 BasicType bt = opd_t->array_element_basic_type();
307 const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
308 : TypeVect::make(bt, vlen);
309 switch (bt) {
310 case T_BOOLEAN:
311 case T_BYTE:
312 return new ReplicateBNode(s, vt);
313 case T_CHAR:
314 case T_SHORT:
315 return new ReplicateSNode(s, vt);
316 case T_INT:
317 return new ReplicateINode(s, vt);
318 case T_LONG:
319 return new ReplicateLNode(s, vt);
320 case T_FLOAT:
321 return new ReplicateFNode(s, vt);
322 case T_DOUBLE:
323 return new ReplicateDNode(s, vt);
324 }
325 fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
326 return NULL;
327 }
328
329 VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) {
330 assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count");
331 // Match shift count type with shift vector type.
332 const TypeVect* vt = TypeVect::make(bt, vlen);
333 switch (shift->Opcode()) {
334 case Op_LShiftI:
335 case Op_LShiftL:
336 return new LShiftCntVNode(cnt, vt);
337 case Op_RShiftI:
338 case Op_RShiftL:
339 case Op_URShiftI:
340 case Op_URShiftL:
341 return new RShiftCntVNode(cnt, vt);
342 }
343 fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]));
344 return NULL;
345 }
346
347 // Return initial Pack node. Additional operands added with add_opd() calls.
348 PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
349 const TypeVect* vt = TypeVect::make(bt, vlen);
350 switch (bt) {
351 case T_BOOLEAN:
352 case T_BYTE:
353 return new PackBNode(s, vt);
354 case T_CHAR:
355 case T_SHORT:
356 return new PackSNode(s, vt);
357 case T_INT:
358 return new PackINode(s, vt);
359 case T_LONG:
360 return new PackLNode(s, vt);
361 case T_FLOAT:
362 return new PackFNode(s, vt);
363 case T_DOUBLE:
364 return new PackDNode(s, vt);
365 }
366 fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
367 return NULL;
368 }
369
370 // Create a binary tree form for Packs. [lo, hi) (half-open) range
371 PackNode* PackNode::binary_tree_pack(int lo, int hi) {
372 int ct = hi - lo;
373 assert(is_power_of_2(ct), "power of 2");
374 if (ct == 2) {
375 PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type());
376 pk->add_opd(in(lo+1));
377 return pk;
378
379 } else {
380 int mid = lo + ct/2;
381 PackNode* n1 = binary_tree_pack(lo, mid);
382 PackNode* n2 = binary_tree_pack(mid, hi );
383
384 BasicType bt = n1->vect_type()->element_basic_type();
385 assert(bt == n2->vect_type()->element_basic_type(), "should be the same");
386 switch (bt) {
387 case T_BOOLEAN:
388 case T_BYTE:
389 return new PackSNode(n1, n2, TypeVect::make(T_SHORT, 2));
390 case T_CHAR:
391 case T_SHORT:
392 return new PackINode(n1, n2, TypeVect::make(T_INT, 2));
393 case T_INT:
394 return new PackLNode(n1, n2, TypeVect::make(T_LONG, 2));
395 case T_LONG:
396 return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
397 case T_FLOAT:
398 return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
399 case T_DOUBLE:
400 return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
401 }
402 fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
403 }
404 return NULL;
405 }
406
407 // Return the vector version of a scalar load node.
408 LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem,
409 Node* adr, const TypePtr* atyp,
410 uint vlen, BasicType bt,
411 ControlDependency control_dependency) {
412 const TypeVect* vt = TypeVect::make(bt, vlen);
413 return new LoadVectorNode(ctl, mem, adr, atyp, vt, control_dependency);
414 }
415
416 // Return the vector version of a scalar store node.
417 StoreVectorNode* StoreVectorNode::make(int opc, Node* ctl, Node* mem,
418 Node* adr, const TypePtr* atyp, Node* val,
419 uint vlen) {
420 return new StoreVectorNode(ctl, mem, adr, atyp, val);
421 }
422
425 assert((int)position < Matcher::max_vector_size(bt), "pos in range");
426 ConINode* pos = ConINode::make((int)position);
427 switch (bt) {
428 case T_BOOLEAN:
429 return new ExtractUBNode(v, pos);
430 case T_BYTE:
431 return new ExtractBNode(v, pos);
432 case T_CHAR:
433 return new ExtractCNode(v, pos);
434 case T_SHORT:
435 return new ExtractSNode(v, pos);
436 case T_INT:
437 return new ExtractINode(v, pos);
438 case T_LONG:
439 return new ExtractLNode(v, pos);
440 case T_FLOAT:
441 return new ExtractFNode(v, pos);
442 case T_DOUBLE:
443 return new ExtractDNode(v, pos);
444 }
445 fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
446 return NULL;
447 }
448
449 int ReductionNode::opcode(int opc, BasicType bt) {
450 int vopc = opc;
451 switch (opc) {
452 case Op_AddI:
453 assert(bt == T_INT, "must be");
454 vopc = Op_AddReductionVI;
455 break;
456 case Op_AddL:
457 assert(bt == T_LONG, "must be");
458 vopc = Op_AddReductionVL;
459 break;
460 case Op_AddF:
461 assert(bt == T_FLOAT, "must be");
462 vopc = Op_AddReductionVF;
463 break;
464 case Op_AddD:
465 assert(bt == T_DOUBLE, "must be");
477 assert(bt == T_FLOAT, "must be");
478 vopc = Op_MulReductionVF;
479 break;
480 case Op_MulD:
481 assert(bt == T_DOUBLE, "must be");
482 vopc = Op_MulReductionVD;
483 break;
484 // TODO: add MulL for targets that support it
485 default:
486 break;
487 }
488 return vopc;
489 }
490
491 // Return the appropriate reduction node.
492 ReductionNode* ReductionNode::make(int opc, Node *ctrl, Node* n1, Node* n2, BasicType bt) {
493
494 int vopc = opcode(opc, bt);
495
496 // This method should not be called for unimplemented vectors.
497 guarantee(vopc != opc, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
498
499 switch (vopc) {
500 case Op_AddReductionVI: return new AddReductionVINode(ctrl, n1, n2);
501 case Op_AddReductionVL: return new AddReductionVLNode(ctrl, n1, n2);
502 case Op_AddReductionVF: return new AddReductionVFNode(ctrl, n1, n2);
503 case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2);
504 case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2);
505 case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2);
506 case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2);
507 case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2);
508 }
509 fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
510 return NULL;
511 }
512
513 bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) {
514 if (is_java_primitive(bt) &&
515 (vlen > 1) && is_power_of_2(vlen) &&
516 Matcher::vector_size_supported(bt, vlen)) {
517 int vopc = ReductionNode::opcode(opc, bt);
518 return vopc != opc && Matcher::match_rule_supported(vopc);
519 }
520 return false;
521 }
522
|
235 case Op_OrI: case Op_OrL:
236 case Op_XorI: case Op_XorL:
237 *start = 1;
238 *end = 3; // 2 vector operands
239 break;
240 case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD:
241 *start = 2;
242 *end = n->req();
243 break;
244 default:
245 *start = 1;
246 *end = n->req(); // default is all operands
247 }
248 }
249
250 // Return the vector version of a scalar operation node.
251 VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
252 const TypeVect* vt = TypeVect::make(bt, vlen);
253 int vopc = VectorNode::opcode(opc, bt);
254 // This method should not be called for unimplemented vectors.
255 guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]);
256 switch (vopc) {
257 case Op_AddVB: return new AddVBNode(n1, n2, vt);
258 case Op_AddVS: return new AddVSNode(n1, n2, vt);
259 case Op_AddVI: return new AddVINode(n1, n2, vt);
260 case Op_AddVL: return new AddVLNode(n1, n2, vt);
261 case Op_AddVF: return new AddVFNode(n1, n2, vt);
262 case Op_AddVD: return new AddVDNode(n1, n2, vt);
263
264 case Op_SubVB: return new SubVBNode(n1, n2, vt);
265 case Op_SubVS: return new SubVSNode(n1, n2, vt);
266 case Op_SubVI: return new SubVINode(n1, n2, vt);
267 case Op_SubVL: return new SubVLNode(n1, n2, vt);
268 case Op_SubVF: return new SubVFNode(n1, n2, vt);
269 case Op_SubVD: return new SubVDNode(n1, n2, vt);
270
271 case Op_MulVS: return new MulVSNode(n1, n2, vt);
272 case Op_MulVI: return new MulVINode(n1, n2, vt);
273 case Op_MulVL: return new MulVLNode(n1, n2, vt);
274 case Op_MulVF: return new MulVFNode(n1, n2, vt);
275 case Op_MulVD: return new MulVDNode(n1, n2, vt);
279
280 case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt);
281 case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt);
282 case Op_LShiftVI: return new LShiftVINode(n1, n2, vt);
283 case Op_LShiftVL: return new LShiftVLNode(n1, n2, vt);
284
285 case Op_RShiftVB: return new RShiftVBNode(n1, n2, vt);
286 case Op_RShiftVS: return new RShiftVSNode(n1, n2, vt);
287 case Op_RShiftVI: return new RShiftVINode(n1, n2, vt);
288 case Op_RShiftVL: return new RShiftVLNode(n1, n2, vt);
289
290 case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt);
291 case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt);
292 case Op_URShiftVI: return new URShiftVINode(n1, n2, vt);
293 case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt);
294
295 case Op_AndV: return new AndVNode(n1, n2, vt);
296 case Op_OrV: return new OrVNode (n1, n2, vt);
297 case Op_XorV: return new XorVNode(n1, n2, vt);
298 }
299 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
300 return NULL;
301
302 }
303
304 // Scalar promotion
305 VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) {
306 BasicType bt = opd_t->array_element_basic_type();
307 const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
308 : TypeVect::make(bt, vlen);
309 switch (bt) {
310 case T_BOOLEAN:
311 case T_BYTE:
312 return new ReplicateBNode(s, vt);
313 case T_CHAR:
314 case T_SHORT:
315 return new ReplicateSNode(s, vt);
316 case T_INT:
317 return new ReplicateINode(s, vt);
318 case T_LONG:
319 return new ReplicateLNode(s, vt);
320 case T_FLOAT:
321 return new ReplicateFNode(s, vt);
322 case T_DOUBLE:
323 return new ReplicateDNode(s, vt);
324 }
325 fatal("Type '%s' is not supported for vectors", type2name(bt));
326 return NULL;
327 }
328
329 VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) {
330 assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count");
331 // Match shift count type with shift vector type.
332 const TypeVect* vt = TypeVect::make(bt, vlen);
333 switch (shift->Opcode()) {
334 case Op_LShiftI:
335 case Op_LShiftL:
336 return new LShiftCntVNode(cnt, vt);
337 case Op_RShiftI:
338 case Op_RShiftL:
339 case Op_URShiftI:
340 case Op_URShiftL:
341 return new RShiftCntVNode(cnt, vt);
342 }
343 fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]);
344 return NULL;
345 }
346
347 // Return initial Pack node. Additional operands added with add_opd() calls.
348 PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
349 const TypeVect* vt = TypeVect::make(bt, vlen);
350 switch (bt) {
351 case T_BOOLEAN:
352 case T_BYTE:
353 return new PackBNode(s, vt);
354 case T_CHAR:
355 case T_SHORT:
356 return new PackSNode(s, vt);
357 case T_INT:
358 return new PackINode(s, vt);
359 case T_LONG:
360 return new PackLNode(s, vt);
361 case T_FLOAT:
362 return new PackFNode(s, vt);
363 case T_DOUBLE:
364 return new PackDNode(s, vt);
365 }
366 fatal("Type '%s' is not supported for vectors", type2name(bt));
367 return NULL;
368 }
369
370 // Create a binary tree form for Packs. [lo, hi) (half-open) range
371 PackNode* PackNode::binary_tree_pack(int lo, int hi) {
372 int ct = hi - lo;
373 assert(is_power_of_2(ct), "power of 2");
374 if (ct == 2) {
375 PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type());
376 pk->add_opd(in(lo+1));
377 return pk;
378
379 } else {
380 int mid = lo + ct/2;
381 PackNode* n1 = binary_tree_pack(lo, mid);
382 PackNode* n2 = binary_tree_pack(mid, hi );
383
384 BasicType bt = n1->vect_type()->element_basic_type();
385 assert(bt == n2->vect_type()->element_basic_type(), "should be the same");
386 switch (bt) {
387 case T_BOOLEAN:
388 case T_BYTE:
389 return new PackSNode(n1, n2, TypeVect::make(T_SHORT, 2));
390 case T_CHAR:
391 case T_SHORT:
392 return new PackINode(n1, n2, TypeVect::make(T_INT, 2));
393 case T_INT:
394 return new PackLNode(n1, n2, TypeVect::make(T_LONG, 2));
395 case T_LONG:
396 return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
397 case T_FLOAT:
398 return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
399 case T_DOUBLE:
400 return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
401 }
402 fatal("Type '%s' is not supported for vectors", type2name(bt));
403 }
404 return NULL;
405 }
406
407 // Return the vector version of a scalar load node.
408 LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem,
409 Node* adr, const TypePtr* atyp,
410 uint vlen, BasicType bt,
411 ControlDependency control_dependency) {
412 const TypeVect* vt = TypeVect::make(bt, vlen);
413 return new LoadVectorNode(ctl, mem, adr, atyp, vt, control_dependency);
414 }
415
416 // Return the vector version of a scalar store node.
417 StoreVectorNode* StoreVectorNode::make(int opc, Node* ctl, Node* mem,
418 Node* adr, const TypePtr* atyp, Node* val,
419 uint vlen) {
420 return new StoreVectorNode(ctl, mem, adr, atyp, val);
421 }
422
425 assert((int)position < Matcher::max_vector_size(bt), "pos in range");
426 ConINode* pos = ConINode::make((int)position);
427 switch (bt) {
428 case T_BOOLEAN:
429 return new ExtractUBNode(v, pos);
430 case T_BYTE:
431 return new ExtractBNode(v, pos);
432 case T_CHAR:
433 return new ExtractCNode(v, pos);
434 case T_SHORT:
435 return new ExtractSNode(v, pos);
436 case T_INT:
437 return new ExtractINode(v, pos);
438 case T_LONG:
439 return new ExtractLNode(v, pos);
440 case T_FLOAT:
441 return new ExtractFNode(v, pos);
442 case T_DOUBLE:
443 return new ExtractDNode(v, pos);
444 }
445 fatal("Type '%s' is not supported for vectors", type2name(bt));
446 return NULL;
447 }
448
449 int ReductionNode::opcode(int opc, BasicType bt) {
450 int vopc = opc;
451 switch (opc) {
452 case Op_AddI:
453 assert(bt == T_INT, "must be");
454 vopc = Op_AddReductionVI;
455 break;
456 case Op_AddL:
457 assert(bt == T_LONG, "must be");
458 vopc = Op_AddReductionVL;
459 break;
460 case Op_AddF:
461 assert(bt == T_FLOAT, "must be");
462 vopc = Op_AddReductionVF;
463 break;
464 case Op_AddD:
465 assert(bt == T_DOUBLE, "must be");
477 assert(bt == T_FLOAT, "must be");
478 vopc = Op_MulReductionVF;
479 break;
480 case Op_MulD:
481 assert(bt == T_DOUBLE, "must be");
482 vopc = Op_MulReductionVD;
483 break;
484 // TODO: add MulL for targets that support it
485 default:
486 break;
487 }
488 return vopc;
489 }
490
491 // Return the appropriate reduction node.
492 ReductionNode* ReductionNode::make(int opc, Node *ctrl, Node* n1, Node* n2, BasicType bt) {
493
494 int vopc = opcode(opc, bt);
495
496 // This method should not be called for unimplemented vectors.
497 guarantee(vopc != opc, "Vector for '%s' is not implemented", NodeClassNames[opc]);
498
499 switch (vopc) {
500 case Op_AddReductionVI: return new AddReductionVINode(ctrl, n1, n2);
501 case Op_AddReductionVL: return new AddReductionVLNode(ctrl, n1, n2);
502 case Op_AddReductionVF: return new AddReductionVFNode(ctrl, n1, n2);
503 case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2);
504 case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2);
505 case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2);
506 case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2);
507 case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2);
508 }
509 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
510 return NULL;
511 }
512
513 bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) {
514 if (is_java_primitive(bt) &&
515 (vlen > 1) && is_power_of_2(vlen) &&
516 Matcher::vector_size_supported(bt, vlen)) {
517 int vopc = ReductionNode::opcode(opc, bt);
518 return vopc != opc && Matcher::match_rule_supported(vopc);
519 }
520 return false;
521 }
522
|