62
63 const TypeVect* vect_type() const { return type()->is_vect(); }
64 uint length() const { return vect_type()->length(); } // Vector length
65 uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
66
67 virtual int Opcode() const;
68
69 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
70
71 static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
72 static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt);
73 static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
74 static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt);
75 static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
76 static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt);
77
78 static int opcode(int opc, BasicType bt);
79 static int replicate_opcode(BasicType bt);
80 static bool implemented(int opc, uint vlen, BasicType bt);
81 static bool is_shift(Node* n);
82 static bool is_vshift(Node* n);
83 static bool is_vshift_cnt(Node* n);
84 static bool is_type_transition_short_to_int(Node* n);
85 static bool is_type_transition_to_int(Node* n);
86 static bool is_muladds2i(Node* n);
87 static bool is_roundopD(Node * n);
88 static bool is_invariant_vector(Node* n);
89 static bool is_all_ones_vector(Node* n);
90 static bool is_vector_bitwise_not_pattern(Node* n);
91
92 // [Start, end) half-open range defining which operands are vectors
93 static void vector_operands(Node* n, uint* start, uint* end);
94
95 static bool is_vector_shift(int opc);
96 static bool is_vector_shift_count(int opc);
97
98 static bool is_vector_shift(Node* n) {
99 return is_vector_shift(n->Opcode());
100 }
101 static bool is_vector_shift_count(Node* n) {
102 return is_vector_shift_count(n->Opcode());
163 static int opcode(int opc, BasicType bt);
164 static bool implemented(int opc, uint vlen, BasicType bt);
165 static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt);
166
167 virtual const Type* bottom_type() const {
168 BasicType vbt = in(1)->bottom_type()->basic_type();
169 return Type::get_const_basic_type(vbt);
170 }
171
172 virtual uint ideal_reg() const {
173 return bottom_type()->ideal_reg();
174 }
175 };
176
177 //------------------------------AddReductionVINode--------------------------------------
178 // Vector add byte, short and int as a reduction
179 class AddReductionVINode : public ReductionNode {
180 public:
181 AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
182 virtual int Opcode() const;
183 virtual uint ideal_reg() const { return Op_RegI; }
184 };
185
186 //------------------------------AddReductionVLNode--------------------------------------
187 // Vector add long as a reduction
188 class AddReductionVLNode : public ReductionNode {
189 public:
190 AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
191 virtual int Opcode() const;
192 virtual const Type* bottom_type() const { return TypeLong::LONG; }
193 virtual uint ideal_reg() const { return Op_RegL; }
194 };
195
196 //------------------------------AddReductionVFNode--------------------------------------
197 // Vector add float as a reduction
198 class AddReductionVFNode : public ReductionNode {
199 public:
200 AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
201 virtual int Opcode() const;
202 virtual const Type* bottom_type() const { return Type::FLOAT; }
203 virtual uint ideal_reg() const { return Op_RegF; }
204 };
205
206 //------------------------------AddReductionVDNode--------------------------------------
207 // Vector add double as a reduction
208 class AddReductionVDNode : public ReductionNode {
209 public:
210 AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
211 virtual int Opcode() const;
212 virtual const Type* bottom_type() const { return Type::DOUBLE; }
213 virtual uint ideal_reg() const { return Op_RegD; }
214 };
215
216 //------------------------------SubVBNode--------------------------------------
217 // Vector subtract byte
218 class SubVBNode : public VectorNode {
219 public:
220 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
221 virtual int Opcode() const;
222 };
223
224 //------------------------------SubVSNode--------------------------------------
225 // Vector subtract short
226 class SubVSNode : public VectorNode {
227 public:
228 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
229 virtual int Opcode() const;
230 };
231
232 //------------------------------SubVINode--------------------------------------
233 // Vector subtract int
338 class CMoveVFNode : public VectorNode {
339 public:
340 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
341 virtual int Opcode() const;
342 };
343
344 //------------------------------CMoveVDNode--------------------------------------
345 // Vector double conditional move
346 class CMoveVDNode : public VectorNode {
347 public:
348 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
349 virtual int Opcode() const;
350 };
351
352 //------------------------------MulReductionVINode--------------------------------------
353 // Vector multiply byte, short and int as a reduction
354 class MulReductionVINode : public ReductionNode {
355 public:
356 MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
357 virtual int Opcode() const;
358 virtual uint ideal_reg() const { return Op_RegI; }
359 };
360
361 //------------------------------MulReductionVLNode--------------------------------------
362 // Vector multiply int as a reduction
363 class MulReductionVLNode : public ReductionNode {
364 public:
365 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
366 virtual int Opcode() const;
367 virtual const Type* bottom_type() const { return TypeLong::LONG; }
368 virtual uint ideal_reg() const { return Op_RegL; }
369 };
370
371 //------------------------------MulReductionVFNode--------------------------------------
372 // Vector multiply float as a reduction
373 class MulReductionVFNode : public ReductionNode {
374 public:
375 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
376 virtual int Opcode() const;
377 virtual const Type* bottom_type() const { return Type::FLOAT; }
378 virtual uint ideal_reg() const { return Op_RegF; }
379 };
380
381 //------------------------------MulReductionVDNode--------------------------------------
382 // Vector multiply double as a reduction
383 class MulReductionVDNode : public ReductionNode {
384 public:
385 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
386 virtual int Opcode() const;
387 virtual const Type* bottom_type() const { return Type::DOUBLE; }
388 virtual uint ideal_reg() const { return Op_RegD; }
389 };
390
391 //------------------------------DivVFNode--------------------------------------
392 // Vector divide float
393 class DivVFNode : public VectorNode {
394 public:
395 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
396 virtual int Opcode() const;
397 };
398
399 //------------------------------DivVDNode--------------------------------------
400 // Vector Divide double
401 class DivVDNode : public VectorNode {
402 public:
403 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
404 virtual int Opcode() const;
405 };
406
407 //------------------------------AbsVBNode--------------------------------------
408 // Vector Abs byte
414
415 //------------------------------AbsVSNode--------------------------------------
416 // Vector Abs short
417 class AbsVSNode : public VectorNode {
418 public:
419 AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
420 virtual int Opcode() const;
421 };
422
423 //------------------------------MinVNode--------------------------------------
424 // Vector Min
425 class MinVNode : public VectorNode {
426 public:
427 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
428 virtual int Opcode() const;
429 };
430
431 //------------------------------MaxVNode--------------------------------------
432 // Vector Max
433 class MaxVNode : public VectorNode {
434 public:
435 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
436 virtual int Opcode() const;
437 };
438
439 //------------------------------AbsVNode--------------------------------------
440 // Vector Abs
441 class AbsVNode : public VectorNode {
442 public:
443 AbsVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
444 virtual int Opcode() const;
445 };
446
447 //------------------------------AbsVINode--------------------------------------
448 // Vector Abs int
449 class AbsVINode : public VectorNode {
450 public:
451 AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
452 virtual int Opcode() const;
453 };
454
455 //------------------------------AbsVLNode--------------------------------------
456 // Vector Abs long
457 class AbsVLNode : public VectorNode {
458 public:
459 AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
460 virtual int Opcode() const;
461 };
462
463 //------------------------------AbsVFNode--------------------------------------
464 // Vector Abs float
465 class AbsVFNode : public VectorNode {
466 public:
467 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
468 virtual int Opcode() const;
469 };
470
471 //------------------------------AbsVDNode--------------------------------------
472 // Vector Abs double
473 class AbsVDNode : public VectorNode {
474 public:
475 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
476 virtual int Opcode() const;
477 };
478
479 //------------------------------NegVINode--------------------------------------
480 // Vector Neg int
481 class NegVINode : public VectorNode {
482 public:
483 NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
484 virtual int Opcode() const;
485 };
486
487 //------------------------------NegVFNode--------------------------------------
488 // Vector Neg float
489 class NegVFNode : public VectorNode {
490 public:
491 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
492 virtual int Opcode() const;
493 };
494
495 //------------------------------NegVDNode--------------------------------------
496 // Vector Neg double
497 class NegVDNode : public VectorNode {
498 public:
499 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
500 virtual int Opcode() const;
501 };
502
514 public:
515 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
516 virtual int Opcode() const;
517 };
518 //------------------------------RoundDoubleVNode--------------------------------
519 // Vector round double
520 class RoundDoubleModeVNode : public VectorNode {
521 public:
522 RoundDoubleModeVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
523 virtual int Opcode() const;
524 };
525
526 //------------------------------SqrtVDNode--------------------------------------
527 // Vector Sqrt double
528 class SqrtVDNode : public VectorNode {
529 public:
530 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
531 virtual int Opcode() const;
532 };
533
534 //------------------------------NotVNode--------------------------------------
535 // Vector Not
536 class NotVNode : public VectorNode {
537 public:
538 NotVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
539 virtual int Opcode() const;
540 };
541
542 //------------------------------LShiftVBNode-----------------------------------
543 // Vector left shift bytes
544 class LShiftVBNode : public VectorNode {
545 public:
546 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
547 virtual int Opcode() const;
548 };
549
550 //------------------------------LShiftVSNode-----------------------------------
551 // Vector left shift shorts
552 class LShiftVSNode : public VectorNode {
553 public:
554 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
555 virtual int Opcode() const;
556 };
557
558 //------------------------------LShiftVINode-----------------------------------
559 // Vector left shift ints
560 class LShiftVINode : public VectorNode {
561 public:
634 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
635 virtual int Opcode() const;
636 };
637
638 //------------------------------LShiftCntVNode---------------------------------
639 // Vector left shift count
640 class LShiftCntVNode : public VectorNode {
641 public:
642 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
643 virtual int Opcode() const;
644 };
645
646 //------------------------------RShiftCntVNode---------------------------------
647 // Vector right shift count
648 class RShiftCntVNode : public VectorNode {
649 public:
650 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
651 virtual int Opcode() const;
652 };
653
654 //------------------------------VLShiftVNode-----------------------------------
655 // Variable vector left shift bytes
656 class VLShiftVNode : public VectorNode {
657 public:
658 VLShiftVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
659 virtual int Opcode() const;
660 };
661
662 //------------------------------VRShiftVNode-----------------------------------
663 // Variable vector right shift bytes
664 class VRShiftVNode : public VectorNode {
665 public:
666 VRShiftVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
667 virtual int Opcode() const;
668 };
669
670 //------------------------------VURShiftVNode-----------------------------------
671 // Variable vector unsigned right shift bytes
672 class VURShiftVNode : public VectorNode {
673 public:
674 VURShiftVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
675 virtual int Opcode() const;
676 };
677
678 //------------------------------AndVNode---------------------------------------
679 // Vector and integer
680 class AndVNode : public VectorNode {
681 public:
682 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
683 virtual int Opcode() const;
684 };
685
686 //------------------------------AndReductionVNode--------------------------------------
687 // Vector and byte, short, int, long as a reduction
688 class AndReductionVNode : public ReductionNode {
689 public:
690 AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
691 virtual int Opcode() const;
692 };
693
694 //------------------------------OrVNode---------------------------------------
695 // Vector or byte, short, int, long as a reduction
696 class OrVNode : public VectorNode {
697 public:
698 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
699 virtual int Opcode() const;
700 };
701
702 //------------------------------OrReductionVNode--------------------------------------
703 // Vector xor byte, short, int, long as a reduction
704 class OrReductionVNode : public ReductionNode {
705 public:
706 OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
707 virtual int Opcode() const;
708 };
709
710 //------------------------------XorReductionVNode--------------------------------------
711 // Vector and int, long as a reduction
712 class XorReductionVNode : public ReductionNode {
713 public:
714 XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
715 virtual int Opcode() const;
716 };
717
718 //------------------------------XorVNode---------------------------------------
719 // Vector xor integer
720 class XorVNode : public VectorNode {
721 public:
722 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
723 virtual int Opcode() const;
724 };
725
726 //------------------------------MinReductionVNode--------------------------------------
727 // Vector min byte, short, int, long, float, double as a reduction
728 class MinReductionVNode : public ReductionNode {
729 public:
730 MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
731 virtual int Opcode() const;
732 };
733
1087 class MacroLogicVNode : public VectorNode {
1088 private:
1089 MacroLogicVNode(Node* in1, Node* in2, Node* in3, Node* fn, const TypeVect* vt)
1090 : VectorNode(in1, in2, in3, fn, vt) {}
1091
1092 public:
1093 virtual int Opcode() const;
1094
1095 static MacroLogicVNode* make(PhaseGVN& igvn, Node* in1, Node* in2, Node* in3, uint truth_table, const TypeVect* vt);
1096 };
1097
1098 class VectorMaskCmpNode : public VectorNode {
1099 private:
1100 BoolTest::mask _predicate;
1101
1102 protected:
1103 uint size_of() const { return sizeof(*this); }
1104
1105 public:
1106 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, ConINode* predicate_node, const TypeVect* vt) :
1107 #ifdef X86
1108 VectorNode(in1, in2, predicate_node, vt),
1109 #else
1110 VectorNode(in1, in2, vt),
1111 #endif
1112 _predicate(predicate) {
1113 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1114 "VectorMaskCmp inputs must have same type for elements");
1115 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1116 "VectorMaskCmp inputs must have same number of elements");
1117 init_class_id(Class_VectorMaskCmp);
1118 }
1119
1120 virtual int Opcode() const;
1121 virtual uint hash() const { return VectorNode::hash() + _predicate; }
1122 virtual bool cmp( const Node &n ) const {
1123 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate;
1124 }
1125 BoolTest::mask get_predicate() { return _predicate; }
1126 #ifndef PRODUCT
1127 virtual void dump_spec(outputStream *st) const;
1128 #endif // PRODUCT
1129 };
1130
1131 // Used to wrap other vector nodes in order to add masking functionality.
1132 class VectorMaskWrapperNode : public VectorNode {
1133 public:
1134 VectorMaskWrapperNode(Node* vector, Node* mask)
1135 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) {
1136 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask");
1137 }
1138
1139 virtual int Opcode() const;
1140 Node* vector_val() const { return in(1); }
1141 Node* vector_mask() const { return in(2); }
1142 };
1143
1144 class VectorTestNode : public Node {
1145 private:
1146 BoolTest::mask _predicate;
1147
1148 protected:
1149 uint size_of() const { return sizeof(*this); }
1150
1151 public:
1152 VectorTestNode( Node *in1, Node *in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) {
1153 assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector");
1154 assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector");
1155 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1156 "same type elements are needed");
1157 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1158 "same number of elements is needed");
1159 }
1160 virtual int Opcode() const;
1161 virtual uint hash() const { return Node::hash() + _predicate; }
1162 virtual bool cmp( const Node &n ) const {
1163 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate;
1164 }
1165 virtual const Type *bottom_type() const { return TypeInt::BOOL; }
1166 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest
1167 // in middle-end, we make it boolean result directly.
1168 BoolTest::mask get_predicate() const { return _predicate; }
1169 };
1170
1171 class VectorBlendNode : public VectorNode {
1172 public:
1173 VectorBlendNode(Node* vec1, Node* vec2, Node* mask)
1174 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) {
1175 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1176 }
1177
1178 virtual int Opcode() const;
1179 Node* vec1() const { return in(1); }
1180 Node* vec2() const { return in(2); }
1181 Node* vec_mask() const { return in(3); }
1182 };
1183
1184 class VectorRearrangeNode : public VectorNode {
1185 public:
1186 VectorRearrangeNode(Node* vec1, Node* shuffle)
1187 : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) {
1188 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1189 }
1190
1191 virtual int Opcode() const;
1192 Node* vec1() const { return in(1); }
1193 Node* vec_shuffle() const { return in(2); }
1194 };
1195
1196
1197 class VectorLoadMaskNode : public VectorNode {
1198 public:
1199 VectorLoadMaskNode(Node* in, const TypeVect* vt)
1200 : VectorNode(in, vt) {
1201 assert(in->is_LoadVector(), "expected load vector");
1202 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean");
1203 }
1204
1205 int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); }
1206 virtual int Opcode() const;
1207 };
1208
1209 class VectorLoadShuffleNode : public VectorNode {
1210 public:
1211 VectorLoadShuffleNode(Node* in, const TypeVect* vt)
1212 : VectorNode(in, vt) {
1213 assert(in->is_LoadVector(), "expected load vector");
1214 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BYTE, "must be BYTE");
1215 }
1216
1217 int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); }
1218 virtual int Opcode() const;
1219 };
1220
1221 class VectorStoreMaskNode : public VectorNode {
1222 private:
1223 int _mask_size;
1224 protected:
1225 uint size_of() const { return sizeof(*this); }
1226
1227 public:
1228 VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem)
1229 : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) {
1230 _mask_size = type2aelembytes(in_type);
1231 }
1232
1233 virtual uint hash() const { return VectorNode::hash() + _mask_size; }
1234 virtual bool cmp( const Node &n ) const {
1235 return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size;
1236 }
1237 int GetInputMaskSize() const { return _mask_size; }
1238 virtual int Opcode() const;
1239 };
1240
1241 // This is intended for use as a simple reinterpret node that has no cast.
1242 class VectorReinterpretNode : public VectorNode {
1243 private:
1244 const TypeVect* _src_vt;
1245 protected:
1246 uint size_of() const { return sizeof(*this); }
1247 public:
1248 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt)
1249 : VectorNode(in, dst_vt), _src_vt(src_vt) { }
1250
1251 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); }
1252 virtual bool cmp( const Node &n ) const {
1253 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt);
1254 }
1255 virtual Node *Identity(PhaseGVN *phase);
1256
1257 virtual int Opcode() const;
1258 };
1259
1260 class VectorCastNode : public VectorNode {
1261 public:
1262 VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
1263 virtual int Opcode() const;
1264
1265 static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen);
1266 static int opcode(BasicType bt);
1267 static bool implemented(BasicType bt, uint vlen);
1268 };
1269
1270 class VectorCastB2XNode : public VectorCastNode {
1271 public:
1272 VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1273 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte");
1274 }
1275 virtual int Opcode() const;
1276 };
1277
1278 class VectorCastS2XNode : public VectorCastNode {
1279 public:
1280 VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1281 assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short");
1282 }
1283 virtual int Opcode() const;
1284 };
1285
1286 class VectorCastI2XNode : public VectorCastNode {
1287 public:
1288 VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1289 assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int");
1290 }
1291 virtual int Opcode() const;
1292 };
1293
1294 class VectorCastL2XNode : public VectorCastNode {
1295 public:
1296 VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1297 assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long");
1298 }
1299 virtual int Opcode() const;
1300 };
1301
1302 class VectorCastF2XNode : public VectorCastNode {
1303 public:
1304 VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1305 assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float");
1306 }
1307 virtual int Opcode() const;
1308 };
1309
1310 class VectorCastD2XNode : public VectorCastNode {
1311 public:
1312 VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1313 assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double");
1314 }
1315 virtual int Opcode() const;
1316 };
1317
1318 class VectorInsertNode : public VectorNode {
1319 public:
1320 VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) {
1321 assert(pos->get_int() >= 0, "positive constants");
1322 assert(pos->get_int() < (int)vt->length(), "index must be less than vector length");
1323 assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type");
1324 }
1325 virtual int Opcode() const;
1326 uint pos() const { return in(3)->get_int(); }
1327
1328 static Node* make(Node* vec, Node* new_val, int position);
1329 };
1330
1331 class VectorBoxNode : public Node {
1332 private:
1333 const TypeInstPtr* const _box_type;
1334 const TypeVect* const _vec_type;
1335 public:
1336 enum {
1337 Box = 1,
1338 Value = 2
1339 };
1340 VectorBoxNode(Compile* C, Node* box, Node* val,
1341 const TypeInstPtr* box_type, const TypeVect* vt)
1342 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) {
1343 init_flags(Flag_is_macro);
1344 C->add_macro_node(this);
1345 }
1346
1347 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; };
1348 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; };
1349
1350 virtual int Opcode() const;
1351 virtual const Type *bottom_type() const { return _box_type; /* TypeInstPtr::BOTTOM? */ }
1352 virtual uint ideal_reg() const { return box_type()->ideal_reg(); }
1353 virtual uint size_of() const { return sizeof(*this); }
1354
1355 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type);
1356 };
1357
1358 class VectorBoxAllocateNode : public CallStaticJavaNode {
1359 public:
1360 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type)
1361 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) {
1362 init_flags(Flag_is_macro);
1363 C->add_macro_node(this);
1364 }
1365
1366 virtual int Opcode() const;
1367 #ifndef PRODUCT
1368 virtual void dump_spec(outputStream *st) const;
1369 #endif // PRODUCT
1370 };
1371
1372 class VectorUnboxNode : public VectorNode {
1373 private:
1374 bool _shuffle_to_vector;
1375 protected:
1376 uint size_of() const { return sizeof(*this); }
1377 public:
1378 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem, bool shuffle_to_vector)
1379 : VectorNode(mem, obj, vec_type) {
1380 _shuffle_to_vector = shuffle_to_vector;
1381 init_flags(Flag_is_macro);
1382 C->add_macro_node(this);
1383 }
1384
1385 virtual int Opcode() const;
1386 Node* obj() const { return in(2); }
1387 Node* mem() const { return in(1); }
1388 virtual Node *Identity(PhaseGVN *phase);
1389 bool is_shuffle_to_vector() { return _shuffle_to_vector; }
1390 };
1391
1392 #endif // SHARE_OPTO_VECTORNODE_HPP
|
62
63 const TypeVect* vect_type() const { return type()->is_vect(); }
64 uint length() const { return vect_type()->length(); } // Vector length
65 uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
66
67 virtual int Opcode() const;
68
69 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
70
71 static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
72 static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt);
73 static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
74 static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt);
75 static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
76 static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt);
77
78 static int opcode(int opc, BasicType bt);
79 static int replicate_opcode(BasicType bt);
80 static bool implemented(int opc, uint vlen, BasicType bt);
81 static bool is_shift(Node* n);
82 static bool is_vshift_cnt(Node* n);
83 static bool is_type_transition_short_to_int(Node* n);
84 static bool is_type_transition_to_int(Node* n);
85 static bool is_muladds2i(Node* n);
86 static bool is_roundopD(Node * n);
87 static bool is_invariant_vector(Node* n);
88 static bool is_all_ones_vector(Node* n);
89 static bool is_vector_bitwise_not_pattern(Node* n);
90
91 // [Start, end) half-open range defining which operands are vectors
92 static void vector_operands(Node* n, uint* start, uint* end);
93
94 static bool is_vector_shift(int opc);
95 static bool is_vector_shift_count(int opc);
96
97 static bool is_vector_shift(Node* n) {
98 return is_vector_shift(n->Opcode());
99 }
100 static bool is_vector_shift_count(Node* n) {
101 return is_vector_shift_count(n->Opcode());
162 static int opcode(int opc, BasicType bt);
163 static bool implemented(int opc, uint vlen, BasicType bt);
164 static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt);
165
166 virtual const Type* bottom_type() const {
167 BasicType vbt = in(1)->bottom_type()->basic_type();
168 return Type::get_const_basic_type(vbt);
169 }
170
171 virtual uint ideal_reg() const {
172 return bottom_type()->ideal_reg();
173 }
174 };
175
176 //------------------------------AddReductionVINode--------------------------------------
177 // Vector add byte, short and int as a reduction
178 class AddReductionVINode : public ReductionNode {
179 public:
180 AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
181 virtual int Opcode() const;
182 };
183
184 //------------------------------AddReductionVLNode--------------------------------------
185 // Vector add long as a reduction
186 class AddReductionVLNode : public ReductionNode {
187 public:
188 AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
189 virtual int Opcode() const;
190 };
191
192 //------------------------------AddReductionVFNode--------------------------------------
193 // Vector add float as a reduction
194 class AddReductionVFNode : public ReductionNode {
195 public:
196 AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
197 virtual int Opcode() const;
198 };
199
200 //------------------------------AddReductionVDNode--------------------------------------
201 // Vector add double as a reduction
202 class AddReductionVDNode : public ReductionNode {
203 public:
204 AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
205 virtual int Opcode() const;
206 };
207
208 //------------------------------SubVBNode--------------------------------------
209 // Vector subtract byte
210 class SubVBNode : public VectorNode {
211 public:
212 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
213 virtual int Opcode() const;
214 };
215
216 //------------------------------SubVSNode--------------------------------------
217 // Vector subtract short
218 class SubVSNode : public VectorNode {
219 public:
220 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
221 virtual int Opcode() const;
222 };
223
224 //------------------------------SubVINode--------------------------------------
225 // Vector subtract int
330 class CMoveVFNode : public VectorNode {
331 public:
332 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
333 virtual int Opcode() const;
334 };
335
336 //------------------------------CMoveVDNode--------------------------------------
337 // Vector double conditional move
338 class CMoveVDNode : public VectorNode {
339 public:
340 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
341 virtual int Opcode() const;
342 };
343
344 //------------------------------MulReductionVINode--------------------------------------
345 // Vector multiply byte, short and int as a reduction
346 class MulReductionVINode : public ReductionNode {
347 public:
348 MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
349 virtual int Opcode() const;
350 };
351
352 //------------------------------MulReductionVLNode--------------------------------------
353 // Vector multiply int as a reduction
354 class MulReductionVLNode : public ReductionNode {
355 public:
356 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
357 virtual int Opcode() const;
358 };
359
360 //------------------------------MulReductionVFNode--------------------------------------
361 // Vector multiply float as a reduction
362 class MulReductionVFNode : public ReductionNode {
363 public:
364 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
365 virtual int Opcode() const;
366 };
367
368 //------------------------------MulReductionVDNode--------------------------------------
369 // Vector multiply double as a reduction
370 class MulReductionVDNode : public ReductionNode {
371 public:
372 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
373 virtual int Opcode() const;
374 };
375
376 //------------------------------DivVFNode--------------------------------------
377 // Vector divide float
378 class DivVFNode : public VectorNode {
379 public:
380 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
381 virtual int Opcode() const;
382 };
383
384 //------------------------------DivVDNode--------------------------------------
385 // Vector Divide double
386 class DivVDNode : public VectorNode {
387 public:
388 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
389 virtual int Opcode() const;
390 };
391
392 //------------------------------AbsVBNode--------------------------------------
393 // Vector Abs byte
399
400 //------------------------------AbsVSNode--------------------------------------
401 // Vector Abs short
402 class AbsVSNode : public VectorNode {
403 public:
404 AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
405 virtual int Opcode() const;
406 };
407
408 //------------------------------MinVNode--------------------------------------
409 // Vector Min
410 class MinVNode : public VectorNode {
411 public:
412 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
413 virtual int Opcode() const;
414 };
415
416 //------------------------------MaxVNode--------------------------------------
417 // Vector Max
418 class MaxVNode : public VectorNode {
419 public:
420 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
421 virtual int Opcode() const;
422 };
423
424 //------------------------------AbsVINode--------------------------------------
425 // Vector Abs int
426 class AbsVINode : public VectorNode {
427 public:
428 AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
429 virtual int Opcode() const;
430 };
431
432 //------------------------------AbsVLNode--------------------------------------
433 // Vector Abs long
434 class AbsVLNode : public VectorNode {
435 public:
436 AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
437 virtual int Opcode() const;
438 };
439
440 //------------------------------AbsVFNode--------------------------------------
441 // Vector Abs float
442 class AbsVFNode : public VectorNode {
443 public:
444 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
445 virtual int Opcode() const;
446 };
447
448 //------------------------------AbsVDNode--------------------------------------
449 // Vector Abs double
450 class AbsVDNode : public VectorNode {
451 public:
452 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
453 virtual int Opcode() const;
454 };
455
456 //------------------------------NegVINode--------------------------------------
457 // Vector Neg int
458 class NegVINode : public VectorNode {
459 public:
460 NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
461 virtual int Opcode() const;
462 };
463
464 //------------------------------NegVFNode--------------------------------------
465 // Vector Neg float
466 class NegVFNode : public VectorNode {
467 public:
468 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
469 virtual int Opcode() const;
470 };
471
472 //------------------------------NegVDNode--------------------------------------
473 // Vector Neg double
474 class NegVDNode : public VectorNode {
475 public:
476 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
477 virtual int Opcode() const;
478 };
479
491 public:
492 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
493 virtual int Opcode() const;
494 };
495 //------------------------------RoundDoubleVNode--------------------------------
496 // Vector round double
497 class RoundDoubleModeVNode : public VectorNode {
498 public:
499 RoundDoubleModeVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
500 virtual int Opcode() const;
501 };
502
503 //------------------------------SqrtVDNode--------------------------------------
504 // Vector Sqrt double
505 class SqrtVDNode : public VectorNode {
506 public:
507 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
508 virtual int Opcode() const;
509 };
510
511 //------------------------------LShiftVBNode-----------------------------------
512 // Vector left shift bytes
513 class LShiftVBNode : public VectorNode {
514 public:
515 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
516 virtual int Opcode() const;
517 };
518
519 //------------------------------LShiftVSNode-----------------------------------
520 // Vector left shift shorts
521 class LShiftVSNode : public VectorNode {
522 public:
523 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
524 virtual int Opcode() const;
525 };
526
527 //------------------------------LShiftVINode-----------------------------------
528 // Vector left shift ints
529 class LShiftVINode : public VectorNode {
530 public:
603 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
604 virtual int Opcode() const;
605 };
606
607 //------------------------------LShiftCntVNode---------------------------------
608 // Vector left shift count
609 class LShiftCntVNode : public VectorNode {
610 public:
611 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
612 virtual int Opcode() const;
613 };
614
615 //------------------------------RShiftCntVNode---------------------------------
616 // Vector right shift count
617 class RShiftCntVNode : public VectorNode {
618 public:
619 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
620 virtual int Opcode() const;
621 };
622
623 //------------------------------AndVNode---------------------------------------
624 // Vector and integer
625 class AndVNode : public VectorNode {
626 public:
627 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
628 virtual int Opcode() const;
629 };
630
631 //------------------------------AndReductionVNode--------------------------------------
632 // Vector and byte, short, int, long as a reduction
633 class AndReductionVNode : public ReductionNode {
634 public:
635 AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
636 virtual int Opcode() const;
637 };
638
639 //------------------------------OrVNode---------------------------------------
640 // Vector or byte, short, int, long as a reduction
641 class OrVNode : public VectorNode {
642 public:
643 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
644 virtual int Opcode() const;
645 };
646
647 //------------------------------OrReductionVNode--------------------------------------
648 // Vector xor byte, short, int, long as a reduction
649 class OrReductionVNode : public ReductionNode {
650 public:
651 OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
652 virtual int Opcode() const;
653 };
654
655 //------------------------------XorReductionVNode--------------------------------------
656 // Vector and int, long as a reduction
657 class XorReductionVNode : public ReductionNode {
658 public:
659 XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
660 virtual int Opcode() const;
661 };
662
663 //------------------------------XorVNode---------------------------------------
664 // Vector xor integer
665 class XorVNode : public VectorNode {
666 public:
667 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
668 virtual int Opcode() const;
669 };
670
671 //------------------------------MinReductionVNode--------------------------------------
672 // Vector min byte, short, int, long, float, double as a reduction
673 class MinReductionVNode : public ReductionNode {
674 public:
675 MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
676 virtual int Opcode() const;
677 };
678
1032 class MacroLogicVNode : public VectorNode {
1033 private:
1034 MacroLogicVNode(Node* in1, Node* in2, Node* in3, Node* fn, const TypeVect* vt)
1035 : VectorNode(in1, in2, in3, fn, vt) {}
1036
1037 public:
1038 virtual int Opcode() const;
1039
1040 static MacroLogicVNode* make(PhaseGVN& igvn, Node* in1, Node* in2, Node* in3, uint truth_table, const TypeVect* vt);
1041 };
1042
1043 class VectorMaskCmpNode : public VectorNode {
1044 private:
1045 BoolTest::mask _predicate;
1046
1047 protected:
1048 uint size_of() const { return sizeof(*this); }
1049
1050 public:
1051 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, ConINode* predicate_node, const TypeVect* vt) :
1052 VectorNode(in1, in2, predicate_node, vt),
1053 _predicate(predicate) {
1054 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1055 "VectorMaskCmp inputs must have same type for elements");
1056 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1057 "VectorMaskCmp inputs must have same number of elements");
1058 init_class_id(Class_VectorMaskCmp);
1059 }
1060
1061 virtual int Opcode() const;
1062 virtual uint hash() const { return VectorNode::hash() + _predicate; }
1063 virtual bool cmp( const Node &n ) const {
1064 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate;
1065 }
1066 BoolTest::mask get_predicate() { return _predicate; }
1067 #ifndef PRODUCT
1068 virtual void dump_spec(outputStream *st) const;
1069 #endif // !PRODUCT
1070 };
1071
1072 // Used to wrap other vector nodes in order to add masking functionality.
1073 class VectorMaskWrapperNode : public VectorNode {
1074 public:
1075 VectorMaskWrapperNode(Node* vector, Node* mask)
1076 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) {
1077 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask");
1078 }
1079
1080 virtual int Opcode() const;
1081 Node* vector_val() const { return in(1); }
1082 Node* vector_mask() const { return in(2); }
1083 };
1084
1085 class VectorTestNode : public Node {
1086 private:
1087 BoolTest::mask _predicate;
1088
1089 protected:
1090 uint size_of() const { return sizeof(*this); }
1091
1092 public:
1093 VectorTestNode( Node *in1, Node *in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) {
1094 assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector");
1095 assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector");
1096 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1097 "same type elements are needed");
1098 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1099 "same number of elements is needed");
1100 }
1101 virtual int Opcode() const;
1102 virtual uint hash() const { return Node::hash() + _predicate; }
1103 virtual bool cmp( const Node &n ) const {
1104 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate;
1105 }
1106 virtual const Type *bottom_type() const { return TypeInt::BOOL; }
1107 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest
1108 // in middle-end, we make it boolean result directly.
1109 BoolTest::mask get_predicate() const { return _predicate; }
1110 };
1111
1112 class VectorBlendNode : public VectorNode {
1113 public:
1114 VectorBlendNode(Node* vec1, Node* vec2, Node* mask)
1115 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) {
1116 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1117 }
1118
1119 virtual int Opcode() const;
1120 Node* vec1() const { return in(1); }
1121 Node* vec2() const { return in(2); }
1122 Node* vec_mask() const { return in(3); }
1123 };
1124
1125 class VectorRearrangeNode : public VectorNode {
1126 public:
1127 VectorRearrangeNode(Node* vec1, Node* shuffle)
1128 : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) {
1129 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1130 }
1131
1132 virtual int Opcode() const;
1133 Node* vec1() const { return in(1); }
1134 Node* vec_shuffle() const { return in(2); }
1135 };
1136
1137
1138 class VectorLoadMaskNode : public VectorNode {
1139 public:
1140 VectorLoadMaskNode(Node* in, const TypeVect* vt)
1141 : VectorNode(in, vt) {
1142 assert(in->is_LoadVector(), "expected load vector");
1143 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean");
1144 }
1145
1146 virtual int Opcode() const;
1147 };
1148
1149 class VectorLoadShuffleNode : public VectorNode {
1150 public:
1151 VectorLoadShuffleNode(Node* in, const TypeVect* vt)
1152 : VectorNode(in, vt) {
1153 assert(in->is_LoadVector(), "expected load vector");
1154 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BYTE, "must be BYTE");
1155 }
1156
1157 int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); }
1158 virtual int Opcode() const;
1159 };
1160
1161 class VectorStoreMaskNode : public VectorNode {
1162 protected:
1163 VectorStoreMaskNode(Node* in1, ConINode* in2, const TypeVect* vt)
1164 : VectorNode(in1, in2, vt) { }
1165
1166 public:
1167 virtual int Opcode() const;
1168
1169 static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem);
1170 };
1171
1172 // This is intended for use as a simple reinterpret node that has no cast.
1173 class VectorReinterpretNode : public VectorNode {
1174 private:
1175 const TypeVect* _src_vt;
1176 protected:
1177 uint size_of() const { return sizeof(*this); }
1178 public:
1179 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt)
1180 : VectorNode(in, dst_vt), _src_vt(src_vt) { }
1181
1182 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); }
1183 virtual bool cmp( const Node &n ) const {
1184 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt);
1185 }
1186 virtual Node *Identity(PhaseGVN *phase);
1187
1188 virtual int Opcode() const;
1189 };
1190
1191 class VectorCastNode : public VectorNode {
1192 public:
1193 VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
1194 virtual int Opcode() const;
1195
1196 static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen);
1197 static int opcode(BasicType bt);
1198 static bool implemented(BasicType bt, uint vlen);
1199 };
1200
1201 class VectorCastB2XNode : public VectorCastNode {
1202 public:
1203 VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1204 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte");
1205 }
1206 virtual int Opcode() const;
1207 };
1208
1209 class VectorCastS2XNode : public VectorCastNode {
1210 public:
1211 VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1212 assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short");
1213 }
1214 virtual int Opcode() const;
1215 };
1216
1217 class VectorCastI2XNode : public VectorCastNode {
1218 public:
1219 VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1220 assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int");
1221 }
1222 virtual int Opcode() const;
1223 };
1224
1225 class VectorCastL2XNode : public VectorCastNode {
1226 public:
1227 VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1228 assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long");
1229 }
1230 virtual int Opcode() const;
1231 };
1232
1233 class VectorCastF2XNode : public VectorCastNode {
1234 public:
1235 VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1236 assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float");
1237 }
1238 virtual int Opcode() const;
1239 };
1240
1241 class VectorCastD2XNode : public VectorCastNode {
1242 public:
1243 VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1244 assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double");
1245 }
1246 virtual int Opcode() const;
1247 };
1248
1249 class VectorInsertNode : public VectorNode {
1250 public:
1251 VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) {
1252 assert(pos->get_int() >= 0, "positive constants");
1253 assert(pos->get_int() < (int)vt->length(), "index must be less than vector length");
1254 assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type");
1255 }
1256 virtual int Opcode() const;
1257 uint pos() const { return in(3)->get_int(); }
1258
1259 static Node* make(Node* vec, Node* new_val, int position);
1260 };
1261
1262 class VectorBoxNode : public Node {
1263 private:
1264 const TypeInstPtr* const _box_type;
1265 const TypeVect* const _vec_type;
1266 public:
1267 enum {
1268 Box = 1,
1269 Value = 2
1270 };
1271 VectorBoxNode(Compile* C, Node* box, Node* val,
1272 const TypeInstPtr* box_type, const TypeVect* vt)
1273 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) {
1274 init_flags(Flag_is_macro);
1275 C->add_macro_node(this);
1276 }
1277
1278 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; };
1279 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; };
1280
1281 virtual int Opcode() const;
1282 virtual const Type* bottom_type() const { return _box_type; }
1283 virtual uint ideal_reg() const { return box_type()->ideal_reg(); }
1284 virtual uint size_of() const { return sizeof(*this); }
1285
1286 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type);
1287 };
1288
1289 class VectorBoxAllocateNode : public CallStaticJavaNode {
1290 public:
1291 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type)
1292 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) {
1293 init_flags(Flag_is_macro);
1294 C->add_macro_node(this);
1295 }
1296
1297 virtual int Opcode() const;
1298 #ifndef PRODUCT
1299 virtual void dump_spec(outputStream *st) const;
1300 #endif // !PRODUCT
1301 };
1302
1303 class VectorUnboxNode : public VectorNode {
1304 private:
1305 bool _shuffle_to_vector;
1306 protected:
1307 uint size_of() const { return sizeof(*this); }
1308 public:
1309 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem, bool shuffle_to_vector)
1310 : VectorNode(mem, obj, vec_type) {
1311 _shuffle_to_vector = shuffle_to_vector;
1312 init_flags(Flag_is_macro);
1313 C->add_macro_node(this);
1314 }
1315
1316 virtual int Opcode() const;
1317 Node* obj() const { return in(2); }
1318 Node* mem() const { return in(1); }
1319 virtual Node *Identity(PhaseGVN *phase);
1320 bool is_shuffle_to_vector() { return _shuffle_to_vector; }
1321 };
1322
1323 #endif // SHARE_OPTO_VECTORNODE_HPP
|