vectornode.cpp 13.6 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23
 */

24 25 26 27
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/connode.hpp"
#include "opto/vectornode.hpp"
D
duke 已提交
28 29 30 31

//------------------------------VectorNode--------------------------------------

// Return the vector operator for the specified scalar operation
32
// and vector length.  Also used to check if the code generator
D
duke 已提交
33
// supports the vector operation.
34
int VectorNode::opcode(int sopc, BasicType bt) {
D
duke 已提交
35 36 37 38 39
  switch (sopc) {
  case Op_AddI:
    switch (bt) {
    case T_BOOLEAN:
    case T_BYTE:      return Op_AddVB;
40
    case T_CHAR:
D
duke 已提交
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
    case T_SHORT:     return Op_AddVS;
    case T_INT:       return Op_AddVI;
    }
    ShouldNotReachHere();
  case Op_AddL:
    assert(bt == T_LONG, "must be");
    return Op_AddVL;
  case Op_AddF:
    assert(bt == T_FLOAT, "must be");
    return Op_AddVF;
  case Op_AddD:
    assert(bt == T_DOUBLE, "must be");
    return Op_AddVD;
  case Op_SubI:
    switch (bt) {
    case T_BOOLEAN:
    case T_BYTE:   return Op_SubVB;
58
    case T_CHAR:
D
duke 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71
    case T_SHORT:  return Op_SubVS;
    case T_INT:    return Op_SubVI;
    }
    ShouldNotReachHere();
  case Op_SubL:
    assert(bt == T_LONG, "must be");
    return Op_SubVL;
  case Op_SubF:
    assert(bt == T_FLOAT, "must be");
    return Op_SubVF;
  case Op_SubD:
    assert(bt == T_DOUBLE, "must be");
    return Op_SubVD;
72 73 74 75 76 77 78 79 80
  case Op_MulI:
    switch (bt) {
    case T_BOOLEAN:
    case T_BYTE:   return 0;   // Unimplemented
    case T_CHAR:
    case T_SHORT:  return Op_MulVS;
    case T_INT:    return Matcher::match_rule_supported(Op_MulVI) ? Op_MulVI : 0; // SSE4_1
    }
    ShouldNotReachHere();
D
duke 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  case Op_MulF:
    assert(bt == T_FLOAT, "must be");
    return Op_MulVF;
  case Op_MulD:
    assert(bt == T_DOUBLE, "must be");
    return Op_MulVD;
  case Op_DivF:
    assert(bt == T_FLOAT, "must be");
    return Op_DivVF;
  case Op_DivD:
    assert(bt == T_DOUBLE, "must be");
    return Op_DivVD;
  case Op_LShiftI:
    switch (bt) {
    case T_BOOLEAN:
    case T_BYTE:   return Op_LShiftVB;
97
    case T_CHAR:
D
duke 已提交
98 99 100 101
    case T_SHORT:  return Op_LShiftVS;
    case T_INT:    return Op_LShiftVI;
    }
    ShouldNotReachHere();
102 103 104
  case Op_LShiftL:
    assert(bt == T_LONG, "must be");
    return Op_LShiftVL;
105
  case Op_RShiftI:
D
duke 已提交
106 107
    switch (bt) {
    case T_BOOLEAN:
108 109 110 111
    case T_BYTE:   return Op_RShiftVB;
    case T_CHAR:
    case T_SHORT:  return Op_RShiftVS;
    case T_INT:    return Op_RShiftVI;
D
duke 已提交
112 113
    }
    ShouldNotReachHere();
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  case Op_RShiftL:
    assert(bt == T_LONG, "must be");
    return Op_RShiftVL;
  case Op_URShiftI:
    switch (bt) {
    case T_BOOLEAN:
    case T_BYTE:   return Op_URShiftVB;
    case T_CHAR:
    case T_SHORT:  return Op_URShiftVS;
    case T_INT:    return Op_URShiftVI;
    }
    ShouldNotReachHere();
  case Op_URShiftL:
    assert(bt == T_LONG, "must be");
    return Op_URShiftVL;
D
duke 已提交
129 130 131 132 133 134 135 136 137 138 139
  case Op_AndI:
  case Op_AndL:
    return Op_AndV;
  case Op_OrI:
  case Op_OrL:
    return Op_OrV;
  case Op_XorI:
  case Op_XorL:
    return Op_XorV;

  case Op_LoadB:
140
  case Op_LoadUB:
141
  case Op_LoadUS:
D
duke 已提交
142 143 144 145 146
  case Op_LoadS:
  case Op_LoadI:
  case Op_LoadL:
  case Op_LoadF:
  case Op_LoadD:
147
    return Op_LoadVector;
D
duke 已提交
148 149 150 151 152 153 154

  case Op_StoreB:
  case Op_StoreC:
  case Op_StoreI:
  case Op_StoreL:
  case Op_StoreF:
  case Op_StoreD:
155
    return Op_StoreVector;
D
duke 已提交
156 157 158 159
  }
  return 0; // Unimplemented
}

