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


3265     case rc_int:
3266       if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
3267         if (is64) {
3268             __ mov(as_Register(Matcher::_regEncode[dst_lo]),
3269                    as_Register(Matcher::_regEncode[src_lo]));
3270         } else {
3271             MacroAssembler _masm(cbuf);
3272             __ movw(as_Register(Matcher::_regEncode[dst_lo]),
3273                     as_Register(Matcher::_regEncode[src_lo]));
3274         }
3275       } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
3276         if (is64) {
3277             __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3278                      as_Register(Matcher::_regEncode[src_lo]));
3279         } else {
3280             __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3281                      as_Register(Matcher::_regEncode[src_lo]));
3282         }
3283       } else {                    // gpr --> stack spill
3284         assert(dst_lo_rc == rc_stack, "spill to bad register class");






3285         __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
3286       }

3287       break;
3288     case rc_float:
3289       if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
3290         if (is64) {
3291             __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
3292                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3293         } else {
3294             __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
3295                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3296         }
3297       } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
3298           if (cbuf) {
3299             __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3300                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3301         } else {
3302             __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3303                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3304         }
3305       } else {                    // fpr --> stack spill
3306         assert(dst_lo_rc == rc_stack, "spill to bad register class");
3307         __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
3308                  is64 ? __ D : __ S, dst_offset);
3309       }
3310       break;
3311     case rc_stack:
3312       if (dst_lo_rc == rc_int) {  // stack --> gpr load







3313         __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);

3314       } else if (dst_lo_rc == rc_float) { // stack --> fpr load
3315         __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3316                    is64 ? __ D : __ S, src_offset);
3317       } else {                    // stack --> stack copy
3318         assert(dst_lo_rc == rc_stack, "spill to bad register class");
3319         __ unspill(rscratch1, is64, src_offset);
3320         __ spill(rscratch1, is64, dst_offset);
3321       }
3322       break;
3323     default:
3324       assert(false, "bad rc_class for spill");
3325       ShouldNotReachHere();
3326     }
3327   }
3328 
3329   if (st) {
3330     st->print("spill ");
3331     if (src_lo_rc == rc_stack) {
3332       st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
3333     } else {


3349 
3350 }
3351 
3352 #ifndef PRODUCT
3353 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3354   if (!ra_)
3355     st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
3356   else
3357     implementation(NULL, ra_, false, st);
3358 }
3359 #endif
3360 
3361 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3362   implementation(&cbuf, ra_, false, NULL);
3363 }
3364 
3365 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
3366   return MachNode::size(ra_);
3367 }
3368 















































































