< prev index next >

src/hotspot/share/opto/matcher.cpp

Print this page
*** 86,10 ***
--- 86,11 ---
    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,10 ***
--- 100,11 ---
    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,10 ***
--- 114,11 ---
    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,11 ***
    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,11 ---
    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,15 ***
    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,16 ---
    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,10 ***
--- 496,11 ---
    // 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,32 ***
       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 (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.
!      idealreg2spillmask[Op_RegI]->OR(*idealreg2regmask[Op_RegF]);
!      idealreg2spillmask[Op_RegF]->OR(*idealreg2regmask[Op_RegI]);
  #ifdef _LP64
!      idealreg2spillmask[Op_RegN]->OR(*idealreg2regmask[Op_RegF]);
!      idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
!      idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
!      idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegD]);
  #else
!      idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegF]);
  #ifdef ARM
!      // ARM has support for moving 64bit values between a pair of
!      // integer registers and a double register
!      idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
!      idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
  #endif
  #endif
!    }
  
    // Make up debug masks.  Any spill slot plus callee-save (SOE) registers.
    // Caller-save (SOC, AS) registers are assumed to be trashable by the various
    // inline-cache fixup routines.
    *idealreg2debugmask  [Op_RegN] = *idealreg2spillmask[Op_RegN];
--- 567,52 ---
       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.
+     idealreg2spillmask[Op_RegI]->OR(*idealreg2regmask[Op_RegF]);
+     idealreg2spillmask[Op_RegF]->OR(*idealreg2regmask[Op_RegI]);
  #ifdef _LP64
!     idealreg2spillmask[Op_RegN]->OR(*idealreg2regmask[Op_RegF]);
!     idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
!     idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
!     idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegD]);
  #else
!     idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegF]);
  #ifdef ARM
!     // ARM has support for moving 64bit values between a pair of
!     // integer registers and a double register
!     idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
!     idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
  #endif
  #endif
!   }
  
    // Make up debug masks.  Any spill slot plus callee-save (SOE) registers.
    // Caller-save (SOC, AS) registers are assumed to be trashable by the various
    // inline-cache fixup routines.
    *idealreg2debugmask  [Op_RegN] = *idealreg2spillmask[Op_RegN];

*** 876,10 ***
--- 901,11 ---
    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,11 ***
        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,10 ---

*** 2411,11 ***
  
  // 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,11 ---
  
  // 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,10 ***
--- 2453,11 ---
      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 >