blob: 65477f122f4e1702fd4f12e5c33b1ba72f5d490a [file] [log] [blame]
bartbedfd232009-03-26 19:07:15 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
sewardjaf44c822007-11-25 14:01:38 +00002/*
bart86562bd2009-02-16 19:43:56 +00003 This file is part of drd, a thread error detector.
sewardjaf44c822007-11-25 14:01:38 +00004
bart86562bd2009-02-16 19:43:56 +00005 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
sewardjaf44c822007-11-25 14:01:38 +00006
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
bart39934d62009-02-15 16:18:03 +000026#include "drd_basics.h" /* DRD_() */
sewardjaf44c822007-11-25 14:01:38 +000027#include "drd_bitmap.h"
28#include "drd_error.h"
29#include "drd_suppression.h"
bart39934d62009-02-15 16:18:03 +000030#include "pub_drd_bitmap.h"
31#include "pub_tool_basics.h" /* Addr, SizeT */
32#include "pub_tool_debuginfo.h" /* VG_(get_objname)() */
33#include "pub_tool_libcassert.h" /* tl_assert() */
34#include "pub_tool_libcbase.h" /* VG_(memset) */
35#include "pub_tool_libcprint.h" /* VG_(printf) */
36#include "pub_tool_machine.h" /* VG_(get_IP)() */
37#include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
sewardjaf44c822007-11-25 14:01:38 +000038
39
bartf647d342008-03-24 19:12:12 +000040/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000041
42static void bm2_merge(struct bitmap2* const bm2l,
43 const struct bitmap2* const bm2r);
bart7b706b32009-05-10 06:55:39 +000044static void bm2_print(const struct bitmap2* const bm2);
sewardjaf44c822007-11-25 14:01:38 +000045
46
bart99edb292009-02-15 15:59:20 +000047/* Local variables. */
bartf647d342008-03-24 19:12:12 +000048
49static ULong s_bitmap_creation_count;
bart7b706b32009-05-10 06:55:39 +000050static ULong s_bitmap_merge_count;
51static ULong s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +000052
53
54/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000055
bart99edb292009-02-15 15:59:20 +000056struct bitmap* DRD_(bm_new)()
sewardjaf44c822007-11-25 14:01:38 +000057{
bartbedfd232009-03-26 19:07:15 +000058 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000059
bartbedfd232009-03-26 19:07:15 +000060 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
61 /* in drd_bitmap.h. */
62 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000063
bartbedfd232009-03-26 19:07:15 +000064 bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
bart8f822af2009-06-08 18:20:42 +000065 DRD_(bm_init)(bm);
sewardjaf44c822007-11-25 14:01:38 +000066
bartbedfd232009-03-26 19:07:15 +000067 s_bitmap_creation_count++;
sewardjaf44c822007-11-25 14:01:38 +000068
bartbedfd232009-03-26 19:07:15 +000069 return bm;
sewardjaf44c822007-11-25 14:01:38 +000070}
71
bart99edb292009-02-15 15:59:20 +000072void DRD_(bm_delete)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +000073{
bartbedfd232009-03-26 19:07:15 +000074 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000075
bart8f822af2009-06-08 18:20:42 +000076 DRD_(bm_cleanup)(bm);
bartbedfd232009-03-26 19:07:15 +000077 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +000078}
79
bart8f822af2009-06-08 18:20:42 +000080/** Initialize *bm. */
81void DRD_(bm_init)(struct bitmap* const bm)
82{
83 unsigned i;
84
85 tl_assert(bm);
86 /* Cache initialization. a1 is initialized with a value that never can
87 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
88 * bits of a1 are always zero for a valid cache entry.
89 */
90 for (i = 0; i < DRD_BITMAP_N_CACHE_ELEM; i++)
91 {
92 bm->cache[i].a1 = ~(UWord)1;
93 bm->cache[i].bm2 = 0;
94 }
95 bm->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), "drd.bitmap.bn.2",
96 VG_(free));
97}
98
99/** Free the memory allocated by DRD_(bm_init)(). */
100void DRD_(bm_cleanup)(struct bitmap* const bm)
101{
102 VG_(OSetGen_Destroy)(bm->oset);
103}
104
sewardjaf44c822007-11-25 14:01:38 +0000105/**
bart36556122008-03-13 19:24:30 +0000106 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000107 * bitmap bm.
bart7b706b32009-05-10 06:55:39 +0000108 *
109 * @note The current implementation of bm_access_range does not work for the
110 * highest addresses in the address range. At least on Linux this is
111 * not a problem since the upper part of the address space is reserved
112 * for the kernel.
sewardjaf44c822007-11-25 14:01:38 +0000113 */
bart99edb292009-02-15 15:59:20 +0000114void DRD_(bm_access_range)(struct bitmap* const bm,
115 const Addr a1, const Addr a2,
116 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000117{
barte6e86c52009-04-25 06:53:00 +0000118 tl_assert(access_type == eLoad || access_type == eStore);
119
120 if (access_type == eLoad)
121 return DRD_(bm_access_range_load)(bm, a1, a2);
122 else
123 return DRD_(bm_access_range_store)(bm, a1, a2);
124}
125
bart7b706b32009-05-10 06:55:39 +0000126void DRD_(bm_access_range_load)(struct bitmap* const bm, Addr a1, Addr a2)
barte6e86c52009-04-25 06:53:00 +0000127{
bartbedfd232009-03-26 19:07:15 +0000128 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000129
bartbedfd232009-03-26 19:07:15 +0000130 tl_assert(bm);
131 tl_assert(a1 < a2);
bart7b706b32009-05-10 06:55:39 +0000132 tl_assert(a2 < first_address_with_higher_msb(a2));
133 tl_assert(a1 == first_address_with_same_lsb(a1));
134 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000135
bartbedfd232009-03-26 19:07:15 +0000136 for (b = a1; b < a2; b = b_next)
137 {
138 Addr b_start;
139 Addr b_end;
140 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000141 UWord b0;
bart36556122008-03-13 19:24:30 +0000142
bart7b706b32009-05-10 06:55:39 +0000143 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000144 if (b_next > a2)
145 {
146 b_next = a2;
147 }
bart36556122008-03-13 19:24:30 +0000148
bart7b706b32009-05-10 06:55:39 +0000149 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
bartbedfd232009-03-26 19:07:15 +0000150 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000151
bart7b706b32009-05-10 06:55:39 +0000152 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000153 b_start = a1;
bart36556122008-03-13 19:24:30 +0000154 else
bart7b706b32009-05-10 06:55:39 +0000155 if (make_address(bm2->addr, 0) < a2)
156 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000157 else
158 break;
bart36556122008-03-13 19:24:30 +0000159
bart7b706b32009-05-10 06:55:39 +0000160 if (make_address(bm2->addr + 1, 0) < a2)
161 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000162 else
163 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000164
165 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000166 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
167 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000168
bart7b706b32009-05-10 06:55:39 +0000169 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
bart36556122008-03-13 19:24:30 +0000170 {
bartf43b1772009-04-25 08:08:33 +0000171 unsigned k;
172
173 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
174 {
175 bm2->bm1.bm0_r[k] = ~(UWord)0;
176 }
177 }
178 else
179 {
bart7b706b32009-05-10 06:55:39 +0000180 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000181 {
182 bm0_set(bm2->bm1.bm0_r, b0);
183 }
bart3772a982008-03-15 08:11:03 +0000184 }
bartbedfd232009-03-26 19:07:15 +0000185 }
sewardjaf44c822007-11-25 14:01:38 +0000186}
187
bart99edb292009-02-15 15:59:20 +0000188void DRD_(bm_access_load_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000189{
bartbedfd232009-03-26 19:07:15 +0000190 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000191}
192
bart99edb292009-02-15 15:59:20 +0000193void DRD_(bm_access_load_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000194{
bartbedfd232009-03-26 19:07:15 +0000195 if ((a1 & 1) == 0)
196 bm_access_aligned_load(bm, a1, 2);
197 else
198 DRD_(bm_access_range)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000199}
200
bart99edb292009-02-15 15:59:20 +0000201void DRD_(bm_access_load_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000202{
bartbedfd232009-03-26 19:07:15 +0000203 if ((a1 & 3) == 0)
204 bm_access_aligned_load(bm, a1, 4);
205 else
206 DRD_(bm_access_range)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000207}
208
bart99edb292009-02-15 15:59:20 +0000209void DRD_(bm_access_load_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000210{
bartbedfd232009-03-26 19:07:15 +0000211 if ((a1 & 7) == 0)
212 bm_access_aligned_load(bm, a1, 8);
213 else if ((a1 & 3) == 0)
214 {
215 bm_access_aligned_load(bm, a1 + 0, 4);
216 bm_access_aligned_load(bm, a1 + 4, 4);
217 }
218 else
219 DRD_(bm_access_range)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000220}
221
bart99edb292009-02-15 15:59:20 +0000222void DRD_(bm_access_range_store)(struct bitmap* const bm,
223 const Addr a1, const Addr a2)
bartf5acbbc2008-05-10 08:22:20 +0000224{
barte6e86c52009-04-25 06:53:00 +0000225 Addr b, b_next;
226
227 tl_assert(bm);
228 tl_assert(a1 < a2);
bart7b706b32009-05-10 06:55:39 +0000229 tl_assert(a2 < first_address_with_higher_msb(a2));
230 tl_assert(a1 == first_address_with_same_lsb(a1));
231 tl_assert(a2 == first_address_with_same_lsb(a2));
barte6e86c52009-04-25 06:53:00 +0000232
233 for (b = a1; b < a2; b = b_next)
234 {
235 Addr b_start;
236 Addr b_end;
237 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000238 UWord b0;
barte6e86c52009-04-25 06:53:00 +0000239
bart7b706b32009-05-10 06:55:39 +0000240 b_next = first_address_with_higher_msb(b);
barte6e86c52009-04-25 06:53:00 +0000241 if (b_next > a2)
242 {
243 b_next = a2;
244 }
245
bart7b706b32009-05-10 06:55:39 +0000246 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
barte6e86c52009-04-25 06:53:00 +0000247 tl_assert(bm2);
248
bart7b706b32009-05-10 06:55:39 +0000249 if (make_address(bm2->addr, 0) < a1)
barte6e86c52009-04-25 06:53:00 +0000250 b_start = a1;
251 else
bart7b706b32009-05-10 06:55:39 +0000252 if (make_address(bm2->addr, 0) < a2)
253 b_start = make_address(bm2->addr, 0);
barte6e86c52009-04-25 06:53:00 +0000254 else
255 break;
barte6e86c52009-04-25 06:53:00 +0000256
bart7b706b32009-05-10 06:55:39 +0000257 if (make_address(bm2->addr + 1, 0) < a2)
258 b_end = make_address(bm2->addr + 1, 0);
barte6e86c52009-04-25 06:53:00 +0000259 else
260 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000261
262 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000263 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
264 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000265
bart7b706b32009-05-10 06:55:39 +0000266 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
barte6e86c52009-04-25 06:53:00 +0000267 {
bartf43b1772009-04-25 08:08:33 +0000268 unsigned k;
269
270 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
271 {
272 bm2->bm1.bm0_w[k] = ~(UWord)0;
273 }
274 }
275 else
276 {
bart7b706b32009-05-10 06:55:39 +0000277 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000278 {
279 bm0_set(bm2->bm1.bm0_w, b0);
280 }
barte6e86c52009-04-25 06:53:00 +0000281 }
282 }
bartf5acbbc2008-05-10 08:22:20 +0000283}
284
bart99edb292009-02-15 15:59:20 +0000285void DRD_(bm_access_store_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000286{
bartbedfd232009-03-26 19:07:15 +0000287 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000288}
289
bart99edb292009-02-15 15:59:20 +0000290void DRD_(bm_access_store_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000291{
bartbedfd232009-03-26 19:07:15 +0000292 if ((a1 & 1) == 0)
293 bm_access_aligned_store(bm, a1, 2);
294 else
295 DRD_(bm_access_range)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000296}
297
bart99edb292009-02-15 15:59:20 +0000298void DRD_(bm_access_store_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000299{
bartbedfd232009-03-26 19:07:15 +0000300 if ((a1 & 3) == 0)
301 bm_access_aligned_store(bm, a1, 4);
302 else
303 DRD_(bm_access_range)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000304}
305
bart99edb292009-02-15 15:59:20 +0000306void DRD_(bm_access_store_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000307{
bartbedfd232009-03-26 19:07:15 +0000308 if ((a1 & 7) == 0)
309 bm_access_aligned_store(bm, a1, 8);
310 else if ((a1 & 3) == 0)
311 {
312 bm_access_aligned_store(bm, a1 + 0, 4);
313 bm_access_aligned_store(bm, a1 + 4, 4);
314 }
315 else
316 DRD_(bm_access_range)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000317}
318
bart99edb292009-02-15 15:59:20 +0000319Bool DRD_(bm_has)(struct bitmap* const bm, const Addr a1, const Addr a2,
320 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000321{
bartda3a77b2009-04-23 20:07:23 +0000322 tl_assert(access_type == eLoad || access_type == eStore);
bartda3a77b2009-04-23 20:07:23 +0000323
324 if (access_type == eLoad)
325 return DRD_(bm_has_any_load)(bm, a1, a2);
326 else
327 return DRD_(bm_has_any_store)(bm, a1, a2);
sewardjaf44c822007-11-25 14:01:38 +0000328}
329
bart99edb292009-02-15 15:59:20 +0000330Bool
331DRD_(bm_has_any_load)(struct bitmap* const bm, const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000332{
bartbedfd232009-03-26 19:07:15 +0000333 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000334
bartbedfd232009-03-26 19:07:15 +0000335 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000336
bartbedfd232009-03-26 19:07:15 +0000337 for (b = a1; b < a2; b = b_next)
338 {
bart7b706b32009-05-10 06:55:39 +0000339 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000340
bart7b706b32009-05-10 06:55:39 +0000341 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000342 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000343 {
bartbedfd232009-03-26 19:07:15 +0000344 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000345 }
bartbedfd232009-03-26 19:07:15 +0000346
347 if (bm2)
348 {
349 Addr b_start;
350 Addr b_end;
351 UWord b0;
352 const struct bitmap1* const p1 = &bm2->bm1;
353
bart7b706b32009-05-10 06:55:39 +0000354 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000355 b_start = a1;
356 else
bart7b706b32009-05-10 06:55:39 +0000357 if (make_address(bm2->addr, 0) < a2)
358 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000359 else
360 break;
361 tl_assert(a1 <= b_start && b_start <= a2);
362
bart7b706b32009-05-10 06:55:39 +0000363 if (make_address(bm2->addr + 1, 0) < a2)
364 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000365 else
366 b_end = a2;
367 tl_assert(a1 <= b_end && b_end <= a2);
368 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000369 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartbedfd232009-03-26 19:07:15 +0000370
bart7b706b32009-05-10 06:55:39 +0000371 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000372 {
373 if (bm0_is_set(p1->bm0_r, b0))
374 {
375 return True;
376 }
377 }
378 }
379 }
380 return 0;
bartd4907072008-03-30 18:41:07 +0000381}
382
bart99edb292009-02-15 15:59:20 +0000383Bool DRD_(bm_has_any_store)(struct bitmap* const bm,
384 const Addr a1, const Addr a2)
bartd4907072008-03-30 18:41:07 +0000385{
bartbedfd232009-03-26 19:07:15 +0000386 Addr b, b_next;
bartd4907072008-03-30 18:41:07 +0000387
bartbedfd232009-03-26 19:07:15 +0000388 tl_assert(bm);
bartd4907072008-03-30 18:41:07 +0000389
bartbedfd232009-03-26 19:07:15 +0000390 for (b = a1; b < a2; b = b_next)
391 {
bart7b706b32009-05-10 06:55:39 +0000392 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000393
bart7b706b32009-05-10 06:55:39 +0000394 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000395 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000396 {
bartbedfd232009-03-26 19:07:15 +0000397 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000398 }
bartbedfd232009-03-26 19:07:15 +0000399
400 if (bm2)
401 {
402 Addr b_start;
403 Addr b_end;
404 UWord b0;
405 const struct bitmap1* const p1 = &bm2->bm1;
406
bart7b706b32009-05-10 06:55:39 +0000407 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000408 b_start = a1;
409 else
bart7b706b32009-05-10 06:55:39 +0000410 if (make_address(bm2->addr, 0) < a2)
411 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000412 else
413 break;
414 tl_assert(a1 <= b_start && b_start <= a2);
415
bart7b706b32009-05-10 06:55:39 +0000416 if (make_address(bm2->addr + 1, 0) < a2)
417 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000418 else
419 b_end = a2;
420 tl_assert(a1 <= b_end && b_end <= a2);
421 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000422 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartbedfd232009-03-26 19:07:15 +0000423
bart7b706b32009-05-10 06:55:39 +0000424 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000425 {
426 if (bm0_is_set(p1->bm0_w, b0))
427 {
428 return True;
429 }
430 }
431 }
432 }
433 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000434}
435
bartc2c81db2008-05-10 11:19:10 +0000436/* Return True if there is a read access, write access or both */
437/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
bart99edb292009-02-15 15:59:20 +0000438Bool DRD_(bm_has_any_access)(struct bitmap* const bm,
439 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000440{
bartbedfd232009-03-26 19:07:15 +0000441 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000442
bartbedfd232009-03-26 19:07:15 +0000443 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000444
bartbedfd232009-03-26 19:07:15 +0000445 for (b = a1; b < a2; b = b_next)
446 {
bart7b706b32009-05-10 06:55:39 +0000447 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000448
bart7b706b32009-05-10 06:55:39 +0000449 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000450 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000451 {
bartbedfd232009-03-26 19:07:15 +0000452 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000453 }
bartbedfd232009-03-26 19:07:15 +0000454
455 if (bm2)
456 {
457 Addr b_start;
458 Addr b_end;
459 UWord b0;
460 const struct bitmap1* const p1 = &bm2->bm1;
461
bart7b706b32009-05-10 06:55:39 +0000462 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000463 b_start = a1;
464 else
bart7b706b32009-05-10 06:55:39 +0000465 if (make_address(bm2->addr, 0) < a2)
466 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000467 else
468 break;
469 tl_assert(a1 <= b_start && b_start <= a2);
470
bart7b706b32009-05-10 06:55:39 +0000471 if (make_address(bm2->addr + 1, 0) < a2)
472 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000473 else
474 b_end = a2;
475 tl_assert(a1 <= b_end && b_end <= a2);
476 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000477 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartbedfd232009-03-26 19:07:15 +0000478
bart7b706b32009-05-10 06:55:39 +0000479 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000480 {
bart8f822af2009-06-08 18:20:42 +0000481 /*
482 * Note: the statement below uses a binary or instead of a logical
483 * or on purpose.
484 */
bartbedfd232009-03-26 19:07:15 +0000485 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
486 {
487 return True;
488 }
489 }
490 }
491 }
492 return False;
sewardjaf44c822007-11-25 14:01:38 +0000493}
494
bart99edb292009-02-15 15:59:20 +0000495/**
496 * Report whether an access of type access_type at address a is recorded in
497 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000498 */
bart99edb292009-02-15 15:59:20 +0000499Bool DRD_(bm_has_1)(struct bitmap* const bm,
500 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000501{
bartbedfd232009-03-26 19:07:15 +0000502 const struct bitmap2* p2;
503 const struct bitmap1* p1;
504 const UWord* p0;
bart7b706b32009-05-10 06:55:39 +0000505 const UWord a0 = address_lsb(a);
sewardjaf44c822007-11-25 14:01:38 +0000506
bartbedfd232009-03-26 19:07:15 +0000507 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000508
bart7b706b32009-05-10 06:55:39 +0000509 p2 = bm2_lookup(bm, address_msb(a));
bartbedfd232009-03-26 19:07:15 +0000510 if (p2)
511 {
512 p1 = &p2->bm1;
513 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
514 return bm0_is_set(p0, a0) ? True : False;
515 }
516 return False;
sewardjaf44c822007-11-25 14:01:38 +0000517}
518
bart7b706b32009-05-10 06:55:39 +0000519void DRD_(bm_clear)(struct bitmap* const bm, Addr a1, Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000520{
bartbedfd232009-03-26 19:07:15 +0000521 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000522
bartbedfd232009-03-26 19:07:15 +0000523 tl_assert(bm);
524 tl_assert(a1);
525 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000526 tl_assert(a1 == first_address_with_same_lsb(a1));
527 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000528
bartbedfd232009-03-26 19:07:15 +0000529 for (b = a1; b < a2; b = b_next)
530 {
bart578eeb42009-04-23 15:42:27 +0000531 struct bitmap2* p2;
532 Addr c;
533
534#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
535 tl_assert(a1 <= b && b < a2);
536#endif
537
bart7b706b32009-05-10 06:55:39 +0000538 p2 = bm2_lookup_exclusive(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000539
bart7b706b32009-05-10 06:55:39 +0000540 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000541 if (b_next > a2)
sewardjaf44c822007-11-25 14:01:38 +0000542 {
bartbedfd232009-03-26 19:07:15 +0000543 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000544 }
bartbedfd232009-03-26 19:07:15 +0000545
barte2c7e672009-04-23 19:23:09 +0000546 if (p2 == 0)
547 continue;
548
bart578eeb42009-04-23 15:42:27 +0000549 c = b;
550 /* If the first address in the bitmap that must be cleared does not */
551 /* start on an UWord boundary, start clearing the first addresses. */
bart7b706b32009-05-10 06:55:39 +0000552 if (uword_lsb(address_lsb(c)))
sewardjaf44c822007-11-25 14:01:38 +0000553 {
bart7b706b32009-05-10 06:55:39 +0000554 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000555 if (c_next > b_next)
556 c_next = b_next;
557#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
558 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
559 && b_next <= a2);
560#endif
bart7b706b32009-05-10 06:55:39 +0000561 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
562 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000563 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000564 }
565 /* If some UWords have to be cleared entirely, do this now. */
bart7b706b32009-05-10 06:55:39 +0000566 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000567 {
bart7b706b32009-05-10 06:55:39 +0000568 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000569#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000570 tl_assert(uword_lsb(address_lsb(c)) == 0);
571 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000572 tl_assert(c_next <= b_next);
bart578eeb42009-04-23 15:42:27 +0000573#endif
bart25a439a2009-04-24 14:49:50 +0000574 if (c_next > c)
575 {
bart7b706b32009-05-10 06:55:39 +0000576 UWord idx = uword_msb(address_lsb(c));
577 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
578 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000579 c = c_next;
580 }
bart578eeb42009-04-23 15:42:27 +0000581 }
582 /* If the last address in the bitmap that must be cleared does not */
583 /* fall on an UWord boundary, clear the last addresses. */
bart25a439a2009-04-24 14:49:50 +0000584#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
585 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
586#endif
bart7b706b32009-05-10 06:55:39 +0000587 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
588 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000589 }
sewardjaf44c822007-11-25 14:01:38 +0000590}
sewardjaf44c822007-11-25 14:01:38 +0000591
bart99edb292009-02-15 15:59:20 +0000592/**
593 * Clear all references to loads in bitmap bm starting at address a1 and
594 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000595 */
bart7b706b32009-05-10 06:55:39 +0000596void DRD_(bm_clear_load)(struct bitmap* const bm, Addr a1, Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000597{
bart578eeb42009-04-23 15:42:27 +0000598 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000599
bart578eeb42009-04-23 15:42:27 +0000600 tl_assert(bm);
601 tl_assert(a1);
602 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000603 tl_assert(a1 == first_address_with_same_lsb(a1));
604 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000605
606 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000607 {
bart578eeb42009-04-23 15:42:27 +0000608 struct bitmap2* p2;
609 Addr c;
610
611#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
612 tl_assert(a1 <= b && b < a2);
613#endif
614
bart7b706b32009-05-10 06:55:39 +0000615 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000616
bart7b706b32009-05-10 06:55:39 +0000617 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000618 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000619 {
bart578eeb42009-04-23 15:42:27 +0000620 b_next = a2;
621 }
622
barte2c7e672009-04-23 19:23:09 +0000623 if (p2 == 0)
624 continue;
625
bart578eeb42009-04-23 15:42:27 +0000626 c = b;
627 /* If the first address in the bitmap that must be cleared does not */
628 /* start on an UWord boundary, start clearing the first addresses. */
629#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
630 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
631#endif
bart7b706b32009-05-10 06:55:39 +0000632 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000633 {
bart7b706b32009-05-10 06:55:39 +0000634 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000635 if (c_next > b_next)
636 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000637#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart25a439a2009-04-24 14:49:50 +0000638 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
639 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000640#endif
bart7b706b32009-05-10 06:55:39 +0000641 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000642 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000643 }
644 /* If some UWords have to be cleared entirely, do this now. */
645#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
646 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
647#endif
bart7b706b32009-05-10 06:55:39 +0000648 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000649 {
bart7b706b32009-05-10 06:55:39 +0000650 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000651#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000652 tl_assert(uword_lsb(address_lsb(c)) == 0);
653 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000654 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
655 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000656#endif
bart25a439a2009-04-24 14:49:50 +0000657 if (c_next > c)
658 {
bart7b706b32009-05-10 06:55:39 +0000659 UWord idx = uword_msb(address_lsb(c));
660 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000661 c = c_next;
662 }
bart578eeb42009-04-23 15:42:27 +0000663 }
664 /* If the last address in the bitmap that must be cleared does not */
665 /* fall on an UWord boundary, clear the last addresses. */
666#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
667 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
668#endif
bart7b706b32009-05-10 06:55:39 +0000669 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000670 }
bart9c4224c2008-03-29 14:40:08 +0000671}
672
bart99edb292009-02-15 15:59:20 +0000673/**
674 * Clear all references to stores in bitmap bm starting at address a1 and
675 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000676 */
bart99edb292009-02-15 15:59:20 +0000677void DRD_(bm_clear_store)(struct bitmap* const bm,
678 const Addr a1, const Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000679{
bart578eeb42009-04-23 15:42:27 +0000680 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000681
bart578eeb42009-04-23 15:42:27 +0000682 tl_assert(bm);
683 tl_assert(a1);
684 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000685 tl_assert(a1 == first_address_with_same_lsb(a1));
686 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000687
688 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000689 {
bart578eeb42009-04-23 15:42:27 +0000690 struct bitmap2* p2;
691 Addr c;
692
693#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
694 tl_assert(a1 <= b && b < a2);
695#endif
696
bart7b706b32009-05-10 06:55:39 +0000697 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000698
bart7b706b32009-05-10 06:55:39 +0000699 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000700 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000701 {
barte6e86c52009-04-25 06:53:00 +0000702 b_next = a2;
bart578eeb42009-04-23 15:42:27 +0000703 }
704
barte2c7e672009-04-23 19:23:09 +0000705 if (p2 == 0)
706 continue;
707
bart578eeb42009-04-23 15:42:27 +0000708 c = b;
709 /* If the first address in the bitmap that must be cleared does not */
710 /* start on an UWord boundary, start clearing the first addresses. */
711#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
712 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
713#endif
bart7b706b32009-05-10 06:55:39 +0000714 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000715 {
bart7b706b32009-05-10 06:55:39 +0000716 Addr c_next = first_address_with_higher_uword_msb(c);
barte6e86c52009-04-25 06:53:00 +0000717 if (c_next > b_next)
718 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000719#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
barte6e86c52009-04-25 06:53:00 +0000720 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
721 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000722#endif
bart7b706b32009-05-10 06:55:39 +0000723 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
barte6e86c52009-04-25 06:53:00 +0000724 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000725 }
726 /* If some UWords have to be cleared entirely, do this now. */
727#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
728 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
729#endif
bart7b706b32009-05-10 06:55:39 +0000730 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000731 {
bart7b706b32009-05-10 06:55:39 +0000732 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000733#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000734 tl_assert(uword_lsb(address_lsb(c)) == 0);
735 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
barte6e86c52009-04-25 06:53:00 +0000736 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
737 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000738#endif
barte6e86c52009-04-25 06:53:00 +0000739 if (c_next > c)
740 {
bart7b706b32009-05-10 06:55:39 +0000741 UWord idx = uword_msb(address_lsb(c));
742 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
barte6e86c52009-04-25 06:53:00 +0000743 c = c_next;
744 }
bart578eeb42009-04-23 15:42:27 +0000745 }
746 /* If the last address in the bitmap that must be cleared does not */
747 /* fall on an UWord boundary, clear the last addresses. */
748#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
749 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
750#endif
bart7b706b32009-05-10 06:55:39 +0000751 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000752 }
bart9c4224c2008-03-29 14:40:08 +0000753}
754
bart99edb292009-02-15 15:59:20 +0000755/**
756 * Clear bitmap bm starting at address a1 and up to but not including address
757 * a2. Return True if and only if any of the addresses was set before
758 * clearing.
bart8bf2f8b2008-03-30 17:56:43 +0000759 */
bart99edb292009-02-15 15:59:20 +0000760Bool DRD_(bm_test_and_clear)(struct bitmap* const bm,
761 const Addr a1, const Addr a2)
bart8bf2f8b2008-03-30 17:56:43 +0000762{
bartbedfd232009-03-26 19:07:15 +0000763 Bool result;
bart8bf2f8b2008-03-30 17:56:43 +0000764
bartbedfd232009-03-26 19:07:15 +0000765 result = DRD_(bm_has_any_access)(bm, a1, a2) != 0;
766 DRD_(bm_clear)(bm, a1, a2);
767 return result;
bart8bf2f8b2008-03-30 17:56:43 +0000768}
769
bart99edb292009-02-15 15:59:20 +0000770Bool DRD_(bm_has_conflict_with)(struct bitmap* const bm,
771 const Addr a1, const Addr a2,
772 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000773{
bartbedfd232009-03-26 19:07:15 +0000774 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000775
bartbedfd232009-03-26 19:07:15 +0000776 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000777
bartbedfd232009-03-26 19:07:15 +0000778 for (b = a1; b < a2; b = b_next)
779 {
bart7b706b32009-05-10 06:55:39 +0000780 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bart36556122008-03-13 19:24:30 +0000781
bart7b706b32009-05-10 06:55:39 +0000782 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000783 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000784 {
bartbedfd232009-03-26 19:07:15 +0000785 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000786 }
bartbedfd232009-03-26 19:07:15 +0000787
788 if (bm2)
789 {
790 Addr b_start;
791 Addr b_end;
792 UWord b0;
793 const struct bitmap1* const p1 = &bm2->bm1;
794
bart7b706b32009-05-10 06:55:39 +0000795 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000796 b_start = a1;
797 else
bart7b706b32009-05-10 06:55:39 +0000798 if (make_address(bm2->addr, 0) < a2)
799 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000800 else
801 break;
802 tl_assert(a1 <= b_start && b_start <= a2);
803
bart7b706b32009-05-10 06:55:39 +0000804 if (make_address(bm2->addr + 1, 0) < a2)
805 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000806 else
807 b_end = a2;
808 tl_assert(a1 <= b_end && b_end <= a2);
809 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000810 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartbedfd232009-03-26 19:07:15 +0000811
bart7b706b32009-05-10 06:55:39 +0000812 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000813 {
814 if (access_type == eLoad)
815 {
816 if (bm0_is_set(p1->bm0_w, b0))
817 {
818 return True;
819 }
820 }
821 else
822 {
823 tl_assert(access_type == eStore);
824 if (bm0_is_set(p1->bm0_r, b0)
825 | bm0_is_set(p1->bm0_w, b0))
826 {
827 return True;
828 }
829 }
830 }
831 }
832 }
833 return False;
sewardjaf44c822007-11-25 14:01:38 +0000834}
835
bart99edb292009-02-15 15:59:20 +0000836Bool DRD_(bm_load_has_conflict_with)(struct bitmap* const bm,
837 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000838{
bartbedfd232009-03-26 19:07:15 +0000839 return DRD_(bm_has_conflict_with)(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000840}
841
bart99edb292009-02-15 15:59:20 +0000842Bool DRD_(bm_load_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000843{
bartbedfd232009-03-26 19:07:15 +0000844 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000845}
846
bart99edb292009-02-15 15:59:20 +0000847Bool DRD_(bm_load_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000848{
bartbedfd232009-03-26 19:07:15 +0000849 if ((a1 & 1) == 0)
850 return bm_aligned_load_has_conflict_with(bm, a1, 2);
851 else
852 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000853}
854
bart99edb292009-02-15 15:59:20 +0000855Bool DRD_(bm_load_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000856{
bartbedfd232009-03-26 19:07:15 +0000857 if ((a1 & 3) == 0)
858 return bm_aligned_load_has_conflict_with(bm, a1, 4);
859 else
860 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000861}
862
bart99edb292009-02-15 15:59:20 +0000863Bool DRD_(bm_load_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000864{
bartbedfd232009-03-26 19:07:15 +0000865 if ((a1 & 7) == 0)
866 return bm_aligned_load_has_conflict_with(bm, a1, 8);
867 else
868 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000869}
870
bart99edb292009-02-15 15:59:20 +0000871Bool DRD_(bm_store_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000872{
bartbedfd232009-03-26 19:07:15 +0000873 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000874}
875
bart99edb292009-02-15 15:59:20 +0000876Bool DRD_(bm_store_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000877{
bartbedfd232009-03-26 19:07:15 +0000878 if ((a1 & 1) == 0)
879 return bm_aligned_store_has_conflict_with(bm, a1, 2);
880 else
881 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000882}
883
bart99edb292009-02-15 15:59:20 +0000884Bool DRD_(bm_store_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000885{
bartbedfd232009-03-26 19:07:15 +0000886 if ((a1 & 3) == 0)
887 return bm_aligned_store_has_conflict_with(bm, a1, 4);
888 else
889 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000890}
891
bart99edb292009-02-15 15:59:20 +0000892Bool DRD_(bm_store_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000893{
bartbedfd232009-03-26 19:07:15 +0000894 if ((a1 & 7) == 0)
895 return bm_aligned_store_has_conflict_with(bm, a1, 8);
896 else
897 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000898}
899
bart99edb292009-02-15 15:59:20 +0000900Bool DRD_(bm_store_has_conflict_with)(struct bitmap* const bm,
901 const Addr a1, const Addr a2)
bart36556122008-03-13 19:24:30 +0000902{
bartbedfd232009-03-26 19:07:15 +0000903 return DRD_(bm_has_conflict_with)(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000904}
905
bart99edb292009-02-15 15:59:20 +0000906/**
907 * Return True if the two bitmaps *lhs and *rhs are identical, and false
908 * if not.
bart7cd7d7f2008-04-14 16:10:01 +0000909 */
bart99edb292009-02-15 15:59:20 +0000910Bool DRD_(bm_equal)(struct bitmap* const lhs, struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000911{
bartbedfd232009-03-26 19:07:15 +0000912 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +0000913 struct bitmap2* bm2r;
bart7cd7d7f2008-04-14 16:10:01 +0000914
bartbedfd232009-03-26 19:07:15 +0000915 /* It's not possible to have two independent iterators over the same OSet, */
916 /* so complain if lhs == rhs. */
917 tl_assert(lhs != rhs);
barta3f61092008-05-04 07:46:20 +0000918
bartbedfd232009-03-26 19:07:15 +0000919 VG_(OSetGen_ResetIter)(lhs->oset);
920 VG_(OSetGen_ResetIter)(rhs->oset);
bart7cd7d7f2008-04-14 16:10:01 +0000921
bart7b706b32009-05-10 06:55:39 +0000922 for ( ; (bm2l = VG_(OSetGen_Next)(lhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +0000923 {
bart7b706b32009-05-10 06:55:39 +0000924 while (bm2l
bartbedfd232009-03-26 19:07:15 +0000925 && ! DRD_(bm_has_any_access)(lhs,
bart7b706b32009-05-10 06:55:39 +0000926 make_address(bm2l->addr, 0),
927 make_address(bm2l->addr + 1, 0)))
bartbedfd232009-03-26 19:07:15 +0000928 {
bart7b706b32009-05-10 06:55:39 +0000929 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +0000930 }
bart7b706b32009-05-10 06:55:39 +0000931 if (bm2l == 0)
bartbedfd232009-03-26 19:07:15 +0000932 break;
933 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000934
bartb634b5d2009-04-26 14:42:33 +0000935 do
bartbedfd232009-03-26 19:07:15 +0000936 {
bart7b706b32009-05-10 06:55:39 +0000937 bm2r = VG_(OSetGen_Next)(rhs->oset);
938 if (bm2r == 0)
bartb634b5d2009-04-26 14:42:33 +0000939 return False;
bartbedfd232009-03-26 19:07:15 +0000940 }
bartb634b5d2009-04-26 14:42:33 +0000941 while (! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000942 make_address(bm2r->addr, 0),
943 make_address(bm2r->addr + 1, 0)));
bartb634b5d2009-04-26 14:42:33 +0000944
bartbedfd232009-03-26 19:07:15 +0000945 tl_assert(bm2r);
946 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000947 make_address(bm2r->addr, 0),
948 make_address(bm2r->addr + 1, 0)));
barta3f61092008-05-04 07:46:20 +0000949
bartbedfd232009-03-26 19:07:15 +0000950 if (bm2l != bm2r
951 && (bm2l->addr != bm2r->addr
952 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
953 {
bartbedfd232009-03-26 19:07:15 +0000954 return False;
955 }
956 }
bartb634b5d2009-04-26 14:42:33 +0000957
958 do
959 {
960 bm2r = VG_(OSetGen_Next)(rhs->oset);
961 } while (bm2r && ! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000962 make_address(bm2r->addr, 0),
963 make_address(bm2r->addr + 1, 0)));
bartbedfd232009-03-26 19:07:15 +0000964 if (bm2r)
965 {
966 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000967 make_address(bm2r->addr, 0),
968 make_address(bm2r->addr + 1, 0)));
bart7cd7d7f2008-04-14 16:10:01 +0000969 return False;
bartbedfd232009-03-26 19:07:15 +0000970 }
971 return True;
bart7cd7d7f2008-04-14 16:10:01 +0000972}
973
bart99edb292009-02-15 15:59:20 +0000974void DRD_(bm_swap)(struct bitmap* const bm1, struct bitmap* const bm2)
sewardjaf44c822007-11-25 14:01:38 +0000975{
bartbedfd232009-03-26 19:07:15 +0000976 OSet* const tmp = bm1->oset;
977 bm1->oset = bm2->oset;
978 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000979}
980
bartf647d342008-03-24 19:12:12 +0000981/** Merge bitmaps *lhs and *rhs into *lhs. */
bart8f822af2009-06-08 18:20:42 +0000982void DRD_(bm_merge2)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +0000983{
bartbedfd232009-03-26 19:07:15 +0000984 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +0000985 struct bitmap2* bm2r;
bart7b706b32009-05-10 06:55:39 +0000986
bart8f822af2009-06-08 18:20:42 +0000987 /*
988 * It's not possible to have two independent iterators over the same OSet,
989 * so complain if lhs == rhs.
990 */
bart7b706b32009-05-10 06:55:39 +0000991 tl_assert(lhs != rhs);
992
993 s_bitmap_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +0000994
bartbedfd232009-03-26 19:07:15 +0000995 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000996
bart7b706b32009-05-10 06:55:39 +0000997 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +0000998 {
bart7b706b32009-05-10 06:55:39 +0000999 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1000 if (bm2l)
bartf647d342008-03-24 19:12:12 +00001001 {
bart7b706b32009-05-10 06:55:39 +00001002 tl_assert(bm2l != bm2r);
1003 bm2_merge(bm2l, bm2r);
bartf647d342008-03-24 19:12:12 +00001004 }
bartbedfd232009-03-26 19:07:15 +00001005 else
1006 {
bart7b706b32009-05-10 06:55:39 +00001007 bm2_insert_copy(lhs, bm2r);
bartbedfd232009-03-26 19:07:15 +00001008 }
1009 }
sewardjaf44c822007-11-25 14:01:38 +00001010}
1011
bart8f822af2009-06-08 18:20:42 +00001012/** Clear bitmap2::recalc. */
1013void DRD_(bm_unmark)(struct bitmap* bm)
1014{
1015 struct bitmap2* bm2;
1016
1017 for (VG_(OSetGen_ResetIter)(bm->oset);
1018 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1019 )
1020 {
1021 bm2->recalc = False;
1022 }
1023}
1024
1025/**
1026 * Report whether bitmap2::recalc has been set for the second level bitmap
1027 * corresponding to address a.
1028 */
1029Bool DRD_(bm_is_marked)(struct bitmap* bm, const Addr a)
1030{
1031 const struct bitmap2* bm2;
1032
1033 bm2 = bm2_lookup(bm, a);
1034 return bm2 && bm2->recalc;
1035}
1036
1037/**
1038 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1039 * at least one access.
1040 *
1041 * @note Any new second-level bitmaps inserted in bml by this function are
1042 * uninitialized.
1043 */
1044void DRD_(bm_mark)(struct bitmap* bml, struct bitmap* bmr)
1045{
1046 struct bitmap2* bm2l;
1047 struct bitmap2* bm2r;
1048
1049 for (VG_(OSetGen_ResetIter)(bmr->oset);
1050 (bm2r = VG_(OSetGen_Next)(bmr->oset)) != 0;
1051 )
1052 {
1053 /*if (DRD_(bm_has_any_access(bmr, make_address(bm2r->addr, 0),
1054 make_address(bm2r->addr + 1, 0))))*/
1055 {
1056 bm2l = bm2_lookup_or_insert(bml, bm2r->addr);
1057 bm2l->recalc = True;
1058 }
1059 }
1060}
1061
1062/** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1063void DRD_(bm_clear_marked)(struct bitmap* bm)
1064{
1065 struct bitmap2* bm2;
1066
1067 for (VG_(OSetGen_ResetIter)(bm->oset);
1068 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1069 )
1070 {
1071 if (bm2->recalc)
1072 bm2_clear(bm2);
1073 }
1074}
1075
1076/** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1077void DRD_(bm_merge2_marked)(struct bitmap* const lhs, struct bitmap* const rhs)
1078{
1079 struct bitmap2* bm2l;
1080 struct bitmap2* bm2r;
1081
1082 tl_assert(lhs != rhs);
1083
1084 /*
1085 * It's not possible to have two independent iterators over the same OSet,
1086 * so complain if lhs == rhs.
1087 */
1088 tl_assert(lhs != rhs);
1089
1090 s_bitmap_merge_count++;
1091
1092 VG_(OSetGen_ResetIter)(rhs->oset);
1093
1094 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
1095 {
1096 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1097 if (bm2l && bm2l->recalc)
1098 {
1099 tl_assert(bm2l != bm2r);
1100 bm2_merge(bm2l, bm2r);
1101 }
1102 }
1103}
1104
1105/** Remove all marked second-level bitmaps that do not contain any access. */
1106void DRD_(bm_remove_cleared_marked)(struct bitmap* bm)
1107{
1108 struct bitmap2* bm2;
1109
1110 VG_(OSetGen_ResetIter)(bm->oset);
1111 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
1112 {
1113 const UWord a1 = bm2->addr;
1114 if (bm2->recalc
1115 && ! DRD_(bm_has_any_access(bm, make_address(a1, 0),
1116 make_address(a1 + 1, 0))))
1117 {
1118 bm2_remove(bm, a1);
1119 VG_(OSetGen_ResetIterAt)(bm->oset, &a1);
1120 }
1121 }
1122}
1123
sewardjaf44c822007-11-25 14:01:38 +00001124/**
1125 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1126 * @param lhs First bitmap.
1127 * @param rhs Bitmap to be compared with lhs.
1128 * @return !=0 if there are data races, == 0 if there are none.
1129 */
bart99edb292009-02-15 15:59:20 +00001130int DRD_(bm_has_races)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +00001131{
bartbedfd232009-03-26 19:07:15 +00001132 VG_(OSetGen_ResetIter)(lhs->oset);
1133 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001134
bartbedfd232009-03-26 19:07:15 +00001135 for (;;)
1136 {
bartbedfd232009-03-26 19:07:15 +00001137 const struct bitmap2* bm2l;
1138 const struct bitmap2* bm2r;
1139 const struct bitmap1* bm1l;
1140 const struct bitmap1* bm1r;
1141 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001142
bart7b706b32009-05-10 06:55:39 +00001143 bm2l = VG_(OSetGen_Next)(lhs->oset);
1144 bm2r = VG_(OSetGen_Next)(rhs->oset);
bartbedfd232009-03-26 19:07:15 +00001145 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
sewardjaf44c822007-11-25 14:01:38 +00001146 {
bartbedfd232009-03-26 19:07:15 +00001147 if (bm2l->addr < bm2r->addr)
bart7b706b32009-05-10 06:55:39 +00001148 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +00001149 else
bart7b706b32009-05-10 06:55:39 +00001150 bm2r = VG_(OSetGen_Next)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001151 }
bartbedfd232009-03-26 19:07:15 +00001152 if (bm2l == 0 || bm2r == 0)
1153 break;
1154
1155 bm1l = &bm2l->bm1;
1156 bm1r = &bm2r->bm1;
1157
1158 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1159 {
1160 unsigned b;
1161 for (b = 0; b < BITS_PER_UWORD; b++)
1162 {
1163 UWord const access_mask
1164 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
1165 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
1166 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
1167 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
bart7b706b32009-05-10 06:55:39 +00001168 Addr const a = make_address(bm2l->addr, k * BITS_PER_UWORD | b);
bartbedfd232009-03-26 19:07:15 +00001169 if (HAS_RACE(access_mask) && ! DRD_(is_suppressed)(a, a + 1))
1170 {
1171 return 1;
1172 }
1173 }
1174 }
1175 }
1176 return 0;
sewardjaf44c822007-11-25 14:01:38 +00001177}
1178
bart99edb292009-02-15 15:59:20 +00001179void DRD_(bm_print)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +00001180{
bartbedfd232009-03-26 19:07:15 +00001181 struct bitmap2* bm2;
sewardjaf44c822007-11-25 14:01:38 +00001182
bart7b706b32009-05-10 06:55:39 +00001183 for (VG_(OSetGen_ResetIter)(bm->oset);
1184 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1185 )
bartbedfd232009-03-26 19:07:15 +00001186 {
bart7b706b32009-05-10 06:55:39 +00001187 bm2_print(bm2);
1188 }
1189}
bartf647d342008-03-24 19:12:12 +00001190
bart7b706b32009-05-10 06:55:39 +00001191static void bm2_print(const struct bitmap2* const bm2)
1192{
1193 const struct bitmap1* bm1;
1194 Addr a;
1195
1196 tl_assert(bm2);
1197
1198 bm1 = &bm2->bm1;
1199 for (a = make_address(bm2->addr, 0);
1200 a <= make_address(bm2->addr + 1, 0) - 1;
1201 a++)
1202 {
1203 const Bool r = bm0_is_set(bm1->bm0_r, address_lsb(a)) != 0;
1204 const Bool w = bm0_is_set(bm1->bm0_w, address_lsb(a)) != 0;
1205 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +00001206 {
bart7b706b32009-05-10 06:55:39 +00001207 VG_(printf)("0x%08lx %c %c\n",
1208 a,
1209 w ? 'W' : ' ',
1210 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +00001211 }
bartbedfd232009-03-26 19:07:15 +00001212 }
sewardjaf44c822007-11-25 14:01:38 +00001213}
1214
bart99edb292009-02-15 15:59:20 +00001215ULong DRD_(bm_get_bitmap_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001216{
bartbedfd232009-03-26 19:07:15 +00001217 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001218}
1219
bart99edb292009-02-15 15:59:20 +00001220ULong DRD_(bm_get_bitmap2_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001221{
bartbedfd232009-03-26 19:07:15 +00001222 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001223}
1224
bart7b706b32009-05-10 06:55:39 +00001225ULong DRD_(bm_get_bitmap2_merge_count)(void)
bartf647d342008-03-24 19:12:12 +00001226{
bart7b706b32009-05-10 06:55:39 +00001227 return s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +00001228}
1229
bart7b706b32009-05-10 06:55:39 +00001230/** Clear the bitmap contents. */
1231static void bm2_clear(struct bitmap2* const bm2)
bartf647d342008-03-24 19:12:12 +00001232{
bartbedfd232009-03-26 19:07:15 +00001233 tl_assert(bm2);
bart7b706b32009-05-10 06:55:39 +00001234 VG_(memset)(&bm2->bm1, 0, sizeof(bm2->bm1));
bartf647d342008-03-24 19:12:12 +00001235}
1236
bart7b706b32009-05-10 06:55:39 +00001237/** Compute *bm2l |= *bm2r. */
1238static
1239void bm2_merge(struct bitmap2* const bm2l, const struct bitmap2* const bm2r)
sewardjaf44c822007-11-25 14:01:38 +00001240{
bartbedfd232009-03-26 19:07:15 +00001241 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001242
bartbedfd232009-03-26 19:07:15 +00001243 tl_assert(bm2l);
1244 tl_assert(bm2r);
1245 tl_assert(bm2l->addr == bm2r->addr);
bart7b706b32009-05-10 06:55:39 +00001246
1247 s_bitmap2_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +00001248
bartbedfd232009-03-26 19:07:15 +00001249 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1250 {
1251 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1252 }
1253 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1254 {
1255 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1256 }
sewardjaf44c822007-11-25 14:01:38 +00001257}