3369 //=============================================================================
3370 
3371 #ifndef PRODUCT
3372 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3373   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3374   int reg = ra_->get_reg_first(this);
3375   st->print("add %s, rsp, #%d]\t# box lock",
3376             Matcher::regName[reg], offset);
3377 }
3378 #endif
3379 
3380 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3381   MacroAssembler _masm(&cbuf);
3382 
3383   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3384   int reg    = ra_->get_encode(this);
3385 
3386   if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
3387     __ add(as_Register(reg), sp, offset);
3388   } else {




3265     case rc_int:
3266       if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
3267         if (is64) {
3268             __ mov(as_Register(Matcher::_regEncode[dst_lo]),
3269                    as_Register(Matcher::_regEncode[src_lo]));
3270         } else {
3271             MacroAssembler _masm(cbuf);
3272             __ movw(as_Register(Matcher::_regEncode[dst_lo]),
3273                     as_Register(Matcher::_regEncode[src_lo]));
3274         }
3275       } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
3276         if (is64) {
3277             __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3278                      as_Register(Matcher::_regEncode[src_lo]));
3279         } else {
3280             __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3281                      as_Register(Matcher::_regEncode[src_lo]));
3282         }
3283       } else {                    // gpr --> stack spill
3284         assert(dst_lo_rc == rc_stack, "spill to bad register class");
3285         if (_spill_type == Pair) {
3286           __ spill(as_Register(Matcher::_regEncode[src_lo]),
3287                    as_Register(Matcher::_regEncode[pair_hi_reg]),
3288                    is64,
3289                    dst_offset);
3290         } else {
3291           __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
3292         }
3293       }
3294       break;
3295     case rc_float:
3296       if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
3297         if (is64) {
3298             __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
3299                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3300         } else {
3301             __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
3302                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3303         }
3304       } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
3305           if (cbuf) {
3306             __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3307                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3308         } else {
3309             __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3310                      as_FloatRegister(Matcher::_regEncode[src_lo]));
3311         }
3312       } else {                    // fpr --> stack spill
3313         assert(dst_lo_rc == rc_stack, "spill to bad register class");
3314         __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
3315                  is64 ? __ D : __ S, dst_offset);
3316       }
3317       break;
3318     case rc_stack:
3319       if (dst_lo_rc == rc_int) {  // stack --> gpr load
3320         if (_spill_type == Pair) {
3321           assert(pair_hi_reg != OptoReg::Bad, "bad register");
3322           __ unspill(as_Register(Matcher::_regEncode[dst_lo]),
3323                      as_Register(Matcher::_regEncode[pair_hi_reg]),
3324                      is64,
3325                      src_offset);
3326         } else {
3327           __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
3328         }
3329       } else if (dst_lo_rc == rc_float) { // stack --> fpr load
3330         __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3331                    is64 ? __ D : __ S, src_offset);
3332       } else {                    // stack --> stack copy
3333         assert(dst_lo_rc == rc_stack, "spill to bad register class");
3334         __ unspill(rscratch1, is64, src_offset);
3335         __ spill(rscratch1, is64, dst_offset);
3336       }
3337       break;
3338     default:
3339       assert(false, "bad rc_class for spill");
3340       ShouldNotReachHere();
3341     }
3342   }
3343 
3344   if (st) {
3345     st->print("spill ");
3346     if (src_lo_rc == rc_stack) {
3347       st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
3348     } else {


3364 
3365 }
3366 
3367 #ifndef PRODUCT
3368 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3369   if (!ra_)
3370     st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
3371   else
3372     implementation(NULL, ra_, false, st);
3373 }
3374 #endif
3375 
3376 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3377   implementation(&cbuf, ra_, false, NULL);
3378 }
3379 
3380 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
3381   return MachNode::size(ra_);
3382 }
3383 
3384 MachNode *MachSpillCopyNode::peephole(Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted) {
3385   MachSpillCopyNode *inst0 = this;
3386   MachSpillCopyNode *inst1 = NULL;
3387   if ( block_index - 1 > 0 ) {
3388     Node *n = block->get_node(block_index - 1);
3389     inst1 = (n->is_MachSpillCopy()) ? n->as_MachSpillCopy() : NULL;
3390   }
3391   if (inst1 == NULL) {
3392     return NULL;
3393   }
3394   if (bottom_type()->isa_vect() != NULL ||
3395       inst1->bottom_type()->isa_vect() != NULL ||
3396       _spill_type == Pair ||
3397       inst1->_spill_type == Pair) {
3398     return NULL;
3399   }
3400   //
3401   OptoReg::Name src_lo = ra_->get_reg_first(in(1));
3402   OptoReg::Name dst_lo = ra_->get_reg_first(this);
3403   enum RC src_lo_rc = rc_class(src_lo);
3404   enum RC dst_lo_rc = rc_class(dst_lo);
3405   OptoReg::Name inst1_src_lo = ra_->get_reg_first(inst1->in(1));
3406   OptoReg::Name inst1_dst_lo = ra_->get_reg_first(inst1);
3407   enum RC inst1_src_lo_rc = rc_class(inst1_src_lo);
3408   enum RC inst1_dst_lo_rc = rc_class(inst1_dst_lo);
3409   if (((src_lo_rc == rc_stack && dst_lo_rc == rc_int)
3410       || (dst_lo_rc == rc_stack && src_lo_rc == rc_int))
3411       && ((inst1_src_lo_rc == rc_stack && inst1_dst_lo_rc == rc_int)
3412           || (inst1_dst_lo_rc == rc_stack && inst1_src_lo_rc == rc_int))) {
3413     OptoReg::Name src_hi = ra_->get_reg_second(in(1));
3414     OptoReg::Name dst_hi = ra_->get_reg_second(this);
3415     enum RC dst_hi_rc = rc_class(dst_hi);
3416     enum RC src_hi_rc = rc_class(src_hi);
3417     OptoReg::Name inst1_src_hi = ra_->get_reg_second(inst1->in(1));
3418     OptoReg::Name inst1_dst_hi = ra_->get_reg_second(inst1);
3419     bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
3420       (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
3421     bool inst1_is64 = (inst1_src_lo & 1) == 0 && inst1_src_lo + 1 == inst1_src_hi &&
3422       (inst1_dst_lo & 1) == 0 && inst1_dst_lo + 1 == inst1_dst_hi;
3423     if (is64 ^ inst1_is64) {
3424       return NULL;
3425     }
3426     int offset = 0;
3427     OptoReg::Name other_reg = OptoReg::Bad;
3428     MachSpillCopyNode* pair = NULL;
3429     int src_offset = ra_->reg2offset(src_lo);
3430     int dst_offset = ra_->reg2offset(dst_lo);
3431     int inst1_src_offset = ra_->reg2offset(inst1_src_lo);
3432     int inst1_dst_offset = ra_->reg2offset(inst1_dst_lo);
3433     if (dst_lo_rc == rc_stack) {
3434       assert(dst_offset >= 0, "invalid offset");
3435       offset = dst_offset - inst1_dst_offset;
3436     } else if (src_lo_rc == rc_stack) {
3437       assert(src_offset >= 0, "invalid offset");
3438       offset = src_offset - inst1_src_offset;
3439     }
3440     // TODO alignment check for some CPU.
3441     if ((is64 && abs(offset) == 8) || (!is64 && abs(offset) == 4)) { // TODO: 8/4 magic number
3442       if (offset < 0) { // (this, inst1)
3443         pair = this;
3444         pair->pair_hi_reg = (src_lo_rc == rc_stack) ? inst1_dst_lo : inst1_src_lo;
3445         if (Verbose) {
3446           tty->print_cr("DEBUG: valid replacement found: %d && %d", pair->_idx, inst1->_idx);
3447         }
3448       } else { // (inst1, this)
3449         pair = inst1;
3450         pair->pair_hi_reg = (src_lo_rc == rc_stack) ? dst_lo : src_lo;
3451         if (Verbose) {
3452           tty->print_cr("DEBUG: valid replacement found: %d && %d", pair->_idx, this->_idx);
3453         }
3454       }
3455       pair->_spill_type = Pair;
3456       deleted = 2;
3457       return pair;
3458     }
3459   }
3460   return NULL;
3461 }
3462 
3463 //=============================================================================
3464 
3465 #ifndef PRODUCT
3466 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3467   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3468   int reg = ra_->get_reg_first(this);
3469   st->print("add %s, rsp, #%d]\t# box lock",
3470             Matcher::regName[reg], offset);
3471 }
3472 #endif
3473 
3474 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3475   MacroAssembler _masm(&cbuf);
3476 
3477   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3478   int reg    = ra_->get_encode(this);
3479 
3480   if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
3481     __ add(as_Register(reg), sp, offset);
3482   } else {


< prev index next >