Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8266746: C1: Replace UnsafeGetRaw with UnsafeGet when setting up OSR entry block #3917

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion src/hotspot/cpu/arm/c1_Defs_arm.hpp
Expand Up @@ -76,6 +76,5 @@ enum {

#define PATCHED_ADDR (204)
#define CARDTABLEBARRIERSET_POST_BARRIER_HELPER
#define GENERATE_ADDRESS_IS_PREFERRED

#endif // CPU_ARM_C1_DEFS_ARM_HPP
2 changes: 0 additions & 2 deletions src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
Expand Up @@ -1172,7 +1172,6 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type,
assert(Assembler::is_simm16(disp_value), "should have set this up");
offset = load(src, disp_value, to_reg, type, wide, unaligned);
} else {
assert(!unaligned, "unexpected");
offset = load(src, disp_reg, to_reg, type, wide);
}

Expand Down Expand Up @@ -1301,7 +1300,6 @@ void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type,
assert(Assembler::is_simm16(disp_value), "should have set this up");
offset = store(from_reg, src, disp_value, type, wide, unaligned);
} else {
assert(!unaligned, "unexpected");
offset = store(from_reg, src, disp_reg, type, wide);
}

Expand Down
155 changes: 0 additions & 155 deletions src/hotspot/share/c1/c1_Canonicalizer.cpp
Expand Up @@ -894,162 +894,7 @@ void Canonicalizer::do_Throw (Throw* x) {}
void Canonicalizer::do_Base (Base* x) {}
void Canonicalizer::do_OsrEntry (OsrEntry* x) {}
void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {}

static bool match_index_and_scale(Instruction* instr,
Instruction** index,
int* log2_scale) {
// Skip conversion ops. This works only on 32bit because of the implicit l2i that the
// unsafe performs.
#ifndef _LP64
Convert* convert = instr->as_Convert();
if (convert != NULL && convert->op() == Bytecodes::_i2l) {
assert(convert->value()->type() == intType, "invalid input type");
instr = convert->value();
}
#endif

ShiftOp* shift = instr->as_ShiftOp();
if (shift != NULL) {
if (shift->op() == Bytecodes::_lshl) {
assert(shift->x()->type() == longType, "invalid input type");
} else {
#ifndef _LP64
if (shift->op() == Bytecodes::_ishl) {
assert(shift->x()->type() == intType, "invalid input type");
} else {
return false;
}
#else
return false;
#endif
}


// Constant shift value?
Constant* con = shift->y()->as_Constant();
if (con == NULL) return false;
// Well-known type and value?
IntConstant* val = con->type()->as_IntConstant();
assert(val != NULL, "Should be an int constant");

*index = shift->x();
int tmp_scale = val->value();
if (tmp_scale >= 0 && tmp_scale < 4) {
*log2_scale = tmp_scale;
return true;
} else {
return false;
}
}

ArithmeticOp* arith = instr->as_ArithmeticOp();
if (arith != NULL) {
// See if either arg is a known constant
Constant* con = arith->x()->as_Constant();
if (con != NULL) {
*index = arith->y();
} else {
con = arith->y()->as_Constant();
if (con == NULL) return false;
*index = arith->x();
}
long const_value;
// Check for integer multiply
if (arith->op() == Bytecodes::_lmul) {
assert((*index)->type() == longType, "invalid input type");
LongConstant* val = con->type()->as_LongConstant();
assert(val != NULL, "expecting a long constant");
const_value = val->value();
} else {
#ifndef _LP64
if (arith->op() == Bytecodes::_imul) {
assert((*index)->type() == intType, "invalid input type");
IntConstant* val = con->type()->as_IntConstant();
assert(val != NULL, "expecting an int constant");
const_value = val->value();
} else {
return false;
}
#else
return false;
#endif
}
switch (const_value) {
case 1: *log2_scale = 0; return true;
case 2: *log2_scale = 1; return true;
case 4: *log2_scale = 2; return true;
case 8: *log2_scale = 3; return true;
default: return false;
}
}

// Unknown instruction sequence; don't touch it
return false;
}


static bool match(UnsafeRawOp* x,
Instruction** base,
Instruction** index,
int* log2_scale) {
ArithmeticOp* root = x->base()->as_ArithmeticOp();
if (root == NULL) return false;
// Limit ourselves to addition for now
if (root->op() != Bytecodes::_ladd) return false;

bool match_found = false;
// Try to find shift or scale op
if (match_index_and_scale(root->y(), index, log2_scale)) {
*base = root->x();
match_found = true;
} else if (match_index_and_scale(root->x(), index, log2_scale)) {
*base = root->y();
match_found = true;
} else if (NOT_LP64(root->y()->as_Convert() != NULL) LP64_ONLY(false)) {
// Skipping i2l works only on 32bit because of the implicit l2i that the unsafe performs.
// 64bit needs a real sign-extending conversion.
Convert* convert = root->y()->as_Convert();
if (convert->op() == Bytecodes::_i2l) {
assert(convert->value()->type() == intType, "should be an int");
// pick base and index, setting scale at 1
*base = root->x();
*index = convert->value();
*log2_scale = 0;
match_found = true;
}
}
// The default solution
if (!match_found) {
*base = root->x();
*index = root->y();
*log2_scale = 0;
}

// If the value is pinned then it will be always be computed so
// there's no profit to reshaping the expression.
return !root->is_pinned();
}


