< prev index next >

src/hotspot/share/opto/regmask.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

*** 1,7 **** /* ! * Copyright (c) 1997, 2019, 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) 1997, 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.
*** 22,31 **** --- 22,32 ---- * */ #include "precompiled.hpp" #include "opto/ad.hpp" + #include "opto/chaitin.hpp" #include "opto/compile.hpp" #include "opto/matcher.hpp" #include "opto/node.hpp" #include "opto/regmask.hpp" #include "utilities/population_count.hpp"
*** 57,90 **** 0 ); //============================================================================= bool RegMask::is_vector(uint ireg) { ! return (ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ); } int RegMask::num_registers(uint ireg) { switch(ireg) { case Op_VecZ: ! return 16; case Op_VecY: ! return 8; case Op_VecX: ! return 4; case Op_VecD: case Op_RegD: case Op_RegL: #ifdef _LP64 case Op_RegP: #endif return 2; } // Op_VecS and the rest ideal registers. return 1; } // Clear out partial bits; leave only bit pairs void RegMask::clear_to_pairs() { assert(valid_watermarks(), "sanity"); for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; --- 58,108 ---- 0 ); //============================================================================= bool RegMask::is_vector(uint ireg) { ! return (ireg == Op_VecA || ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ); } int RegMask::num_registers(uint ireg) { switch(ireg) { case Op_VecZ: ! return SlotsPerVecZ; case Op_VecY: ! return SlotsPerVecY; case Op_VecX: ! return SlotsPerVecX; case Op_VecD: + return SlotsPerVecD; case Op_RegD: case Op_RegL: #ifdef _LP64 case Op_RegP: #endif return 2; + case Op_VecA: + assert(Matcher::supports_scalable_vector(), "does not support scalable vector"); + return SlotsPerVecA; } // Op_VecS and the rest ideal registers. return 1; } + int RegMask::num_registers(uint ireg, LRG &lrg) { + int n_regs = num_registers(ireg); + + // assigned is OptoReg which is selected by register allocator + OptoReg::Name assigned = lrg.reg(); + assert(OptoReg::is_valid(assigned), "should be valid opto register"); + + if (lrg.is_scalable() && OptoReg::is_stack(assigned)) { + n_regs = lrg.scalable_reg_slots(); + } + return n_regs; + } + // Clear out partial bits; leave only bit pairs void RegMask::clear_to_pairs() { assert(valid_watermarks(), "sanity"); for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i];
*** 155,173 **** } else if (is_bound1() || is_bound_pair()) { return true; } return false; } // only indicies of power 2 are accessed, so index 3 is only filled in for storage. static int low_bits[5] = { 0x55555555, 0x11111111, 0x01010101, 0x00000000, 0x00010001 }; // Find the lowest-numbered register set in the mask. Return the // HIGHEST register number in the set, or BAD if no sets. // Works also for size 1. ! OptoReg::Name RegMask::find_first_set(const int size) const { assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); assert(valid_watermarks(), "sanity"); for (int i = _lwm; i <= _hwm; i++) { if (_A[i]) { // Found some bits // Convert to bit number, return hi bit in pair return OptoReg::Name((i<<_LogWordBits) + find_lowest_bit(_A[i]) + (size - 1)); --- 173,206 ---- } else if (is_bound1() || is_bound_pair()) { return true; } return false; } + // Check that whether given reg number with size is valid + // for current regmask, where reg is the highest number. + bool RegMask::is_valid_reg(OptoReg::Name reg, const int size) const { + for (int i = 0; i < size; i++) { + if (!Member(reg - i)) { + return false; + } + } + return true; + } // only indicies of power 2 are accessed, so index 3 is only filled in for storage. static int low_bits[5] = { 0x55555555, 0x11111111, 0x01010101, 0x00000000, 0x00010001 }; // Find the lowest-numbered register set in the mask. Return the // HIGHEST register number in the set, or BAD if no sets. // Works also for size 1. ! OptoReg::Name RegMask::find_first_set(LRG &lrg, const int size) const { ! if (lrg.is_scalable()) { ! // For scalable vector register, regmask is SlotsPerVecA bits aligned. ! assert(is_aligned_sets(SlotsPerVecA), "mask is not aligned, adjacent sets"); ! } else { assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); + } assert(valid_watermarks(), "sanity"); for (int i = _lwm; i <= _hwm; i++) { if (_A[i]) { // Found some bits // Convert to bit number, return hi bit in pair return OptoReg::Name((i<<_LogWordBits) + find_lowest_bit(_A[i]) + (size - 1));
*** 243,258 **** for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; while (bits) { // Check bits for pairing int bit = bits & -bits; // Extract low bit // Low bit is not odd means its mis-aligned. ! if ((bit & low_bits_mask) == 0) return false; // Do extra work since (bit << size) may overflow. int hi_bit = bit << (size-1); // high bit int set = hi_bit + ((hi_bit-1) & ~(bit-1)); // Check for aligned adjacent bits in this set ! if ((bits & set) != set) return false; bits -= set; // Remove this set } } return true; } --- 276,295 ---- for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; while (bits) { // Check bits for pairing int bit = bits & -bits; // Extract low bit // Low bit is not odd means its mis-aligned. ! if ((bit & low_bits_mask) == 0) { ! return false; ! } // Do extra work since (bit << size) may overflow. int hi_bit = bit << (size-1); // high bit int set = hi_bit + ((hi_bit-1) & ~(bit-1)); // Check for aligned adjacent bits in this set ! if ((bits & set) != set) { ! return false; ! } bits -= set; // Remove this set } } return true; }
< prev index next >