Mercurial > hg > truffle
comparison src/share/vm/opto/vectornode.cpp @ 6619:5af51c882207
7192963: assert(_in[req-1] == this) failed: Must pass arg count to 'new'
Summary: Fixed Pack node generation. Not vectorize shift instructions if count is not the same for all shifts and if count is vector.
Reviewed-by: twisti
author | kvn |
---|---|
date | Wed, 22 Aug 2012 11:55:40 -0700 |
parents | 4b0d6fd74911 |
children | e626685e9f6c |
comparison
equal
deleted
inserted
replaced
6618:0bfcb7a3e12d | 6619:5af51c882207 |
---|---|
29 //------------------------------VectorNode-------------------------------------- | 29 //------------------------------VectorNode-------------------------------------- |
30 | 30 |
31 // Return the vector operator for the specified scalar operation | 31 // Return the vector operator for the specified scalar operation |
32 // and vector length. Also used to check if the code generator | 32 // and vector length. Also used to check if the code generator |
33 // supports the vector operation. | 33 // supports the vector operation. |
34 int VectorNode::opcode(int sopc, uint vlen, BasicType bt) { | 34 int VectorNode::opcode(int sopc, BasicType bt) { |
35 switch (sopc) { | 35 switch (sopc) { |
36 case Op_AddI: | 36 case Op_AddI: |
37 switch (bt) { | 37 switch (bt) { |
38 case T_BOOLEAN: | 38 case T_BOOLEAN: |
39 case T_BYTE: return Op_AddVB; | 39 case T_BYTE: return Op_AddVB; |
159 | 159 |
160 bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { | 160 bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { |
161 if (is_java_primitive(bt) && | 161 if (is_java_primitive(bt) && |
162 (vlen > 1) && is_power_of_2(vlen) && | 162 (vlen > 1) && is_power_of_2(vlen) && |
163 Matcher::vector_size_supported(bt, vlen)) { | 163 Matcher::vector_size_supported(bt, vlen)) { |
164 int vopc = VectorNode::opcode(opc, vlen, bt); | 164 int vopc = VectorNode::opcode(opc, bt); |
165 return vopc > 0 && Matcher::has_match_rule(vopc); | 165 return vopc > 0 && Matcher::has_match_rule(vopc); |
166 } | 166 } |
167 return false; | 167 return false; |
168 } | 168 } |
169 | 169 |
193 return true; | 193 return true; |
194 } | 194 } |
195 return false; | 195 return false; |
196 } | 196 } |
197 | 197 |
198 // [Start, end) half-open range defining which operands are vectors | |
199 void VectorNode::vector_operands(Node* n, uint* start, uint* end) { | |
200 switch (n->Opcode()) { | |
201 case Op_LoadB: case Op_LoadUB: | |
202 case Op_LoadS: case Op_LoadUS: | |
203 case Op_LoadI: case Op_LoadL: | |
204 case Op_LoadF: case Op_LoadD: | |
205 case Op_LoadP: case Op_LoadN: | |
206 *start = 0; | |
207 *end = 0; // no vector operands | |
208 break; | |
209 case Op_StoreB: case Op_StoreC: | |
210 case Op_StoreI: case Op_StoreL: | |
211 case Op_StoreF: case Op_StoreD: | |
212 case Op_StoreP: case Op_StoreN: | |
213 *start = MemNode::ValueIn; | |
214 *end = MemNode::ValueIn + 1; // 1 vector operand | |
215 break; | |
216 case Op_LShiftI: case Op_LShiftL: | |
217 case Op_RShiftI: case Op_RShiftL: | |
218 case Op_URShiftI: case Op_URShiftL: | |
219 *start = 1; | |
220 *end = 2; // 1 vector operand | |
221 break; | |
222 case Op_AddI: case Op_AddL: case Op_AddF: case Op_AddD: | |
223 case Op_SubI: case Op_SubL: case Op_SubF: case Op_SubD: | |
224 case Op_MulI: case Op_MulL: case Op_MulF: case Op_MulD: | |
225 case Op_DivF: case Op_DivD: | |
226 case Op_AndI: case Op_AndL: | |
227 case Op_OrI: case Op_OrL: | |
228 case Op_XorI: case Op_XorL: | |
229 *start = 1; | |
230 *end = 3; // 2 vector operands | |
231 break; | |
232 case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD: | |
233 *start = 2; | |
234 *end = n->req(); | |
235 break; | |
236 default: | |
237 *start = 1; | |
238 *end = n->req(); // default is all operands | |
239 } | |
240 } | |
241 | |
198 // Return the vector version of a scalar operation node. | 242 // Return the vector version of a scalar operation node. |
199 VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { | 243 VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { |
200 const TypeVect* vt = TypeVect::make(bt, vlen); | 244 const TypeVect* vt = TypeVect::make(bt, vlen); |
201 int vopc = VectorNode::opcode(opc, vlen, bt); | 245 int vopc = VectorNode::opcode(opc, bt); |
202 | 246 |
203 switch (vopc) { | 247 switch (vopc) { |
204 case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt); | 248 case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt); |
205 case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vt); | 249 case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vt); |
206 case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vt); | 250 case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vt); |
276 PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) { | 320 PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) { |
277 const TypeVect* vt = TypeVect::make(bt, vlen); | 321 const TypeVect* vt = TypeVect::make(bt, vlen); |
278 switch (bt) { | 322 switch (bt) { |
279 case T_BOOLEAN: | 323 case T_BOOLEAN: |
280 case T_BYTE: | 324 case T_BYTE: |
281 return new (C, vlen+1) PackBNode(s, vt); | 325 return new (C, 2) PackBNode(s, vt); |
282 case T_CHAR: | 326 case T_CHAR: |
283 case T_SHORT: | 327 case T_SHORT: |
284 return new (C, vlen+1) PackSNode(s, vt); | 328 return new (C, 2) PackSNode(s, vt); |
285 case T_INT: | 329 case T_INT: |
286 return new (C, vlen+1) PackINode(s, vt); | 330 return new (C, 2) PackINode(s, vt); |
287 case T_LONG: | 331 case T_LONG: |
288 return new (C, vlen+1) PackLNode(s, vt); | 332 return new (C, 2) PackLNode(s, vt); |
289 case T_FLOAT: | 333 case T_FLOAT: |
290 return new (C, vlen+1) PackFNode(s, vt); | 334 return new (C, 2) PackFNode(s, vt); |
291 case T_DOUBLE: | 335 case T_DOUBLE: |
292 return new (C, vlen+1) PackDNode(s, vt); | 336 return new (C, 2) PackDNode(s, vt); |
293 } | 337 } |
294 ShouldNotReachHere(); | 338 ShouldNotReachHere(); |
295 return NULL; | 339 return NULL; |
296 } | 340 } |
297 | 341 |
298 // Create a binary tree form for Packs. [lo, hi) (half-open) range | 342 // Create a binary tree form for Packs. [lo, hi) (half-open) range |
299 Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) { | 343 PackNode* PackNode::binary_tree_pack(Compile* C, int lo, int hi) { |
300 int ct = hi - lo; | 344 int ct = hi - lo; |
301 assert(is_power_of_2(ct), "power of 2"); | 345 assert(is_power_of_2(ct), "power of 2"); |
302 if (ct == 2) { | 346 if (ct == 2) { |
303 PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type()); | 347 PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type()); |
304 pk->add_opd(1, in(lo+1)); | 348 pk->add_opd(in(lo+1)); |
305 return pk; | 349 return pk; |
306 | 350 |
307 } else { | 351 } else { |
308 int mid = lo + ct/2; | 352 int mid = lo + ct/2; |
309 Node* n1 = binaryTreePack(C, lo, mid); | 353 PackNode* n1 = binary_tree_pack(C, lo, mid); |
310 Node* n2 = binaryTreePack(C, mid, hi ); | 354 PackNode* n2 = binary_tree_pack(C, mid, hi ); |
311 | 355 |
312 BasicType bt = vect_type()->element_basic_type(); | 356 BasicType bt = n1->vect_type()->element_basic_type(); |
357 assert(bt == n2->vect_type()->element_basic_type(), "should be the same"); | |
313 switch (bt) { | 358 switch (bt) { |
314 case T_BOOLEAN: | 359 case T_BOOLEAN: |
315 case T_BYTE: | 360 case T_BYTE: |
316 return new (C, 3) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); | 361 return new (C, 3) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); |
317 case T_CHAR: | 362 case T_CHAR: |