< prev index next >

src/hotspot/share/opto/postaloc.cpp

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
--- 1,7 ---
  /*
!  * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

*** 264,13 ***
    // intermediate copies might be illegal, i.e., value is stored down to stack
    // then reloaded BUT survives in a register the whole way.
    Node *val = skip_copies(n->in(k));
    if (val == x) return blk_adjust; // No progress?
  
-   int n_regs = RegMask::num_registers(val->ideal_reg());
    uint val_idx = _lrg_map.live_range_id(val);
    OptoReg::Name val_reg = lrgs(val_idx).reg();
  
    // See if it happens to already be in the correct register!
    // (either Phi's direct register, or the common case of the name
    // never-clobbered original-def register)
    if (register_contains_value(val, val_reg, n_regs, value)) {
--- 264,13 ---
    // intermediate copies might be illegal, i.e., value is stored down to stack
    // then reloaded BUT survives in a register the whole way.
    Node *val = skip_copies(n->in(k));
    if (val == x) return blk_adjust; // No progress?
  
    uint val_idx = _lrg_map.live_range_id(val);
    OptoReg::Name val_reg = lrgs(val_idx).reg();
+   int n_regs = RegMask::num_registers(val->ideal_reg(), lrgs(val_idx));
  
    // See if it happens to already be in the correct register!
    // (either Phi's direct register, or the common case of the name
    // never-clobbered original-def register)
    if (register_contains_value(val, val_reg, n_regs, value)) {

*** 303,12 ***
        }
        if (ignore_self) continue;
      }
  
      Node *vv = value[reg];
      if (n_regs > 1) { // Doubles and vectors check for aligned-adjacent set
!       uint last = (n_regs-1); // Looking for the last part of a set
        if ((reg&last) != last) continue; // Wrong part of a set
        if (!register_contains_value(vv, reg, n_regs, value)) continue; // Different value
      }
      if( vv == val ||            // Got a direct hit?
          (t && vv && vv->bottom_type() == t && vv->is_Mach() &&
--- 303,30 ---
        }
        if (ignore_self) continue;
      }
  
      Node *vv = value[reg];
+     // For scalable register, number of registers may be inconsistent between
+     // "val_reg" and "reg". For example, when "val" resides in register
+     // but "reg" is located in stack.
+     if (lrgs(val_idx).is_scalable()) {
+       assert(val->ideal_reg() == Op_VecA, "scalable vector register");
+       if (OptoReg::is_stack(reg)) {
+         n_regs = lrgs(val_idx).scalable_reg_slots();
+       } else {
+         n_regs = RegMask::SlotsPerVecA;
+       }
+     }
      if (n_regs > 1) { // Doubles and vectors check for aligned-adjacent set
!       uint last;
+       if (lrgs(val_idx).is_scalable()) {
+         assert(val->ideal_reg() == Op_VecA, "scalable vector register");
+         // For scalable vector register, regmask is always SlotsPerVecA bits aligned
+         last = RegMask::SlotsPerVecA - 1;
+       } else {
+         last = (n_regs-1); // Looking for the last part of a set
+       }
        if ((reg&last) != last) continue; // Wrong part of a set
        if (!register_contains_value(vv, reg, n_regs, value)) continue; // Different value
      }
      if( vv == val ||            // Got a direct hit?
          (t && vv && vv->bottom_type() == t && vv->is_Mach() &&

*** 589,11 ***
      // For all Phi's
      for (j = 1; j < phi_dex; j++) {
        uint k;
        Node *phi = block->get_node(j);
        uint pidx = _lrg_map.live_range_id(phi);
!       OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
  
        // Remove copies remaining on edges.  Check for junk phi.
        Node *u = NULL;
        for (k = 1; k < phi->req(); k++) {
          Node *x = phi->in(k);
--- 607,11 ---
      // For all Phi's
      for (j = 1; j < phi_dex; j++) {
        uint k;
        Node *phi = block->get_node(j);
        uint pidx = _lrg_map.live_range_id(phi);
!       OptoReg::Name preg = lrgs(pidx).reg();
  
        // Remove copies remaining on edges.  Check for junk phi.
        Node *u = NULL;
        for (k = 1; k < phi->req(); k++) {
          Node *x = phi->in(k);

*** 617,11 ***
        // the new values.  Not illegal by itself but throws the over-strong
        // assert in scheduling.
        if( pidx ) {
          value.map(preg,phi);
          regnd.map(preg,phi);
!         int n_regs = RegMask::num_registers(phi->ideal_reg());
          for (int l = 1; l < n_regs; l++) {
            OptoReg::Name preg_lo = OptoReg::add(preg,-l);
            value.map(preg_lo,phi);
            regnd.map(preg_lo,phi);
          }
--- 635,11 ---
        // the new values.  Not illegal by itself but throws the over-strong
        // assert in scheduling.
        if( pidx ) {
          value.map(preg,phi);
          regnd.map(preg,phi);
!         int n_regs = RegMask::num_registers(phi->ideal_reg(), lrgs(pidx));
          for (int l = 1; l < n_regs; l++) {
            OptoReg::Name preg_lo = OptoReg::add(preg,-l);
            value.map(preg_lo,phi);
            regnd.map(preg_lo,phi);
          }

*** 661,11 ***
              Node *valdef = skip_copies(def); // tighten up val through non-useless copies
              value.map(ureg,valdef); // record improved reaching-def info
              regnd.map(ureg,   def);
              // Record other half of doubles
              uint def_ideal_reg = def->ideal_reg();
!             int n_regs = RegMask::num_registers(def_ideal_reg);
              for (int l = 1; l < n_regs; l++) {
                OptoReg::Name ureg_lo = OptoReg::add(ureg,-l);
                if (!value[ureg_lo] &&
                    (!RegMask::can_represent(ureg_lo) ||
                     lrgs(useidx).mask().Member(ureg_lo))) { // Nearly always adjacent
--- 679,11 ---
              Node *valdef = skip_copies(def); // tighten up val through non-useless copies
              value.map(ureg,valdef); // record improved reaching-def info
              regnd.map(ureg,   def);
              // Record other half of doubles
              uint def_ideal_reg = def->ideal_reg();
!             int n_regs = RegMask::num_registers(def_ideal_reg, lrgs(_lrg_map.live_range_id(def)));
              for (int l = 1; l < n_regs; l++) {
                OptoReg::Name ureg_lo = OptoReg::add(ureg,-l);
                if (!value[ureg_lo] &&
                    (!RegMask::can_represent(ureg_lo) ||
                     lrgs(useidx).mask().Member(ureg_lo))) { // Nearly always adjacent

*** 705,11 ***
          regnd.map(nreg, NULL);
          value.map(nreg, NULL);
        }
  
        uint n_ideal_reg = n->ideal_reg();
!       int n_regs = RegMask::num_registers(n_ideal_reg);
        if (n_regs == 1) {
          // If Node 'n' does not change the value mapped by the register,
          // then 'n' is a useless copy.  Do not update the register->node
          // mapping so 'n' will go dead.
          if( value[nreg] != val ) {
--- 723,11 ---
          regnd.map(nreg, NULL);
          value.map(nreg, NULL);
        }
  
        uint n_ideal_reg = n->ideal_reg();
!       int n_regs = RegMask::num_registers(n_ideal_reg, lrgs(lidx));
        if (n_regs == 1) {
          // If Node 'n' does not change the value mapped by the register,
          // then 'n' is a useless copy.  Do not update the register->node
          // mapping so 'n' will go dead.
          if( value[nreg] != val ) {
< prev index next >