< 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 >