Mercurial > hg > graal-compiler
comparison src/share/vm/opto/superword.cpp @ 6183:6f8f439e247d
7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
Summary: disable vectorization of a memory access with more elements per vector than one which is used for alignment on sparc
Reviewed-by: twisti
author | kvn |
---|---|
date | Tue, 19 Jun 2012 15:12:56 -0700 |
parents | 8c92982cbbc4 |
children | 006050192a5a |
comparison
equal
deleted
inserted
replaced
6182:765ee2d1674b | 6183:6f8f439e247d |
---|---|
220 } | 220 } |
221 | 221 |
222 // Create initial pack pairs of memory operations for which | 222 // Create initial pack pairs of memory operations for which |
223 // alignment is set and vectors will be aligned. | 223 // alignment is set and vectors will be aligned. |
224 bool create_pack = true; | 224 bool create_pack = true; |
225 if (memory_alignment(mem_ref, best_iv_adjustment) != 0) { | 225 if (memory_alignment(mem_ref, best_iv_adjustment) == 0) { |
226 if (!Matcher::misaligned_vectors_ok()) { | |
227 int vw = vector_width(mem_ref); | |
228 int vw_best = vector_width(best_align_to_mem_ref); | |
229 if (vw > vw_best) { | |
230 // Do not vectorize a memory access with more elements per vector | |
231 // if unaligned memory access is not allowed because number of | |
232 // iterations in pre-loop will be not enough to align it. | |
233 create_pack = false; | |
234 } | |
235 } | |
236 } else { | |
226 if (same_velt_type(mem_ref, best_align_to_mem_ref)) { | 237 if (same_velt_type(mem_ref, best_align_to_mem_ref)) { |
227 // Can't allow vectorization of unaligned memory accesses with the | 238 // Can't allow vectorization of unaligned memory accesses with the |
228 // same type since it could be overlapped accesses to the same array. | 239 // same type since it could be overlapped accesses to the same array. |
229 create_pack = false; | 240 create_pack = false; |
230 } else { | 241 } else { |
355 int min_size = max_jint; | 366 int min_size = max_jint; |
356 int min_iv_offset = max_jint; | 367 int min_iv_offset = max_jint; |
357 for (uint j = 0; j < memops.size(); j++) { | 368 for (uint j = 0; j < memops.size(); j++) { |
358 MemNode* s = memops.at(j)->as_Mem(); | 369 MemNode* s = memops.at(j)->as_Mem(); |
359 if (s->is_Store()) { | 370 if (s->is_Store()) { |
360 int vw = vector_width_in_bytes(velt_basic_type(s)); | 371 int vw = vector_width_in_bytes(s); |
361 assert(vw > 1, "sanity"); | 372 assert(vw > 1, "sanity"); |
362 SWPointer p(s, this); | 373 SWPointer p(s, this); |
363 if (cmp_ct.at(j) > max_ct || | 374 if (cmp_ct.at(j) > max_ct || |
364 cmp_ct.at(j) == max_ct && | 375 cmp_ct.at(j) == max_ct && |
365 (vw > max_vw || | 376 (vw > max_vw || |
378 // If no stores, look at loads | 389 // If no stores, look at loads |
379 if (max_ct == 0) { | 390 if (max_ct == 0) { |
380 for (uint j = 0; j < memops.size(); j++) { | 391 for (uint j = 0; j < memops.size(); j++) { |
381 MemNode* s = memops.at(j)->as_Mem(); | 392 MemNode* s = memops.at(j)->as_Mem(); |
382 if (s->is_Load()) { | 393 if (s->is_Load()) { |
383 int vw = vector_width_in_bytes(velt_basic_type(s)); | 394 int vw = vector_width_in_bytes(s); |
384 assert(vw > 1, "sanity"); | 395 assert(vw > 1, "sanity"); |
385 SWPointer p(s, this); | 396 SWPointer p(s, this); |
386 if (cmp_ct.at(j) > max_ct || | 397 if (cmp_ct.at(j) > max_ct || |
387 cmp_ct.at(j) == max_ct && | 398 cmp_ct.at(j) == max_ct && |
388 (vw > max_vw || | 399 (vw > max_vw || |
438 if (ABS(span) == p.memory_size()) | 449 if (ABS(span) == p.memory_size()) |
439 return true; | 450 return true; |
440 | 451 |
441 // If initial offset from start of object is computable, | 452 // If initial offset from start of object is computable, |
442 // compute alignment within the vector. | 453 // compute alignment within the vector. |
443 BasicType bt = velt_basic_type(p.mem()); | 454 int vw = vector_width_in_bytes(p.mem()); |
444 int vw = vector_width_in_bytes(bt); | |
445 assert(vw > 1, "sanity"); | 455 assert(vw > 1, "sanity"); |
446 if (vw % span == 0) { | 456 if (vw % span == 0) { |
447 Node* init_nd = pre_end->init_trip(); | 457 Node* init_nd = pre_end->init_trip(); |
448 if (init_nd->is_Con() && p.invar() == NULL) { | 458 if (init_nd->is_Con() && p.invar() == NULL) { |
449 int init = init_nd->bottom_type()->is_int()->get_con(); | 459 int init = init_nd->bottom_type()->is_int()->get_con(); |
466 // Calculate loop's iv adjustment for this memory ops. | 476 // Calculate loop's iv adjustment for this memory ops. |
467 int SuperWord::get_iv_adjustment(MemNode* mem_ref) { | 477 int SuperWord::get_iv_adjustment(MemNode* mem_ref) { |
468 SWPointer align_to_ref_p(mem_ref, this); | 478 SWPointer align_to_ref_p(mem_ref, this); |
469 int offset = align_to_ref_p.offset_in_bytes(); | 479 int offset = align_to_ref_p.offset_in_bytes(); |
470 int scale = align_to_ref_p.scale_in_bytes(); | 480 int scale = align_to_ref_p.scale_in_bytes(); |
471 BasicType bt = velt_basic_type(mem_ref); | 481 int vw = vector_width_in_bytes(mem_ref); |
472 int vw = vector_width_in_bytes(bt); | |
473 assert(vw > 1, "sanity"); | 482 assert(vw > 1, "sanity"); |
474 int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1; | 483 int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1; |
475 int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw; | 484 int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw; |
476 | 485 |
477 #ifndef PRODUCT | 486 #ifndef PRODUCT |
1359 Node* pm = p->at(j); | 1368 Node* pm = p->at(j); |
1360 _igvn.replace_node(pm, vn); | 1369 _igvn.replace_node(pm, vn); |
1361 } | 1370 } |
1362 _igvn._worklist.push(vn); | 1371 _igvn._worklist.push(vn); |
1363 #ifdef ASSERT | 1372 #ifdef ASSERT |
1364 if (TraceSuperWord) { | 1373 if (TraceNewVectors) { |
1365 tty->print("new Vector node: "); | 1374 tty->print("new Vector node: "); |
1366 vn->dump(); | 1375 vn->dump(); |
1367 } | 1376 } |
1368 #endif | 1377 #endif |
1369 } | 1378 } |
1399 VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t); | 1408 VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t); |
1400 | 1409 |
1401 _phase->_igvn.register_new_node_with_optimizer(vn); | 1410 _phase->_igvn.register_new_node_with_optimizer(vn); |
1402 _phase->set_ctrl(vn, _phase->get_ctrl(opd)); | 1411 _phase->set_ctrl(vn, _phase->get_ctrl(opd)); |
1403 #ifdef ASSERT | 1412 #ifdef ASSERT |
1404 if (TraceSuperWord) { | 1413 if (TraceNewVectors) { |
1405 tty->print("new Vector node: "); | 1414 tty->print("new Vector node: "); |
1406 vn->dump(); | 1415 vn->dump(); |
1407 } | 1416 } |
1408 #endif | 1417 #endif |
1409 return vn; | 1418 return vn; |
1422 pk->add_opd(i, in); | 1431 pk->add_opd(i, in); |
1423 } | 1432 } |
1424 _phase->_igvn.register_new_node_with_optimizer(pk); | 1433 _phase->_igvn.register_new_node_with_optimizer(pk); |
1425 _phase->set_ctrl(pk, _phase->get_ctrl(opd)); | 1434 _phase->set_ctrl(pk, _phase->get_ctrl(opd)); |
1426 #ifdef ASSERT | 1435 #ifdef ASSERT |
1427 if (TraceSuperWord) { | 1436 if (TraceNewVectors) { |
1428 tty->print("new Pack node: "); | 1437 tty->print("new Vector node: "); |
1429 pk->dump(); | 1438 pk->dump(); |
1430 } | 1439 } |
1431 #endif | 1440 #endif |
1432 return pk; | 1441 return pk; |
1433 } | 1442 } |
1762 int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) { | 1771 int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) { |
1763 SWPointer p(s, this); | 1772 SWPointer p(s, this); |
1764 if (!p.valid()) { | 1773 if (!p.valid()) { |
1765 return bottom_align; | 1774 return bottom_align; |
1766 } | 1775 } |
1767 int vw = vector_width_in_bytes(velt_basic_type(s)); | 1776 int vw = vector_width_in_bytes(s); |
1768 if (vw < 2) { | 1777 if (vw < 2) { |
1769 return bottom_align; // No vectors for this type | 1778 return bottom_align; // No vectors for this type |
1770 } | 1779 } |
1771 int offset = p.offset_in_bytes(); | 1780 int offset = p.offset_in_bytes(); |
1772 offset += iv_adjust_in_bytes; | 1781 offset += iv_adjust_in_bytes; |
1976 // Solving for lim: | 1985 // Solving for lim: |
1977 // (e - lim0 + N) % V == 0 | 1986 // (e - lim0 + N) % V == 0 |
1978 // N = (V - (e - lim0)) % V | 1987 // N = (V - (e - lim0)) % V |
1979 // lim = lim0 - (V - (e - lim0)) % V | 1988 // lim = lim0 - (V - (e - lim0)) % V |
1980 | 1989 |
1981 int vw = vector_width_in_bytes(velt_basic_type(align_to_ref)); | 1990 int vw = vector_width_in_bytes(align_to_ref); |
1982 assert(vw > 1, "sanity"); | |
1983 int stride = iv_stride(); | 1991 int stride = iv_stride(); |
1984 int scale = align_to_ref_p.scale_in_bytes(); | 1992 int scale = align_to_ref_p.scale_in_bytes(); |
1985 int elt_size = align_to_ref_p.memory_size(); | 1993 int elt_size = align_to_ref_p.memory_size(); |
1986 int v_align = vw / elt_size; | 1994 int v_align = vw / elt_size; |
1995 assert(v_align > 1, "sanity"); | |
1987 int k = align_to_ref_p.offset_in_bytes() / elt_size; | 1996 int k = align_to_ref_p.offset_in_bytes() / elt_size; |
1988 | 1997 |
1989 Node *kn = _igvn.intcon(k); | 1998 Node *kn = _igvn.intcon(k); |
1990 | 1999 |
1991 Node *e = kn; | 2000 Node *e = kn; |