void Canonicalizer::do_UnsafeRawOp(UnsafeRawOp* x) {
Instruction* base = NULL;
Instruction* index = NULL;
int log2_scale;

if (match(x, &base, &index, &log2_scale)) {
x->set_base(base);
x->set_index(index);
x->set_log2_scale(log2_scale);
if (PrintUnsafeOptimization) {
tty->print_cr("Canonicalizer: UnsafeRawOp id %d: base = id %d, index = id %d, log2_scale = %d",
x->id(), x->base()->id(), x->index()->id(), x->log2_scale());
}
}
}

void Canonicalizer::do_RoundFP(RoundFP* x) {}
void Canonicalizer::do_UnsafeGetRaw(UnsafeGetRaw* x) { if (OptimizeUnsafes) do_UnsafeRawOp(x); }
void Canonicalizer::do_UnsafePutRaw(UnsafePutRaw* x) { if (OptimizeUnsafes) do_UnsafeRawOp(x); }
void Canonicalizer::do_UnsafeGetObject(UnsafeGetObject* x) {}
void Canonicalizer::do_UnsafePutObject(UnsafePutObject* x) {}
void Canonicalizer::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
Expand Down
8 changes: 0 additions & 8 deletions src/hotspot/share/c1/c1_Canonicalizer.hpp
Expand Up @@ -46,12 +46,6 @@ class Canonicalizer: InstructionVisitor {
#endif
void move_const_to_right(Op2* x);
void do_Op2(Op2* x);
void do_UnsafeRawOp(UnsafeRawOp* x);

void unsafe_raw_match(UnsafeRawOp* x,
Instruction** base,
Instruction** index,
int* scale);

public:
Canonicalizer(Compilation* c, Value x, int bci) : _compilation(c), _canonical(x), _bci(bci) {
Expand Down Expand Up @@ -100,8 +94,6 @@ class Canonicalizer: InstructionVisitor {
virtual void do_OsrEntry (OsrEntry* x);
virtual void do_ExceptionObject(ExceptionObject* x);
virtual void do_RoundFP (RoundFP* x);
virtual void do_UnsafeGetRaw (UnsafeGetRaw* x);
virtual void do_UnsafePutRaw (UnsafePutRaw* x);
virtual void do_UnsafeGetObject(UnsafeGetObject* x);
virtual void do_UnsafePutObject(UnsafePutObject* x);
virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
Expand Down
27 changes: 5 additions & 22 deletions src/hotspot/share/c1/c1_GraphBuilder.cpp
Expand Up @@ -3148,10 +3148,11 @@ void GraphBuilder::setup_osr_entry_block() {
// doesn't so pretend that the interpreter passed in null.
get = append(new Constant(objectNull));
} else {
get = append(new UnsafeGetRaw(as_BasicType(local->type()), e,
append(new Constant(new IntConstant(offset))),
0,
true /*unaligned*/, true /*wide*/));
Value off_val = append(new Constant(new IntConstant(offset)));
get = append(new UnsafeGetObject(as_BasicType(local->type()), e,
off_val,
false/*is_volatile*/,
true/*is_raw*/));
}
_state->store_local(index, get);
}
Expand Down Expand Up @@ -4248,24 +4249,6 @@ void GraphBuilder::append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_
kill_all();
}


void GraphBuilder::append_unsafe_get_raw(ciMethod* callee, BasicType t) {
Values* args = state()->pop_arguments(callee->arg_size());
null_check(args->at(0));
Instruction* op = append(new UnsafeGetRaw(t, args->at(1), false));
push(op->type(), op);
compilation()->set_has_unsafe_access(true);
}


void GraphBuilder::append_unsafe_put_raw(ciMethod* callee, BasicType t) {
Values* args = state()->pop_arguments(callee->arg_size());
null_check(args->at(0));
Instruction* op = append(new UnsafePutRaw(t, args->at(1), args->at(2)));
compilation()->set_has_unsafe_access(true);
}


void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
ValueStack* state_before = copy_state_for_exception();
ValueType* result_type = as_ValueType(callee->return_type());
Expand Down
2 changes: 0 additions & 2 deletions src/hotspot/share/c1/c1_GraphBuilder.hpp
Expand Up @@ -375,8 +375,6 @@ class GraphBuilder {

void append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile);
void append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile);
void append_unsafe_get_raw(ciMethod* callee, BasicType t);
void append_unsafe_put_raw(ciMethod* callee, BasicType t);
void append_unsafe_CAS(ciMethod* callee);
void append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add);
void append_char_access(ciMethod* callee, bool is_store);
Expand Down