Home | History | Annotate | Download | only in drd
      1 /*
      2   This file is part of drd, a thread error detector.
      3 
      4   Copyright (C) 2006-2013 Bart Van Assche <bvanassche (at) acm.org>.
      5 
      6   This program is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU General Public License as
      8   published by the Free Software Foundation; either version 2 of the
      9   License, or (at your option) any later version.
     10 
     11   This program is distributed in the hope that it will be useful, but
     12   WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   General Public License for more details.
     15 
     16   You should have received a copy of the GNU General Public License
     17   along with this program; if not, write to the Free Software
     18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     19   02111-1307, USA.
     20 
     21   The GNU General Public License is contained in the file COPYING.
     22 */
     23 
     24 
     25 #include "drd_basics.h"           /* DRD_() */
     26 #include "drd_bitmap.h"
     27 #include "drd_error.h"
     28 #include "drd_suppression.h"
     29 #include "pub_drd_bitmap.h"
     30 #include "pub_tool_basics.h"      /* Addr, SizeT */
     31 #include "pub_tool_debuginfo.h"   /* VG_(get_objname)() */
     32 #include "pub_tool_libcassert.h"  /* tl_assert() */
     33 #include "pub_tool_libcbase.h"    /* VG_(memset) */
     34 #include "pub_tool_libcprint.h"   /* VG_(printf) */
     35 #include "pub_tool_machine.h"     /* VG_(get_IP)() */
     36 #include "pub_tool_mallocfree.h"  /* VG_(malloc), VG_(free) */
     37 
     38 
     39 /* Local function declarations. */
     40 
     41 static void bm2_merge(struct bitmap2* const bm2l,
     42                       const struct bitmap2* const bm2r);
     43 static void bm2_print(const struct bitmap2* const bm2);
     44 
     45 
     46 /* Local variables. */
     47 
     48 static OSet* s_bm2_set_template;
     49 static ULong s_bitmap_creation_count;
     50 static ULong s_bitmap_merge_count;
     51 static ULong s_bitmap2_merge_count;
     52 
     53 
     54 /* Function definitions. */
     55 
     56 void DRD_(bm_module_init)(void)
     57 {
     58    tl_assert(!s_bm2_set_template);
     59    s_bm2_set_template
     60       = VG_(OSetGen_Create_With_Pool)(0, 0, VG_(malloc), "drd.bitmap.bn.2",
     61                                       VG_(free), 512, sizeof(struct bitmap2));
     62 }
     63 
     64 void DRD_(bm_module_cleanup)(void)
     65 {
     66    tl_assert(s_bm2_set_template);
     67    VG_(OSetGen_Destroy)(s_bm2_set_template);
     68    s_bm2_set_template = NULL;
     69 }
     70 
     71 struct bitmap* DRD_(bm_new)()
     72 {
     73    struct bitmap* bm;
     74 
     75    /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
     76    /* in drd_bitmap.h.                                                    */
     77    tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
     78 
     79    bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
     80    DRD_(bm_init)(bm);
     81 
     82    return bm;
     83 }
     84 
     85 void DRD_(bm_delete)(struct bitmap* const bm)
     86 {
     87    tl_assert(bm);
     88 
     89    DRD_(bm_cleanup)(bm);
     90    VG_(free)(bm);
     91 }
     92 
     93 /** Initialize *bm. */
     94 void DRD_(bm_init)(struct bitmap* const bm)
     95 {
     96    unsigned i;
     97 
     98    tl_assert(bm);
     99    /*
    100     * Cache initialization. a1 is initialized with a value that never can
    101     * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
    102     * bits of a1 are always zero for a valid cache entry.
    103     */
    104    for (i = 0; i < DRD_BITMAP_N_CACHE_ELEM; i++)
    105    {
    106       bm->cache[i].a1  = ~(UWord)1;
    107       bm->cache[i].bm2 = 0;
    108    }
    109    bm->oset = VG_(OSetGen_EmptyClone)(s_bm2_set_template);
    110 
    111    s_bitmap_creation_count++;
    112 }
    113 
    114 /** Free the memory allocated by DRD_(bm_init)(). */
    115 void DRD_(bm_cleanup)(struct bitmap* const bm)
    116 {
    117    VG_(OSetGen_Destroy)(bm->oset);
    118 }
    119 
    120 /**
    121  * Record an access of type access_type at addresses a .. a + size - 1 in
    122  * bitmap bm.
    123  *
    124  * @note The current implementation of bm_access_range does not work for the
    125  * highest addresses in the address range. At least on Linux this is
    126  * not a problem since the upper part of the address space is reserved
    127  * for the kernel.
    128  */
    129 void DRD_(bm_access_range)(struct bitmap* const bm,
    130                            const Addr a1, const Addr a2,
    131                            const BmAccessTypeT access_type)
    132 {
    133    tl_assert(access_type == eLoad || access_type == eStore);
    134 
    135    if (access_type == eLoad)
    136       return DRD_(bm_access_range_load)(bm, a1, a2);
    137    else
    138       return DRD_(bm_access_range_store)(bm, a1, a2);
    139 }
    140 
    141 void DRD_(bm_access_range_load)(struct bitmap* const bm, Addr a1, Addr a2)
    142 {
    143    Addr b, b_next;
    144 
    145    tl_assert(bm);
    146    tl_assert(a1 <= a2);
    147    tl_assert(a2 < first_address_with_higher_msb(a2));
    148    tl_assert(a1 == first_address_with_same_lsb(a1));
    149    tl_assert(a2 == first_address_with_same_lsb(a2));
    150 
    151    for (b = a1; b < a2; b = b_next)
    152    {
    153       Addr b_start;
    154       Addr b_end;
    155       struct bitmap2* bm2;
    156       UWord b0;
    157 
    158       b_next = first_address_with_higher_msb(b);
    159       if (b_next > a2)
    160       {
    161          b_next = a2;
    162       }
    163 
    164       bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
    165       tl_assert(bm2);
    166 
    167       if (make_address(bm2->addr, 0) < a1)
    168          b_start = a1;
    169       else
    170          if (make_address(bm2->addr, 0) < a2)
    171             b_start = make_address(bm2->addr, 0);
    172          else
    173             break;
    174 
    175       if (make_address(bm2->addr + 1, 0) < a2)
    176          b_end = make_address(bm2->addr + 1, 0);
    177       else
    178          b_end = a2;
    179 
    180       tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
    181       tl_assert(address_msb(b_start) == address_msb(b_end - 1));
    182       tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
    183 
    184       if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
    185       {
    186          unsigned k;
    187 
    188          for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
    189          {
    190             bm2->bm1.bm0_r[k] = ~(UWord)0;
    191          }
    192       }
    193       else
    194       {
    195          for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    196          {
    197             bm0_set(bm2->bm1.bm0_r, b0);
    198          }
    199       }
    200    }
    201 }
    202 
    203 void DRD_(bm_access_load_1)(struct bitmap* const bm, const Addr a1)
    204 {
    205    bm_access_aligned_load(bm, a1, 1);
    206 }
    207 
    208 void DRD_(bm_access_load_2)(struct bitmap* const bm, const Addr a1)
    209 {
    210    if ((a1 & 1) == 0)
    211       bm_access_aligned_load(bm, a1, 2);
    212    else
    213       DRD_(bm_access_range)(bm, a1, a1 + 2, eLoad);
    214 }
    215 
    216 void DRD_(bm_access_load_4)(struct bitmap* const bm, const Addr a1)
    217 {
    218    if ((a1 & 3) == 0)
    219       bm_access_aligned_load(bm, a1, 4);
    220    else
    221       DRD_(bm_access_range)(bm, a1, a1 + 4, eLoad);
    222 }
    223 
    224 void DRD_(bm_access_load_8)(struct bitmap* const bm, const Addr a1)
    225 {
    226    if ((a1 & 7) == 0)
    227       bm_access_aligned_load(bm, a1, 8);
    228    else if ((a1 & 3) == 0)
    229    {
    230       bm_access_aligned_load(bm, a1 + 0, 4);
    231       bm_access_aligned_load(bm, a1 + 4, 4);
    232    }
    233    else
    234       DRD_(bm_access_range)(bm, a1, a1 + 8, eLoad);
    235 }
    236 
    237 void DRD_(bm_access_range_store)(struct bitmap* const bm,
    238                                  const Addr a1, const Addr a2)
    239 {
    240    Addr b, b_next;
    241 
    242    tl_assert(bm);
    243    tl_assert(a1 <= a2);
    244    tl_assert(a2 < first_address_with_higher_msb(a2));
    245    tl_assert(a1 == first_address_with_same_lsb(a1));
    246    tl_assert(a2 == first_address_with_same_lsb(a2));
    247 
    248    for (b = a1; b < a2; b = b_next)
    249    {
    250       Addr b_start;
    251       Addr b_end;
    252       struct bitmap2* bm2;
    253       UWord b0;
    254 
    255       b_next = first_address_with_higher_msb(b);
    256       if (b_next > a2)
    257       {
    258          b_next = a2;
    259       }
    260 
    261       bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
    262       tl_assert(bm2);
    263 
    264       if (make_address(bm2->addr, 0) < a1)
    265          b_start = a1;
    266       else
    267          if (make_address(bm2->addr, 0) < a2)
    268             b_start = make_address(bm2->addr, 0);
    269          else
    270             break;
    271 
    272       if (make_address(bm2->addr + 1, 0) < a2)
    273          b_end = make_address(bm2->addr + 1, 0);
    274       else
    275          b_end = a2;
    276 
    277       tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
    278       tl_assert(address_msb(b_start) == address_msb(b_end - 1));
    279       tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
    280 
    281       if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
    282       {
    283          unsigned k;
    284 
    285          for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
    286          {
    287             bm2->bm1.bm0_w[k] = ~(UWord)0;
    288          }
    289       }
    290       else
    291       {
    292          for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    293          {
    294             bm0_set(bm2->bm1.bm0_w, b0);
    295          }
    296       }
    297    }
    298 }
    299 
    300 void DRD_(bm_access_store_1)(struct bitmap* const bm, const Addr a1)
    301 {
    302    bm_access_aligned_store(bm, a1, 1);
    303 }
    304 
    305 void DRD_(bm_access_store_2)(struct bitmap* const bm, const Addr a1)
    306 {
    307    if ((a1 & 1) == 0)
    308       bm_access_aligned_store(bm, a1, 2);
    309    else
    310       DRD_(bm_access_range)(bm, a1, a1 + 2, eStore);
    311 }
    312 
    313 void DRD_(bm_access_store_4)(struct bitmap* const bm, const Addr a1)
    314 {
    315    if ((a1 & 3) == 0)
    316       bm_access_aligned_store(bm, a1, 4);
    317    else
    318       DRD_(bm_access_range)(bm, a1, a1 + 4, eStore);
    319 }
    320 
    321 void DRD_(bm_access_store_8)(struct bitmap* const bm, const Addr a1)
    322 {
    323    if ((a1 & 7) == 0)
    324       bm_access_aligned_store(bm, a1, 8);
    325    else if ((a1 & 3) == 0)
    326    {
    327       bm_access_aligned_store(bm, a1 + 0, 4);
    328       bm_access_aligned_store(bm, a1 + 4, 4);
    329    }
    330    else
    331       DRD_(bm_access_range)(bm, a1, a1 + 8, eStore);
    332 }
    333 
    334 Bool DRD_(bm_has)(struct bitmap* const bm, const Addr a1, const Addr a2,
    335                   const BmAccessTypeT access_type)
    336 {
    337    tl_assert(access_type == eLoad || access_type == eStore);
    338 
    339    if (access_type == eLoad)
    340       return DRD_(bm_has_any_load)(bm, a1, a2);
    341    else
    342       return DRD_(bm_has_any_store)(bm, a1, a2);
    343 }
    344 
    345 Bool DRD_(bm_has_any_load_g)(struct bitmap* const bm)
    346 {
    347    struct bitmap2* bm2;
    348 
    349    tl_assert(bm);
    350 
    351    VG_(OSetGen_ResetIter)(bm->oset);
    352    for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != NULL; ) {
    353       Addr b_start;
    354       Addr b_end;
    355       UWord b0;
    356       const struct bitmap1* const p1 = &bm2->bm1;
    357 
    358       b_start = make_address(bm2->addr, 0);
    359       b_end = make_address(bm2->addr + 1, 0);
    360 
    361       for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    362          if (bm0_is_set(p1->bm0_r, b0))
    363             return True;
    364    }
    365    return False;
    366 }
    367 
    368 Bool
    369 DRD_(bm_has_any_load)(struct bitmap* const bm, const Addr a1, const Addr a2)
    370 {
    371    Addr b, b_next;
    372 
    373    tl_assert(bm);
    374 
    375    for (b = a1; b < a2; b = b_next)
    376    {
    377       const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
    378 
    379       b_next = first_address_with_higher_msb(b);
    380       if (b_next > a2)
    381       {
    382          b_next = a2;
    383       }
    384 
    385       if (bm2)
    386       {
    387          Addr b_start;
    388          Addr b_end;
    389          UWord b0;
    390          const struct bitmap1* const p1 = &bm2->bm1;
    391 
    392          if (make_address(bm2->addr, 0) < a1)
    393             b_start = a1;
    394          else
    395             if (make_address(bm2->addr, 0) < a2)
    396                b_start = make_address(bm2->addr, 0);
    397             else
    398                break;
    399          tl_assert(a1 <= b_start && b_start <= a2);
    400 
    401          if (make_address(bm2->addr + 1, 0) < a2)
    402             b_end = make_address(bm2->addr + 1, 0);
    403          else
    404             b_end = a2;
    405          tl_assert(a1 <= b_end && b_end <= a2);
    406          tl_assert(b_start < b_end);
    407          tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
    408 
    409          for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    410          {
    411             if (bm0_is_set(p1->bm0_r, b0))
    412             {
    413                return True;
    414             }
    415          }
    416       }
    417    }
    418    return 0;
    419 }
    420 
    421 Bool DRD_(bm_has_any_store)(struct bitmap* const bm,
    422                             const Addr a1, const Addr a2)
    423 {
    424    Addr b, b_next;
    425 
    426    tl_assert(bm);
    427 
    428    for (b = a1; b < a2; b = b_next)
    429    {
    430       const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
    431 
    432       b_next = first_address_with_higher_msb(b);
    433       if (b_next > a2)
    434       {
    435          b_next = a2;
    436       }
    437 
    438       if (bm2)
    439       {
    440          Addr b_start;
    441          Addr b_end;
    442          UWord b0;
    443          const struct bitmap1* const p1 = &bm2->bm1;
    444 
    445          if (make_address(bm2->addr, 0) < a1)
    446             b_start = a1;
    447          else
    448             if (make_address(bm2->addr, 0) < a2)
    449                b_start = make_address(bm2->addr, 0);
    450             else
    451                break;
    452          tl_assert(a1 <= b_start && b_start <= a2);
    453 
    454          if (make_address(bm2->addr + 1, 0) < a2)
    455             b_end = make_address(bm2->addr + 1, 0);
    456          else
    457             b_end = a2;
    458          tl_assert(a1 <= b_end && b_end <= a2);
    459          tl_assert(b_start < b_end);
    460          tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
    461 
    462          for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    463          {
    464             if (bm0_is_set(p1->bm0_w, b0))
    465             {
    466                return True;
    467             }
    468          }
    469       }
    470    }
    471    return 0;
    472 }
    473 
    474 /* Return True if there is a read access, write access or both   */
    475 /* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
    476 Bool DRD_(bm_has_any_access)(struct bitmap* const bm,
    477                              const Addr a1, const Addr a2)
    478 {
    479    Addr b, b_next;
    480 
    481    tl_assert(bm);
    482 
    483    for (b = a1; b < a2; b = b_next)
    484    {
    485       const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
    486 
    487       b_next = first_address_with_higher_msb(b);
    488       if (b_next > a2)
    489       {
    490          b_next = a2;
    491       }
    492 
    493       if (bm2)
    494       {
    495          Addr b_start;
    496          Addr b_end;
    497          UWord b0;
    498          const struct bitmap1* const p1 = &bm2->bm1;
    499 
    500          if (make_address(bm2->addr, 0) < a1)
    501             b_start = a1;
    502          else
    503             if (make_address(bm2->addr, 0) < a2)
    504                b_start = make_address(bm2->addr, 0);
    505             else
    506                break;
    507          tl_assert(a1 <= b_start && b_start <= a2);
    508 
    509          if (make_address(bm2->addr + 1, 0) < a2)
    510             b_end = make_address(bm2->addr + 1, 0);
    511          else
    512             b_end = a2;
    513          tl_assert(a1 <= b_end && b_end <= a2);
    514          tl_assert(b_start < b_end);
    515          tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
    516 
    517          for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    518          {
    519             /*
    520              * Note: the statement below uses a binary or instead of a logical
    521              * or on purpose.
    522              */
    523             if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
    524             {
    525                return True;
    526             }
    527          }
    528       }
    529    }
    530    return False;
    531 }
    532 
    533 /**
    534  * Report whether an access of type access_type at address a is recorded in
    535  * bitmap bm.
    536  */
    537 Bool DRD_(bm_has_1)(struct bitmap* const bm,
    538                     const Addr a, const BmAccessTypeT access_type)
    539 {
    540    const struct bitmap2* p2;
    541    const struct bitmap1* p1;
    542    const UWord* p0;
    543    const UWord a0 = address_lsb(a);
    544 
    545    tl_assert(bm);
    546 
    547    p2 = bm2_lookup(bm, address_msb(a));
    548    if (p2)
    549    {
    550       p1 = &p2->bm1;
    551       p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
    552       return bm0_is_set(p0, a0) ? True : False;
    553    }
    554    return False;
    555 }
    556 
    557 void DRD_(bm_clear)(struct bitmap* const bm, Addr a1, Addr a2)
    558 {
    559    Addr b, b_next;
    560 
    561    tl_assert(bm);
    562    tl_assert(a1);
    563    tl_assert(a1 <= a2);
    564    tl_assert(a1 == first_address_with_same_lsb(a1));
    565    tl_assert(a2 == first_address_with_same_lsb(a2));
    566 
    567    for (b = a1; b < a2; b = b_next)
    568    {
    569       struct bitmap2* p2;
    570       Addr c;
    571 
    572 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    573       tl_assert(a1 <= b && b < a2);
    574 #endif
    575 
    576       p2 = bm2_lookup_exclusive(bm, address_msb(b));
    577 
    578       b_next = first_address_with_higher_msb(b);
    579       if (b_next > a2)
    580       {
    581          b_next = a2;
    582       }
    583 
    584       if (p2 == 0)
    585          continue;
    586 
    587       c = b;
    588       /* If the first address in the bitmap that must be cleared does not */
    589       /* start on an UWord boundary, start clearing the first addresses.  */
    590       if (uword_lsb(address_lsb(c)))
    591       {
    592          Addr c_next = first_address_with_higher_uword_msb(c);
    593          if (c_next > b_next)
    594             c_next = b_next;
    595 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    596          tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
    597                    && b_next <= a2);
    598 #endif
    599          bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
    600          bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
    601          c = c_next;
    602       }
    603       /* If some UWords have to be cleared entirely, do this now. */
    604       if (uword_lsb(address_lsb(c)) == 0)
    605       {
    606          Addr c_next = first_address_with_same_uword_lsb(b_next);
    607 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    608          tl_assert(uword_lsb(address_lsb(c)) == 0);
    609          tl_assert(uword_lsb(address_lsb(c_next)) == 0);
    610          tl_assert(c_next <= b_next);
    611 #endif
    612          if (c_next > c)
    613          {
    614             UWord idx = uword_msb(address_lsb(c));
    615             VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
    616             VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
    617             c = c_next;
    618          }
    619       }
    620       /* If the last address in the bitmap that must be cleared does not */
    621       /* fall on an UWord boundary, clear the last addresses.            */
    622 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    623       tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
    624 #endif
    625       bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
    626       bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
    627    }
    628 }
    629 
    630 /**
    631  * Clear all references to loads in bitmap bm starting at address a1 and
    632  * up to but not including address a2.
    633  */
    634 void DRD_(bm_clear_load)(struct bitmap* const bm, Addr a1, Addr a2)
    635 {
    636    Addr b, b_next;
    637 
    638    tl_assert(bm);
    639    tl_assert(a1);
    640    tl_assert(a1 <= a2);
    641    tl_assert(a1 == first_address_with_same_lsb(a1));
    642    tl_assert(a2 == first_address_with_same_lsb(a2));
    643 
    644    for (b = a1; b < a2; b = b_next)
    645    {
    646       struct bitmap2* p2;
    647       Addr c;
    648 
    649 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    650       tl_assert(a1 <= b && b < a2);
    651 #endif
    652 
    653       p2 = bm2_lookup_exclusive(bm, address_msb(b));
    654 
    655       b_next = first_address_with_higher_msb(b);
    656       if (b_next > a2)
    657       {
    658          b_next = a2;
    659       }
    660 
    661       if (p2 == 0)
    662          continue;
    663 
    664       c = b;
    665       /* If the first address in the bitmap that must be cleared does not */
    666       /* start on an UWord boundary, start clearing the first addresses.  */
    667 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    668       tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
    669 #endif
    670       if (uword_lsb(address_lsb(c)))
    671       {
    672          Addr c_next = first_address_with_higher_uword_msb(c);
    673          if (c_next > b_next)
    674             c_next = b_next;
    675 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    676          tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
    677                    && b_next <= a2);
    678 #endif
    679          bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
    680          c = c_next;
    681       }
    682       /* If some UWords have to be cleared entirely, do this now. */
    683 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    684       tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
    685 #endif
    686       if (uword_lsb(address_lsb(c)) == 0)
    687       {
    688          Addr c_next = first_address_with_same_uword_lsb(b_next);
    689 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    690          tl_assert(uword_lsb(address_lsb(c)) == 0);
    691          tl_assert(uword_lsb(address_lsb(c_next)) == 0);
    692          tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
    693                    && b_next <= a2);
    694 #endif
    695          if (c_next > c)
    696          {
    697             UWord idx = uword_msb(address_lsb(c));
    698             VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
    699             c = c_next;
    700          }
    701       }
    702       /* If the last address in the bitmap that must be cleared does not */
    703       /* fall on an UWord boundary, clear the last addresses.            */
    704 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    705       tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
    706 #endif
    707       bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
    708    }
    709 }
    710 
    711 /**
    712  * Clear all references to stores in bitmap bm starting at address a1 and
    713  * up to but not including address a2.
    714  */
    715 void DRD_(bm_clear_store)(struct bitmap* const bm,
    716                           const Addr a1, const Addr a2)
    717 {
    718    Addr b, b_next;
    719 
    720    tl_assert(bm);
    721    tl_assert(a1);
    722    tl_assert(a1 <= a2);
    723    tl_assert(a1 == first_address_with_same_lsb(a1));
    724    tl_assert(a2 == first_address_with_same_lsb(a2));
    725 
    726    for (b = a1; b < a2; b = b_next)
    727    {
    728       struct bitmap2* p2;
    729       Addr c;
    730 
    731 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    732       tl_assert(a1 <= b && b < a2);
    733 #endif
    734 
    735       p2 = bm2_lookup_exclusive(bm, address_msb(b));
    736 
    737       b_next = first_address_with_higher_msb(b);
    738       if (b_next > a2)
    739       {
    740          b_next = a2;
    741       }
    742 
    743       if (p2 == 0)
    744          continue;
    745 
    746       c = b;
    747       /* If the first address in the bitmap that must be cleared does not */
    748       /* start on an UWord boundary, start clearing the first addresses.  */
    749 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    750       tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
    751 #endif
    752       if (uword_lsb(address_lsb(c)))
    753       {
    754          Addr c_next = first_address_with_higher_uword_msb(c);
    755          if (c_next > b_next)
    756             c_next = b_next;
    757 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    758          tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
    759                    && b_next <= a2);
    760 #endif
    761          bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
    762          c = c_next;
    763       }
    764       /* If some UWords have to be cleared entirely, do this now. */
    765 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    766       tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
    767 #endif
    768       if (uword_lsb(address_lsb(c)) == 0)
    769       {
    770          Addr c_next = first_address_with_same_uword_lsb(b_next);
    771 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    772          tl_assert(uword_lsb(address_lsb(c)) == 0);
    773          tl_assert(uword_lsb(address_lsb(c_next)) == 0);
    774          tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
    775                    && b_next <= a2);
    776 #endif
    777          if (c_next > c)
    778          {
    779             UWord idx = uword_msb(address_lsb(c));
    780             VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
    781             c = c_next;
    782          }
    783       }
    784       /* If the last address in the bitmap that must be cleared does not */
    785       /* fall on an UWord boundary, clear the last addresses.            */
    786 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
    787       tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
    788 #endif
    789       bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
    790    }
    791 }
    792 
    793 /**
    794  * Clear bitmap bm starting at address a1 and up to but not including address
    795  * a2. Return True if and only if any of the addresses was set before
    796  * clearing.
    797  */
    798 Bool DRD_(bm_test_and_clear)(struct bitmap* const bm,
    799                              const Addr a1, const Addr a2)
    800 {
    801    Bool result;
    802 
    803    result = DRD_(bm_has_any_access)(bm, a1, a2) != 0;
    804    DRD_(bm_clear)(bm, a1, a2);
    805    return result;
    806 }
    807 
    808 Bool DRD_(bm_has_conflict_with)(struct bitmap* const bm,
    809                                 const Addr a1, const Addr a2,
    810                                 const BmAccessTypeT access_type)
    811 {
    812    Addr b, b_next;
    813 
    814    tl_assert(bm);
    815 
    816    for (b = a1; b < a2; b = b_next)
    817    {
    818       const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
    819 
    820       b_next = first_address_with_higher_msb(b);
    821       if (b_next > a2)
    822       {
    823          b_next = a2;
    824       }
    825 
    826       if (bm2)
    827       {
    828          Addr b_start;
    829          Addr b_end;
    830          UWord b0;
    831          const struct bitmap1* const p1 = &bm2->bm1;
    832 
    833          if (make_address(bm2->addr, 0) < a1)
    834             b_start = a1;
    835          else
    836             if (make_address(bm2->addr, 0) < a2)
    837                b_start = make_address(bm2->addr, 0);
    838             else
    839                break;
    840          tl_assert(a1 <= b_start && b_start <= a2);
    841 
    842          if (make_address(bm2->addr + 1, 0) < a2)
    843             b_end = make_address(bm2->addr + 1, 0);
    844          else
    845             b_end = a2;
    846          tl_assert(a1 <= b_end && b_end <= a2);
    847          tl_assert(b_start < b_end);
    848          tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
    849 
    850          for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
    851          {
    852             if (access_type == eLoad)
    853             {
    854                if (bm0_is_set(p1->bm0_w, b0))
    855                {
    856                   return True;
    857                }
    858             }
    859             else
    860             {
    861                tl_assert(access_type == eStore);
    862                if (bm0_is_set(p1->bm0_r, b0)
    863                    | bm0_is_set(p1->bm0_w, b0))
    864                {
    865                   return True;
    866                }
    867             }
    868          }
    869       }
    870    }
    871    return False;
    872 }
    873 
    874 Bool DRD_(bm_load_has_conflict_with)(struct bitmap* const bm,
    875                                      const Addr a1, const Addr a2)
    876 {
    877    return DRD_(bm_has_conflict_with)(bm, a1, a2, eLoad);
    878 }
    879 
    880 Bool DRD_(bm_load_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    881 {
    882    return bm_aligned_load_has_conflict_with(bm, a1, 1);
    883 }
    884 
    885 Bool DRD_(bm_load_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    886 {
    887    if ((a1 & 1) == 0)
    888       return bm_aligned_load_has_conflict_with(bm, a1, 2);
    889    else
    890       return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eLoad);
    891 }
    892 
    893 Bool DRD_(bm_load_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    894 {
    895    if ((a1 & 3) == 0)
    896       return bm_aligned_load_has_conflict_with(bm, a1, 4);
    897    else
    898       return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eLoad);
    899 }
    900 
    901 Bool DRD_(bm_load_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    902 {
    903    if ((a1 & 7) == 0)
    904       return bm_aligned_load_has_conflict_with(bm, a1, 8);
    905    else
    906       return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eLoad);
    907 }
    908 
    909 Bool DRD_(bm_store_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    910 {
    911    return bm_aligned_store_has_conflict_with(bm, a1, 1);
    912 }
    913 
    914 Bool DRD_(bm_store_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    915 {
    916    if ((a1 & 1) == 0)
    917       return bm_aligned_store_has_conflict_with(bm, a1, 2);
    918    else
    919       return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eStore);
    920 }
    921 
    922 Bool DRD_(bm_store_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    923 {
    924    if ((a1 & 3) == 0)
    925       return bm_aligned_store_has_conflict_with(bm, a1, 4);
    926    else
    927       return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eStore);
    928 }
    929 
    930 Bool DRD_(bm_store_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
    931 {
    932    if ((a1 & 7) == 0)
    933       return bm_aligned_store_has_conflict_with(bm, a1, 8);
    934    else
    935       return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eStore);
    936 }
    937 
    938 Bool DRD_(bm_store_has_conflict_with)(struct bitmap* const bm,
    939                                       const Addr a1, const Addr a2)
    940 {
    941    return DRD_(bm_has_conflict_with)(bm, a1, a2, eStore);
    942 }
    943 
    944 /**
    945  * Return True if the two bitmaps *lhs and *rhs are identical, and false
    946  * if not.
    947  */
    948 Bool DRD_(bm_equal)(struct bitmap* const lhs, struct bitmap* const rhs)
    949 {
    950    struct bitmap2* bm2l;
    951    struct bitmap2* bm2r;
    952 
    953    /* It's not possible to have two independent iterators over the same OSet, */
    954    /* so complain if lhs == rhs.                                              */
    955    tl_assert(lhs != rhs);
    956 
    957    VG_(OSetGen_ResetIter)(lhs->oset);
    958    VG_(OSetGen_ResetIter)(rhs->oset);
    959 
    960    for ( ; (bm2l = VG_(OSetGen_Next)(lhs->oset)) != 0; )
    961    {
    962       while (bm2l
    963              && ! DRD_(bm_has_any_access)(lhs,
    964                                           make_address(bm2l->addr, 0),
    965                                           make_address(bm2l->addr + 1, 0)))
    966       {
    967          bm2l = VG_(OSetGen_Next)(lhs->oset);
    968       }
    969       if (bm2l == 0)
    970          break;
    971       tl_assert(bm2l);
    972 
    973       do
    974       {
    975          bm2r = VG_(OSetGen_Next)(rhs->oset);
    976          if (bm2r == 0)
    977             return False;
    978       }
    979       while (! DRD_(bm_has_any_access)(rhs,
    980                                        make_address(bm2r->addr, 0),
    981                                        make_address(bm2r->addr + 1, 0)));
    982 
    983       tl_assert(bm2r);
    984       tl_assert(DRD_(bm_has_any_access)(rhs,
    985                                         make_address(bm2r->addr, 0),
    986                                         make_address(bm2r->addr + 1, 0)));
    987 
    988       if (bm2l != bm2r
    989           && (bm2l->addr != bm2r->addr
    990               || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
    991       {
    992          return False;
    993       }
    994    }
    995 
    996    do
    997    {
    998       bm2r = VG_(OSetGen_Next)(rhs->oset);
    999    } while (bm2r && ! DRD_(bm_has_any_access)(rhs,
   1000                                               make_address(bm2r->addr, 0),
   1001                                               make_address(bm2r->addr + 1, 0)));
   1002    if (bm2r)
   1003    {
   1004       tl_assert(DRD_(bm_has_any_access)(rhs,
   1005                                         make_address(bm2r->addr, 0),
   1006                                         make_address(bm2r->addr + 1, 0)));
   1007       return False;
   1008    }
   1009    return True;
   1010 }
   1011 
   1012 void DRD_(bm_swap)(struct bitmap* const bm1, struct bitmap* const bm2)
   1013 {
   1014    OSet* const tmp = bm1->oset;
   1015    bm1->oset = bm2->oset;
   1016    bm2->oset = tmp;
   1017 }
   1018 
   1019 /** Merge bitmaps *lhs and *rhs into *lhs. */
   1020 void DRD_(bm_merge2)(struct bitmap* const lhs, struct bitmap* const rhs)
   1021 {
   1022    struct bitmap2* bm2l;
   1023    struct bitmap2* bm2r;
   1024 
   1025    /*
   1026     * It's not possible to have two independent iterators over the same OSet,
   1027     * so complain if lhs == rhs.
   1028     */
   1029    tl_assert(lhs != rhs);
   1030 
   1031    s_bitmap_merge_count++;
   1032 
   1033    VG_(OSetGen_ResetIter)(rhs->oset);
   1034 
   1035    for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
   1036    {
   1037       bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
   1038       if (bm2l)
   1039       {
   1040          tl_assert(bm2l != bm2r);
   1041          bm2_merge(bm2l, bm2r);
   1042       }
   1043       else
   1044       {
   1045          bm2_insert_copy(lhs, bm2r);
   1046       }
   1047    }
   1048 }
   1049 
   1050 /** Clear bitmap2::recalc. */
   1051 void DRD_(bm_unmark)(struct bitmap* bm)
   1052 {
   1053    struct bitmap2* bm2;
   1054 
   1055    for (VG_(OSetGen_ResetIter)(bm->oset);
   1056         (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
   1057         )
   1058    {
   1059       bm2->recalc = False;
   1060    }
   1061 }
   1062 
   1063 /**
   1064  * Report whether bitmap2::recalc has been set for the second level bitmap
   1065  * corresponding to address a.
   1066  */
   1067 Bool DRD_(bm_is_marked)(struct bitmap* bm, const Addr a)
   1068 {
   1069    const struct bitmap2* bm2;
   1070 
   1071    bm2 = bm2_lookup(bm, a);
   1072    return bm2 && bm2->recalc;
   1073 }
   1074 
   1075 /**
   1076  * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
   1077  * at least one access.
   1078  *
   1079  * @note Any new second-level bitmaps inserted in bml by this function are
   1080  *       uninitialized.
   1081  */
   1082 void DRD_(bm_mark)(struct bitmap* bml, struct bitmap* bmr)
   1083 {
   1084    struct bitmap2* bm2l;
   1085    struct bitmap2* bm2r;
   1086 
   1087    for (VG_(OSetGen_ResetIter)(bmr->oset);
   1088         (bm2r = VG_(OSetGen_Next)(bmr->oset)) != 0;
   1089         )
   1090    {
   1091       bm2l = bm2_lookup_or_insert(bml, bm2r->addr);
   1092       bm2l->recalc = True;
   1093    }
   1094 }
   1095 
   1096 /** Clear all second-level bitmaps for which bitmap2::recalc == True. */
   1097 void DRD_(bm_clear_marked)(struct bitmap* bm)
   1098 {
   1099    struct bitmap2* bm2;
   1100 
   1101    for (VG_(OSetGen_ResetIter)(bm->oset);
   1102         (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
   1103         )
   1104    {
   1105       if (bm2->recalc)
   1106          bm2_clear(bm2);
   1107    }
   1108 }
   1109 
   1110 /** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
   1111 void DRD_(bm_merge2_marked)(struct bitmap* const lhs, struct bitmap* const rhs)
   1112 {
   1113    struct bitmap2* bm2l;
   1114    struct bitmap2* bm2r;
   1115 
   1116    /*
   1117     * It's not possible to have two independent iterators over the same OSet,
   1118     * so complain if lhs == rhs.
   1119     */
   1120    tl_assert(lhs != rhs);
   1121 
   1122    s_bitmap_merge_count++;
   1123 
   1124    VG_(OSetGen_ResetIter)(rhs->oset);
   1125 
   1126    for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
   1127    {
   1128       bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
   1129       if (bm2l && bm2l->recalc)
   1130       {
   1131          tl_assert(bm2l != bm2r);
   1132          bm2_merge(bm2l, bm2r);
   1133       }
   1134    }
   1135 }
   1136 
   1137 /** Remove all marked second-level bitmaps that do not contain any access. */
   1138 void DRD_(bm_remove_cleared_marked)(struct bitmap* bm)
   1139 {
   1140    struct bitmap2* bm2;
   1141 
   1142    VG_(OSetGen_ResetIter)(bm->oset);
   1143    for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
   1144    {
   1145       const UWord a1 = bm2->addr;
   1146       if (bm2->recalc
   1147           && ! DRD_(bm_has_any_access(bm, make_address(a1, 0),
   1148                                       make_address(a1 + 1, 0))))
   1149       {
   1150          bm2_remove(bm, a1);
   1151          VG_(OSetGen_ResetIterAt)(bm->oset, &a1);
   1152       }
   1153    }
   1154 }
   1155 
   1156 /**
   1157  * Report whether there are any RW / WR / WW patterns in lhs and rhs.
   1158  * @param lhs First bitmap.
   1159  * @param rhs Bitmap to be compared with lhs.
   1160  * @return !=0 if there are data races, == 0 if there are none.
   1161  */
   1162 int DRD_(bm_has_races)(struct bitmap* const lhs, struct bitmap* const rhs)
   1163 {
   1164    VG_(OSetGen_ResetIter)(lhs->oset);
   1165    VG_(OSetGen_ResetIter)(rhs->oset);
   1166 
   1167    for (;;)
   1168    {
   1169       const struct bitmap2* bm2l;
   1170       const struct bitmap2* bm2r;
   1171       const struct bitmap1* bm1l;
   1172       const struct bitmap1* bm1r;
   1173       unsigned k;
   1174 
   1175       bm2l = VG_(OSetGen_Next)(lhs->oset);
   1176       bm2r = VG_(OSetGen_Next)(rhs->oset);
   1177       while (bm2l && bm2r && bm2l->addr != bm2r->addr)
   1178       {
   1179          if (bm2l->addr < bm2r->addr)
   1180             bm2l = VG_(OSetGen_Next)(lhs->oset);
   1181          else
   1182             bm2r = VG_(OSetGen_Next)(rhs->oset);
   1183       }
   1184       if (bm2l == 0 || bm2r == 0)
   1185          break;
   1186 
   1187       bm1l = &bm2l->bm1;
   1188       bm1r = &bm2r->bm1;
   1189 
   1190       for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
   1191       {
   1192          unsigned b;
   1193          for (b = 0; b < BITS_PER_UWORD; b++)
   1194          {
   1195             UWord const access_mask
   1196                = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
   1197                | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
   1198                | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
   1199                | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
   1200             Addr const a = make_address(bm2l->addr, k * BITS_PER_UWORD | b);
   1201             if (HAS_RACE(access_mask) && ! DRD_(is_suppressed)(a, a + 1))
   1202             {
   1203                return 1;
   1204             }
   1205          }
   1206       }
   1207    }
   1208    return 0;
   1209 }
   1210 
   1211 void DRD_(bm_print)(struct bitmap* const bm)
   1212 {
   1213    struct bitmap2* bm2;
   1214 
   1215    for (VG_(OSetGen_ResetIter)(bm->oset);
   1216         (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
   1217         )
   1218    {
   1219       bm2_print(bm2);
   1220    }
   1221 }
   1222 
   1223 static void bm2_print(const struct bitmap2* const bm2)
   1224 {
   1225    const struct bitmap1* bm1;
   1226    Addr a;
   1227 
   1228    tl_assert(bm2);
   1229 
   1230    bm1 = &bm2->bm1;
   1231    for (a = make_address(bm2->addr, 0);
   1232         a <= make_address(bm2->addr + 1, 0) - 1;
   1233         a++)
   1234    {
   1235       const Bool r = bm0_is_set(bm1->bm0_r, address_lsb(a)) != 0;
   1236       const Bool w = bm0_is_set(bm1->bm0_w, address_lsb(a)) != 0;
   1237       if (r || w)
   1238       {
   1239          VG_(printf)("0x%08lx %c %c\n",
   1240                      a,
   1241                      w ? 'W' : ' ',
   1242                      r ? 'R' : ' ');
   1243       }
   1244    }
   1245 }
   1246 
   1247 ULong DRD_(bm_get_bitmap_creation_count)(void)
   1248 {
   1249    return s_bitmap_creation_count;
   1250 }
   1251 
   1252 ULong DRD_(bm_get_bitmap2_creation_count)(void)
   1253 {
   1254    return s_bitmap2_creation_count;
   1255 }
   1256 
   1257 ULong DRD_(bm_get_bitmap2_merge_count)(void)
   1258 {
   1259    return s_bitmap2_merge_count;
   1260 }
   1261 
   1262 /** Compute *bm2l |= *bm2r. */
   1263 static
   1264 void bm2_merge(struct bitmap2* const bm2l, const struct bitmap2* const bm2r)
   1265 {
   1266    unsigned k;
   1267 
   1268    tl_assert(bm2l);
   1269    tl_assert(bm2r);
   1270    tl_assert(bm2l->addr == bm2r->addr);
   1271 
   1272    s_bitmap2_merge_count++;
   1273 
   1274    for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
   1275    {
   1276       bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
   1277    }
   1278    for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
   1279    {
   1280       bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
   1281    }
   1282 }
   1283