1 /* 2 * Copyright (c) 2007, 2019, 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 #ifndef SHARE_OPTO_VECTORNODE_HPP 25 #define SHARE_OPTO_VECTORNODE_HPP 26 27 #include "opto/callnode.hpp" 28 #include "opto/matcher.hpp" 29 #include "opto/memnode.hpp" 30 #include "opto/node.hpp" 31 #include "opto/opcodes.hpp" 32 33 //------------------------------VectorNode------------------------------------- 34 // Vector Operation 35 class VectorNode : public TypeNode { 36 public: 37 VectorNode(Node * n1,const TypeVect * vt)38 VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) { 39 init_class_id(Class_Vector); 40 init_req(1, n1); 41 } VectorNode(Node * n1,Node * n2,const TypeVect * vt)42 VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) { 43 init_class_id(Class_Vector); 44 init_req(1, n1); 45 init_req(2, n2); 46 } 47 VectorNode(Node * n1,Node * n2,Node * n3,const TypeVect * vt)48 VectorNode(Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 4) { 49 init_class_id(Class_Vector); 50 init_req(1, n1); 51 init_req(2, n2); 52 init_req(3, n3); 53 } 54 VectorNode(Node * n0,Node * n1,Node * n2,Node * n3,const TypeVect * vt)55 VectorNode(Node *n0, Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 5) { 56 init_class_id(Class_Vector); 57 init_req(1, n0); 58 init_req(2, n1); 59 init_req(3, n2); 60 init_req(4, n3); 61 } 62 vect_type() const63 const TypeVect* vect_type() const { return type()->is_vect(); } length() const64 uint length() const { return vect_type()->length(); } // Vector length length_in_bytes() const65 uint length_in_bytes() const { return vect_type()->length_in_bytes(); } 66 67 virtual int Opcode() const; 68 ideal_reg() const69 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 bool is_shift_opcode(int opc); 79 80 static int opcode(int opc, BasicType bt); 81 static int replicate_opcode(BasicType bt); 82 static bool implemented(int opc, uint vlen, BasicType bt); 83 static bool is_shift(Node* n); 84 static bool is_vshift_cnt(Node* n); 85 static bool is_type_transition_short_to_int(Node* n); 86 static bool is_type_transition_to_int(Node* n); 87 static bool is_muladds2i(Node* n); 88 static bool is_roundopD(Node* n); 89 static bool is_scalar_rotate(Node* n); 90 static bool is_vector_rotate_supported(int vopc, uint vlen, BasicType bt); 91 static bool is_invariant_vector(Node* n); 92 static bool is_all_ones_vector(Node* n); 93 static bool is_vector_bitwise_not_pattern(Node* n); 94 static Node* degenerate_vector_rotate(Node* n1, Node* n2, bool is_rotate_left, int vlen, 95 BasicType bt, PhaseGVN* phase); 96 97 // [Start, end) half-open range defining which operands are vectors 98 static void vector_operands(Node* n, uint* start, uint* end); 99 100 static bool is_vector_shift(int opc); 101 static bool is_vector_shift_count(int opc); 102 is_vector_shift(Node * n)103 static bool is_vector_shift(Node* n) { 104 return is_vector_shift(n->Opcode()); 105 } is_vector_shift_count(Node * n)106 static bool is_vector_shift_count(Node* n) { 107 return is_vector_shift_count(n->Opcode()); 108 } 109 }; 110 111 //===========================Vector=ALU=Operations============================= 112 113 //------------------------------AddVBNode-------------------------------------- 114 // Vector add byte 115 class AddVBNode : public VectorNode { 116 public: AddVBNode(Node * in1,Node * in2,const TypeVect * vt)117 AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 118 virtual int Opcode() const; 119 }; 120 121 //------------------------------AddVSNode-------------------------------------- 122 // Vector add char/short 123 class AddVSNode : public VectorNode { 124 public: AddVSNode(Node * in1,Node * in2,const TypeVect * vt)125 AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 126 virtual int Opcode() const; 127 }; 128 129 //------------------------------AddVINode-------------------------------------- 130 // Vector add int 131 class AddVINode : public VectorNode { 132 public: AddVINode(Node * in1,Node * in2,const TypeVect * vt)133 AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 134 virtual int Opcode() const; 135 }; 136 137 //------------------------------AddVLNode-------------------------------------- 138 // Vector add long 139 class AddVLNode : public VectorNode { 140 public: AddVLNode(Node * in1,Node * in2,const TypeVect * vt)141 AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 142 virtual int Opcode() const; 143 }; 144 145 //------------------------------AddVFNode-------------------------------------- 146 // Vector add float 147 class AddVFNode : public VectorNode { 148 public: AddVFNode(Node * in1,Node * in2,const TypeVect * vt)149 AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 150 virtual int Opcode() const; 151 }; 152 153 //------------------------------AddVDNode-------------------------------------- 154 // Vector add double 155 class AddVDNode : public VectorNode { 156 public: AddVDNode(Node * in1,Node * in2,const TypeVect * vt)157 AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 158 virtual int Opcode() const; 159 }; 160 161 //------------------------------ReductionNode------------------------------------ 162 // Perform reduction of a vector 163 class ReductionNode : public Node { 164 public: ReductionNode(Node * ctrl,Node * in1,Node * in2)165 ReductionNode(Node *ctrl, Node* in1, Node* in2) : Node(ctrl, in1, in2) {} 166 167 static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt); 168 static int opcode(int opc, BasicType bt); 169 static bool implemented(int opc, uint vlen, BasicType bt); 170 static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt); 171 bottom_type() const172 virtual const Type* bottom_type() const { 173 BasicType vbt = in(1)->bottom_type()->basic_type(); 174 return Type::get_const_basic_type(vbt); 175 } 176 ideal_reg() const177 virtual uint ideal_reg() const { 178 return bottom_type()->ideal_reg(); 179 } 180 }; 181 182 //------------------------------AddReductionVINode-------------------------------------- 183 // Vector add byte, short and int as a reduction 184 class AddReductionVINode : public ReductionNode { 185 public: AddReductionVINode(Node * ctrl,Node * in1,Node * in2)186 AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 187 virtual int Opcode() const; 188 }; 189 190 //------------------------------AddReductionVLNode-------------------------------------- 191 // Vector add long as a reduction 192 class AddReductionVLNode : public ReductionNode { 193 public: AddReductionVLNode(Node * ctrl,Node * in1,Node * in2)194 AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 195 virtual int Opcode() const; 196 }; 197 198 //------------------------------AddReductionVFNode-------------------------------------- 199 // Vector add float as a reduction 200 class AddReductionVFNode : public ReductionNode { 201 public: AddReductionVFNode(Node * ctrl,Node * in1,Node * in2)202 AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 203 virtual int Opcode() const; 204 }; 205 206 //------------------------------AddReductionVDNode-------------------------------------- 207 // Vector add double as a reduction 208 class AddReductionVDNode : public ReductionNode { 209 public: AddReductionVDNode(Node * ctrl,Node * in1,Node * in2)210 AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 211 virtual int Opcode() const; 212 }; 213 214 //------------------------------SubVBNode-------------------------------------- 215 // Vector subtract byte 216 class SubVBNode : public VectorNode { 217 public: SubVBNode(Node * in1,Node * in2,const TypeVect * vt)218 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 219 virtual int Opcode() const; 220 }; 221 222 //------------------------------SubVSNode-------------------------------------- 223 // Vector subtract short 224 class SubVSNode : public VectorNode { 225 public: SubVSNode(Node * in1,Node * in2,const TypeVect * vt)226 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 227 virtual int Opcode() const; 228 }; 229 230 //------------------------------SubVINode-------------------------------------- 231 // Vector subtract int 232 class SubVINode : public VectorNode { 233 public: SubVINode(Node * in1,Node * in2,const TypeVect * vt)234 SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 235 virtual int Opcode() const; 236 }; 237 238 //------------------------------SubVLNode-------------------------------------- 239 // Vector subtract long 240 class SubVLNode : public VectorNode { 241 public: SubVLNode(Node * in1,Node * in2,const TypeVect * vt)242 SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 243 virtual int Opcode() const; 244 }; 245 246 //------------------------------SubVFNode-------------------------------------- 247 // Vector subtract float 248 class SubVFNode : public VectorNode { 249 public: SubVFNode(Node * in1,Node * in2,const TypeVect * vt)250 SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 251 virtual int Opcode() const; 252 }; 253 254 //------------------------------SubVDNode-------------------------------------- 255 // Vector subtract double 256 class SubVDNode : public VectorNode { 257 public: SubVDNode(Node * in1,Node * in2,const TypeVect * vt)258 SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 259 virtual int Opcode() const; 260 }; 261 262 //------------------------------MulVBNode-------------------------------------- 263 // Vector multiply byte 264 class MulVBNode : public VectorNode { 265 public: MulVBNode(Node * in1,Node * in2,const TypeVect * vt)266 MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 267 virtual int Opcode() const; 268 }; 269 270 //------------------------------MulVSNode-------------------------------------- 271 // Vector multiply short 272 class MulVSNode : public VectorNode { 273 public: MulVSNode(Node * in1,Node * in2,const TypeVect * vt)274 MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 275 virtual int Opcode() const; 276 }; 277 278 //------------------------------MulVINode-------------------------------------- 279 // Vector multiply int 280 class MulVINode : public VectorNode { 281 public: MulVINode(Node * in1,Node * in2,const TypeVect * vt)282 MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 283 virtual int Opcode() const; 284 }; 285 286 //------------------------------MulVLNode-------------------------------------- 287 // Vector multiply long 288 class MulVLNode : public VectorNode { 289 public: MulVLNode(Node * in1,Node * in2,const TypeVect * vt)290 MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 291 virtual int Opcode() const; 292 }; 293 294 //------------------------------MulVFNode-------------------------------------- 295 // Vector multiply float 296 class MulVFNode : public VectorNode { 297 public: MulVFNode(Node * in1,Node * in2,const TypeVect * vt)298 MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 299 virtual int Opcode() const; 300 }; 301 302 //------------------------------MulVDNode-------------------------------------- 303 // Vector multiply double 304 class MulVDNode : public VectorNode { 305 public: MulVDNode(Node * in1,Node * in2,const TypeVect * vt)306 MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 307 virtual int Opcode() const; 308 }; 309 310 //------------------------------MulAddVS2VINode-------------------------------- 311 // Vector multiply shorts to int and add adjacent ints. 312 class MulAddVS2VINode : public VectorNode { 313 public: MulAddVS2VINode(Node * in1,Node * in2,const TypeVect * vt)314 MulAddVS2VINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 315 virtual int Opcode() const; 316 }; 317 318 //------------------------------FmaVDNode-------------------------------------- 319 // Vector multiply double 320 class FmaVDNode : public VectorNode { 321 public: FmaVDNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)322 FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 323 virtual int Opcode() const; 324 }; 325 326 //------------------------------FmaVFNode-------------------------------------- 327 // Vector multiply float 328 class FmaVFNode : public VectorNode { 329 public: FmaVFNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)330 FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 331 virtual int Opcode() const; 332 }; 333 334 //------------------------------CMoveVFNode-------------------------------------- 335 // Vector float conditional move 336 class CMoveVFNode : public VectorNode { 337 public: CMoveVFNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)338 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 339 virtual int Opcode() const; 340 }; 341 342 //------------------------------CMoveVDNode-------------------------------------- 343 // Vector double conditional move 344 class CMoveVDNode : public VectorNode { 345 public: CMoveVDNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)346 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 347 virtual int Opcode() const; 348 }; 349 350 //------------------------------MulReductionVINode-------------------------------------- 351 // Vector multiply byte, short and int as a reduction 352 class MulReductionVINode : public ReductionNode { 353 public: MulReductionVINode(Node * ctrl,Node * in1,Node * in2)354 MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 355 virtual int Opcode() const; 356 }; 357 358 //------------------------------MulReductionVLNode-------------------------------------- 359 // Vector multiply int as a reduction 360 class MulReductionVLNode : public ReductionNode { 361 public: MulReductionVLNode(Node * ctrl,Node * in1,Node * in2)362 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 363 virtual int Opcode() const; 364 }; 365 366 //------------------------------MulReductionVFNode-------------------------------------- 367 // Vector multiply float as a reduction 368 class MulReductionVFNode : public ReductionNode { 369 public: MulReductionVFNode(Node * ctrl,Node * in1,Node * in2)370 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 371 virtual int Opcode() const; 372 }; 373 374 //------------------------------MulReductionVDNode-------------------------------------- 375 // Vector multiply double as a reduction 376 class MulReductionVDNode : public ReductionNode { 377 public: MulReductionVDNode(Node * ctrl,Node * in1,Node * in2)378 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 379 virtual int Opcode() const; 380 }; 381 382 //------------------------------DivVFNode-------------------------------------- 383 // Vector divide float 384 class DivVFNode : public VectorNode { 385 public: DivVFNode(Node * in1,Node * in2,const TypeVect * vt)386 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 387 virtual int Opcode() const; 388 }; 389 390 //------------------------------DivVDNode-------------------------------------- 391 // Vector Divide double 392 class DivVDNode : public VectorNode { 393 public: DivVDNode(Node * in1,Node * in2,const TypeVect * vt)394 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 395 virtual int Opcode() const; 396 }; 397 398 //------------------------------AbsVBNode-------------------------------------- 399 // Vector Abs byte 400 class AbsVBNode : public VectorNode { 401 public: AbsVBNode(Node * in,const TypeVect * vt)402 AbsVBNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 403 virtual int Opcode() const; 404 }; 405 406 //------------------------------AbsVSNode-------------------------------------- 407 // Vector Abs short 408 class AbsVSNode : public VectorNode { 409 public: AbsVSNode(Node * in,const TypeVect * vt)410 AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 411 virtual int Opcode() const; 412 }; 413 414 //------------------------------MinVNode-------------------------------------- 415 // Vector Min 416 class MinVNode : public VectorNode { 417 public: MinVNode(Node * in1,Node * in2,const TypeVect * vt)418 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 419 virtual int Opcode() const; 420 }; 421 422 //------------------------------MaxVNode-------------------------------------- 423 // Vector Max 424 class MaxVNode : public VectorNode { 425 public: MaxVNode(Node * in1,Node * in2,const TypeVect * vt)426 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 427 virtual int Opcode() const; 428 }; 429 430 //------------------------------AbsVINode-------------------------------------- 431 // Vector Abs int 432 class AbsVINode : public VectorNode { 433 public: AbsVINode(Node * in,const TypeVect * vt)434 AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 435 virtual int Opcode() const; 436 }; 437 438 //------------------------------AbsVLNode-------------------------------------- 439 // Vector Abs long 440 class AbsVLNode : public VectorNode { 441 public: AbsVLNode(Node * in,const TypeVect * vt)442 AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 443 virtual int Opcode() const; 444 }; 445 446 //------------------------------AbsVFNode-------------------------------------- 447 // Vector Abs float 448 class AbsVFNode : public VectorNode { 449 public: AbsVFNode(Node * in,const TypeVect * vt)450 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 451 virtual int Opcode() const; 452 }; 453 454 //------------------------------AbsVDNode-------------------------------------- 455 // Vector Abs double 456 class AbsVDNode : public VectorNode { 457 public: AbsVDNode(Node * in,const TypeVect * vt)458 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 459 virtual int Opcode() const; 460 }; 461 462 //------------------------------NegVINode-------------------------------------- 463 // Vector Neg int 464 class NegVINode : public VectorNode { 465 public: NegVINode(Node * in,const TypeVect * vt)466 NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 467 virtual int Opcode() const; 468 }; 469 470 //------------------------------NegVFNode-------------------------------------- 471 // Vector Neg float 472 class NegVFNode : public VectorNode { 473 public: NegVFNode(Node * in,const TypeVect * vt)474 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 475 virtual int Opcode() const; 476 }; 477 478 //------------------------------NegVDNode-------------------------------------- 479 // Vector Neg double 480 class NegVDNode : public VectorNode { 481 public: NegVDNode(Node * in,const TypeVect * vt)482 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 483 virtual int Opcode() const; 484 }; 485 486 //------------------------------PopCountVINode--------------------------------- 487 // Vector popcount integer bits 488 class PopCountVINode : public VectorNode { 489 public: PopCountVINode(Node * in,const TypeVect * vt)490 PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 491 virtual int Opcode() const; 492 }; 493 494 //------------------------------SqrtVFNode-------------------------------------- 495 // Vector Sqrt float 496 class SqrtVFNode : public VectorNode { 497 public: SqrtVFNode(Node * in,const TypeVect * vt)498 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 499 virtual int Opcode() const; 500 }; 501 //------------------------------RoundDoubleVNode-------------------------------- 502 // Vector round double 503 class RoundDoubleModeVNode : public VectorNode { 504 public: RoundDoubleModeVNode(Node * in1,Node * in2,const TypeVect * vt)505 RoundDoubleModeVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 506 virtual int Opcode() const; 507 }; 508 509 //------------------------------SqrtVDNode-------------------------------------- 510 // Vector Sqrt double 511 class SqrtVDNode : public VectorNode { 512 public: SqrtVDNode(Node * in,const TypeVect * vt)513 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 514 virtual int Opcode() const; 515 }; 516 517 //------------------------------LShiftVBNode----------------------------------- 518 // Vector left shift bytes 519 class LShiftVBNode : public VectorNode { 520 public: LShiftVBNode(Node * in1,Node * in2,const TypeVect * vt)521 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 522 virtual int Opcode() const; 523 }; 524 525 //------------------------------LShiftVSNode----------------------------------- 526 // Vector left shift shorts 527 class LShiftVSNode : public VectorNode { 528 public: LShiftVSNode(Node * in1,Node * in2,const TypeVect * vt)529 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 530 virtual int Opcode() const; 531 }; 532 533 //------------------------------LShiftVINode----------------------------------- 534 // Vector left shift ints 535 class LShiftVINode : public VectorNode { 536 public: LShiftVINode(Node * in1,Node * in2,const TypeVect * vt)537 LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 538 virtual int Opcode() const; 539 }; 540 541 //------------------------------LShiftVLNode----------------------------------- 542 // Vector left shift longs 543 class LShiftVLNode : public VectorNode { 544 public: LShiftVLNode(Node * in1,Node * in2,const TypeVect * vt)545 LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 546 virtual int Opcode() const; 547 }; 548 549 //------------------------------RShiftVBNode----------------------------------- 550 // Vector right arithmetic (signed) shift bytes 551 class RShiftVBNode : public VectorNode { 552 public: RShiftVBNode(Node * in1,Node * in2,const TypeVect * vt)553 RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 554 virtual int Opcode() const; 555 }; 556 557 //------------------------------RShiftVSNode----------------------------------- 558 // Vector right arithmetic (signed) shift shorts 559 class RShiftVSNode : public VectorNode { 560 public: RShiftVSNode(Node * in1,Node * in2,const TypeVect * vt)561 RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 562 virtual int Opcode() const; 563 }; 564 565 //------------------------------RShiftVINode----------------------------------- 566 // Vector right arithmetic (signed) shift ints 567 class RShiftVINode : public VectorNode { 568 public: RShiftVINode(Node * in1,Node * in2,const TypeVect * vt)569 RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 570 virtual int Opcode() const; 571 }; 572 573 //------------------------------RShiftVLNode----------------------------------- 574 // Vector right arithmetic (signed) shift longs 575 class RShiftVLNode : public VectorNode { 576 public: RShiftVLNode(Node * in1,Node * in2,const TypeVect * vt)577 RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 578 virtual int Opcode() const; 579 }; 580 581 //------------------------------URShiftVBNode---------------------------------- 582 // Vector right logical (unsigned) shift bytes 583 class URShiftVBNode : public VectorNode { 584 public: URShiftVBNode(Node * in1,Node * in2,const TypeVect * vt)585 URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 586 virtual int Opcode() const; 587 }; 588 589 //------------------------------URShiftVSNode---------------------------------- 590 // Vector right logical (unsigned) shift shorts 591 class URShiftVSNode : public VectorNode { 592 public: URShiftVSNode(Node * in1,Node * in2,const TypeVect * vt)593 URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 594 virtual int Opcode() const; 595 }; 596 597 //------------------------------URShiftVINode---------------------------------- 598 // Vector right logical (unsigned) shift ints 599 class URShiftVINode : public VectorNode { 600 public: URShiftVINode(Node * in1,Node * in2,const TypeVect * vt)601 URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 602 virtual int Opcode() const; 603 }; 604 605 //------------------------------URShiftVLNode---------------------------------- 606 // Vector right logical (unsigned) shift longs 607 class URShiftVLNode : public VectorNode { 608 public: URShiftVLNode(Node * in1,Node * in2,const TypeVect * vt)609 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 610 virtual int Opcode() const; 611 }; 612 613 //------------------------------LShiftCntVNode--------------------------------- 614 // Vector left shift count 615 class LShiftCntVNode : public VectorNode { 616 public: LShiftCntVNode(Node * cnt,const TypeVect * vt)617 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 618 virtual int Opcode() const; 619 }; 620 621 //------------------------------RShiftCntVNode--------------------------------- 622 // Vector right shift count 623 class RShiftCntVNode : public VectorNode { 624 public: RShiftCntVNode(Node * cnt,const TypeVect * vt)625 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 626 virtual int Opcode() const; 627 }; 628 629 //------------------------------AndVNode--------------------------------------- 630 // Vector and integer 631 class AndVNode : public VectorNode { 632 public: AndVNode(Node * in1,Node * in2,const TypeVect * vt)633 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 634 virtual int Opcode() const; 635 }; 636 637 //------------------------------AndReductionVNode-------------------------------------- 638 // Vector and byte, short, int, long as a reduction 639 class AndReductionVNode : public ReductionNode { 640 public: AndReductionVNode(Node * ctrl,Node * in1,Node * in2)641 AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 642 virtual int Opcode() const; 643 }; 644 645 //------------------------------OrVNode--------------------------------------- 646 // Vector or byte, short, int, long as a reduction 647 class OrVNode : public VectorNode { 648 public: OrVNode(Node * in1,Node * in2,const TypeVect * vt)649 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 650 virtual int Opcode() const; 651 }; 652 653 //------------------------------OrReductionVNode-------------------------------------- 654 // Vector xor byte, short, int, long as a reduction 655 class OrReductionVNode : public ReductionNode { 656 public: OrReductionVNode(Node * ctrl,Node * in1,Node * in2)657 OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 658 virtual int Opcode() const; 659 }; 660 661 //------------------------------XorReductionVNode-------------------------------------- 662 // Vector and int, long as a reduction 663 class XorReductionVNode : public ReductionNode { 664 public: XorReductionVNode(Node * ctrl,Node * in1,Node * in2)665 XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 666 virtual int Opcode() const; 667 }; 668 669 //------------------------------XorVNode--------------------------------------- 670 // Vector xor integer 671 class XorVNode : public VectorNode { 672 public: XorVNode(Node * in1,Node * in2,const TypeVect * vt)673 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 674 virtual int Opcode() const; 675 }; 676 677 //------------------------------MinReductionVNode-------------------------------------- 678 // Vector min byte, short, int, long, float, double as a reduction 679 class MinReductionVNode : public ReductionNode { 680 public: MinReductionVNode(Node * ctrl,Node * in1,Node * in2)681 MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 682 virtual int Opcode() const; 683 }; 684 685 //------------------------------MaxReductionVNode-------------------------------------- 686 // Vector min byte, short, int, long, float, double as a reduction 687 class MaxReductionVNode : public ReductionNode { 688 public: MaxReductionVNode(Node * ctrl,Node * in1,Node * in2)689 MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 690 virtual int Opcode() const; 691 }; 692 693 //================================= M E M O R Y =============================== 694 695 //------------------------------LoadVectorNode--------------------------------- 696 // Load Vector from memory 697 class LoadVectorNode : public LoadNode { 698 public: LoadVectorNode(Node * c,Node * mem,Node * adr,const TypePtr * at,const TypeVect * vt,ControlDependency control_dependency=LoadNode::DependsOnlyOnTest)699 LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest) 700 : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) { 701 init_class_id(Class_LoadVector); 702 set_mismatched_access(); 703 } 704 vect_type() const705 const TypeVect* vect_type() const { return type()->is_vect(); } length() const706 uint length() const { return vect_type()->length(); } // Vector length 707 708 virtual int Opcode() const; 709 ideal_reg() const710 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } memory_type() const711 virtual BasicType memory_type() const { return T_VOID; } memory_size() const712 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 713 store_Opcode() const714 virtual int store_Opcode() const { return Op_StoreVector; } 715 716 static LoadVectorNode* make(int opc, Node* ctl, Node* mem, 717 Node* adr, const TypePtr* atyp, 718 uint vlen, BasicType bt, 719 ControlDependency control_dependency = LoadNode::DependsOnlyOnTest); element_size(void)720 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 721 }; 722 723 //------------------------------LoadVectorGatherNode------------------------------ 724 // Load Vector from memory via index map 725 class LoadVectorGatherNode : public LoadVectorNode { 726 public: LoadVectorGatherNode(Node * c,Node * mem,Node * adr,const TypePtr * at,const TypeVect * vt,Node * indices)727 LoadVectorGatherNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, Node* indices) 728 : LoadVectorNode(c, mem, adr, at, vt) { 729 init_class_id(Class_LoadVectorGather); 730 assert(indices->bottom_type()->is_vect(), "indices must be in vector"); 731 add_req(indices); 732 assert(req() == MemNode::ValueIn + 1, "match_edge expects that last input is in MemNode::ValueIn"); 733 } 734 735 virtual int Opcode() const; match_edge(uint idx) const736 virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } 737 }; 738 739 //------------------------------StoreVectorNode-------------------------------- 740 // Store Vector to memory 741 class StoreVectorNode : public StoreNode { 742 public: StoreVectorNode(Node * c,Node * mem,Node * adr,const TypePtr * at,Node * val)743 StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val) 744 : StoreNode(c, mem, adr, at, val, MemNode::unordered) { 745 init_class_id(Class_StoreVector); 746 set_mismatched_access(); 747 } 748 vect_type() const749 const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); } length() const750 uint length() const { return vect_type()->length(); } // Vector length 751 752 virtual int Opcode() const; 753 ideal_reg() const754 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } memory_type() const755 virtual BasicType memory_type() const { return T_VOID; } memory_size() const756 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 757 758 static StoreVectorNode* make(int opc, Node* ctl, Node* mem, 759 Node* adr, const TypePtr* atyp, Node* val, 760 uint vlen); 761 element_size(void)762 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 763 }; 764 765 //------------------------------StoreVectorScatterNode------------------------------ 766 // Store Vector into memory via index map 767 768 class StoreVectorScatterNode : public StoreVectorNode { 769 public: StoreVectorScatterNode(Node * c,Node * mem,Node * adr,const TypePtr * at,Node * val,Node * indices)770 StoreVectorScatterNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val, Node* indices) 771 : StoreVectorNode(c, mem, adr, at, val) { 772 init_class_id(Class_StoreVectorScatter); 773 assert(indices->bottom_type()->is_vect(), "indices must be in vector"); 774 add_req(indices); 775 assert(req() == MemNode::ValueIn + 2, "match_edge expects that last input is in MemNode::ValueIn+1"); 776 } 777 virtual int Opcode() const; match_edge(uint idx) const778 virtual uint match_edge(uint idx) const { return idx == MemNode::Address || 779 idx == MemNode::ValueIn || 780 idx == MemNode::ValueIn + 1; } 781 }; 782 783 class StoreVectorMaskedNode : public StoreVectorNode { 784 public: StoreVectorMaskedNode(Node * c,Node * mem,Node * dst,Node * src,const TypePtr * at,Node * mask)785 StoreVectorMaskedNode(Node* c, Node* mem, Node* dst, Node* src, const TypePtr* at, Node* mask) 786 : StoreVectorNode(c, mem, dst, at, src) { 787 assert(mask->bottom_type()->is_long(), "sanity"); 788 init_class_id(Class_StoreVector); 789 set_mismatched_access(); 790 add_req(mask); 791 } 792 793 virtual int Opcode() const; 794 match_edge(uint idx) const795 virtual uint match_edge(uint idx) const { 796 return idx > 1; 797 } 798 Node* Ideal(PhaseGVN* phase, bool can_reshape); 799 }; 800 801 class LoadVectorMaskedNode : public LoadVectorNode { 802 public: LoadVectorMaskedNode(Node * c,Node * mem,Node * src,const TypePtr * at,const TypeVect * vt,Node * mask)803 LoadVectorMaskedNode(Node* c, Node* mem, Node* src, const TypePtr* at, const TypeVect* vt, Node* mask) 804 : LoadVectorNode(c, mem, src, at, vt) { 805 assert(mask->bottom_type()->is_long(), "sanity"); 806 init_class_id(Class_LoadVector); 807 set_mismatched_access(); 808 add_req(mask); 809 } 810 811 virtual int Opcode() const; 812 match_edge(uint idx) const813 virtual uint match_edge(uint idx) const { 814 return idx > 1; 815 } 816 Node* Ideal(PhaseGVN* phase, bool can_reshape); 817 }; 818 819 class VectorMaskGenNode : public TypeNode { 820 public: VectorMaskGenNode(Node * length,const Type * ty,const Type * ety)821 VectorMaskGenNode(Node* length, const Type* ty, const Type* ety): TypeNode(ty, 2), _elemType(ety) { 822 init_req(1, length); 823 } 824 825 virtual int Opcode() const; get_elem_type()826 const Type* get_elem_type() { return _elemType;} size_of() const827 virtual uint size_of() const { return sizeof(VectorMaskGenNode); } 828 829 private: 830 const Type* _elemType; 831 }; 832 833 //=========================Promote_Scalar_to_Vector============================ 834 835 //------------------------------ReplicateBNode--------------------------------- 836 // Replicate byte scalar to be vector 837 class ReplicateBNode : public VectorNode { 838 public: ReplicateBNode(Node * in1,const TypeVect * vt)839 ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 840 virtual int Opcode() const; 841 }; 842 843 //------------------------------ReplicateSNode--------------------------------- 844 // Replicate short scalar to be vector 845 class ReplicateSNode : public VectorNode { 846 public: ReplicateSNode(Node * in1,const TypeVect * vt)847 ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 848 virtual int Opcode() const; 849 }; 850 851 //------------------------------ReplicateINode--------------------------------- 852 // Replicate int scalar to be vector 853 class ReplicateINode : public VectorNode { 854 public: ReplicateINode(Node * in1,const TypeVect * vt)855 ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 856 virtual int Opcode() const; 857 }; 858 859 //------------------------------ReplicateLNode--------------------------------- 860 // Replicate long scalar to be vector 861 class ReplicateLNode : public VectorNode { 862 public: ReplicateLNode(Node * in1,const TypeVect * vt)863 ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 864 virtual int Opcode() const; 865 }; 866 867 //------------------------------ReplicateFNode--------------------------------- 868 // Replicate float scalar to be vector 869 class ReplicateFNode : public VectorNode { 870 public: ReplicateFNode(Node * in1,const TypeVect * vt)871 ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 872 virtual int Opcode() const; 873 }; 874 875 //------------------------------ReplicateDNode--------------------------------- 876 // Replicate double scalar to be vector 877 class ReplicateDNode : public VectorNode { 878 public: ReplicateDNode(Node * in1,const TypeVect * vt)879 ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 880 virtual int Opcode() const; 881 }; 882 883 //========================Pack_Scalars_into_a_Vector=========================== 884 885 //------------------------------PackNode--------------------------------------- 886 // Pack parent class (not for code generation). 887 class PackNode : public VectorNode { 888 public: PackNode(Node * in1,const TypeVect * vt)889 PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} PackNode(Node * in1,Node * n2,const TypeVect * vt)890 PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {} 891 virtual int Opcode() const; 892 add_opd(Node * n)893 void add_opd(Node* n) { 894 add_req(n); 895 } 896 897 // Create a binary tree form for Packs. [lo, hi) (half-open) range 898 PackNode* binary_tree_pack(int lo, int hi); 899 900 static PackNode* make(Node* s, uint vlen, BasicType bt); 901 }; 902 903 //------------------------------PackBNode-------------------------------------- 904 // Pack byte scalars into vector 905 class PackBNode : public PackNode { 906 public: PackBNode(Node * in1,const TypeVect * vt)907 PackBNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 908 virtual int Opcode() const; 909 }; 910 911 //------------------------------PackSNode-------------------------------------- 912 // Pack short scalars into a vector 913 class PackSNode : public PackNode { 914 public: PackSNode(Node * in1,const TypeVect * vt)915 PackSNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} PackSNode(Node * in1,Node * in2,const TypeVect * vt)916 PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 917 virtual int Opcode() const; 918 }; 919 920 //------------------------------PackINode-------------------------------------- 921 // Pack integer scalars into a vector 922 class PackINode : public PackNode { 923 public: PackINode(Node * in1,const TypeVect * vt)924 PackINode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} PackINode(Node * in1,Node * in2,const TypeVect * vt)925 PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 926 virtual int Opcode() const; 927 }; 928 929 //------------------------------PackLNode-------------------------------------- 930 // Pack long scalars into a vector 931 class PackLNode : public PackNode { 932 public: PackLNode(Node * in1,const TypeVect * vt)933 PackLNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} PackLNode(Node * in1,Node * in2,const TypeVect * vt)934 PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 935 virtual int Opcode() const; 936 }; 937 938 //------------------------------Pack2LNode------------------------------------- 939 // Pack 2 long scalars into a vector 940 class Pack2LNode : public PackNode { 941 public: Pack2LNode(Node * in1,Node * in2,const TypeVect * vt)942 Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 943 virtual int Opcode() const; 944 }; 945 946 //------------------------------PackFNode-------------------------------------- 947 // Pack float scalars into vector 948 class PackFNode : public PackNode { 949 public: PackFNode(Node * in1,const TypeVect * vt)950 PackFNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} PackFNode(Node * in1,Node * in2,const TypeVect * vt)951 PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 952 virtual int Opcode() const; 953 }; 954 955 //------------------------------PackDNode-------------------------------------- 956 // Pack double scalars into a vector 957 class PackDNode : public PackNode { 958 public: PackDNode(Node * in1,const TypeVect * vt)959 PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} PackDNode(Node * in1,Node * in2,const TypeVect * vt)960 PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 961 virtual int Opcode() const; 962 }; 963 964 //------------------------------Pack2DNode------------------------------------- 965 // Pack 2 double scalars into a vector 966 class Pack2DNode : public PackNode { 967 public: Pack2DNode(Node * in1,Node * in2,const TypeVect * vt)968 Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 969 virtual int Opcode() const; 970 }; 971 972 973 class VectorLoadConstNode : public VectorNode { 974 public: VectorLoadConstNode(Node * in1,const TypeVect * vt)975 VectorLoadConstNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 976 virtual int Opcode() const; 977 }; 978 979 //========================Extract_Scalar_from_Vector=========================== 980 981 //------------------------------ExtractNode------------------------------------ 982 // Extract a scalar from a vector at position "pos" 983 class ExtractNode : public Node { 984 public: ExtractNode(Node * src,ConINode * pos)985 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) { 986 assert(in(2)->get_int() >= 0, "positive constants"); 987 } 988 virtual int Opcode() const; pos() const989 uint pos() const { return in(2)->get_int(); } 990 991 static Node* make(Node* v, uint position, BasicType bt); 992 static int opcode(BasicType bt); 993 }; 994 995 //------------------------------ExtractBNode----------------------------------- 996 // Extract a byte from a vector at position "pos" 997 class ExtractBNode : public ExtractNode { 998 public: ExtractBNode(Node * src,ConINode * pos)999 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1000 virtual int Opcode() const; bottom_type() const1001 virtual const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const1002 virtual uint ideal_reg() const { return Op_RegI; } 1003 }; 1004 1005 //------------------------------ExtractUBNode---------------------------------- 1006 // Extract a boolean from a vector at position "pos" 1007 class ExtractUBNode : public ExtractNode { 1008 public: ExtractUBNode(Node * src,ConINode * pos)1009 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1010 virtual int Opcode() const; bottom_type() const1011 virtual const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const1012 virtual uint ideal_reg() const { return Op_RegI; } 1013 }; 1014 1015 //------------------------------ExtractCNode----------------------------------- 1016 // Extract a char from a vector at position "pos" 1017 class ExtractCNode : public ExtractNode { 1018 public: ExtractCNode(Node * src,ConINode * pos)1019 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1020 virtual int Opcode() const; bottom_type() const1021 virtual const Type *bottom_type() const { return TypeInt::CHAR; } ideal_reg() const1022 virtual uint ideal_reg() const { return Op_RegI; } 1023 }; 1024 1025 //------------------------------ExtractSNode----------------------------------- 1026 // Extract a short from a vector at position "pos" 1027 class ExtractSNode : public ExtractNode { 1028 public: ExtractSNode(Node * src,ConINode * pos)1029 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1030 virtual int Opcode() const; bottom_type() const1031 virtual const Type *bottom_type() const { return TypeInt::SHORT; } ideal_reg() const1032 virtual uint ideal_reg() const { return Op_RegI; } 1033 }; 1034 1035 //------------------------------ExtractINode----------------------------------- 1036 // Extract an int from a vector at position "pos" 1037 class ExtractINode : public ExtractNode { 1038 public: ExtractINode(Node * src,ConINode * pos)1039 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1040 virtual int Opcode() const; bottom_type() const1041 virtual const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const1042 virtual uint ideal_reg() const { return Op_RegI; } 1043 }; 1044 1045 //------------------------------ExtractLNode----------------------------------- 1046 // Extract a long from a vector at position "pos" 1047 class ExtractLNode : public ExtractNode { 1048 public: ExtractLNode(Node * src,ConINode * pos)1049 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1050 virtual int Opcode() const; bottom_type() const1051 virtual const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const1052 virtual uint ideal_reg() const { return Op_RegL; } 1053 }; 1054 1055 //------------------------------ExtractFNode----------------------------------- 1056 // Extract a float from a vector at position "pos" 1057 class ExtractFNode : public ExtractNode { 1058 public: ExtractFNode(Node * src,ConINode * pos)1059 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1060 virtual int Opcode() const; bottom_type() const1061 virtual const Type *bottom_type() const { return Type::FLOAT; } ideal_reg() const1062 virtual uint ideal_reg() const { return Op_RegF; } 1063 }; 1064 1065 //------------------------------ExtractDNode----------------------------------- 1066 // Extract a double from a vector at position "pos" 1067 class ExtractDNode : public ExtractNode { 1068 public: ExtractDNode(Node * src,ConINode * pos)1069 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1070 virtual int Opcode() const; bottom_type() const1071 virtual const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const1072 virtual uint ideal_reg() const { return Op_RegD; } 1073 }; 1074 1075 //------------------------------SetVectMaskINode------------------------------- 1076 // Provide a mask for a vector predicate machine 1077 class SetVectMaskINode : public Node { 1078 public: SetVectMaskINode(Node * c,Node * in1)1079 SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {} 1080 virtual int Opcode() const; bottom_type() const1081 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const1082 virtual uint ideal_reg() const { return Op_RegI; } Value(PhaseGVN * phase) const1083 virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; } 1084 }; 1085 1086 //------------------------------MacroLogicVNode------------------------------- 1087 // Vector logical operations packing node. 1088 class MacroLogicVNode : public VectorNode { 1089 private: MacroLogicVNode(Node * in1,Node * in2,Node * in3,Node * fn,const TypeVect * vt)1090 MacroLogicVNode(Node* in1, Node* in2, Node* in3, Node* fn, const TypeVect* vt) 1091 : VectorNode(in1, in2, in3, fn, vt) {} 1092 1093 public: 1094 virtual int Opcode() const; 1095 1096 static MacroLogicVNode* make(PhaseGVN& igvn, Node* in1, Node* in2, Node* in3, uint truth_table, const TypeVect* vt); 1097 }; 1098 1099 class VectorMaskCmpNode : public VectorNode { 1100 private: 1101 BoolTest::mask _predicate; 1102 1103 protected: size_of() const1104 uint size_of() const { return sizeof(*this); } 1105 1106 public: VectorMaskCmpNode(BoolTest::mask predicate,Node * in1,Node * in2,ConINode * predicate_node,const TypeVect * vt)1107 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, ConINode* predicate_node, const TypeVect* vt) : 1108 VectorNode(in1, in2, predicate_node, vt), 1109 _predicate(predicate) { 1110 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1111 "VectorMaskCmp inputs must have same type for elements"); 1112 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1113 "VectorMaskCmp inputs must have same number of elements"); 1114 init_class_id(Class_VectorMaskCmp); 1115 } 1116 1117 virtual int Opcode() const; hash() const1118 virtual uint hash() const { return VectorNode::hash() + _predicate; } cmp(const Node & n) const1119 virtual bool cmp( const Node &n ) const { 1120 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; 1121 } get_predicate()1122 BoolTest::mask get_predicate() { return _predicate; } 1123 #ifndef PRODUCT 1124 virtual void dump_spec(outputStream *st) const; 1125 #endif // !PRODUCT 1126 }; 1127 1128 // Used to wrap other vector nodes in order to add masking functionality. 1129 class VectorMaskWrapperNode : public VectorNode { 1130 public: VectorMaskWrapperNode(Node * vector,Node * mask)1131 VectorMaskWrapperNode(Node* vector, Node* mask) 1132 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) { 1133 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask"); 1134 } 1135 1136 virtual int Opcode() const; vector_val() const1137 Node* vector_val() const { return in(1); } vector_mask() const1138 Node* vector_mask() const { return in(2); } 1139 }; 1140 1141 class VectorTestNode : public Node { 1142 private: 1143 BoolTest::mask _predicate; 1144 1145 protected: size_of() const1146 uint size_of() const { return sizeof(*this); } 1147 1148 public: VectorTestNode(Node * in1,Node * in2,BoolTest::mask predicate)1149 VectorTestNode(Node* in1, Node* in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) { 1150 assert(in2->bottom_type()->is_vect() == in2->bottom_type()->is_vect(), "same vector type"); 1151 } 1152 virtual int Opcode() const; hash() const1153 virtual uint hash() const { return Node::hash() + _predicate; } cmp(const Node & n) const1154 virtual bool cmp( const Node &n ) const { 1155 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate; 1156 } bottom_type() const1157 virtual const Type *bottom_type() const { return TypeInt::BOOL; } ideal_reg() const1158 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest 1159 // in middle-end, we make it boolean result directly. get_predicate() const1160 BoolTest::mask get_predicate() const { return _predicate; } 1161 }; 1162 1163 class VectorBlendNode : public VectorNode { 1164 public: VectorBlendNode(Node * vec1,Node * vec2,Node * mask)1165 VectorBlendNode(Node* vec1, Node* vec2, Node* mask) 1166 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) { 1167 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1168 } 1169 1170 virtual int Opcode() const; vec1() const1171 Node* vec1() const { return in(1); } vec2() const1172 Node* vec2() const { return in(2); } vec_mask() const1173 Node* vec_mask() const { return in(3); } 1174 }; 1175 1176 class VectorRearrangeNode : public VectorNode { 1177 public: VectorRearrangeNode(Node * vec1,Node * shuffle)1178 VectorRearrangeNode(Node* vec1, Node* shuffle) 1179 : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) { 1180 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1181 } 1182 1183 virtual int Opcode() const; vec1() const1184 Node* vec1() const { return in(1); } vec_shuffle() const1185 Node* vec_shuffle() const { return in(2); } 1186 }; 1187 1188 class VectorLoadShuffleNode : public VectorNode { 1189 public: VectorLoadShuffleNode(Node * in,const TypeVect * vt)1190 VectorLoadShuffleNode(Node* in, const TypeVect* vt) 1191 : VectorNode(in, vt) { 1192 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be BYTE"); 1193 } 1194 GetOutShuffleSize() const1195 int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1196 virtual int Opcode() const; 1197 }; 1198 1199 class VectorLoadMaskNode : public VectorNode { 1200 public: VectorLoadMaskNode(Node * in,const TypeVect * vt)1201 VectorLoadMaskNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) { 1202 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BOOLEAN, "must be boolean"); 1203 } 1204 1205 virtual int Opcode() const; 1206 virtual Node* Identity(PhaseGVN* phase); 1207 }; 1208 1209 class VectorStoreMaskNode : public VectorNode { 1210 protected: VectorStoreMaskNode(Node * in1,ConINode * in2,const TypeVect * vt)1211 VectorStoreMaskNode(Node* in1, ConINode* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 1212 1213 public: 1214 virtual int Opcode() const; 1215 virtual Node* Identity(PhaseGVN* phase); 1216 1217 static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem); 1218 }; 1219 1220 // This is intended for use as a simple reinterpret node that has no cast. 1221 class VectorReinterpretNode : public VectorNode { 1222 private: 1223 const TypeVect* _src_vt; 1224 protected: size_of() const1225 uint size_of() const { return sizeof(*this); } 1226 public: VectorReinterpretNode(Node * in,const TypeVect * src_vt,const TypeVect * dst_vt)1227 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt) 1228 : VectorNode(in, dst_vt), _src_vt(src_vt) { } 1229 hash() const1230 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); } cmp(const Node & n) const1231 virtual bool cmp( const Node &n ) const { 1232 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt); 1233 } 1234 virtual Node* Identity(PhaseGVN* phase); 1235 1236 virtual int Opcode() const; 1237 }; 1238 1239 class VectorCastNode : public VectorNode { 1240 public: VectorCastNode(Node * in,const TypeVect * vt)1241 VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 1242 virtual int Opcode() const; 1243 1244 static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); 1245 static int opcode(BasicType bt); 1246 static bool implemented(BasicType bt, uint vlen); 1247 1248 virtual Node* Identity(PhaseGVN* phase); 1249 }; 1250 1251 class VectorCastB2XNode : public VectorCastNode { 1252 public: VectorCastB2XNode(Node * in,const TypeVect * vt)1253 VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1254 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); 1255 } 1256 virtual int Opcode() const; 1257 }; 1258 1259 class VectorCastS2XNode : public VectorCastNode { 1260 public: VectorCastS2XNode(Node * in,const TypeVect * vt)1261 VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1262 assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); 1263 } 1264 virtual int Opcode() const; 1265 }; 1266 1267 class VectorCastI2XNode : public VectorCastNode { 1268 public: VectorCastI2XNode(Node * in,const TypeVect * vt)1269 VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1270 assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); 1271 } 1272 virtual int Opcode() const; 1273 }; 1274 1275 class VectorCastL2XNode : public VectorCastNode { 1276 public: VectorCastL2XNode(Node * in,const TypeVect * vt)1277 VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1278 assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long"); 1279 } 1280 virtual int Opcode() const; 1281 }; 1282 1283 class VectorCastF2XNode : public VectorCastNode { 1284 public: VectorCastF2XNode(Node * in,const TypeVect * vt)1285 VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1286 assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); 1287 } 1288 virtual int Opcode() const; 1289 }; 1290 1291 class VectorCastD2XNode : public VectorCastNode { 1292 public: VectorCastD2XNode(Node * in,const TypeVect * vt)1293 VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1294 assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); 1295 } 1296 virtual int Opcode() const; 1297 }; 1298 1299 class VectorInsertNode : public VectorNode { 1300 public: VectorInsertNode(Node * vsrc,Node * new_val,ConINode * pos,const TypeVect * vt)1301 VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) { 1302 assert(pos->get_int() >= 0, "positive constants"); 1303 assert(pos->get_int() < (int)vt->length(), "index must be less than vector length"); 1304 assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type"); 1305 } 1306 virtual int Opcode() const; pos() const1307 uint pos() const { return in(3)->get_int(); } 1308 1309 static Node* make(Node* vec, Node* new_val, int position); 1310 }; 1311 1312 class VectorBoxNode : public Node { 1313 private: 1314 const TypeInstPtr* const _box_type; 1315 const TypeVect* const _vec_type; 1316 public: 1317 enum { 1318 Box = 1, 1319 Value = 2 1320 }; VectorBoxNode(Compile * C,Node * box,Node * val,const TypeInstPtr * box_type,const TypeVect * vt)1321 VectorBoxNode(Compile* C, Node* box, Node* val, 1322 const TypeInstPtr* box_type, const TypeVect* vt) 1323 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) { 1324 init_flags(Flag_is_macro); 1325 C->add_macro_node(this); 1326 } 1327 box_type() const1328 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; }; vec_type() const1329 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; }; 1330 1331 virtual int Opcode() const; bottom_type() const1332 virtual const Type* bottom_type() const { return _box_type; } ideal_reg() const1333 virtual uint ideal_reg() const { return box_type()->ideal_reg(); } size_of() const1334 virtual uint size_of() const { return sizeof(*this); } 1335 1336 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type); 1337 }; 1338 1339 class VectorBoxAllocateNode : public CallStaticJavaNode { 1340 public: VectorBoxAllocateNode(Compile * C,const TypeInstPtr * vbox_type)1341 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type) 1342 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) { 1343 init_flags(Flag_is_macro); 1344 C->add_macro_node(this); 1345 } 1346 1347 virtual int Opcode() const; 1348 #ifndef PRODUCT 1349 virtual void dump_spec(outputStream *st) const; 1350 #endif // !PRODUCT 1351 }; 1352 1353 class VectorUnboxNode : public VectorNode { 1354 private: 1355 bool _shuffle_to_vector; 1356 protected: size_of() const1357 uint size_of() const { return sizeof(*this); } 1358 public: VectorUnboxNode(Compile * C,const TypeVect * vec_type,Node * obj,Node * mem,bool shuffle_to_vector)1359 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem, bool shuffle_to_vector) 1360 : VectorNode(mem, obj, vec_type) { 1361 _shuffle_to_vector = shuffle_to_vector; 1362 init_flags(Flag_is_macro); 1363 C->add_macro_node(this); 1364 } 1365 1366 virtual int Opcode() const; obj() const1367 Node* obj() const { return in(2); } mem() const1368 Node* mem() const { return in(1); } 1369 virtual Node* Identity(PhaseGVN* phase); 1370 Node* Ideal(PhaseGVN* phase, bool can_reshape); is_shuffle_to_vector()1371 bool is_shuffle_to_vector() { return _shuffle_to_vector; } 1372 }; 1373 1374 class RotateRightVNode : public VectorNode { 1375 public: RotateRightVNode(Node * in1,Node * in2,const TypeVect * vt)1376 RotateRightVNode(Node* in1, Node* in2, const TypeVect* vt) 1377 : VectorNode(in1, in2, vt) {} 1378 1379 virtual int Opcode() const; 1380 Node* Ideal(PhaseGVN* phase, bool can_reshape); 1381 }; 1382 1383 class RotateLeftVNode : public VectorNode { 1384 public: RotateLeftVNode(Node * in1,Node * in2,const TypeVect * vt)1385 RotateLeftVNode(Node* in1, Node* in2, const TypeVect* vt) 1386 : VectorNode(in1, in2, vt) {} 1387 1388 virtual int Opcode() const; 1389 Node* Ideal(PhaseGVN* phase, bool can_reshape); 1390 }; 1391 1392 #endif // SHARE_OPTO_VECTORNODE_HPP 1393