< prev index next >

src/hotspot/share/opto/chaitin.cpp

Print this page
*** 75,10 ***
--- 75,11 ---
    tty->print("Cost:%4.2g Area:%4.2g Score:%4.2g ",_cost,_area, score());
    // Flags
    if( _is_oop ) tty->print("Oop ");
    if( _is_float ) tty->print("Float ");
    if( _is_vector ) tty->print("Vector ");
+   if( _is_predicate ) tty->print("Predicate ");
    if( _is_scalable ) tty->print("Scalable ");
    if( _was_spilled1 ) tty->print("Spilled ");
    if( _was_spilled2 ) tty->print("Spilled2 ");
    if( _direct_conflict ) tty->print("Direct_conflict ");
    if( _fat_proj ) tty->print("Fat ");

*** 636,11 ***
    for (uint i=0; i < _lrg_map.size(); i++) {
      if (_lrg_map.live_range_id(i)) { // Live range associated with Node?
        LRG &lrg = lrgs(_lrg_map.live_range_id(i));
        if (!lrg.alive()) {
          set_bad(i);
!       } else if (lrg.num_regs() == 1) {
          set1(i, lrg.reg());
        } else {                  // Must be a register-set
          if (!lrg._fat_proj) {   // Must be aligned adjacent register set
            // Live ranges record the highest register in their mask.
            // We want the low register for the AD file writer's convenience.
--- 637,12 ---
    for (uint i=0; i < _lrg_map.size(); i++) {
      if (_lrg_map.live_range_id(i)) { // Live range associated with Node?
        LRG &lrg = lrgs(_lrg_map.live_range_id(i));
        if (!lrg.alive()) {
          set_bad(i);
!       } else if ((lrg.num_regs() == 1 && !lrg.is_scalable()) ||
+                  (lrg.is_scalable() && lrg.scalable_reg_slots() == 1)) {
          set1(i, lrg.reg());
        } else {                  // Must be a register-set
          if (!lrg._fat_proj) {   // Must be aligned adjacent register set
            // Live ranges record the highest register in their mask.
            // We want the low register for the AD file writer's convenience.

*** 651,19 ***
              // registers, num_regs is RegMask::SlotsPerVecA for reg mask of scalable
              // vector. If they are allocated on stack, we need to get the actual
              // num_regs, which reflects the physical length of scalable registers.
              num_regs = lrg.scalable_reg_slots();
            }
!           OptoReg::Name lo = OptoReg::add(hi, (1-num_regs)); // Find lo
!           // We have to use pair [lo,lo+1] even for wide vectors because
!           // the rest of code generation works only with pairs. It is safe
!           // since for registers encoding only 'lo' is used.
!           // Second reg from pair is used in ScheduleAndBundle on SPARC where
!           // vector max size is 8 which corresponds to registers pair.
!           // It is also used in BuildOopMaps but oop operations are not
!           // vectorized.
!           set2(i, lo);
          } else {                // Misaligned; extract 2 bits
            OptoReg::Name hi = lrg.reg(); // Get hi register
            lrg.Remove(hi);       // Yank from mask
            int lo = lrg.mask().find_first_elem(); // Find lo
            set_pair(i, hi, lo);
--- 653,23 ---
              // registers, num_regs is RegMask::SlotsPerVecA for reg mask of scalable
              // vector. If they are allocated on stack, we need to get the actual
              // num_regs, which reflects the physical length of scalable registers.
              num_regs = lrg.scalable_reg_slots();
            }
!           if (num_regs == 1) {
!             set1(i, hi);
!           } else {
!             OptoReg::Name lo = OptoReg::add(hi, (1 - num_regs)); // Find lo
!             // We have to use pair [lo,lo+1] even for wide vectors/vmasks because
!             // the rest of code generation works only with pairs. It is safe
!             // since for registers encoding only 'lo' is used.
!             // Second reg from pair is used in ScheduleAndBundle with vector max
!             // size 8 which corresponds to registers pair.
+             // It is also used in BuildOopMaps but oop operations are not
+             // vectorized.
+             set2(i, lo);
+           }
          } else {                // Misaligned; extract 2 bits
            OptoReg::Name hi = lrg.reg(); // Get hi register
            lrg.Remove(hi);       // Yank from mask
            int lo = lrg.mask().find_first_elem(); // Find lo
            set_pair(i, hi, lo);

*** 822,12 ***
              // If it is allocated in stack, we need to get the actual
              // physical length of scalable vector register.
              lrg.set_scalable_reg_slots(Matcher::scalable_vector_reg_size(T_FLOAT));
            }
          }
          assert(n_type->isa_vect() == NULL || lrg._is_vector ||
!                ireg == Op_RegD || ireg == Op_RegL  || ireg == Op_RegVectMask,
                 "vector must be in vector registers");
  
          // Check for bound register masks
          const RegMask &lrgmask = lrg.mask();
          if (lrgmask.is_bound(ireg)) {
--- 828,26 ---
              // If it is allocated in stack, we need to get the actual
              // physical length of scalable vector register.
              lrg.set_scalable_reg_slots(Matcher::scalable_vector_reg_size(T_FLOAT));
            }
          }
+ 
+         if (ireg == Op_RegVectMask) {
+           assert(Matcher::has_predicated_vectors(), "predicated vector should be supported");
+           lrg._is_predicate = 1;
+           if (Matcher::supports_scalable_vector()) {
+             lrg._is_scalable = 1;
+             // For scalable predicate, when it is allocated in physical register,
+             // num_regs is RegMask::SlotsPerRegVectMask for reg mask,
+             // which may not be the actual physical register size.
+             // If it is allocated in stack, we need to get the actual
+             // physical length of scalable predicate register.
+             lrg.set_scalable_reg_slots(Matcher::scalable_predicate_reg_slots());
+           }
+         }
          assert(n_type->isa_vect() == NULL || lrg._is_vector ||
!                ireg == Op_RegD || ireg == Op_RegL || ireg == Op_RegVectMask,
                 "vector must be in vector registers");
  
          // Check for bound register masks
          const RegMask &lrgmask = lrg.mask();
          if (lrgmask.is_bound(ireg)) {

*** 917,10 ***
--- 937,12 ---
              lrg._fat_proj = 1;
              lrg._is_bound = 1;
            }
            break;
          case Op_RegVectMask:
+           assert(Matcher::has_predicated_vectors(), "sanity");
+           assert(RegMask::num_registers(Op_RegVectMask) == RegMask::SlotsPerRegVectMask, "sanity");
            lrg.set_num_regs(RegMask::SlotsPerRegVectMask);
            lrg.set_reg_pressure(1);
            break;
          case Op_RegF:
          case Op_RegI:

*** 1369,10 ***
--- 1391,15 ---
            mask.clear_to_sets(RegMask::SlotsPerVecA); // Align by SlotsPerVecA bits
            assigned = mask.find_first_set(lrg, num_regs);
          }
        }
        return OptoReg::Bad; // will cause chunk change, and retry next chunk
+     } else if (lrg._is_predicate) {
+       assert(num_regs == RegMask::SlotsPerRegVectMask, "scalable predicate register");
+       num_regs = lrg.scalable_reg_slots();
+       mask.clear_to_sets(num_regs);
+       return mask.find_first_set(lrg, num_regs);
      }
    }
  
    return assigned;
  }

*** 1415,11 ***
          return reg;
      }
    }
  
    // If no bias info exists, just go with the register selection ordering
!   if (lrg._is_vector || lrg.num_regs() == 2) {
      // Find an aligned set
      return OptoReg::add(find_first_set(lrg, lrg.mask(), chunk), chunk);
    }
  
    // CNC - Fun hack.  Alternate 1st and 2nd selection.  Enables post-allocate
--- 1442,11 ---
          return reg;
      }
    }
  
    // If no bias info exists, just go with the register selection ordering
!   if (lrg._is_vector || lrg.num_regs() == 2 || lrg.is_scalable()) {
      // Find an aligned set
      return OptoReg::add(find_first_set(lrg, lrg.mask(), chunk), chunk);
    }
  
    // CNC - Fun hack.  Alternate 1st and 2nd selection.  Enables post-allocate
< prev index next >