160 161 162 163
bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
  if (is_java_primitive(bt) &&
      (vlen > 1) && is_power_of_2(vlen) &&
      Matcher::vector_size_supported(bt, vlen)) {
164
    int vopc = VectorNode::opcode(opc, bt);
165
    return vopc > 0 && Matcher::has_match_rule(vopc);
D
duke 已提交
166
  }
167
  return false;
D
duke 已提交
168 169
}

170 171 172 173 174 175 176 177 178 179 180 181 182
bool VectorNode::is_shift(Node* n) {
  switch (n->Opcode()) {
  case Op_LShiftI:
  case Op_LShiftL:
  case Op_RShiftI:
  case Op_RShiftL:
  case Op_URShiftI:
  case Op_URShiftL:
    return true;
  }
  return false;
}

K
kvn 已提交
183
// Check if input is loop invariant vector.
184
bool VectorNode::is_invariant_vector(Node* n) {
K
kvn 已提交
185
  // Only Replicate vector nodes are loop invariant for now.
186 187 188 189 190 191 192 193 194 195 196 197
  switch (n->Opcode()) {
  case Op_ReplicateB:
  case Op_ReplicateS:
  case Op_ReplicateI:
  case Op_ReplicateL:
  case Op_ReplicateF:
  case Op_ReplicateD:
    return true;
  }
  return false;
}

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
// [Start, end) half-open range defining which operands are vectors
void VectorNode::vector_operands(Node* n, uint* start, uint* end) {
  switch (n->Opcode()) {
  case Op_LoadB:   case Op_LoadUB:
  case Op_LoadS:   case Op_LoadUS:
  case Op_LoadI:   case Op_LoadL:
  case Op_LoadF:   case Op_LoadD:
  case Op_LoadP:   case Op_LoadN:
    *start = 0;
    *end   = 0; // no vector operands
    break;
  case Op_StoreB:  case Op_StoreC:
  case Op_StoreI:  case Op_StoreL:
  case Op_StoreF:  case Op_StoreD:
  case Op_StoreP:  case Op_StoreN:
    *start = MemNode::ValueIn;
    *end   = MemNode::ValueIn + 1; // 1 vector operand
    break;
  case Op_LShiftI:  case Op_LShiftL:
  case Op_RShiftI:  case Op_RShiftL:
  case Op_URShiftI: case Op_URShiftL:
    *start = 1;
    *end   = 2; // 1 vector operand
    break;
  case Op_AddI: case Op_AddL: case Op_AddF: case Op_AddD:
  case Op_SubI: case Op_SubL: case Op_SubF: case Op_SubD:
  case Op_MulI: case Op_MulL: case Op_MulF: case Op_MulD:
  case Op_DivF: case Op_DivD:
  case Op_AndI: case Op_AndL:
  case Op_OrI:  case Op_OrL:
  case Op_XorI: case Op_XorL:
    *start = 1;
    *end   = 3; // 2 vector operands
    break;
  case Op_CMoveI:  case Op_CMoveL:  case Op_CMoveF:  case Op_CMoveD:
    *start = 2;
    *end   = n->req();
    break;
  default:
    *start = 1;
    *end   = n->req(); // default is all operands
  }
}

D
duke 已提交
242
// Return the vector version of a scalar operation node.
243 244
VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
  const TypeVect* vt = TypeVect::make(bt, vlen);
245
  int vopc = VectorNode::opcode(opc, bt);
