Mercurial > hg > truffle
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; |