< prev index next >

src/hotspot/share/opto/matcher.cpp

Print this page
rev 60615 : 8231441: Initial SVE backend support
Reviewed-by: adinn, pli
Contributed-by: joshua.zhu@arm.com, yang.zhang@arm.com, ningsheng.jian@arm.com

*** 86,95 **** --- 86,96 ---- idealreg2spillmask [Op_RegN] = NULL; idealreg2spillmask [Op_RegL] = NULL; idealreg2spillmask [Op_RegF] = NULL; idealreg2spillmask [Op_RegD] = NULL; idealreg2spillmask [Op_RegP] = NULL; + idealreg2spillmask [Op_VecA] = NULL; idealreg2spillmask [Op_VecS] = NULL; idealreg2spillmask [Op_VecD] = NULL; idealreg2spillmask [Op_VecX] = NULL; idealreg2spillmask [Op_VecY] = NULL; idealreg2spillmask [Op_VecZ] = NULL;
*** 99,108 **** --- 100,110 ---- idealreg2debugmask [Op_RegN] = NULL; idealreg2debugmask [Op_RegL] = NULL; idealreg2debugmask [Op_RegF] = NULL; idealreg2debugmask [Op_RegD] = NULL; idealreg2debugmask [Op_RegP] = NULL; + idealreg2debugmask [Op_VecA] = NULL; idealreg2debugmask [Op_VecS] = NULL; idealreg2debugmask [Op_VecD] = NULL; idealreg2debugmask [Op_VecX] = NULL; idealreg2debugmask [Op_VecY] = NULL; idealreg2debugmask [Op_VecZ] = NULL;
*** 112,121 **** --- 114,124 ---- idealreg2mhdebugmask[Op_RegN] = NULL; idealreg2mhdebugmask[Op_RegL] = NULL; idealreg2mhdebugmask[Op_RegF] = NULL; idealreg2mhdebugmask[Op_RegD] = NULL; idealreg2mhdebugmask[Op_RegP] = NULL; + idealreg2mhdebugmask[Op_VecA] = NULL; idealreg2mhdebugmask[Op_VecS] = NULL; idealreg2mhdebugmask[Op_VecD] = NULL; idealreg2mhdebugmask[Op_VecX] = NULL; idealreg2mhdebugmask[Op_VecY] = NULL; idealreg2mhdebugmask[Op_VecZ] = NULL;
*** 425,435 **** rms[TypeFunc::ReturnAdr] = ret_adr; rms[TypeFunc::FramePtr ] = fp; return rms; } ! #define NOF_STACK_MASKS (3*6+5) // Create the initial stack mask used by values spilling to the stack. // Disallow any debug info in outgoing argument areas by setting the // initial mask accordingly. void Matcher::init_first_stack_mask() { --- 428,438 ---- rms[TypeFunc::ReturnAdr] = ret_adr; rms[TypeFunc::FramePtr ] = fp; return rms; } ! #define NOF_STACK_MASKS (3*6+6) // Create the initial stack mask used by values spilling to the stack. // Disallow any debug info in outgoing argument areas by setting the // initial mask accordingly. void Matcher::init_first_stack_mask() {
*** 461,475 **** idealreg2mhdebugmask[Op_RegL] = &rms[14]; idealreg2mhdebugmask[Op_RegF] = &rms[15]; idealreg2mhdebugmask[Op_RegD] = &rms[16]; idealreg2mhdebugmask[Op_RegP] = &rms[17]; ! idealreg2spillmask [Op_VecS] = &rms[18]; ! idealreg2spillmask [Op_VecD] = &rms[19]; ! idealreg2spillmask [Op_VecX] = &rms[20]; ! idealreg2spillmask [Op_VecY] = &rms[21]; ! idealreg2spillmask [Op_VecZ] = &rms[22]; OptoReg::Name i; // At first, start with the empty mask C->FIRST_STACK_mask().Clear(); --- 464,479 ---- idealreg2mhdebugmask[Op_RegL] = &rms[14]; idealreg2mhdebugmask[Op_RegF] = &rms[15]; idealreg2mhdebugmask[Op_RegD] = &rms[16]; idealreg2mhdebugmask[Op_RegP] = &rms[17]; ! idealreg2spillmask [Op_VecA] = &rms[18]; ! idealreg2spillmask [Op_VecS] = &rms[19]; ! idealreg2spillmask [Op_VecD] = &rms[20]; ! idealreg2spillmask [Op_VecX] = &rms[21]; ! idealreg2spillmask [Op_VecY] = &rms[22]; ! idealreg2spillmask [Op_VecZ] = &rms[23]; OptoReg::Name i; // At first, start with the empty mask C->FIRST_STACK_mask().Clear();
*** 492,501 **** --- 496,506 ---- // Make spill masks. Registers for their class, plus FIRST_STACK_mask. RegMask aligned_stack_mask = C->FIRST_STACK_mask(); // Keep spill masks aligned. aligned_stack_mask.clear_to_pairs(); assert(aligned_stack_mask.is_AllStack(), "should be infinite stack"); + RegMask scalable_stack_mask = aligned_stack_mask; *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP]; #ifdef _LP64 *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN]; idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask());
*** 562,571 **** --- 567,596 ---- aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecZ); assert(aligned_stack_mask.is_AllStack(), "should be infinite stack"); *idealreg2spillmask[Op_VecZ] = *idealreg2regmask[Op_VecZ]; idealreg2spillmask[Op_VecZ]->OR(aligned_stack_mask); } + + if (Matcher::supports_scalable_vector()) { + int k = 1; + OptoReg::Name in = OptoReg::add(_in_arg_limit, -1); + // Exclude last input arg stack slots to avoid spilling vector register there, + // otherwise vector spills could stomp over stack slots in caller frame. + for (; (in >= init_in) && (k < scalable_vector_reg_size(T_FLOAT)); k++) { + scalable_stack_mask.Remove(in); + in = OptoReg::add(in, -1); + } + + // For VecA + scalable_stack_mask.clear_to_sets(RegMask::SlotsPerVecA); + assert(scalable_stack_mask.is_AllStack(), "should be infinite stack"); + *idealreg2spillmask[Op_VecA] = *idealreg2regmask[Op_VecA]; + idealreg2spillmask[Op_VecA]->OR(scalable_stack_mask); + } else { + *idealreg2spillmask[Op_VecA] = RegMask::Empty; + } + if (UseFPUForSpilling) { // This mask logic assumes that the spill operations are // symmetric and that the registers involved are the same size. // On sparc for instance we may have to use 64 bit moves will // kill 2 registers when used with F0-F31.
*** 876,885 **** --- 901,911 ---- idealreg2regmask[Op_RegI] = regmask_for_ideal_register(Op_RegI, ret); idealreg2regmask[Op_RegP] = regmask_for_ideal_register(Op_RegP, ret); idealreg2regmask[Op_RegF] = regmask_for_ideal_register(Op_RegF, ret); idealreg2regmask[Op_RegD] = regmask_for_ideal_register(Op_RegD, ret); idealreg2regmask[Op_RegL] = regmask_for_ideal_register(Op_RegL, ret); + idealreg2regmask[Op_VecA] = regmask_for_ideal_register(Op_VecA, ret); idealreg2regmask[Op_VecS] = regmask_for_ideal_register(Op_VecS, ret); idealreg2regmask[Op_VecD] = regmask_for_ideal_register(Op_VecD, ret); idealreg2regmask[Op_VecX] = regmask_for_ideal_register(Op_VecX, ret); idealreg2regmask[Op_VecY] = regmask_for_ideal_register(Op_VecY, ret); idealreg2regmask[Op_VecZ] = regmask_for_ideal_register(Op_VecZ, ret);
*** 1561,1571 **** control = Label_Root(m, s, control, mem); if (C->failing()) return NULL; } } - // Call DFA to match this node, and return svec->DFA( n->Opcode(), n ); #ifdef ASSERT uint x; --- 1587,1596 ----
*** 2411,2421 **** // Compute RegMask for an ideal register. const RegMask* Matcher::regmask_for_ideal_register(uint ideal_reg, Node* ret) { const Type* t = Type::mreg2type[ideal_reg]; if (t == NULL) { ! assert(ideal_reg >= Op_VecS && ideal_reg <= Op_VecZ, "not a vector: %d", ideal_reg); return NULL; // not supported } Node* fp = ret->in(TypeFunc::FramePtr); Node* mem = ret->in(TypeFunc::Memory); const TypePtr* atp = TypePtr::BOTTOM; --- 2436,2446 ---- // Compute RegMask for an ideal register. const RegMask* Matcher::regmask_for_ideal_register(uint ideal_reg, Node* ret) { const Type* t = Type::mreg2type[ideal_reg]; if (t == NULL) { ! assert(ideal_reg >= Op_VecA && ideal_reg <= Op_VecZ, "not a vector: %d", ideal_reg); return NULL; // not supported } Node* fp = ret->in(TypeFunc::FramePtr); Node* mem = ret->in(TypeFunc::Memory); const TypePtr* atp = TypePtr::BOTTOM;
*** 2428,2437 **** --- 2453,2463 ---- case Op_RegP: spill = new LoadPNode(NULL, mem, fp, atp, t->is_ptr(), mo); break; case Op_RegF: spill = new LoadFNode(NULL, mem, fp, atp, t, mo); break; case Op_RegD: spill = new LoadDNode(NULL, mem, fp, atp, t, mo); break; case Op_RegL: spill = new LoadLNode(NULL, mem, fp, atp, t->is_long(), mo); break; + case Op_VecA: // fall-through case Op_VecS: // fall-through case Op_VecD: // fall-through case Op_VecX: // fall-through case Op_VecY: // fall-through case Op_VecZ: spill = new LoadVectorNode(NULL, mem, fp, atp, t->is_vect()); break;
< prev index next >