comparison src/share/vm/opto/superword.cpp @ 6794:8ae8f9dd7099

7199010: incorrect vector alignment Summary: Fixed vectors alignment when several arrays are accessed in one loop. Reviewed-by: roland, twisti
author kvn
date Wed, 19 Sep 2012 16:50:26 -0700
parents 137868b7aa6f
children 06f52c4d0e18
comparison
equal deleted inserted replaced
6793:9d89c76b0505 6794:8ae8f9dd7099
177 // Get list of memory operations 177 // Get list of memory operations
178 Node_List memops; 178 Node_List memops;
179 for (int i = 0; i < _block.length(); i++) { 179 for (int i = 0; i < _block.length(); i++) {
180 Node* n = _block.at(i); 180 Node* n = _block.at(i);
181 if (n->is_Mem() && !n->is_LoadStore() && in_bb(n) && 181 if (n->is_Mem() && !n->is_LoadStore() && in_bb(n) &&
182 n->Opcode() != Op_LoadUI2L &&
182 is_java_primitive(n->as_Mem()->memory_type())) { 183 is_java_primitive(n->as_Mem()->memory_type())) {
183 int align = memory_alignment(n->as_Mem(), 0); 184 int align = memory_alignment(n->as_Mem(), 0);
184 if (align != bottom_align) { 185 if (align != bottom_align) {
185 memops.push(n); 186 memops.push(n);
186 } 187 }
479 int offset = align_to_ref_p.offset_in_bytes(); 480 int offset = align_to_ref_p.offset_in_bytes();
480 int scale = align_to_ref_p.scale_in_bytes(); 481 int scale = align_to_ref_p.scale_in_bytes();
481 int vw = vector_width_in_bytes(mem_ref); 482 int vw = vector_width_in_bytes(mem_ref);
482 assert(vw > 1, "sanity"); 483 assert(vw > 1, "sanity");
483 int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1; 484 int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1;
484 int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw; 485 // At least one iteration is executed in pre-loop by default. As result
486 // several iterations are needed to align memory operations in main-loop even
487 // if offset is 0.
488 int iv_adjustment_in_bytes = (stride_sign * vw - (offset % vw));
489 int elt_size = align_to_ref_p.memory_size();
490 assert(((ABS(iv_adjustment_in_bytes) % elt_size) == 0),
491 err_msg_res("(%d) should be divisible by (%d)", iv_adjustment_in_bytes, elt_size));
492 int iv_adjustment = iv_adjustment_in_bytes/elt_size;
485 493
486 #ifndef PRODUCT 494 #ifndef PRODUCT
487 if (TraceSuperWord) 495 if (TraceSuperWord)
488 tty->print_cr("\noffset = %d iv_adjust = %d elt_size = %d scale = %d iv_stride = %d vect_size %d", 496 tty->print_cr("\noffset = %d iv_adjust = %d elt_size = %d scale = %d iv_stride = %d vect_size %d",
489 offset, iv_adjustment, align_to_ref_p.memory_size(), scale, iv_stride(), vw); 497 offset, iv_adjustment, elt_size, scale, iv_stride(), vw);
490 #endif 498 #endif
491 return iv_adjustment; 499 return iv_adjustment;
492 } 500 }
493 501
494 //---------------------------dependence_graph--------------------------- 502 //---------------------------dependence_graph---------------------------
1814 #endif 1822 #endif
1815 } 1823 }
1816 1824
1817 //------------------------------memory_alignment--------------------------- 1825 //------------------------------memory_alignment---------------------------
1818 // Alignment within a vector memory reference 1826 // Alignment within a vector memory reference
1819 int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) { 1827 int SuperWord::memory_alignment(MemNode* s, int iv_adjust) {
1820 SWPointer p(s, this); 1828 SWPointer p(s, this);
1821 if (!p.valid()) { 1829 if (!p.valid()) {
1822 return bottom_align; 1830 return bottom_align;
1823 } 1831 }
1824 int vw = vector_width_in_bytes(s); 1832 int vw = vector_width_in_bytes(s);
1825 if (vw < 2) { 1833 if (vw < 2) {
1826 return bottom_align; // No vectors for this type 1834 return bottom_align; // No vectors for this type
1827 } 1835 }
1828 int offset = p.offset_in_bytes(); 1836 int offset = p.offset_in_bytes();
1829 offset += iv_adjust_in_bytes; 1837 offset += iv_adjust*p.memory_size();
1830 int off_rem = offset % vw; 1838 int off_rem = offset % vw;
1831 int off_mod = off_rem >= 0 ? off_rem : off_rem + vw; 1839 int off_mod = off_rem >= 0 ? off_rem : off_rem + vw;
1832 return off_mod; 1840 return off_mod;
1833 } 1841 }
1834 1842
1847 return t; 1855 return t;
1848 } 1856 }
1849 1857
1850 bool SuperWord::same_velt_type(Node* n1, Node* n2) { 1858 bool SuperWord::same_velt_type(Node* n1, Node* n2) {
1851 const Type* vt1 = velt_type(n1); 1859 const Type* vt1 = velt_type(n1);
1852 const Type* vt2 = velt_type(n1); 1860 const Type* vt2 = velt_type(n2);
1853 if (vt1->basic_type() == T_INT && vt2->basic_type() == T_INT) { 1861 if (vt1->basic_type() == T_INT && vt2->basic_type() == T_INT) {
1854 // Compare vectors element sizes for integer types. 1862 // Compare vectors element sizes for integer types.
1855 return data_size(n1) == data_size(n2); 1863 return data_size(n1) == data_size(n2);
1856 } 1864 }
1857 return vt1 == vt2; 1865 return vt1 == vt2;