K
kvn 已提交
246 247
  // This method should not be called for unimplemented vectors.
  guarantee(vopc > 0, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
D
duke 已提交
248 249

  switch (vopc) {
250 251 252 253 254 255
  case Op_AddVB: return new (C) AddVBNode(n1, n2, vt);
  case Op_AddVS: return new (C) AddVSNode(n1, n2, vt);
  case Op_AddVI: return new (C) AddVINode(n1, n2, vt);
  case Op_AddVL: return new (C) AddVLNode(n1, n2, vt);
  case Op_AddVF: return new (C) AddVFNode(n1, n2, vt);
  case Op_AddVD: return new (C) AddVDNode(n1, n2, vt);
256

257 258 259 260 261 262
  case Op_SubVB: return new (C) SubVBNode(n1, n2, vt);
  case Op_SubVS: return new (C) SubVSNode(n1, n2, vt);
  case Op_SubVI: return new (C) SubVINode(n1, n2, vt);
  case Op_SubVL: return new (C) SubVLNode(n1, n2, vt);
  case Op_SubVF: return new (C) SubVFNode(n1, n2, vt);
  case Op_SubVD: return new (C) SubVDNode(n1, n2, vt);
263

264 265 266 267
  case Op_MulVS: return new (C) MulVSNode(n1, n2, vt);
  case Op_MulVI: return new (C) MulVINode(n1, n2, vt);
  case Op_MulVF: return new (C) MulVFNode(n1, n2, vt);
  case Op_MulVD: return new (C) MulVDNode(n1, n2, vt);
268

269 270
  case Op_DivVF: return new (C) DivVFNode(n1, n2, vt);
  case Op_DivVD: return new (C) DivVDNode(n1, n2, vt);
271

272 273 274 275
  case Op_LShiftVB: return new (C) LShiftVBNode(n1, n2, vt);
  case Op_LShiftVS: return new (C) LShiftVSNode(n1, n2, vt);
  case Op_LShiftVI: return new (C) LShiftVINode(n1, n2, vt);
  case Op_LShiftVL: return new (C) LShiftVLNode(n1, n2, vt);
276

277 278 279 280
  case Op_RShiftVB: return new (C) RShiftVBNode(n1, n2, vt);
  case Op_RShiftVS: return new (C) RShiftVSNode(n1, n2, vt);
  case Op_RShiftVI: return new (C) RShiftVINode(n1, n2, vt);
  case Op_RShiftVL: return new (C) RShiftVLNode(n1, n2, vt);
281

282 283 284 285
  case Op_URShiftVB: return new (C) URShiftVBNode(n1, n2, vt);
  case Op_URShiftVS: return new (C) URShiftVSNode(n1, n2, vt);
  case Op_URShiftVI: return new (C) URShiftVINode(n1, n2, vt);
  case Op_URShiftVL: return new (C) URShiftVLNode(n1, n2, vt);
286

287 288 289
  case Op_AndV: return new (C) AndVNode(n1, n2, vt);
  case Op_OrV:  return new (C) OrVNode (n1, n2, vt);
  case Op_XorV: return new (C) XorVNode(n1, n2, vt);
290
  }
K
kvn 已提交
291
  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
292
  return NULL;
D
duke 已提交
293

294
}
D
duke 已提交
295

296 297 298 299 300 301 302 303
// Scalar promotion
VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t) {
  BasicType bt = opd_t->array_element_basic_type();
  const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
                                          : TypeVect::make(bt, vlen);
  switch (bt) {
  case T_BOOLEAN:
  case T_BYTE:
304
    return new (C) ReplicateBNode(s, vt);
305 306
  case T_CHAR:
  case T_SHORT:
307
    return new (C) ReplicateSNode(s, vt);
308
  case T_INT:
309
    return new (C) ReplicateINode(s, vt);
310
  case T_LONG:
311
    return new (C) ReplicateLNode(s, vt);
312
  case T_FLOAT:
313
    return new (C) ReplicateFNode(s, vt);
314
  case T_DOUBLE:
315
    return new (C) ReplicateDNode(s, vt);
D
duke 已提交
316
  }
K
kvn 已提交
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
  return NULL;
}

VectorNode* VectorNode::shift_count(Compile* C, Node* shift, Node* cnt, uint vlen, BasicType bt) {
  assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count");
  // Match shift count type with shift vector type.
  const TypeVect* vt = TypeVect::make(bt, vlen);
  switch (shift->Opcode()) {
  case Op_LShiftI:
  case Op_LShiftL:
    return new (C) LShiftCntVNode(cnt, vt);
  case Op_RShiftI:
  case Op_RShiftL:
  case Op_URShiftI:
  case Op_URShiftL:
    return new (C) RShiftCntVNode(cnt, vt);
  }
  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]));
