src/share/vm/opto/superword.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/superword.cpp Thu Jul 26 18:06:27 2012
--- new/src/share/vm/opto/superword.cpp Thu Jul 26 18:06:27 2012
*** 1355,1364 ****
--- 1355,1370 ----
vn = StoreVectorNode::make(_phase->C, opc, ctl, mem, adr, atyp, val, vlen);
} else if (n->req() == 3) {
// Promote operands to vector
Node* in1 = vector_opd(p, 1);
Node* in2 = vector_opd(p, 2);
+ if (VectorNode::is_invariant_vector(in1) && (n->is_Add() || n->is_Mul())) {
+ // Move invariant vector input into second position to avoid register spilling.
+ Node* tmp = in1;
+ in1 = in2;
+ in2 = tmp;
+ }
vn = VectorNode::make(_phase->C, opc, in1, in2, vlen, velt_basic_type(n));
} else {
ShouldNotReachHere();
}
assert(vn != NULL, "sanity");
*** 1398,1407 ****
--- 1404,1443 ----
if (same_opd) {
if (opd->is_Vector() || opd->is_LoadVector()) {
return opd; // input is matching vector
}
+ if ((opd_idx == 2) && VectorNode::is_shift(p0)) {
+ // No vector is needed for shift count.
+ // Vector instructions do not mask shift count, do it here.
+ Compile* C = _phase->C;
+ Node* cnt = opd;
+ juint mask = (p0->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
+ const TypeInt* t = opd->find_int_type();
+ if (t != NULL && t->is_con()) {
+ juint shift = t->get_con();
+ if (shift > mask) { // Unsigned cmp
+ cnt = ConNode::make(C, TypeInt::make(shift & mask));
+ }
+ } else {
+ if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) {
+ cnt = ConNode::make(C, TypeInt::make(mask));
+ _phase->_igvn.register_new_node_with_optimizer(cnt);
+ cnt = new (C, 3) AndINode(opd, cnt);
+ _phase->_igvn.register_new_node_with_optimizer(cnt);
+ _phase->set_ctrl(cnt, _phase->get_ctrl(opd));
+ }
+ assert(opd->bottom_type()->isa_int(), "int type only");
+ // Move non constant shift count into XMM register.
+ cnt = new (_phase->C, 2) MoveI2FNode(cnt);
+ }
+ if (cnt != opd) {
+ _phase->_igvn.register_new_node_with_optimizer(cnt);
+ _phase->set_ctrl(cnt, _phase->get_ctrl(opd));
+ }
+ return cnt;
+ }
assert(!opd->is_StoreVector(), "such vector is not expected here");
// Convert scalar input to vector with the same number of elements as
// p0's vector. Use p0's type because size of operand's container in
// vector should match p0's size regardless operand's size.
const Type* p0_t = velt_type(p0);
*** 1716,1745 ****
--- 1752,1772 ----
// Propagate narrowed type backwards through operations
// that don't depend on higher order bits
for (int i = _block.length() - 1; i >= 0; i--) {
Node* n = _block.at(i);
// Only integer types need be examined
if (n->bottom_type()->isa_int()) {
+ const Type* vt = velt_type(n);
+ if (vt->basic_type() == T_INT) {
uint start, end;
vector_opd_range(n, &start, &end);
const Type* vt = velt_type(n);
for (uint j = start; j < end; j++) {
Node* in = n->in(j);
! // Don't propagate through a type conversion
! if (n->bottom_type() != in->bottom_type())
continue;
switch(in->Opcode()) {
case Op_AddI: case Op_AddL:
case Op_SubI: case Op_SubL:
case Op_MulI: case Op_MulL:
case Op_AndI: case Op_AndL:
case Op_OrI: case Op_OrL:
case Op_XorI: case Op_XorL:
case Op_LShiftI: case Op_LShiftL:
case Op_CMoveI: case Op_CMoveL:
if (in_bb(in)) {
! // Don't propagate through a memory
! if (!in->is_Mem() && in_bb(in) && velt_type(in)->basic_type() == T_INT &&
+ data_size(n) < data_size(in)) {
bool same_type = true;
for (DUIterator_Fast kmax, k = in->fast_outs(kmax); k < kmax; k++) {
Node *use = in->fast_out(k);
if (!in_bb(use) || !same_velt_type(use, n)) {
same_type = false;
*** 1751,1761 ****
--- 1778,1787 ----
}
}
}
}
}
}
#ifndef PRODUCT
if (TraceSuperWord && Verbose) {
for (int i = 0; i < _block.length(); i++) {
Node* n = _block.at(i);
velt_type(n)->dump();
*** 1790,1803 ****
--- 1816,1827 ----
if (n->is_Mem()) {
return Type::get_const_basic_type(n->as_Mem()->memory_type());
}
const Type* t = _igvn.type(n);
if (t->basic_type() == T_INT) {
if (t->higher_equal(TypeInt::BOOL)) return TypeInt::BOOL;
if (t->higher_equal(TypeInt::BYTE)) return TypeInt::BYTE;
if (t->higher_equal(TypeInt::CHAR)) return TypeInt::CHAR;
if (t->higher_equal(TypeInt::SHORT)) return TypeInt::SHORT;
+ // A narrow type of arithmetic operations will be determined by
+ // propagating the type of memory operations.
return TypeInt::INT;
}
return t;
}
src/share/vm/opto/superword.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File