< prev index next > src/hotspot/share/opto/regmask.cpp
Print this page
/*
! * 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.
/*
! * 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.
*
*/
#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"
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];
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];
} 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));
} 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));
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;
}
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 >