From: Julian Seward Date: Sat, 6 Dec 2008 23:34:52 +0000 (+0000) Subject: * Add a VG_(sizeSWA) function X-Git-Tag: svn/VALGRIND_3_4_0~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5aa3e073b7a4d2f2b69f0c9805e5635a1964f6fa;p=thirdparty%2Fvalgrind.git * Add a VG_(sizeSWA) function * Fix spacing a bit git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8808 --- diff --git a/coregrind/m_sparsewa.c b/coregrind/m_sparsewa.c index 9fad5ba09e..97fa02459c 100644 --- a/coregrind/m_sparsewa.c +++ b/coregrind/m_sparsewa.c @@ -115,7 +115,6 @@ static inline UWord swa_bitarray_read_then_clear ( UChar* arr, UWord ix ) { //////// SWA helper functions (iteration) -inline static void swa_PUSH ( SparseWA* swa, UWord partial_key, Int curr_ix, void* curr_nd, Int resume_point ) { @@ -130,7 +129,6 @@ static void swa_PUSH ( SparseWA* swa, UWord partial_key, Int curr_ix, swa->isUsed = sp+1; } -inline static void swa_POP ( SparseWA* swa, UWord* partial_key, Int* curr_ix, void** curr_nd, Int* resume_point ) @@ -165,6 +163,7 @@ static Level0* swa_new_Level0 ( SparseWA* swa ) return level0; } + //////// SWA public interface void VG_(initIterSWA) ( SparseWA* swa ) @@ -173,6 +172,7 @@ void VG_(initIterSWA) ( SparseWA* swa ) if (swa->root) swa_PUSH(swa, 0, 0, swa->root, 1/*start_new_node*/); } + Bool VG_(nextIterSWA)( SparseWA* swa, /*OUT*/UWord* keyP, /*OUT*/UWord* valP ) { @@ -230,6 +230,7 @@ Bool VG_(nextIterSWA)( SparseWA* swa, goto dispatch; } + SparseWA* VG_(newSWA) ( void*(*alloc_nofail)(HChar* cc, SizeT), HChar* cc, void(*dealloc)(void*) ) @@ -247,6 +248,7 @@ SparseWA* VG_(newSWA) ( void*(*alloc_nofail)(HChar* cc, SizeT), return swa; } + static void swa_deleteSWA_wrk ( void(*dealloc)(void*), void* nd ) { Int i; @@ -263,7 +265,6 @@ static void swa_deleteSWA_wrk ( void(*dealloc)(void*), void* nd ) } dealloc(nd); } - void VG_(deleteSWA) ( SparseWA* swa ) { if (swa->root) @@ -271,6 +272,7 @@ void VG_(deleteSWA) ( SparseWA* swa ) swa->dealloc(swa); } + Bool VG_(lookupSWA) ( SparseWA* swa, /*OUT*/UWord* keyP, /*OUT*/UWord* valP, UWord key ) @@ -305,6 +307,7 @@ Bool VG_(lookupSWA) ( SparseWA* swa, return True; } + Bool VG_(addToSWA) ( SparseWA* swa, UWord key, UWord val ) { Int i; @@ -361,6 +364,7 @@ Bool VG_(addToSWA) ( SparseWA* swa, UWord key, UWord val ) return already_present; } + Bool VG_(delFromSWA) ( SparseWA* swa, /*OUT*/UWord* oldK, /*OUT*/UWord* oldV, UWord key ) { @@ -427,6 +431,48 @@ Bool VG_(delFromSWA) ( SparseWA* swa, return True; } + +static UWord swa_sizeSWA_wrk ( void* nd ) +{ + Int i; + UWord sum = 0; + if (*(UWord*)nd == LevelN_MAGIC) { + LevelN* levelN = (LevelN*)nd; + for (i = 0; i < 256; i++) { + if (levelN->child[i]) { + sum += swa_sizeSWA_wrk( levelN->child[i] ); + } + } + } else { + Level0* level0; + vg_assert(*(UWord*)nd == Level0_MAGIC); + level0 = (Level0*)nd; + for (i = 0; i < 256/8; i += 2) { + UWord x = level0->inUse[i+0]; /* assume zero-extend */ + UWord y = level0->inUse[i+1]; /* assume zero-extend */ + /* do 'sum += popcount(x) + popcount(y)' for byte-sized x, y */ + /* unroll the loop twice so as to expose more ILP */ + x = (x & 0x55) + ((x >> 1) & 0x55); + y = (y & 0x55) + ((y >> 1) & 0x55); + x = (x & 0x33) + ((x >> 2) & 0x33); + y = (y & 0x33) + ((y >> 2) & 0x33); + x = (x & 0x0F) + ((x >> 4) & 0x0F); + y = (y & 0x0F) + ((y >> 4) & 0x0F); + sum += x + y; + } + } + return sum; +} +UWord VG_(sizeSWA) ( SparseWA* swa ) +{ + if (swa->root) + return swa_sizeSWA_wrk ( swa->root ); + else + return 0; +} + + + /*--------------------------------------------------------------------*/ /*--- end m_sparsewa.c ---*/ /*--------------------------------------------------------------------*/ diff --git a/include/pub_tool_sparsewa.h b/include/pub_tool_sparsewa.h index 91f5b584fa..92191f2436 100644 --- a/include/pub_tool_sparsewa.h +++ b/include/pub_tool_sparsewa.h @@ -87,6 +87,10 @@ void VG_(initIterSWA) ( SparseWA* swa ); Bool VG_(nextIterSWA)( SparseWA* swa, /*OUT*/UWord* keyP, /*OUT*/UWord* valP ); +// How many elements are there in 'swa'? NOTE: dangerous in the +// sense that this is not an O(1) operation but rather O(N), +// since it involves walking the whole tree. +UWord VG_(sizeSWA) ( SparseWA* swa ); #endif // __PUB_TOOL_SPARSEWA_H