blob: 85eec568d265aa9e3799caa165c9a6ad4cf6e3c4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//MVM
#include <iostream>
using namespace std;
#include <stdio.h>
#include "bit_vector.h"
/*
* Sum of bits of correspondent bytes.
*/
static unsigned O3_bitcount[256] = {
0, 1, 1, 2, 1, 2, 2, 3 /* 00000111 */, 1, 2, 2, 3, 2, 3, 3, 4 /* 00001111 */,
1, 2, 2, 3, 2, 3, 3, 4 /* 00010111 */, 2, 3, 3, 4, 3, 4, 4, 5 /* 00011111 */,
1, 2, 2, 3, 2, 3, 3, 4 /* 00100111 */, 2, 3, 3, 4, 3, 4, 4, 5 /* 00101111 */,
2, 3, 3, 4, 3, 4, 4, 5 /* 00110111 */, 3, 4, 4, 5, 4, 5, 5, 6 /* 00111111 */,
1, 2, 2, 3, 2, 3, 3, 4 /* 01000111 */, 2, 3, 3, 4, 3, 4, 4, 5 /* 01001111 */,
2, 3, 3, 4, 3, 4, 4, 5 /* 01010111 */, 3, 4, 4, 5, 4, 5, 5, 6 /* 01011111 */,
2, 3, 3, 4, 3, 4, 4, 5 /* 01100111 */, 3, 4, 4, 5, 4, 5, 5, 6 /* 01101111 */,
3, 4, 4, 5, 4, 5, 5, 6 /* 01110111 */, 4, 5, 5, 6, 5, 6, 6, 7 /* 01111111 */,
1, 2, 2, 3, 2, 3, 3, 4 /* 10000111 */, 2, 3, 3, 4, 3, 4, 4, 5 /* 10001111 */,
2, 3, 3, 4, 3, 4, 4, 5 /* 10010111 */, 3, 4, 4, 5, 4, 5, 5, 6 /* 10011111 */,
2, 3, 3, 4, 3, 4, 4, 5 /* 10100111 */, 3, 4, 4, 5, 4, 5, 5, 6 /* 10101111 */,
3, 4, 4, 5, 4, 5, 5, 6 /* 10110111 */, 4, 5, 5, 6, 5, 6, 6, 7 /* 10111111 */,
2, 3, 3, 4, 3, 4, 4, 5 /* 11000111 */, 3, 4, 4, 5, 4, 5, 5, 6 /* 11001111 */,
3, 4, 4, 5, 4, 5, 5, 6 /* 11010111 */, 4, 5, 5, 6, 5, 6, 6, 7 /* 11011111 */,
3, 4, 4, 5, 4, 5, 5, 6 /* 11100111 */, 4, 5, 5, 6, 5, 6, 6, 7 /* 11101111 */,
4, 5, 5, 6, 5, 6, 6, 7 /* 11110111 */, 5, 6, 6, 7, 6, 7, 7, 8 /* 11111111 */
};
unsigned Bit_Vector::bits_set()
{
unsigned result = 0;
unsigned i;
for (i=0; i<_n_words-1; i++)
{
unsigned char *tmp = (unsigned char *)&_words[i];
for (unsigned j=0; j<BV_word_size; j++)
result += O3_bitcount[tmp[j]];
}
BV_word_type tmp1 = _words[i];
unsigned remaining = _n_bits % BV_word_n_bits;
if (remaining > 0)
tmp1 &= (((BV_word_type)1 << remaining) - 1);
unsigned char *tmp = (unsigned char *)&tmp1;
for (unsigned j=0; j<BV_word_size; j++)
result += O3_bitcount[tmp[j]];
return result;
}
unsigned Bit_Vector::bits_set_without_regs()
{
return bits_set() - O3_bitcount[_words[0] & 0xff];
}
void Bit_Vector::fill_in_index_array_no_regs(unsigned *array)
{
unsigned cur = 0;
for (unsigned i=1; i<_n_words*BV_word_size; i++)
{
unsigned char val = ((unsigned char *)_words)[i];
if (O3_bitcount[val] > 0)
{
for (unsigned j=0; j<8; j++)
{
if (val & ((BV_word_type)1 << j))
{
array[cur++] = i*8 + j;
}
}
}
}
}
void Bit_Vector::fill_in_index_array(unsigned *array)
{
unsigned cur = 0;
for (unsigned i=0; i<_n_words*BV_word_size; i++)
{
unsigned char val = ((unsigned char *)_words)[i];
if (O3_bitcount[val] > 0)
{
for (unsigned j=0; j<8; j++)
{
if (val & ((BV_word_type)1 << j))
{
array[cur++] = i*8 + j;
}
}
}
}
}
void Bit_Vector::fill_in_index_array_inverted(unsigned *array)
{
unsigned cur = 0;
for (unsigned i=0; i<_n_words*BV_word_size; i++)
{
unsigned char val = (unsigned char)(((unsigned char *)_words)[i] ^ 0xff);
if (O3_bitcount[val] > 0)
{
for (unsigned j=0; j<8; j++)
{
if (val & ((BV_word_type)1 << j))
{
array[cur++] = i*8 + j;
}
}
}
}
}
static void __print_a_bv (ostream &cout, BV_word_type *_vector, unsigned _n_elems) {
unsigned print_count = 0;
for (unsigned i = 0; i < _n_elems; i++) {
BV_word_type v = _vector[i];
if (v==0)
continue;
for(unsigned j = 0; j<BV_word_n_bits; j++,v>>=1)
if (v & 1) {
if (print_count++)
cout << " ";
cout << (unsigned)(j+i*BV_word_n_bits);
}
}
}
static inline void _print_a_range (ostream &cout, unsigned *p_print_count,
unsigned lo,
unsigned hi) {
char buf[32];
assert(lo<=hi);
if ((*p_print_count)++)
cout << " ";
sprintf(buf,(lo==hi?"%u":"%u-%u"), lo, hi);
cout << buf;
}
static void __print_a_bv_in_range (ostream &cout,BV_word_type *_vector, unsigned _n_elems) {
unsigned print_count = 0;
#define BV_INV_LEADING_BIT1 -1
int leading_bit1 = BV_INV_LEADING_BIT1, ending_bit1 = 0;
for (unsigned i = 0; i < _n_elems; i++) {
BV_word_type v = _vector[i];
if (v==0) {
if (leading_bit1 >= 0) {
_print_a_range(cout, &print_count, leading_bit1, ending_bit1);
leading_bit1 = BV_INV_LEADING_BIT1;
}
continue;
}
for(unsigned j = 0; j<BV_word_n_bits; j++,v>>=1)
if (v & 1) {
if (leading_bit1 >= 0) {
ending_bit1++;
} else
leading_bit1 = ending_bit1 = j+i*BV_word_n_bits;
} else
if (leading_bit1 >= 0) {
_print_a_range(cout, &print_count, leading_bit1, ending_bit1);
leading_bit1 = BV_INV_LEADING_BIT1;
}
}
if (leading_bit1 >= 0) {
_print_a_range(cout,&print_count, leading_bit1, ending_bit1);
leading_bit1 = BV_INV_LEADING_BIT1;
}
}
void Bit_Vector::print (ostream &cout, char *name) {
if (name) {
cout << "(set " << name << " {";
} else
cout << "(set {";
__print_a_bv(cout,_words, _n_words);
cout << "})\n";
}
void Bit_Vector::print_in_range (ostream & cout,char *name) {
if (name) {
cout << "(set " << name << " {";
} else
cout << "(set {";
__print_a_bv_in_range(cout,_words, _n_words);
cout << "})\n";
}
//---------------------------------------------------------------------------
// Bit_Vector_Array
//
Bit_Vector_Array::Bit_Vector_Array (unsigned n_bv,
unsigned n_bv_bit,
MemoryPool &mem ) {
_n_bv = n_bv;
_n_bv_bit = n_bv_bit;
unsigned n_bv_byte = Bit_Vector::mem_size(n_bv_bit);
assert((n_bv_byte%BV_word_size)==0);
_n_bv_elem = n_bv_byte / BV_word_size;
unsigned n_byte = n_bv_byte * n_bv;
_vector_array = (BV_word_type *)mem.alloc(n_byte);
clear_all();
}
Bit_Vector_Array::~Bit_Vector_Array () {}
void Bit_Vector_Array::init (unsigned n_bv,
unsigned n_bv_bit,
BV_word_type *_bva_mem ) {
_n_bv = n_bv;
_n_bv_bit = n_bv_bit;
unsigned n_bv_byte = Bit_Vector::mem_size(n_bv_bit);
assert((n_bv_byte%BV_word_size)==0);
_n_bv_elem = n_bv_byte / BV_word_size;
_vector_array = _bva_mem;
clear_all();
}
unsigned Bit_Vector_Array::mem_size (unsigned n_bv, unsigned n_bv_bit) {
unsigned n_bv_word = (n_bv_bit + BV_word_n_bits-1) / BV_word_n_bits;
unsigned n_bv_byte = n_bv_word * BV_word_size;
return n_bv_byte * n_bv;
}
void Bit_Vector_Array::clear_all () {
unsigned n_elems = _n_bv_elem * _n_bv;
for (unsigned i = 0; i < n_elems; i++)
_vector_array[i] = 0;
}
void Bit_Vector_Array::print (ostream &cout, char *name) {
if (name) {
cout << "(set " << name << " {";
} else
cout << "(set {";
BV_word_type *bv = _vector_array;
for(unsigned j=0; j<_n_bv; j++,bv+=_n_bv_elem) {
if (j)
cout << "/";
__print_a_bv(cout,bv, _n_bv_elem);
}
cout << "})\n";
}
void Bit_Vector_Array::print_in_range (ostream &cout, char *name) {
if (name) {
cout << "(set " << name << " {";
} else
cout << "(set {";
BV_word_type *bv = _vector_array;
for(unsigned j=0; j<_n_bv; j++,bv+=_n_bv_elem) {
if (j)
cout << "/";
__print_a_bv_in_range(cout,bv, _n_bv_elem);
}
cout << "})\n";
}