8233708: VectorSet cleanup

Reviewed-by: neliasso, shade, thartmann
This commit is contained in:
Claes Redestad 2019-11-07 12:12:39 +01:00
parent f07d377d6f
commit 12adeca887
23 changed files with 147 additions and 872 deletions

View File

@ -151,7 +151,7 @@ bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) {
void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i)) {
bm >>= i;
bm.remove(i);
}
}
}
@ -1280,9 +1280,9 @@ void BCEscapeAnalyzer::clear_escape_info() {
set_modified(var, OFFSET_ANY, 4);
set_global_escape(var);
}
_arg_local.Clear();
_arg_stack.Clear();
_arg_returned.Clear();
_arg_local.clear();
_arg_stack.clear();
_arg_returned.clear();
_return_local = false;
_return_allocated = false;
_allocated_escapes = true;
@ -1334,7 +1334,7 @@ void BCEscapeAnalyzer::compute_escape_info() {
// Do not scan method if it has no object parameters and
// does not returns an object (_return_allocated is set in initialize()).
if (_arg_local.Size() == 0 && !_return_allocated) {
if (_arg_local.is_empty() && !_return_allocated) {
// Clear all info since method's bytecode was not analysed and
// set pessimistic escape information.
clear_escape_info();
@ -1457,10 +1457,10 @@ BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
, _parent(parent)
, _level(parent == NULL ? 0 : parent->level() + 1) {
if (!_conservative) {
_arg_local.Clear();
_arg_stack.Clear();
_arg_returned.Clear();
_dirty.Clear();
_arg_local.clear();
_arg_stack.clear();
_arg_returned.clear();
_dirty.clear();
Arena* arena = CURRENT_ENV->arena();
_arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint));
Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint));

View File

@ -758,7 +758,7 @@ bool ShenandoahBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode
return true;
} else if (mode == LoopOptsShenandoahPostExpand) {
assert(UseShenandoahGC, "only for shenandoah");
visited.Clear();
visited.clear();
ShenandoahBarrierC2Support::optimize_after_expansion(visited, nstack, worklist, phase);
return true;
}

View File

