static void test_bv_xor(TestCase *tc, void *data) { # define XOR_SIZE 1000 static const int xor_cnt = 500; BitVector *xor_bv; BitVector *bv1 = bv_new(); BitVector *bv2 = bv_new(); char set[XOR_SIZE]; char set1[XOR_SIZE]; char set2[XOR_SIZE]; int i; int count = 0; (void)data; memset(set, 0, XOR_SIZE); memset(set1, 0, XOR_SIZE); memset(set2, 0, XOR_SIZE); for (i = 0; i < xor_cnt; i++) { int bit = rand() % XOR_SIZE; bv_set(bv1, bit); set1[bit] = 1; } for (i = 0; i < xor_cnt; i++) { int bit = rand() % XOR_SIZE; bv_set(bv2, bit); set2[bit] = 1; } for (i = 0; i < XOR_SIZE; i++) { if (set1[i] != set2[i]) { set[i] = 1; count++; } } xor_bv = bv_xor(bv1, bv2); Aiequal(count, xor_bv->count); for (i = 0; i < XOR_SIZE; i++) { if (!Aiequal(set[i], bv_get(xor_bv, i))) { Tmsg("At position %d, bv1 is %d and bv2 is %d\n", i, bv_get(bv1, i), bv_get(bv2, i)); } } bv1 = bv_xor_x(bv1, bv2); Assert(bv_eq(bv1, xor_bv), "BitVectors should be equal"); bv_destroy(bv2); bv_destroy(xor_bv); bv2 = bv_new(); xor_bv = bv_xor(bv1, bv2); Assert(bv_eq(bv1, xor_bv), "XORed BitVector equals bv1"); bv_destroy(bv1); bv_destroy(bv2); bv_destroy(xor_bv); }
static void test_bv_or(TestCase *tc, void *data) { # define OR_SIZE 1000 static const int or_cnt = 500; BitVector *or_bv; BitVector *bv1 = bv_new(); BitVector *bv2 = bv_new(); char set[OR_SIZE]; int i; int count = 0; (void)data; memset(set, 0, OR_SIZE); for (i = 0; i < or_cnt; i++) { int bit = rand() % OR_SIZE; bv_set(bv1, bit); if (0 == set[bit]) { count++; set[bit] = 1; } } for (i = 0; i < or_cnt; i++) { int bit = rand() % OR_SIZE; bv_set(bv2, bit); if (0 == set[bit]) { count++; set[bit] = 1; } } or_bv = bv_or(bv1, bv2); Aiequal(count, or_bv->count); for (i = 0; i < OR_SIZE; i++) { Aiequal(set[i], bv_get(or_bv, i)); } bv1 = bv_or_x(bv1, bv2); Assert(bv_eq(bv1, or_bv), "BitVectors should be equal"); bv_destroy(bv2); bv_destroy(or_bv); bv2 = bv_new(); or_bv = bv_or(bv1, bv2); Assert(bv_eq(bv1, or_bv), "ORed BitVector equals bv1"); bv_destroy(bv1); bv_destroy(bv2); bv_destroy(or_bv); }
/* * call-seq: * bv1 == bv2 -> bool * bv1 != bv2 -> bool * bv1.eql(bv2) -> bool * * Compares two bit vectors and returns true if both bitvectors have the same * bits set. */ VALUE frt_bv_eql(VALUE self, VALUE other) { BitVector *bv1, *bv2; GET_BV(bv1, self); GET_BV(bv2, other); return bv_eq(bv1, bv2) ? Qtrue : Qfalse; }
static void test_bv_eq_hash(TestCase *tc, void *data) { static int const COUNT = 1000; int i; BitVector *bv1 = bv_new(); BitVector *bv2 = bv_new(); (void)data; test_bveq(bv1, bv2); Assert(bv_eq(bv1, bv1), "bv_eq on self should work"); bv_set(bv1, 1); test_bvneq(bv1, bv2); bv_set(bv2, 11); test_bvneq(bv1, bv2); bv_set(bv1, 11); bv_set(bv2, 1); test_bveq(bv1, bv2); /* This will increase size of bv1 to 1000 */ bv_unset(bv1, 1000); /* difference in size shouldn't matter */ test_bveq(bv1, bv2); for (i = 0; i < COUNT; i++) { int bit = rand() % COUNT; bv_set(bv1, bit); bv_set(bv2, bit); } test_bveq(bv1, bv2); bv_destroy(bv1); bv_destroy(bv2); /* although the saet bits will be equal, the extension will be different*/ bv1 = set_bits(bv_new(), "1, 3, 5"); bv2 = bv_not_x(set_bits(bv_new(), "0, 2, 4")); bv_set(bv2, 5); test_bvneq(bv1, bv2); bv_destroy(bv2); bv2 = set_bits(bv_new(), "1, 3, 5"); bv1 = bv_not_x(bv1); bv2 = bv_not_x(bv2); bv_unset(bv1, 1000); test_bvneq(bv1, bv2); bv_destroy(bv1); bv_destroy(bv2); }
static void test_bv_combined_boolean_ops(TestCase *tc, void *data) { BitVector *bv1 = bv_new(); BitVector *bv2 = bv_new(); BitVector *bv3; BitVector *bv4; BitVector *bv5; BitVector *bv_empty = bv_new(); (void)data; set_bits(bv1, "1, 5, 7"); set_bits(bv2, "1, 8, 20"); bv3 = bv_not(bv1); Aiequal(bv3->size, bv1->size); bv4 = bv_and(bv1, bv3); Assert(bv_eq(bv4, bv_empty), "bv & ~bv == empty BitVector"); bv_destroy(bv4); bv4 = bv_and(bv2, bv3); bv5 = set_bits(bv_new(), "8, 20"); Assert(bv_eq(bv4, bv5), "~[1,5,7] & [1,8,20] == [8,20]"); bv_destroy(bv4); bv_destroy(bv5); bv4 = bv_or(bv1, bv3); bv5 = bv_not(bv_empty); Assert(bv_eq(bv4, bv5), "bv | ~bv == all 1s"); bv_destroy(bv4); bv_destroy(bv5); bv4 = bv_or(bv2, bv3); bv5 = bv_not_x(set_bits(bv_new(), "5, 7")); Assert(bv_eq(bv4, bv5), "~[1,5,7] | [1,8,20] == ~[5, 7]"); bv_destroy(bv4); bv_destroy(bv5); bv4 = bv_xor(bv1, bv3); bv5 = bv_not(bv_empty); Assert(bv_eq(bv4, bv5), "bv ^ ~bv == full BitVector"); bv_destroy(bv4); bv_destroy(bv5); bv4 = bv_xor(bv2, bv3); bv5 = bv_not_x(set_bits(bv_new(), "5, 7, 8, 20")); Assert(bv_eq(bv4, bv5), "~[1,5,7] ^ [1,8,20] == ~[5, 7, 8, 20]"); bv_destroy(bv4); bv_destroy(bv5); bv_destroy(bv1); bv_destroy(bv2); bv_destroy(bv3); bv_destroy(bv_empty); }
static void test_bv_not(TestCase *tc, void *data) { BitVector *bv = bv_new(), *not_bv; int i; (void)data; set_bits(bv, "1, 5, 25, 41, 97, 185"); Aiequal(186, bv->size); not_bv = bv_not(bv); Aiequal(bv->count, not_bv->count); for (i = 0; i < 300; i++) { Aiequal(1 - bv_get(bv, i), bv_get(not_bv, i)); } bv_not_x(bv); Assert(bv_eq(bv, not_bv), "BitVectors equal"); bv_destroy(bv); bv_destroy(not_bv); }
/* lvrelax: compute live variable info for block b if necessary (if updates have been performed by any of its successors), or in any case if force is true. */ static void lvrelax (i_bb_t b, int force) { unsigned int i; bvt out, fout; /* "Out" bit vectors */ bvt in, fin; /* "In" bit vector */ i_bb_t *n = b->n; /* List of successors */ i_bb_t *p = b->p; /* List of predecessors */ unsigned int nn = b->nn; /* Numbers of predecessors and successors */ unsigned int np = b->np; assert(b); /* Either this is the first round or we are here because we need to update something */ assert(force || b->iupdates+b->fupdates > 0); if (nn == 0) { /* Sinks: in = use */ assert(force); /* Sinks are touched only once */ if (num_i) { /* Handle ints */ b->ilv_in = bv_cp(b->iv_use); /* Increase updates for each predecessor */ for (i = 0; i < np; i++) ++p[i]->iupdates; iupdates += np; /* Increase updates count */ } if (num_f) { /* Handle floats */ b->flv_in = bv_cp(b->fv_use); for (i = 0; i < np; i++) ++p[i]->fupdates; fupdates += np; } return; /* Nothing more to be done for sinks */ } /* Handle integers */ if (num_i && (b->iupdates || force)) { out = bv_cp(b->ilv_out); /* out = \sum_{s\in succ}{in(s)} */ for (i = 0; i < nn; i++) { assert(n[i]); if (n[i]->ilv_in) bv_union(out, n[i]->ilv_in); } /* in = use + (out - def) */ if (!bv_eq(b->ilv_out, out)) { b->ilv_out = out; in = bv_cp(out); } else in = out; /* We don't use 'out': optimize away bv_cp */ bv_diff(in, b->iv_def); bv_union(in, b->iv_use); iupdates -= b->iupdates;/* This node has just been updates */ assert(iupdates >= 0); b->iupdates = 0; if (!b->ilv_in || !bv_eq(b->ilv_in, in)) { b->ilv_in = in; for (i = 0; i < np; i++) ++p[i]->iupdates; iupdates += np; /* Increase updates count; always >= 0 */ } } /* Handle floats */ if (num_f && (b->fupdates || force)) { fout = bv_cp(b->flv_out); /* out = \sum_{s\in succ}{in(s)} */ for (i = 0; i < nn; i++) { assert(n[i]); if (n[i]->flv_in) bv_union(fout, n[i]->flv_in); } /* in = use + (out - def) */ if (!bv_eq(b->flv_out, fout)) { b->flv_out = fout; fin = bv_cp(fout); } else fin = fout; /* We don't use 'out': optimize away bv_cp */ bv_diff(fin, b->fv_def); bv_union(fin, b->fv_use); fupdates -= b->fupdates; assert(fupdates >= 0); b->fupdates = 0; if (!b->flv_in || !bv_eq(b->flv_in, fin)) { b->flv_in = fin; for (i = 0; i < np; i++) ++p[i]->fupdates; /* Increase updates count; always >= 0 */ fupdates += np; } } }
static void test_bv_and(TestCase *tc, void *data) { # define AND_SIZE 1000 static const int and_cnt = 500; BitVector *and_bv; BitVector *bv1 = bv_new(); BitVector *bv2 = bv_new(); BitVector *not_bv1, *not_bv2, *or_bv, *not_and_bv; char set1[AND_SIZE]; char set2[AND_SIZE]; int i; int count = 0; (void)data; memset(set1, 0, AND_SIZE); memset(set2, 0, AND_SIZE); for (i = 0; i < and_cnt; i++) { int bit = rand() % AND_SIZE; bv_set(bv1, bit); set1[bit] = 1; } for (i = 0; i < and_cnt; i++) { int bit = rand() % AND_SIZE; bv_set(bv2, bit); if (1 == set1[bit] && !set2[bit]) { count++; set2[bit] = 1; } } not_bv1 = bv_not(bv1); not_bv2 = bv_not(bv2); and_bv = bv_and(not_bv1, not_bv2); not_and_bv = bv_not(and_bv); or_bv = bv_or(bv1, bv2); Assert(bv_eq(not_and_bv, or_bv), "BitVectors should be equal"); bv_destroy(not_bv1); bv_destroy(not_bv2); bv_destroy(and_bv); bv_destroy(not_and_bv); bv_destroy(or_bv); and_bv = bv_and(bv1, bv2); Aiequal(count, and_bv->count); for (i = 0; i < AND_SIZE; i++) { Aiequal(set2[i], bv_get(and_bv, i)); } bv1 = bv_and_x(bv1, bv2); Assert(bv_eq(bv1, and_bv), "BitVectors should be equal"); bv_destroy(bv2); bv_destroy(and_bv); bv2 = bv_new(); and_bv = bv_and(bv1, bv2); Assert(bv_eq(bv2, and_bv), "ANDed BitVector should be empty"); bv_destroy(bv1); bv_destroy(bv2); bv_destroy(and_bv); bv1 = bv_new(); bv_not_x(bv1); bv2 = bv_new(); bv_set(bv2, 10); bv_set(bv2, 11); bv_set(bv2, 20); and_bv = bv_and(bv1, bv2); Assert(bv_eq(bv2, and_bv), "ANDed BitVector should be equal"); bv_destroy(bv1); bv_destroy(bv2); bv_destroy(and_bv); }