提交 67eb2798 编写于 作者: K kvn

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
上级 8c62e0f3
...@@ -2061,7 +2061,7 @@ instruct Repl8I_imm(vecY dst, immI con) %{ ...@@ -2061,7 +2061,7 @@ instruct Repl8I_imm(vecY dst, immI con) %{
// Integer could be loaded into xmm register directly from memory. // Integer could be loaded into xmm register directly from memory.
instruct Repl2I_mem(vecD dst, memory mem) %{ instruct Repl2I_mem(vecD dst, memory mem) %{
predicate(n->as_Vector()->length() == 2); predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateI mem)); match(Set dst (ReplicateI (LoadVector mem)));
format %{ "movd $dst,$mem\n\t" format %{ "movd $dst,$mem\n\t"
"pshufd $dst,$dst,0x00\t! replicate2I" %} "pshufd $dst,$dst,0x00\t! replicate2I" %}
ins_encode %{ ins_encode %{
...@@ -2073,7 +2073,7 @@ instruct Repl2I_mem(vecD dst, memory mem) %{ ...@@ -2073,7 +2073,7 @@ instruct Repl2I_mem(vecD dst, memory mem) %{
instruct Repl4I_mem(vecX dst, memory mem) %{ instruct Repl4I_mem(vecX dst, memory mem) %{
predicate(n->as_Vector()->length() == 4); predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateI mem)); match(Set dst (ReplicateI (LoadVector mem)));
format %{ "movd $dst,$mem\n\t" format %{ "movd $dst,$mem\n\t"
"pshufd $dst,$dst,0x00\t! replicate4I" %} "pshufd $dst,$dst,0x00\t! replicate4I" %}
ins_encode %{ ins_encode %{
...@@ -2085,7 +2085,7 @@ instruct Repl4I_mem(vecX dst, memory mem) %{ ...@@ -2085,7 +2085,7 @@ instruct Repl4I_mem(vecX dst, memory mem) %{
instruct Repl8I_mem(vecY dst, memory mem) %{ instruct Repl8I_mem(vecY dst, memory mem) %{
predicate(n->as_Vector()->length() == 8); predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateI mem)); match(Set dst (ReplicateI (LoadVector mem)));
format %{ "movd $dst,$mem\n\t" format %{ "movd $dst,$mem\n\t"
"pshufd $dst,$dst,0x00\n\t" "pshufd $dst,$dst,0x00\n\t"
"vinsertf128h $dst,$dst,$dst\t! replicate8I" %} "vinsertf128h $dst,$dst,$dst\t! replicate8I" %}
...@@ -2225,7 +2225,7 @@ instruct Repl4L_imm(vecY dst, immL con) %{ ...@@ -2225,7 +2225,7 @@ instruct Repl4L_imm(vecY dst, immL con) %{
// Long could be loaded into xmm register directly from memory. // Long could be loaded into xmm register directly from memory.
instruct Repl2L_mem(vecX dst, memory mem) %{ instruct Repl2L_mem(vecX dst, memory mem) %{
predicate(n->as_Vector()->length() == 2); predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateL mem)); match(Set dst (ReplicateL (LoadVector mem)));
format %{ "movq $dst,$mem\n\t" format %{ "movq $dst,$mem\n\t"
"movlhps $dst,$dst\t! replicate2L" %} "movlhps $dst,$dst\t! replicate2L" %}
ins_encode %{ ins_encode %{
...@@ -2237,7 +2237,7 @@ instruct Repl2L_mem(vecX dst, memory mem) %{ ...@@ -2237,7 +2237,7 @@ instruct Repl2L_mem(vecX dst, memory mem) %{
instruct Repl4L_mem(vecY dst, memory mem) %{ instruct Repl4L_mem(vecY dst, memory mem) %{
predicate(n->as_Vector()->length() == 4); predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateL mem)); match(Set dst (ReplicateL (LoadVector mem)));
format %{ "movq $dst,$mem\n\t" format %{ "movq $dst,$mem\n\t"
"movlhps $dst,$dst\n\t" "movlhps $dst,$dst\n\t"
"vinsertf128h $dst,$dst,$dst\t! replicate4L" %} "vinsertf128h $dst,$dst,$dst\t! replicate4L" %}
......
...@@ -299,9 +299,12 @@ ...@@ -299,9 +299,12 @@
develop(bool, SuperWordRTDepCheck, false, \ develop(bool, SuperWordRTDepCheck, false, \
"Enable runtime dependency checks.") \ "Enable runtime dependency checks.") \
\ \
product(bool, TraceSuperWord, false, \ notproduct(bool, TraceSuperWord, false, \
"Trace superword transforms") \ "Trace superword transforms") \
\ \
notproduct(bool, TraceNewVectors, false, \
"Trace creation of Vector nodes") \
\
product_pd(bool, OptoBundling, \ product_pd(bool, OptoBundling, \
"Generate nops to fill i-cache lines") \ "Generate nops to fill i-cache lines") \
\ \
......
...@@ -222,7 +222,18 @@ void SuperWord::find_adjacent_refs() { ...@@ -222,7 +222,18 @@ void SuperWord::find_adjacent_refs() {
// Create initial pack pairs of memory operations for which // Create initial pack pairs of memory operations for which
// alignment is set and vectors will be aligned. // alignment is set and vectors will be aligned.
bool create_pack = true; bool create_pack = true;
if (memory_alignment(mem_ref, best_iv_adjustment) != 0) { if (memory_alignment(mem_ref, best_iv_adjustment) == 0) {
if (!Matcher::misaligned_vectors_ok()) {
int vw = vector_width(mem_ref);
int vw_best = vector_width(best_align_to_mem_ref);
if (vw > vw_best) {
// Do not vectorize a memory access with more elements per vector
// if unaligned memory access is not allowed because number of
// iterations in pre-loop will be not enough to align it.
create_pack = false;
}
}
} else {
if (same_velt_type(mem_ref, best_align_to_mem_ref)) { if (same_velt_type(mem_ref, best_align_to_mem_ref)) {
// Can't allow vectorization of unaligned memory accesses with the // Can't allow vectorization of unaligned memory accesses with the
// same type since it could be overlapped accesses to the same array. // same type since it could be overlapped accesses to the same array.
...@@ -357,7 +368,7 @@ MemNode* SuperWord::find_align_to_ref(Node_List &memops) { ...@@ -357,7 +368,7 @@ MemNode* SuperWord::find_align_to_ref(Node_List &memops) {
for (uint j = 0; j < memops.size(); j++) { for (uint j = 0; j < memops.size(); j++) {
MemNode* s = memops.at(j)->as_Mem(); MemNode* s = memops.at(j)->as_Mem();
if (s->is_Store()) { if (s->is_Store()) {
int vw = vector_width_in_bytes(velt_basic_type(s)); int vw = vector_width_in_bytes(s);
assert(vw > 1, "sanity"); assert(vw > 1, "sanity");
SWPointer p(s, this); SWPointer p(s, this);
if (cmp_ct.at(j) > max_ct || if (cmp_ct.at(j) > max_ct ||
...@@ -380,7 +391,7 @@ MemNode* SuperWord::find_align_to_ref(Node_List &memops) { ...@@ -380,7 +391,7 @@ MemNode* SuperWord::find_align_to_ref(Node_List &memops) {
for (uint j = 0; j < memops.size(); j++) { for (uint j = 0; j < memops.size(); j++) {
MemNode* s = memops.at(j)->as_Mem(); MemNode* s = memops.at(j)->as_Mem();
if (s->is_Load()) { if (s->is_Load()) {
int vw = vector_width_in_bytes(velt_basic_type(s)); int vw = vector_width_in_bytes(s);
assert(vw > 1, "sanity"); assert(vw > 1, "sanity");
SWPointer p(s, this); SWPointer p(s, this);
if (cmp_ct.at(j) > max_ct || if (cmp_ct.at(j) > max_ct ||
...@@ -440,8 +451,7 @@ bool SuperWord::ref_is_alignable(SWPointer& p) { ...@@ -440,8 +451,7 @@ bool SuperWord::ref_is_alignable(SWPointer& p) {
// If initial offset from start of object is computable, // If initial offset from start of object is computable,
// compute alignment within the vector. // compute alignment within the vector.
BasicType bt = velt_basic_type(p.mem()); int vw = vector_width_in_bytes(p.mem());
int vw = vector_width_in_bytes(bt);
assert(vw > 1, "sanity"); assert(vw > 1, "sanity");
if (vw % span == 0) { if (vw % span == 0) {
Node* init_nd = pre_end->init_trip(); Node* init_nd = pre_end->init_trip();
...@@ -468,8 +478,7 @@ int SuperWord::get_iv_adjustment(MemNode* mem_ref) { ...@@ -468,8 +478,7 @@ int SuperWord::get_iv_adjustment(MemNode* mem_ref) {
SWPointer align_to_ref_p(mem_ref, this); SWPointer align_to_ref_p(mem_ref, this);
int offset = align_to_ref_p.offset_in_bytes(); int offset = align_to_ref_p.offset_in_bytes();
int scale = align_to_ref_p.scale_in_bytes(); int scale = align_to_ref_p.scale_in_bytes();
BasicType bt = velt_basic_type(mem_ref); int vw = vector_width_in_bytes(mem_ref);
int vw = vector_width_in_bytes(bt);
assert(vw > 1, "sanity"); assert(vw > 1, "sanity");
int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1; int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1;
int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw; int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw;
...@@ -1361,7 +1370,7 @@ void SuperWord::output() { ...@@ -1361,7 +1370,7 @@ void SuperWord::output() {
} }
_igvn._worklist.push(vn); _igvn._worklist.push(vn);
#ifdef ASSERT #ifdef ASSERT
if (TraceSuperWord) { if (TraceNewVectors) {
tty->print("new Vector node: "); tty->print("new Vector node: ");
vn->dump(); vn->dump();
} }
...@@ -1401,7 +1410,7 @@ Node* SuperWord::vector_opd(Node_List* p, int opd_idx) { ...@@ -1401,7 +1410,7 @@ Node* SuperWord::vector_opd(Node_List* p, int opd_idx) {
_phase->_igvn.register_new_node_with_optimizer(vn); _phase->_igvn.register_new_node_with_optimizer(vn);
_phase->set_ctrl(vn, _phase->get_ctrl(opd)); _phase->set_ctrl(vn, _phase->get_ctrl(opd));
#ifdef ASSERT #ifdef ASSERT
if (TraceSuperWord) { if (TraceNewVectors) {
tty->print("new Vector node: "); tty->print("new Vector node: ");
vn->dump(); vn->dump();
} }
...@@ -1424,8 +1433,8 @@ Node* SuperWord::vector_opd(Node_List* p, int opd_idx) { ...@@ -1424,8 +1433,8 @@ Node* SuperWord::vector_opd(Node_List* p, int opd_idx) {
_phase->_igvn.register_new_node_with_optimizer(pk); _phase->_igvn.register_new_node_with_optimizer(pk);
_phase->set_ctrl(pk, _phase->get_ctrl(opd)); _phase->set_ctrl(pk, _phase->get_ctrl(opd));
#ifdef ASSERT #ifdef ASSERT
if (TraceSuperWord) { if (TraceNewVectors) {
tty->print("new Pack node: "); tty->print("new Vector node: ");
pk->dump(); pk->dump();
} }
#endif #endif
...@@ -1764,7 +1773,7 @@ int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) { ...@@ -1764,7 +1773,7 @@ int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) {
if (!p.valid()) { if (!p.valid()) {
return bottom_align; return bottom_align;
} }
int vw = vector_width_in_bytes(velt_basic_type(s)); int vw = vector_width_in_bytes(s);
if (vw < 2) { if (vw < 2) {
return bottom_align; // No vectors for this type return bottom_align; // No vectors for this type
} }
...@@ -1978,12 +1987,12 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) { ...@@ -1978,12 +1987,12 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
// N = (V - (e - lim0)) % V // N = (V - (e - lim0)) % V
// lim = lim0 - (V - (e - lim0)) % V // lim = lim0 - (V - (e - lim0)) % V
int vw = vector_width_in_bytes(velt_basic_type(align_to_ref)); int vw = vector_width_in_bytes(align_to_ref);
assert(vw > 1, "sanity");
int stride = iv_stride(); int stride = iv_stride();
int scale = align_to_ref_p.scale_in_bytes(); int scale = align_to_ref_p.scale_in_bytes();
int elt_size = align_to_ref_p.memory_size(); int elt_size = align_to_ref_p.memory_size();
int v_align = vw / elt_size; int v_align = vw / elt_size;
assert(v_align > 1, "sanity");
int k = align_to_ref_p.offset_in_bytes() / elt_size; int k = align_to_ref_p.offset_in_bytes() / elt_size;
Node *kn = _igvn.intcon(k); Node *kn = _igvn.intcon(k);
......
...@@ -264,11 +264,14 @@ class SuperWord : public ResourceObj { ...@@ -264,11 +264,14 @@ class SuperWord : public ResourceObj {
_iv = lp->as_CountedLoop()->phi()->as_Phi(); } _iv = lp->as_CountedLoop()->phi()->as_Phi(); }
int iv_stride() { return lp()->as_CountedLoop()->stride_con(); } int iv_stride() { return lp()->as_CountedLoop()->stride_con(); }
int vector_width_in_bytes(BasicType bt) { int vector_width(Node* n) {
return MIN2(ABS(iv_stride())*type2aelembytes(bt), BasicType bt = velt_basic_type(n);
Matcher::vector_width_in_bytes(bt)); return MIN2(ABS(iv_stride()), Matcher::max_vector_size(bt));
}
int vector_width_in_bytes(Node* n) {
BasicType bt = velt_basic_type(n);
return vector_width(n)*type2aelembytes(bt);
} }
MemNode* align_to_ref() { return _align_to_ref; } MemNode* align_to_ref() { return _align_to_ref; }
void set_align_to_ref(MemNode* m) { _align_to_ref = m; } void set_align_to_ref(MemNode* m) { _align_to_ref = m; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册