@ -2368,7 +2368,7 @@ void MemoryGraphFixer::collect_memory_nodes() {
// Iterate over CFG nodes in rpo and propagate memory state to
// compute memory state at regions, creating new phis if needed.
Node_List rpo_list;
visited.Clear();
visited.clear();
_phase->rpo(_phase->C->root(), stack, visited, rpo_list);
Node* root = rpo_list.pop();
assert(root == _phase->C->root(), "");

View File

@ -1,143 +0,0 @@
/*
* 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "libadt/set.hpp"
#include "memory/allocation.inline.hpp"
// Sets - An Abstract Data Type
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
//-------------------------Virtual Functions-----------------------------------
// These functions MUST be implemented by the inheriting class.
class VectorSet;
const VectorSet *Set::asVectorSet() const { assert(0); return NULL; }
//------------------------------setstr-----------------------------------------
// Create a string with a printable representation of a set.
// The caller must deallocate the string.
char *Set::setstr() const
{
Set &set = clone(); // Virtually copy the basic set.
set.Sort(); // Sort elements for in-order retrieval
uint len = 128; // Total string space
char *buf = NEW_C_HEAP_ARRAY(char,len, mtCompiler);// Some initial string space
char *s = buf; // Current working string pointer
*s++ = '{';
*s = '\0';
// For all elements of the Set
uint hi = (uint)-2, lo = (uint)-2;
for( SetI i(&set); i.test(); ++i ) {
if( hi+1 == i.elem ) { // Moving sequentially thru range?
hi = i.elem; // Yes, just update hi end of range
} else { // Else range ended
if( buf+len-s < 25 ) { // Generous trailing space for upcoming numbers
int offset = (int)(s-buf);// Not enuf space; compute offset into buffer
len <<= 1; // Double string size
buf = REALLOC_C_HEAP_ARRAY(char,buf,len, mtCompiler); // Reallocate doubled size
s = buf+offset; // Get working pointer into new bigger buffer
}
if( lo != (uint)-2 ) { // Startup? No! Then print previous range.
if( lo != hi ) sprintf(s,"%d-%d,",lo,hi);
else sprintf(s,"%d,",lo);
s += strlen(s); // Advance working string
}
hi = lo = i.elem;
}
}
if( lo != (uint)-2 ) {
if( buf+len-s < 25 ) { // Generous trailing space for upcoming numbers
int offset = (int)(s-buf);// Not enuf space; compute offset into buffer
len <<= 1; // Double string size
buf = (char*)ReallocateHeap(buf,len, mtCompiler); // Reallocate doubled size
s = buf+offset; // Get working pointer into new bigger buffer
}
if( lo != hi ) sprintf(s,"%d-%d}",lo,hi);
else sprintf(s,"%d}",lo);
} else strcat(s,"}");
// Don't delete the clone 'set' since it is allocated on Arena.
return buf;
}
//------------------------------print------------------------------------------
// Handier print routine
void Set::print() const
{
char *printable_set = setstr();
tty->print_cr("%s", printable_set);
FreeHeap(printable_set);
}
//------------------------------parse------------------------------------------
// Convert a textual representation of a Set, to a Set and union into "this"
// Set. Return the amount of text parsed in "len", or zero in "len".
int Set::parse(const char *s)
{
char c; // Parse character
const char *t = s; // Save the starting position of s.
do c = *s++; // Skip characters
while( c && (c <= ' ') ); // Till no more whitespace or EOS
if( c != '{' ) return 0; // Oops, not a Set openner
if( *s == '}' ) return 2; // The empty Set
// Sets are filled with values of the form "xx," or "xx-yy," with the comma
// a "}" at the very end.
while( 1 ) { // While have elements in the Set
char *u; // Pointer to character ending parse
uint hi, i; // Needed for range handling below
uint elem = (uint)strtoul(s,&u,10);// Get element
if( u == s ) return 0; // Bogus crude
s = u; // Skip over the number
c = *s++; // Get the number seperator
switch ( c ) { // Different seperators
case '}': // Last simple element
case ',': // Simple element
(*this) <<= elem; // Insert the simple element into the Set
break; // Go get next element
case '-': // Range
hi = (uint)strtoul(s,&u,10); // Get element
if( u == s ) return 0; // Bogus crude
for( i=elem; i<=hi; i++ )
(*this) <<= i; // Insert the entire range into the Set
s = u; // Skip over the number
c = *s++; // Get the number seperator
break;
}
if( c == '}' ) break; // End of the Set
if( c != ',' ) return 0; // Bogus garbage
}
return (int)(s-t); // Return length parsed
}
//------------------------------Iterator---------------------------------------
SetI_::~SetI_()
{
}

View File

@ -1,231 +0,0 @@
/*
* 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_LIBADT_SET_HPP
#define SHARE_LIBADT_SET_HPP
#include "memory/allocation.hpp"
// Sets - An Abstract Data Type
class SparseSet;
class VectorSet;
class ListSet;
class CoSet;
class ostream;
class SetI_;
// These sets can grow or shrink, based on the initial size and the largest
// element currently in them. Basically, they allow a bunch of bits to be
// grouped together, tested, set & cleared, intersected, etc. The basic
// Set class is an abstract class, and cannot be constructed. Instead,
// one of VectorSet, SparseSet, or ListSet is created. Each variation has
// different asymptotic running times for different operations, and different
// constants of proportionality as well.
// {n = number of elements, N = largest element}
// VectorSet SparseSet ListSet
// Create O(N) O(1) O(1)
// Clear O(N) O(1) O(1)
// Insert O(1) O(1) O(log n)
// Delete O(1) O(1) O(log n)
// Member O(1) O(1) O(log n)
// Size O(N) O(1) O(1)
// Copy O(N) O(n) O(n)
// Union O(N) O(n) O(n log n)
// Intersect O(N) O(n) O(n log n)
// Difference O(N) O(n) O(n log n)
// Equal O(N) O(n) O(n log n)
// ChooseMember O(N) O(1) O(1)
// Sort O(1) O(n log n) O(1)
// Forall O(N) O(n) O(n)
// Complement O(1) O(1) O(1)
// TIME: N/32 n 8*n Accesses
// SPACE: N/8 4*N+4*n 8*n Bytes
// Create: Make an empty set
// Clear: Remove all the elements of a Set
// Insert: Insert an element into a Set; duplicates are ignored
// Delete: Removes an element from a Set
// Member: Tests for membership in a Set
// Size: Returns the number of members of a Set
// Copy: Copy or assign one Set to another
// Union: Union 2 sets together
// Intersect: Intersect 2 sets together
// Difference: Compute A & !B; remove from set A those elements in set B
// Equal: Test for equality between 2 sets
// ChooseMember Pick a random member
// Sort: If no other operation changes the set membership, a following
// Forall will iterate the members in ascending order.
// Forall: Iterate over the elements of a Set. Operations that modify
// the set membership during iteration work, but the iterator may
// skip any member or duplicate any member.
// Complement: Only supported in the Co-Set variations. It adds a small
// constant-time test to every Set operation.
//
// PERFORMANCE ISSUES:
// If you "cast away" the specific set variation you are using, and then do
// operations on the basic "Set" object you will pay a virtual function call
// to get back the specific set variation. On the other hand, using the
// generic Set means you can change underlying implementations by just
// changing the initial declaration. Examples:
// void foo(VectorSet vs1, VectorSet vs2) { vs1 |= vs2; }
// "foo" must be called with a VectorSet. The vector set union operation
// is called directly.
// void foo(Set vs1, Set vs2) { vs1 |= vs2; }
// "foo" may be called with *any* kind of sets; suppose it is called with
// VectorSets. Two virtual function calls are used to figure out the that vs1
// and vs2 are VectorSets. In addition, if vs2 is not a VectorSet then a
// temporary VectorSet copy of vs2 will be made before the union proceeds.
//
// VectorSets have a small constant. Time and space are proportional to the
// largest element. Fine for dense sets and largest element < 10,000.
// SparseSets have a medium constant. Time is proportional to the number of
// elements, space is proportional to the largest element.
// Fine (but big) with the largest element < 100,000.
// ListSets have a big constant. Time *and space* are proportional to the
// number of elements. They work well for a few elements of *any* size
// (i.e. sets of pointers)!
//------------------------------Set--------------------------------------------
class Set : public ResourceObj {
protected:
// Creates a new, empty set.
Set(Arena *arena) : _set_arena(arena) {};
// Creates a new set from an existing set
Set(const Set & s) : ResourceObj(s) {};
public:
// Set assignment; deep-copy guts
virtual Set &operator =(const Set &s)=0;
virtual Set &clone(void) const=0;
// Virtual destructor
virtual ~Set() {};
// Add member to set
virtual Set &operator <<=(uint elem)=0;
// virtual Set operator << (uint elem);
// Delete member from set
virtual Set &operator >>=(uint elem)=0;
// virtual Set operator >> (uint elem);
// Membership test. Result is Zero (absent)/ Non-Zero (present)
virtual int operator [](uint elem) const=0;
// Intersect sets
virtual Set &operator &=(const Set &s)=0;
// virtual Set operator & (const Set &s) const;
// Union sets
virtual Set &operator |=(const Set &s)=0;
// virtual Set operator | (const Set &s) const;
// Difference sets
virtual Set &operator -=(const Set &s)=0;
// virtual Set operator - (const Set &s) const;
// Tests for equality. Result is Zero (false)/ Non-Zero (true)
virtual int operator ==(const Set &s) const=0;
int operator !=(const Set &s) const { return !(*this == s); }
virtual int disjoint(const Set &s) const=0;
// Tests for strict subset. Result is Zero (false)/ Non-Zero (true)
virtual int operator < (const Set &s) const=0;
int operator > (const Set &s) const { return s < *this; }
// Tests for subset. Result is Zero (false)/ Non-Zero (true)
virtual int operator <=(const Set &s) const=0;
int operator >=(const Set &s) const { return s <= *this; }
// Clear all the elements in the Set
virtual void Clear(void)=0;
// Return the number of members in the Set
virtual uint Size(void) const=0;
// If an iterator follows a "Sort()" without any Set-modifying operations
// inbetween then the iterator will visit the elements in ascending order.
virtual void Sort(void)=0;
// Convert a set to printable string in an allocated buffer.
// The caller must deallocate the string.
virtual char *setstr(void) const;
// Print the Set on "stdout". Can be conveniently called in the debugger
void print() const;
// Parse text from the string into the Set. Return length parsed.
virtual int parse(const char *s);
// Convert a generic Set to a specific Set
virtual const VectorSet *asVectorSet(void) const;
// Hash the set. Sets of different types but identical elements will NOT
// hash the same. Same set type, same elements WILL hash the same.
virtual int hash() const = 0;
protected:
friend class SetI;
virtual class SetI_ *iterate(uint&) const=0;
// Need storeage for the set
Arena *_set_arena;
};
//------------------------------Iteration--------------------------------------
// Loop thru all elements of the set, setting "elem" to the element numbers
// in random order. Inserted or deleted elements during this operation may
// or may not be iterated over; untouched elements will be affected once.
// Usage: for( SetI i(s); i.test(); i++ ) { body = i.elem; } ...OR...
// for( i.reset(s); i.test(); i++ ) { body = i.elem; }
class SetI_ : public ResourceObj {
protected:
friend class SetI;
virtual ~SetI_();
virtual uint next(void)=0;
virtual int test(void)=0;
};
class SetI {
protected:
SetI_ *impl;
public:
uint elem; // The publically accessible element
SetI( const Set *s ) { impl = s->iterate(elem); }
~SetI() { delete impl; }
void reset( const Set *s ) { delete impl; impl = s->iterate(elem); }
void operator ++(void) { elem = impl->next(); }
int test(void) { return impl->test(); }
};
#endif // SHARE_LIBADT_SET_HPP

View File

@ -27,339 +27,61 @@
#include "memory/allocation.inline.hpp"
#include "memory/arena.hpp"
// Vector Sets - An Abstract Data Type
// BitsInByte is a lookup table which tells the number of bits that
// are in the looked-up number. It is very useful in VectorSet_Size.
uint8_t bitsInByte[BITS_IN_BYTE_ARRAY_SIZE] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
//------------------------------VectorSet--------------------------------------
// Create a new, empty Set.
VectorSet::VectorSet(Arena *arena) : Set(arena) {
VectorSet::VectorSet(Arena *arena) {
_set_arena = arena;
size = 2; // Small initial size
data = (uint32_t *)_set_arena->Amalloc(size*sizeof(uint32_t));
data[0] = 0; // No elements
data[1] = 0;
}
//------------------------------operator=--------------------------------------
Set &VectorSet::operator = (const Set &set)
{
if( &set == this ) return *this;
FREE_FAST(data);
// The cast is a virtual function that checks that "set" is a VectorSet.
slamin(*(set.asVectorSet()));
return *this;
}
//------------------------------slamin-----------------------------------------
// Initialize one set with another. No regard is made to the existing Set.
void VectorSet::slamin(const VectorSet& s)
{
size = s.size; // Use new size
data = (uint32_t*)s._set_arena->Amalloc(size*sizeof(uint32_t)); // Make array of required size
memcpy( data, s.data, size*sizeof(uint32_t) ); // Fill the array
}
//------------------------------grow-------------------------------------------
// Expand the existing set to a bigger size
void VectorSet::grow( uint newsize )
{
newsize = (newsize+31) >> 5; // Convert to longwords
void VectorSet::grow(uint newsize) {
newsize = (newsize+31) >> 5;
uint x = size;
while( x < newsize ) x <<= 1;
while (x < newsize) {
x <<= 1;
}
data = (uint32_t *)_set_arena->Arealloc(data, size*sizeof(uint32_t), x*sizeof(uint32_t));
memset((char *)(data + size), 0, (x - size)*sizeof(uint32_t));
memset((char*)(data + size), 0, (x - size) * sizeof(uint32_t));
size = x;
}
//------------------------------operator<<=------------------------------------
// Insert a member into an existing Set.
Set &VectorSet::operator <<= (uint elem)
{
uint word = elem >> 5; // Get the longword offset
uint32_t mask = 1L << (elem & 31); // Get bit mask
if( word >= size ) // Need to grow set?
grow(elem+1); // Then grow it
data[word] |= mask; // Set new bit
return *this;
}
//------------------------------operator>>=------------------------------------
// Delete a member from an existing Set.
Set &VectorSet::operator >>= (uint elem)
{
uint word = elem >> 5; // Get the longword offset
if( word >= size ) // Beyond the last?
return *this; // Then it's clear & return clear
uint32_t mask = 1L << (elem & 31); // Get bit mask
data[word] &= ~mask; // Clear bit
return *this;
}
//------------------------------operator&=-------------------------------------
// Intersect one set into another.
VectorSet &VectorSet::operator &= (const VectorSet &s)
{
// NOTE: The intersection is never any larger than the smallest set.
if( s.size < size ) size = s.size; // Get smaller size
uint32_t *u1 = data; // Pointer to the destination data
uint32_t *u2 = s.data; // Pointer to the source data
for( uint i=0; i<size; i++) // For data in set
*u1++ &= *u2++; // Copy and AND longwords
return *this; // Return set
}
//------------------------------operator&=-------------------------------------
Set &VectorSet::operator &= (const Set &set)
{
// The cast is a virtual function that checks that "set" is a VectorSet.
return (*this) &= *(set.asVectorSet());
}
//------------------------------operator|=-------------------------------------
// Union one set into another.
VectorSet &VectorSet::operator |= (const VectorSet &s)
{
// This many words must be unioned
uint cnt = ((size<s.size)?size:s.size);
uint32_t *u1 = data; // Pointer to the destination data
uint32_t *u2 = s.data; // Pointer to the source data
for( uint i=0; i<cnt; i++) // Copy and OR the two sets
*u1++ |= *u2++;
if( size < s.size ) { // Is set 2 larger than set 1?
// Extend result by larger set
grow(s.size*sizeof(uint32_t)*8);
memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32_t));
void VectorSet::insert(uint elem) {
uint word = elem >> 5;
uint32_t mask = 1L << (elem & 31);
if (word >= size) {
grow(elem + 1);
}
return *this; // Return result set
data[word] |= mask;
}
//------------------------------operator|=-------------------------------------
Set &VectorSet::operator |= (const Set &set)
{
// The cast is a virtual function that checks that "set" is a VectorSet.
return (*this) |= *(set.asVectorSet());
}
//------------------------------operator-=-------------------------------------
// Difference one set from another.
VectorSet &VectorSet::operator -= (const VectorSet &s)
{
// This many words must be unioned
uint cnt = ((size<s.size)?size:s.size);
uint32_t *u1 = data; // Pointer to the destination data
uint32_t *u2 = s.data; // Pointer to the source data
for( uint i=0; i<cnt; i++ ) // For data in set
*u1++ &= ~(*u2++); // A <-- A & ~B with longwords
return *this; // Return new set
}
//------------------------------operator-=-------------------------------------
Set &VectorSet::operator -= (const Set &set)
{
// The cast is a virtual function that checks that "set" is a VectorSet.
return (*this) -= *(set.asVectorSet());
}
//------------------------------compare----------------------------------------
// Compute 2 booleans: bits in A not B, bits in B not A.
// Return X0 -- A is not a subset of B
// X1 -- A is a subset of B
// 0X -- B is not a subset of A
// 1X -- B is a subset of A
int VectorSet::compare (const VectorSet &s) const
{
uint32_t *u1 = data; // Pointer to the destination data
uint32_t *u2 = s.data; // Pointer to the source data
uint32_t AnotB = 0, BnotA = 0;
// This many words must be unioned
uint cnt = ((size<s.size)?size:s.size);
// Get bits for both sets
uint i; // Exit value of loop
for( i=0; i<cnt; i++ ) { // For data in BOTH sets
uint32_t A = *u1++; // Data from one guy
uint32_t B = *u2++; // Data from other guy
AnotB |= (A & ~B); // Compute bits in A not B
BnotA |= (B & ~A); // Compute bits in B not A
}
// Get bits from bigger set
if( size < s.size ) {
for( ; i<s.size; i++ ) // For data in larger set
BnotA |= *u2++; // These bits are in B not A
} else {
for( ; i<size; i++ ) // For data in larger set
AnotB |= *u1++; // These bits are in A not B
}
// Set & return boolean flags
return ((!BnotA)<<1) + (!AnotB);
}
//------------------------------operator==-------------------------------------
// Test for set equality
int VectorSet::operator == (const VectorSet &s) const
{
return compare(s) == 3; // TRUE if A and B are mutual subsets
}
//------------------------------operator==-------------------------------------
int VectorSet::operator == (const Set &set) const
{
// The cast is a virtual function that checks that "set" is a VectorSet.
return (*this) == *(set.asVectorSet());
}
//------------------------------disjoint---------------------------------------
// Check for sets being disjoint.
int VectorSet::disjoint(const Set &set) const
{
// The cast is a virtual function that checks that "set" is a VectorSet.
const VectorSet &s = *(set.asVectorSet());
// NOTE: The intersection is never any larger than the smallest set.
uint small_size = ((size<s.size)?size:s.size);
uint32_t *u1 = data; // Pointer to the destination data
uint32_t *u2 = s.data; // Pointer to the source data
for( uint i=0; i<small_size; i++) // For data in set
if( *u1++ & *u2++ ) // If any elements in common
return 0; // Then not disjoint
return 1; // Else disjoint
}
//------------------------------operator<--------------------------------------
// Test for strict subset
int VectorSet::operator < (const VectorSet &s) const
{
return compare(s) == 1; // A subset B, B not subset A
}
//------------------------------operator<--------------------------------------
int VectorSet::operator < (const Set &set) const
{
// The cast is a virtual function that checks that "set" is a VectorSet.
return (*this) < *(set.asVectorSet());
}
//------------------------------operator<=-------------------------------------
// Test for subset
int VectorSet::operator <= (const VectorSet &s) const
{
return compare(s) & 1; // A subset B
}
//------------------------------operator<=-------------------------------------
int VectorSet::operator <= (const Set &set) const
{
// The cast is a virtual function that checks that "set" is a VectorSet.
return (*this) <= *(set.asVectorSet());
}
//------------------------------operator[]-------------------------------------
// Test for membership. A Zero/Non-Zero value is returned!
int VectorSet::operator[](uint elem) const
{
uint word = elem >> 5; // Get the longword offset
if( word >= size ) // Beyond the last?
return 0; // Then it's clear
uint32_t mask = 1L << (elem & 31); // Get bit mask
return ((data[word] & mask))!=0; // Return the sense of the bit
}
//------------------------------Clear------------------------------------------
// Clear a set
void VectorSet::Clear(void)
{
void VectorSet::clear() {
if( size > 100 ) { // Reclaim storage only if huge
FREE_RESOURCE_ARRAY(uint32_t,data,size);
size = 2; // Small initial size
data = NEW_RESOURCE_ARRAY(uint32_t,size);
}
memset( data, 0, size*sizeof(uint32_t) );
memset(data, 0, size*sizeof(uint32_t));
}
//------------------------------Size-------------------------------------------
// Return number of elements in a Set
uint VectorSet::Size(void) const
{
uint sum = 0; // Cumulative size so far.
uint8_t* currByte = (uint8_t*) data;
for( uint32_t i = 0; i < (size<<2); i++) // While have bytes to process
sum += bitsInByte[*currByte++]; // Add bits in current byte to size.
return sum;
// Return true if the set is empty
bool VectorSet::is_empty() const {
for (uint32_t i = 0; i < size; i++) {
if (data[i] != 0) {
return false;
}
}
return true;
}
//------------------------------Sort-------------------------------------------
// Sort the elements for the next forall statement
void VectorSet::Sort(void)
{
}
//------------------------------hash-------------------------------------------
int VectorSet::hash() const
{
int VectorSet::hash() const {
uint32_t _xor = 0;
uint lim = ((size<4)?size:4);
for( uint i = 0; i < lim; i++ )
uint lim = ((size < 4) ? size : 4);
for (uint i = 0; i < lim; i++) {
_xor ^= data[i];
}
return (int)_xor;
}
//------------------------------iterate----------------------------------------
// Used by Set::print().
class VSetI_ : public SetI_ {
VectorSetI vsi;
public:
VSetI_( const VectorSet *vset, uint &elem ) : vsi(vset) { elem = vsi.elem; }
uint next(void) { ++vsi; return vsi.elem; }
int test(void) { return vsi.test(); }
};
SetI_ *VectorSet::iterate(uint &elem) const {
return new(ResourceObj::C_HEAP, mtInternal) VSetI_(this, elem);
}
//=============================================================================
//------------------------------next-------------------------------------------
// Find and return the next element of a vector set, or return garbage and
// make "VectorSetI::test()" fail.
uint VectorSetI::next(void)
{
j++; // Next element in word
mask = (mask & max_jint) << 1;// Next bit in word
do { // Do While still have words
while( mask ) { // While have bits in word
if( s->data[i] & mask ) { // If found a bit
return (i<<5)+j; // Return the bit address
}
j++; // Skip to next bit
mask = (mask & max_jint) << 1;
}
j = 0; // No more bits in word; setup for next word
mask = 1;
for( i++; (i<s->size) && (!s->data[i]); i++ ); // Skip to non-zero word
} while( i<s->size );
return max_juint; // No element, iterated them all
}

View File

@ -25,161 +25,85 @@
#ifndef SHARE_LIBADT_VECTSET_HPP
#define SHARE_LIBADT_VECTSET_HPP
#include "libadt/set.hpp"
#include "memory/allocation.hpp"
#define BITS_IN_BYTE_ARRAY_SIZE 256
// Vector Sets - An Abstract Data Type
//INTERFACE
// Vector Sets
// These sets can grow or shrink, based on the initial size and the largest
// element currently in them. Slow and bulky for sparse sets, these sets
// are super for dense sets. They are fast and compact when dense.
// TIME:
// O(1) - Insert, Delete, Member, Sort
// O(max_element) - Create, Clear, Size, Copy, Union, Intersect, Difference,
// Equal, ChooseMember, Forall
// SPACE: (max_element)/(8*sizeof(int))
// element currently in them.
//------------------------------VectorSet--------------------------------------
class VectorSet : public Set {
friend class VectorSetI; // Friendly iterator class
protected:
class VectorSet : public ResourceObj {
private:
uint size; // Size of data IN LONGWORDS (32bits)
uint32_t* data; // The data, bit packed
Arena *_set_arena;
void slamin( const VectorSet& s ); // Initialize one set with another
int compare(const VectorSet &s) const; // Compare set contents
void grow(uint newsize); // Grow vector to required bitsize
void grow(uint newsize); // Grow vector to required bitsize
public:
VectorSet(Arena *arena); // Creates a new, empty set.
VectorSet(const VectorSet &s) : Set(s._set_arena) {slamin(s);} // Set clone; deep-copy guts
Set &operator =(const Set &s); // Set clone; deep-copy guts
VectorSet &operator =(const VectorSet &s) // Set clone; deep-copy guts
{ if( &s != this ) { slamin(s); } return *this; }
VectorSet(Arena *arena);
~VectorSet() {}
Set &clone(void) const { return *(new VectorSet(*this)); }
void insert(uint elem);
Set &operator <<=(uint elem); // Add member to set
VectorSet operator << (uint elem) // Add member to new set
{ VectorSet foo(*this); foo <<= elem; return foo; }
Set &operator >>=(uint elem); // Delete member from set
VectorSet operator >> (uint elem) // Delete member from new set
{ VectorSet foo(*this); foo >>= elem; return foo; }
VectorSet &operator &=(const VectorSet &s); // Intersect sets into first set
Set &operator &=(const Set &s); // Intersect sets into first set
VectorSet operator & (const VectorSet &s) const
{ VectorSet foo(*this); foo &= s; return foo; }
VectorSet &operator |=(const VectorSet &s); // Intersect sets into first set
Set &operator |=(const Set &s); // Intersect sets into first set
VectorSet operator | (const VectorSet &s) const
{ VectorSet foo(*this); foo |= s; return foo; }
VectorSet &operator -=(const VectorSet &s); // Intersect sets into first set
Set &operator -=(const Set &s); // Intersect sets into first set
VectorSet operator - (const VectorSet &s) const
{ VectorSet foo(*this); foo -= s; return foo; }
int operator ==(const VectorSet &s) const; // True if sets are equal
int operator ==(const Set &s) const; // True if sets are equal
int operator < (const VectorSet &s) const; // True if strict subset
int operator < (const Set &s) const; // True if strict subset
int operator <=(const VectorSet &s) const; // True if subset relation holds.
int operator <=(const Set &s) const; // True if subset relation holds.
int disjoint (const Set &s) const; // True if sets are disjoint
int operator [](uint elem) const; // Test for membership
void Clear(void); // Clear a set
uint Size(void) const; // Number of elements in the Set.
void Sort(void); // Sort before iterating
int hash() const; // Hash function
void Reset(void) { // Reset a set
memset( data, 0, size*sizeof(uint32_t) );
void clear();
bool is_empty() const;
int hash() const;
void reset() {
memset(data, 0, size*sizeof(uint32_t));
}
/* Removed for MCC BUG
operator const VectorSet* (void) const { return this; } */
const VectorSet *asVectorSet() const { return this; }
// Expose internals for speed-critical fast iterators
uint word_size() const { return size; }
// Fast inlined "test and set". Replaces the idiom:
// if( visited[idx] ) return;
// visited <<= idx;
// if (visited.test(idx)) return;
// visited.set(idx);
// With:
// if( visited.test_set(idx) ) return;
// if (visited.test_set(idx)) return;
//
int test_set( uint elem ) {
int test_set(uint elem) {
uint word = elem >> 5; // Get the longword offset
if( word >= size ) // Beyond the last?
return test_set_grow(elem); // Then grow; set; return 0;
if (word >= size) {
// Then grow; set; return 0;
this->insert(elem);
return 0;
}
uint32_t mask = 1L << (elem & 31); // Get bit mask
uint32_t datum = data[word] & mask;// Get bit
data[word] |= mask; // Set bit
return datum; // Return bit
}
int test_set_grow( uint elem ) { // Insert & return 0;
(*this) <<= elem; // Insert into set
return 0; // Return 0!
}
// Fast inlined test
int test( uint elem ) const {
uint word = elem >> 5; // Get the longword offset
if( word >= size ) return 0; // Beyond the last?
uint32_t mask = 1L << (elem & 31); // Get bit mask
return data[word] & mask; // Get bit
int test(uint elem) const {
uint word = elem >> 5;
if (word >= size) {
return 0;
}
uint32_t mask = 1L << (elem & 31);
return data[word] & mask;
}
void remove(uint elem) {
uint word = elem >> 5;
if (word >= size) {
return;
}
uint32_t mask = 1L << (elem & 31);
data[word] &= ~mask; // Clear bit
}
// Fast inlined set
void set( uint elem ) {
uint word = elem >> 5; // Get the longword offset
if( word >= size ) { // Beyond the last?
test_set_grow(elem); // Then grow and set
void set(uint elem) {
uint word = elem >> 5;
if (word >= size) {
this->insert(elem);
} else {
uint32_t mask = 1L << (elem & 31); // Get bit mask
data[word] |= mask; // Set bit
uint32_t mask = 1L << (elem & 31);
data[word] |= mask;
}
}
private:
SetI_ *iterate(uint&) const;
};
//------------------------------Iteration--------------------------------------
// Loop thru all elements of the set, setting "elem" to the element numbers
// in random order. Inserted or deleted elements during this operation may
// or may not be iterated over; untouched elements will be affected once.
// Usage: for( VectorSetI i(s); i.test(); i++ ) { body = i.elem; }
class VectorSetI : public StackObj {
friend class VectorSet;
const VectorSet *s;
uint i, j;
uint32_t mask;
uint next(void);
public:
uint elem; // The publically accessible element
VectorSetI( const VectorSet *vset ) :
s(vset),
i((uint)-1L),
j((uint)-1L),
mask((unsigned)(1L<<31)) {
elem = next();
}
void operator ++(void) { elem = next(); }
int test(void) { return i < s->size; }
};
#endif // SHARE_LIBADT_VECTSET_HPP

View File

@ -1197,12 +1197,12 @@ void PhaseChaitin::Simplify( ) {
// Check for just becoming of-low-degree just counting registers.
// _must_spill live ranges are already on the low degree list.
if( n->just_lo_degree() && !n->_must_spill ) {
assert(!(*_ifg->_yanked)[neighbor],"Cannot move to lo degree twice");
if (n->just_lo_degree() && !n->_must_spill) {
assert(!_ifg->_yanked->test(neighbor), "Cannot move to lo degree twice");
// Pull from hi-degree list
uint prev = n->_prev;
uint next = n->_next;
if( prev ) lrgs(prev)._next = next;
if (prev) lrgs(prev)._next = next;
else _hi_degree = next;
lrgs(next)._prev = prev;
n->_next = _lo_degree;
@ -1212,7 +1212,7 @@ void PhaseChaitin::Simplify( ) {
} // End of while lo-degree/lo_stk_degree worklist not empty
// Check for got everything: is hi-degree list empty?
if( !_hi_degree ) break;
if (!_hi_degree) break;
// Time to pick a potential spill guy
uint lo_score = _hi_degree;
@ -1223,8 +1223,8 @@ void PhaseChaitin::Simplify( ) {
// Find cheapest guy
debug_only( int lo_no_simplify=0; );
for( uint i = _hi_degree; i; i = lrgs(i)._next ) {
assert( !(*_ifg->_yanked)[i], "" );
for (uint i = _hi_degree; i; i = lrgs(i)._next) {
assert(!_ifg->_yanked->test(i), "");
// It's just vaguely possible to move hi-degree to lo-degree without
// going through a just-lo-degree stage: If you remove a double from
// a float live range it's degree will drop by 2 and you can skip the
@ -1249,7 +1249,7 @@ void PhaseChaitin::Simplify( ) {
// one block. In which case their area is 0 and score set to max.
// In such case choose bound live range over unbound to free registers
// or with smaller cost to spill.
if( iscore < score ||
if ( iscore < score ||
(iscore == score && iarea > area && lrgs(lo_score)._was_spilled2) ||
(iscore == score && iarea == area &&
( (ibound && !bound) || (ibound == bound && (icost < cost)) )) ) {
@ -1332,7 +1332,7 @@ OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
uint copy_lrg = _lrg_map.find(lrg._copy_bias);
if( copy_lrg != 0 ) {
// If he has a color,
if( !(*(_ifg->_yanked))[copy_lrg] ) {
if(!_ifg->_yanked->test(copy_lrg)) {
OptoReg::Name reg = lrgs(copy_lrg).reg();
// And it is legal for you,
if (is_legal_reg(lrg, reg, chunk))

View File

@ -338,7 +338,7 @@ void Compile::update_dead_node_list(Unique_Node_List &useful) {
for (uint node_idx = 0; node_idx < max_idx; node_idx++) {
// If node with index node_idx is not in useful set,
// mark it as dead in dead node list.
if (! useful_node_set.test(node_idx) ) {
if (!useful_node_set.test(node_idx)) {
record_dead_node(node_idx);
}
}

View File

@ -915,9 +915,7 @@ class Compile : public Phase {
void record_dead_node(uint idx) { if (_dead_node_list.test_set(idx)) return;
_dead_node_count++;
}
bool is_dead_node(uint idx) { return _dead_node_list.test(idx) != 0; }
uint dead_node_count() { return _dead_node_count; }
void reset_dead_node_list() { _dead_node_list.Reset();
void reset_dead_node_list() { _dead_node_list.reset();
_dead_node_count = 0;
}
uint live_nodes() const {

View File

@ -1414,7 +1414,7 @@ int ConnectionGraph::add_java_object_edges(JavaObjectNode* jobj, bool populate_w
}
}
_worklist.clear();
_in_worklist.Reset();
_in_worklist.reset();
return new_edges;
}

View File

@ -850,7 +850,7 @@ Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited,
stack.push(root, root->outcnt());
// Clear the visited bits
visited.Clear();
visited.clear();
}
// Iterator for the Node_Backward_Iterator
@ -1372,7 +1372,7 @@ void PhaseCFG::global_code_motion() {
// Find the earliest Block any instruction can be placed in. Some
// instructions are pinned into Blocks. Unpinned instructions can
// appear in last block in which all their inputs occur.
visited.Clear();
visited.clear();
Node_Stack stack(arena, (C->live_nodes() >> 2) + 16); // pre-grow
if (!schedule_early(visited, stack)) {
// Bailout without retry
@ -1392,7 +1392,7 @@ void PhaseCFG::global_code_motion() {
// Now schedule all codes as LATE as possible. This is the LCA in the
// dominator tree of all USES of a value. Pick the block with the least
// loop nesting depth that is lowest in the dominator tree.
// ( visited.Clear() called in schedule_late()->Node_Backward_Iterator() )
// ( visited.clear() called in schedule_late()->Node_Backward_Iterator() )
schedule_late(visited, stack);
if (C->failing()) {
// schedule_late fails only when graph is incorrect.
@ -1473,7 +1473,7 @@ void PhaseCFG::global_code_motion() {
// Schedule locally. Right now a simple topological sort.
// Later, do a real latency aware scheduler.
GrowableArray<int> ready_cnt(C->unique(), C->unique(), -1);
visited.Clear();
visited.reset();
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
if (!schedule_local(block, ready_cnt, visited, recalc_pressure_nodes)) {

View File

@ -584,7 +584,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
#ifdef ASSERT
if (node->debug_orig() != NULL) {
temp_set->Clear();
temp_set->clear();
stringStream dorigStream;
Node* dorig = node->debug_orig();
while (dorig && temp_set->test_set(dorig->_idx)) {

View File

@ -141,10 +141,10 @@ IndexSet *PhaseIFG::remove_node( uint a ) {
}
// Re-insert a yanked Node.
void PhaseIFG::re_insert( uint a ) {
void PhaseIFG::re_insert(uint a) {
assert( _is_square, "only on square" );
assert( _yanked->test(a), "" );
(*_yanked) >>= a;
_yanked->remove(a);
IndexSetIterator elements(&_adjs[a]);
uint datum;
@ -198,7 +198,7 @@ void PhaseIFG::dump() const {
_is_square ? "square" : "triangular" );
if( _is_square ) {
for( uint i = 0; i < _maxlrg; i++ ) {
tty->print( (*_yanked)[i] ? "XX " : " ");
tty->print(_yanked->test(i) ? "XX " : " ");
tty->print("L%d: { ",i);
IndexSetIterator elements(&_adjs[i]);
uint datum;
@ -214,7 +214,7 @@ void PhaseIFG::dump() const {
// Triangular
for( uint i = 0; i < _maxlrg; i++ ) {
uint j;
tty->print( (*_yanked)[i] ? "XX " : " ");
tty->print(_yanked->test(i) ? "XX " : " ");
tty->print("L%d: { ",i);
for( j = _maxlrg; j > i; j-- )
if( test_edge(j - 1,i) ) {
@ -249,7 +249,7 @@ void PhaseIFG::stats() const {
void PhaseIFG::verify( const PhaseChaitin *pc ) const {
// IFG is square, sorted and no need for Find
for( uint i = 0; i < _maxlrg; i++ ) {
assert(!((*_yanked)[i]) || !neighbor_cnt(i), "Is removed completely" );
assert(!_yanked->test(i) || !neighbor_cnt(i), "Is removed completely" );
IndexSet *set = &_adjs[i];
IndexSetIterator elements(set);
uint idx;
@ -258,7 +258,7 @@ void PhaseIFG::verify( const PhaseChaitin *pc ) const {
assert(idx != i, "Must have empty diagonal");
assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
assert(_adjs[idx].member(i), "IFG not square");
assert(!(*_yanked)[idx], "No yanked neighbors");
assert(!_yanked->test(idx), "No yanked neighbors");
assert(last < idx, "not sorted increasing");
last = idx;
}

View File

@ -2121,7 +2121,7 @@ bool IdealLoopTree::beautify_loops( PhaseIdealLoop *phase ) {
void IdealLoopTree::allpaths_check_safepts(VectorSet &visited, Node_List &stack) {
assert(stack.size() == 0, "empty stack");
stack.push(_tail);
visited.Clear();
visited.clear();
visited.set(_tail->_idx);
while (stack.size() > 0) {
Node* n = stack.pop();
@ -2930,12 +2930,12 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
int stack_size = (C->live_nodes() >> 1) + 16; // (live_nodes>>1)+16 from Java2D stats
Node_Stack nstack( a, stack_size );
visited.Clear();
visited.clear();
Node_List worklist(a);
// Don't need C->root() on worklist since
// it will be processed among C->top() inputs
worklist.push( C->top() );
visited.set( C->top()->_idx ); // Set C->top() as visited now
worklist.push(C->top());
visited.set(C->top()->_idx); // Set C->top() as visited now
build_loop_early( visited, worklist, nstack );
// Given early legal placement, try finding counted loops. This placement
@ -2945,12 +2945,12 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
}
// Find latest loop placement. Find ideal loop placement.
visited.Clear();
visited.clear();
init_dom_lca_tags();
// Need C->root() on worklist when processing outs
worklist.push( C->root() );
worklist.push(C->root());
NOT_PRODUCT( C->verify_graph_edges(); )
worklist.push( C->top() );
worklist.push(C->top());
build_loop_late( visited, worklist, nstack );
if (_verify_only) {
@ -3046,7 +3046,7 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
// Check for aggressive application of split-if and other transforms
// that require basic-block info (like cloning through Phi's)
if( SplitIfBlocks && do_split_ifs ) {
visited.Clear();
visited.clear();
split_if_with_blocks( visited, nstack);
NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); );
}

View File

@ -2726,7 +2726,7 @@ void PhaseIdealLoop::clone_for_special_use_inside_loop( IdealLoopTree *loop, Nod
_igvn.register_new_node_with_optimizer(n_clone);
set_ctrl(n_clone, get_ctrl(n));
sink_list.push(n_clone);
not_peel <<= n_clone->_idx; // add n_clone to not_peel set.
not_peel.set(n_clone->_idx);
#ifndef PRODUCT
if (TracePartialPeeling) {
tty->print_cr("special not_peeled cloning old: %d new: %d", n->_idx, n_clone->_idx);
@ -3236,8 +3236,8 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
if (n->in(0) == NULL && !n->is_Load() && !n->is_CMove()) {
cloned_for_outside_use += clone_for_use_outside_loop(loop, n, worklist);
sink_list.push(n);
peel >>= n->_idx; // delete n from peel set.
not_peel <<= n->_idx; // add n to not_peel set.
peel.remove(n->_idx);
not_peel.set(n->_idx);
peel_list.remove(i);
incr = false;
#ifndef PRODUCT

View File

@ -157,7 +157,7 @@ void Matcher::verify_new_nodes_only(Node* xroot) {
worklist.push(xroot);
while (worklist.size() > 0) {
Node* n = worklist.pop();
visited <<= n->_idx;
visited.set(n->_idx);
assert(C->node_arena()->contains(n), "dead node");
for (uint j = 0; j < n->req(); j++) {
Node* in = n->in(j);
@ -340,7 +340,7 @@ void Matcher::match( ) {
// Recursively match trees from old space into new space.
// Correct leaves of new-space Nodes; they point to old-space.
_visited.Clear(); // Clear visit bits for xform call
_visited.clear();
C->set_cached_top_node(xform( C->top(), live_nodes ));
if (!C->failing()) {
Node* xroot = xform( C->root(), 1 );

View File

@ -2399,14 +2399,15 @@ void Node_List::dump_simple() const {
//=============================================================================
//------------------------------remove-----------------------------------------
void Unique_Node_List::remove( Node *n ) {
if( _in_worklist[n->_idx] ) {
for( uint i = 0; i < size(); i++ )
if( _nodes[i] == n ) {
map(i,Node_List::pop());
_in_worklist >>= n->_idx;
void Unique_Node_List::remove(Node* n) {
if (_in_worklist.test(n->_idx)) {
for (uint i = 0; i < size(); i++) {
if (_nodes[i] == n) {
map(i, Node_List::pop());
_in_worklist.remove(n->_idx);
return;
}
}
ShouldNotReachHere();
}
}
@ -2415,11 +2416,11 @@ void Unique_Node_List::remove( Node *n ) {
// Remove useless nodes from worklist
void Unique_Node_List::remove_useless_nodes(VectorSet &useful) {
for( uint i = 0; i < size(); ++i ) {
for (uint i = 0; i < size(); ++i) {
Node *n = at(i);
assert( n != NULL, "Did not expect null entries in worklist");
if( ! useful.test(n->_idx) ) {
_in_worklist >>= n->_idx;
if (!useful.test(n->_idx)) {
_in_worklist.remove(n->_idx);
map(i,Node_List::pop());
// Node *replacement = Node_List::pop();
// if( i != size() ) { // Check if removing last entry

View File

@ -1521,9 +1521,9 @@ public:
void remove( Node *n );
bool member( Node *n ) { return _in_worklist.test(n->_idx) != 0; }
VectorSet &member_set(){ return _in_worklist; }
VectorSet& member_set(){ return _in_worklist; }
void push( Node *b ) {
void push(Node* b) {
if( !_in_worklist.test_set(b->_idx) )
Node_List::push(b);
}
@ -1532,24 +1532,27 @@ public:
Node *b = at(_clock_index);
map( _clock_index, Node_List::pop());
if (size() != 0) _clock_index++; // Always start from 0
_in_worklist >>= b->_idx;
_in_worklist.remove(b->_idx);
return b;
}
Node *remove( uint i ) {
Node *remove(uint i) {
Node *b = Node_List::at(i);
_in_worklist >>= b->_idx;
_in_worklist.remove(b->_idx);
map(i,Node_List::pop());
return b;
}
void yank( Node *n ) { _in_worklist >>= n->_idx; Node_List::yank(n); }
void yank(Node *n) {
_in_worklist.remove(n->_idx);
Node_List::yank(n);
}
void clear() {
_in_worklist.Clear(); // Discards storage but grows automatically
_in_worklist.clear(); // Discards storage but grows automatically
Node_List::clear();
_clock_index = 0;
}
// Used after parsing to remove useless nodes before Iterative GVN
void remove_useless_nodes(VectorSet &useful);
void remove_useless_nodes(VectorSet& useful);
#ifndef PRODUCT
void print_set() const { _in_worklist.print(); }

View File

@ -91,7 +91,7 @@ public:
return _table[table_index];
}
void remove_useless_nodes(VectorSet &useful); // replace with sentinel
void remove_useless_nodes(VectorSet& useful); // replace with sentinel
void replace_with(NodeHash* nh);
void check_no_speculative_types(); // Check no speculative part for type nodes in table

View File

@ -379,7 +379,7 @@ Node_List PhaseStringOpts::collect_toString_calls() {
Node_List string_calls;
Node_List worklist;
_visited.Clear();
_visited.clear();
// Prime the worklist
for (uint i = 1; i < C->root()->len(); i++) {
@ -1033,7 +1033,7 @@ bool StringConcat::validate_control_flow() {
// Validate that all these results produced are contained within
// this cluster of objects. First collect all the results produced
// by calls in the region.
_stringopts->_visited.Clear();
_stringopts->_visited.clear();
Node_List worklist;
Node* final_result = _end->proj_out_or_null(TypeFunc::Parms);
for (uint i = 0; i < _control.size(); i++) {

View File

@ -359,11 +359,11 @@ class SuperWord : public ResourceObj {
void set_bb_idx(Node* n, int i) { _bb_idx.at_put_grow(n->_idx, i); }
// visited set accessors
void visited_clear() { _visited.Clear(); }
void visited_clear() { _visited.clear(); }
void visited_set(Node* n) { return _visited.set(bb_idx(n)); }
int visited_test(Node* n) { return _visited.test(bb_idx(n)); }
int visited_test_set(Node* n) { return _visited.test_set(bb_idx(n)); }
void post_visited_clear() { _post_visited.Clear(); }
void post_visited_clear() { _post_visited.clear(); }
void post_visited_set(Node* n) { return _post_visited.set(bb_idx(n)); }
int post_visited_test(Node* n) { return _post_visited.test(bb_idx(n)); }

View File

@ -23,12 +23,13 @@
*/
#include "precompiled.hpp"
#include "libadt/vectset.hpp"
#include "runtime/os.hpp"
#include "utilities/population_count.hpp"
#include "utilities/globalDefinitions.hpp"
#include "unittest.hpp"
#define BITS_IN_BYTE_ARRAY_SIZE 256
uint8_t test_popcnt_bitsInByte[BITS_IN_BYTE_ARRAY_SIZE] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,