Skip to content
Permalink
Browse files
8266746: C1: Replace UnsafeGetRaw with UnsafeGet when setting up OSR …
…entry block

Replace UnsafeGetRaw with UnsafeGetObject when setting up OSR entry block, and rename Unsafe{Get,Put}Object to Unsafe{Get,Put}

Reviewed-by: thartmann, dlong, mdoerr
  • Loading branch information
Yi Yang committed Jul 1, 2021
1 parent 4660f72 commit d89e630cdf05d4ddd07893fa8fe90c32a7eb5433
@@ -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
@@ -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);
}

@@ -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);
}

@@ -857,171 +857,16 @@ 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) {}
void Canonicalizer::do_ProfileCall(ProfileCall* x) {}
void Canonicalizer::do_RoundFP (RoundFP* x) {}
void Canonicalizer::do_UnsafeGet (UnsafeGet* x) {}
void Canonicalizer::do_UnsafePut (UnsafePut* x) {}
void Canonicalizer::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {}
void Canonicalizer::do_ProfileCall (ProfileCall* x) {}
void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {}
void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {}
void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {}
void Canonicalizer::do_ProfileInvoke (ProfileInvoke* x) {}
void Canonicalizer::do_RuntimeCall (RuntimeCall* x) {}
void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
#ifdef ASSERT
void Canonicalizer::do_Assert(Assert* x) {}
void Canonicalizer::do_Assert (Assert* x) {}
#endif
void Canonicalizer::do_MemBar(MemBar* x) {}
void Canonicalizer::do_MemBar (MemBar* x) {}
@@ -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) {
@@ -99,11 +93,9 @@ 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);
virtual void do_UnsafeGet (UnsafeGet* x);
virtual void do_UnsafePut (UnsafePut* x);
virtual void do_UnsafeGetAndSet(UnsafeGetAndSet* x);
virtual void do_ProfileCall (ProfileCall* x);
virtual void do_ProfileReturnType (ProfileReturnType* x);
virtual void do_ProfileInvoke (ProfileInvoke* x);
Loading

1 comment on commit d89e630

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on d89e630 Jul 1, 2021

Please sign in to comment.