// only simm13 constants can be inlined bool LIRGenerator:: can_inline_as_constant(Value i) const { if (i->type()->as_IntConstant() != NULL) { return Assembler::is_simm13(i->type()->as_IntConstant()->value()); } else { return can_store_as_constant(i, as_BasicType(i->type())); } }
FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) { assert(_init_done, "should already be completed"); _framesize = -1; _num_spills = -1; assert(monitors >= 0, "not set"); _num_monitors = monitors; assert(reserved_argument_area_size >= 0, "not set"); _reserved_argument_area_size = MAX2(4, reserved_argument_area_size) * BytesPerWord; _argcount = method->arg_size(); _argument_locations = new intArray(_argcount, -1); _incoming_arguments = java_calling_convention(signature_type_array_for(method), false); _oop_map_arg_count = _incoming_arguments->reserved_stack_slots(); int java_index = 0; for (int i = 0; i < _incoming_arguments->length(); i++) { LIR_Opr opr = _incoming_arguments->at(i); if (opr->is_address()) { LIR_Address* address = opr->as_address_ptr(); _argument_locations->at_put(java_index, address->disp() - STACK_BIAS); _incoming_arguments->args()->at_put(i, LIR_OprFact::stack(java_index, as_BasicType(as_ValueType(address->type())))); } java_index += type2size[opr->type()]; } }
LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { LIR_Opr opr; switch (type->tag()) { case intTag: opr = FrameMap::rax_opr; break; case objectTag: opr = FrameMap::rax_oop_opr; break; case longTag: opr = FrameMap::long0_opr; break; case floatTag: opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr : FrameMap::fpu0_float_opr; break; case doubleTag: opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr; break; case addressTag: default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; } assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch"); return opr; }
static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) { Klass* refk_oop = NULL; BasicType result = as_BasicType(java_class, &refk_oop); (*reference_klass) = KlassHandle(refk_oop); return result; }
LIR_Opr new_register(ValueType* type) { return new_register(as_BasicType(type)); }
LIR_Opr new_register(Value value) { return new_register(as_BasicType(value->type())); }
void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { assert(x->number_of_arguments() == 4, "wrong type"); LIRItem obj (x->argument_at(0), this); // object LIRItem offset(x->argument_at(1), this); // offset of field LIRItem cmp (x->argument_at(2), this); // value to compare with field LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp assert(obj.type()->tag() == objectTag, "invalid type"); // In 64bit the type can be long, sparc doesn't have this assert // assert(offset.type()->tag() == intTag, "invalid type"); assert(cmp.type()->tag() == type->tag(), "invalid type"); assert(val.type()->tag() == type->tag(), "invalid type"); // get address of field obj.load_item(); offset.load_nonconstant(); if (type == objectType) { cmp.load_item_force(FrameMap::rax_oop_opr); val.load_item(); } else if (type == intType) { cmp.load_item_force(FrameMap::rax_opr); val.load_item(); } else if (type == longType) { cmp.load_item_force(FrameMap::long0_opr); val.load_item_force(FrameMap::long1_opr); } else { ShouldNotReachHere(); } LIR_Opr addr = new_pointer_register(); LIR_Address* a; if(offset.result()->is_constant()) { a = new LIR_Address(obj.result(), NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()), as_BasicType(type)); } else { a = new LIR_Address(obj.result(), offset.result(), LIR_Address::times_1, 0, as_BasicType(type)); } __ leal(LIR_OprFact::address(a), addr); if (type == objectType) { // Write-barrier needed for Object fields. // Do the pre-write barrier, if any. pre_barrier(addr, false, NULL); } LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience if (type == objectType) __ cas_obj(addr, cmp.result(), val.result(), ill, ill); else if (type == intType) __ cas_int(addr, cmp.result(), val.result(), ill, ill); else if (type == longType) __ cas_long(addr, cmp.result(), val.result(), ill, ill); else { ShouldNotReachHere(); } // generate conditional move of boolean result LIR_Opr result = rlock_result(x); __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, as_BasicType(type)); if (type == objectType) { // Write-barrier needed for Object fields. // Seems to be precise post_barrier(addr, val.result()); } }
void LoopInvariantCodeMotion::process_block(BlockBegin* block) { TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id())); Instruction* prev = block; Instruction* cur = block->next(); while (cur != NULL) { // determine if cur instruction is loop invariant // only selected instruction types are processed here bool cur_invariant = false; if (cur->as_Constant() != NULL) { cur_invariant = !cur->can_trap(); } else if (cur->as_ArithmeticOp() != NULL || cur->as_LogicOp() != NULL || cur->as_ShiftOp() != NULL) { assert(cur->as_Op2() != NULL, "must be Op2"); Op2* op2 = (Op2*)cur; cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y()); } else if (cur->as_LoadField() != NULL) { LoadField* lf = (LoadField*)cur; // deoptimizes on NullPointerException cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj()) && _insert_is_pred; } else if (cur->as_ArrayLength() != NULL) { ArrayLength *length = cur->as_ArrayLength(); cur_invariant = is_invariant(length->array()); } else if (cur->as_LoadIndexed() != NULL) { LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed(); cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index()) && _insert_is_pred; } if (cur_invariant) { // perform value numbering and mark instruction as loop-invariant _gvn->substitute(cur); if (cur->as_Constant() == NULL) { // ensure that code for non-constant instructions is always generated cur->pin(); } // remove cur instruction from loop block and append it to block before loop Instruction* next = cur->next(); Instruction* in = _insertion_point->next(); _insertion_point = _insertion_point->set_next(cur); cur->set_next(in); // Deoptimize on exception cur->set_flag(Instruction::DeoptimizeOnException, true); // Clear exception handlers cur->set_exception_handlers(NULL); TRACE_VALUE_NUMBERING(tty->print_cr("Instruction %c%d is loop invariant", cur->type()->tchar(), cur->id())); if (cur->state_before() != NULL) { cur->set_state_before(_state->copy()); } if (cur->exception_state() != NULL) { cur->set_exception_state(_state->copy()); } cur = prev->set_next(next); } else { prev = cur; cur = cur->next(); } } }
void kill_array(ValueType* type) { current_map()->kill_array(type); BasicType basic_type = as_BasicType(type); assert(basic_type >= 0 && basic_type <= T_ARRAY, "Invalid type"); _has_indexed_store[basic_type] = true; }