D
duke 已提交
336 337 338
  return NULL;
}

339 340 341 342 343 344
// Return initial Pack node. Additional operands added with add_opd() calls.
PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) {
  const TypeVect* vt = TypeVect::make(bt, vlen);
  switch (bt) {
  case T_BOOLEAN:
  case T_BYTE:
345
    return new (C) PackBNode(s, vt);
346 347
  case T_CHAR:
  case T_SHORT:
348
    return new (C) PackSNode(s, vt);
349
  case T_INT:
350
    return new (C) PackINode(s, vt);
351
  case T_LONG:
352
    return new (C) PackLNode(s, vt);
353
  case T_FLOAT:
354
    return new (C) PackFNode(s, vt);
355
  case T_DOUBLE:
356
    return new (C) PackDNode(s, vt);
357
  }
K
kvn 已提交
358
  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
359 360
  return NULL;
}
D
duke 已提交
361

362
// Create a binary tree form for Packs. [lo, hi) (half-open) range
363
PackNode* PackNode::binary_tree_pack(Compile* C, int lo, int hi) {
364 365 366 367
  int ct = hi - lo;
  assert(is_power_of_2(ct), "power of 2");
  if (ct == 2) {
    PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type());
368
    pk->add_opd(in(lo+1));
369
    return pk;
D
duke 已提交
370

371 372
  } else {
    int mid = lo + ct/2;
373 374
    PackNode* n1 = binary_tree_pack(C, lo,  mid);
    PackNode* n2 = binary_tree_pack(C, mid, hi );
D
duke 已提交
375

376 377
    BasicType bt = n1->vect_type()->element_basic_type();
    assert(bt == n2->vect_type()->element_basic_type(), "should be the same");
378 379 380
    switch (bt) {
    case T_BOOLEAN:
    case T_BYTE:
381
      return new (C) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2));
382 383
    case T_CHAR:
    case T_SHORT:
384
      return new (C) PackINode(n1, n2, TypeVect::make(T_INT, 2));
385
    case T_INT:
386
      return new (C) PackLNode(n1, n2, TypeVect::make(T_LONG, 2));
387
    case T_LONG:
388
      return new (C) Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
389
    case T_FLOAT:
390
      return new (C) PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
391
    case T_DOUBLE:
392
      return new (C) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
393
    }
K
kvn 已提交
394
    fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
D
duke 已提交
395
  }
396 397 398 399 400 401 402
  return NULL;
}

// Return the vector version of a scalar load node.
LoadVectorNode* LoadVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
                                     Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) {
  const TypeVect* vt = TypeVect::make(bt, vlen);
403
  return new (C) LoadVectorNode(ctl, mem, adr, atyp, vt);
D
duke 已提交
404 405 406
}

// Return the vector version of a scalar store node.
407
StoreVectorNode* StoreVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
K
kvn 已提交
408
                                       Node* adr, const TypePtr* atyp, Node* val,
D
duke 已提交
409
                                       uint vlen) {
410
  return new (C) StoreVectorNode(ctl, mem, adr, atyp, val);
D
duke 已提交
411 412 413
}

// Extract a scalar element of vector.
414 415
Node* ExtractNode::make(Compile* C, Node* v, uint position, BasicType bt) {
  assert((int)position < Matcher::max_vector_size(bt), "pos in range");
D
duke 已提交
416 417 418
  ConINode* pos = ConINode::make(C, (int)position);
  switch (bt) {
  case T_BOOLEAN:
419
    return new (C) ExtractUBNode(v, pos);
D
duke 已提交
420
  case T_BYTE:
421
    return new (C) ExtractBNode(v, pos);
D
duke 已提交
422
  case T_CHAR:
423
    return new (C) ExtractCNode(v, pos);
D
duke 已提交
424
  case T_SHORT:
425
    return new (C) ExtractSNode(v, pos);
D
duke 已提交
426
  case T_INT:
427
    return new (C) ExtractINode(v, pos);
D
duke 已提交
428
  case T_LONG:
429
    return new (C) ExtractLNode(v, pos);
D
duke 已提交
430
  case T_FLOAT:
431
    return new (C) ExtractFNode(v, pos);
D
duke 已提交
432
  case T_DOUBLE:
433
    return new (C) ExtractDNode(v, pos);
D
duke 已提交
434
  }
K
kvn 已提交
435
  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
D
duke 已提交
436 437
  return NULL;
}
438