< prev index next >

src/hotspot/cpu/aarch64/aarch64.ad

Print this page
rev 48394 : [RFC] MachSpillCopy peephole
Enable OptoPeephole by default on AArch64.
Add manually defined peephole() method for MachSpillCopy node.

*** 3280,3291 **** --- 3280,3298 ---- __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo])); } } else { // gpr --> stack spill assert(dst_lo_rc == rc_stack, "spill to bad register class"); + if (_spill_type == Pair) { + __ spill(as_Register(Matcher::_regEncode[src_lo]), + as_Register(Matcher::_regEncode[pair_hi_reg]), + is64, + dst_offset); + } else { __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); } + } break; case rc_float: if (dst_lo_rc == rc_int) { // fpr --> gpr copy if (is64) { __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
*** 3308,3318 **** --- 3315,3333 ---- is64 ? __ D : __ S, dst_offset); } break; case rc_stack: if (dst_lo_rc == rc_int) { // stack --> gpr load + if (_spill_type == Pair) { + assert(pair_hi_reg != OptoReg::Bad, "bad register"); + __ unspill(as_Register(Matcher::_regEncode[dst_lo]), + as_Register(Matcher::_regEncode[pair_hi_reg]), + is64, + src_offset); + } else { __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); + } } else if (dst_lo_rc == rc_float) { // stack --> fpr load __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), is64 ? __ D : __ S, src_offset); } else { // stack --> stack copy assert(dst_lo_rc == rc_stack, "spill to bad register class");
*** 3364,3373 **** --- 3379,3467 ---- uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { return MachNode::size(ra_); } + MachNode *MachSpillCopyNode::peephole(Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted) { + MachSpillCopyNode *inst0 = this; + MachSpillCopyNode *inst1 = NULL; + if ( block_index - 1 > 0 ) { + Node *n = block->get_node(block_index - 1); + inst1 = (n->is_MachSpillCopy()) ? n->as_MachSpillCopy() : NULL; + } + if (inst1 == NULL) { + return NULL; + } + if (bottom_type()->isa_vect() != NULL || + inst1->bottom_type()->isa_vect() != NULL || + _spill_type == Pair || + inst1->_spill_type == Pair) { + return NULL; + } + // + OptoReg::Name src_lo = ra_->get_reg_first(in(1)); + OptoReg::Name dst_lo = ra_->get_reg_first(this); + enum RC src_lo_rc = rc_class(src_lo); + enum RC dst_lo_rc = rc_class(dst_lo); + OptoReg::Name inst1_src_lo = ra_->get_reg_first(inst1->in(1)); + OptoReg::Name inst1_dst_lo = ra_->get_reg_first(inst1); + enum RC inst1_src_lo_rc = rc_class(inst1_src_lo); + enum RC inst1_dst_lo_rc = rc_class(inst1_dst_lo); + if (((src_lo_rc == rc_stack && dst_lo_rc == rc_int) + || (dst_lo_rc == rc_stack && src_lo_rc == rc_int)) + && ((inst1_src_lo_rc == rc_stack && inst1_dst_lo_rc == rc_int) + || (inst1_dst_lo_rc == rc_stack && inst1_src_lo_rc == rc_int))) { + OptoReg::Name src_hi = ra_->get_reg_second(in(1)); + OptoReg::Name dst_hi = ra_->get_reg_second(this); + enum RC dst_hi_rc = rc_class(dst_hi); + enum RC src_hi_rc = rc_class(src_hi); + OptoReg::Name inst1_src_hi = ra_->get_reg_second(inst1->in(1)); + OptoReg::Name inst1_dst_hi = ra_->get_reg_second(inst1); + bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && + (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; + bool inst1_is64 = (inst1_src_lo & 1) == 0 && inst1_src_lo + 1 == inst1_src_hi && + (inst1_dst_lo & 1) == 0 && inst1_dst_lo + 1 == inst1_dst_hi; + if (is64 ^ inst1_is64) { + return NULL; + } + int offset = 0; + OptoReg::Name other_reg = OptoReg::Bad; + MachSpillCopyNode* pair = NULL; + int src_offset = ra_->reg2offset(src_lo); + int dst_offset = ra_->reg2offset(dst_lo); + int inst1_src_offset = ra_->reg2offset(inst1_src_lo); + int inst1_dst_offset = ra_->reg2offset(inst1_dst_lo); + if (dst_lo_rc == rc_stack) { + assert(dst_offset >= 0, "invalid offset"); + offset = dst_offset - inst1_dst_offset; + } else if (src_lo_rc == rc_stack) { + assert(src_offset >= 0, "invalid offset"); + offset = src_offset - inst1_src_offset; + } + // TODO alignment check for some CPU. + if ((is64 && abs(offset) == 8) || (!is64 && abs(offset) == 4)) { // TODO: 8/4 magic number + if (offset < 0) { // (this, inst1) + pair = this; + pair->pair_hi_reg = (src_lo_rc == rc_stack) ? inst1_dst_lo : inst1_src_lo; + if (Verbose) { + tty->print_cr("DEBUG: valid replacement found: %d && %d", pair->_idx, inst1->_idx); + } + } else { // (inst1, this) + pair = inst1; + pair->pair_hi_reg = (src_lo_rc == rc_stack) ? dst_lo : src_lo; + if (Verbose) { + tty->print_cr("DEBUG: valid replacement found: %d && %d", pair->_idx, this->_idx); + } + } + pair->_spill_type = Pair; + deleted = 2; + return pair; + } + } + return NULL; + } + //============================================================================= #ifndef PRODUCT void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
< prev index next >