Skip to content

Commit 7d3b72d

Browse files
author
florian
committed
Add limited support for printing floating point numbers to
VG_(debugLog_vprintf). Remove function VG_(percentify) and fix up its call sites (part of fixing BZ #337869. Allow the width in a format specification to be '*', i.e. the width is given as an additional function argument. The limitations for printing floating point numbers are: (1) %f is the only supported format. Width and precision can be specified. (2) Funny numbers (NaN and such) are not supported. (3) Floating point numbers need to be benign in the sense that their integral part fits into an ULong. This is good enough for our purposes. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14806 a5019735-40e9-0310-863c-91ae7b9d1cf9
1 parent 7571340 commit 7d3b72d

18 files changed

+466
-164
lines changed

cachegrind/cg_main.c

+28-36
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,6 @@ static UInt ULong_width(ULong n)
15631563

15641564
static void cg_fini(Int exitcode)
15651565
{
1566-
static HChar buf1[128], buf2[128], buf3[128], buf4[123]; // FIXME
15671566
static HChar fmt[128]; // OK; large enough
15681567

15691568
CacheCC D_total;
@@ -1599,11 +1598,10 @@ static void cg_fini(Int exitcode)
15991598
VG_(umsg)(fmt, "LLi misses: ", Ir_total.mL);
16001599

16011600
if (0 == Ir_total.a) Ir_total.a = 1;
1602-
VG_(percentify)(Ir_total.m1, Ir_total.a, 2, l1+1, buf1);
1603-
VG_(umsg)("I1 miss rate: %s\n", buf1);
1604-
1605-
VG_(percentify)(Ir_total.mL, Ir_total.a, 2, l1+1, buf1);
1606-
VG_(umsg)("LLi miss rate: %s\n", buf1);
1601+
VG_(umsg)("I1 miss rate: %*.2f%%\n", l1,
1602+
Ir_total.m1 * 100.0 / Ir_total.a);
1603+
VG_(umsg)("LLi miss rate: %*.2f%%\n", l1,
1604+
Ir_total.mL * 100.0 / Ir_total.a);
16071605
VG_(umsg)("\n");
16081606

16091607
/* D cache results. Use the D_refs.rd and D_refs.wr values to
@@ -1626,15 +1624,14 @@ static void cg_fini(Int exitcode)
16261624
if (0 == D_total.a) D_total.a = 1;
16271625
if (0 == Dr_total.a) Dr_total.a = 1;
16281626
if (0 == Dw_total.a) Dw_total.a = 1;
1629-
VG_(percentify)( D_total.m1, D_total.a, 1, l1+1, buf1);
1630-
VG_(percentify)(Dr_total.m1, Dr_total.a, 1, l2+1, buf2);
1631-
VG_(percentify)(Dw_total.m1, Dw_total.a, 1, l3+1, buf3);
1632-
VG_(umsg)("D1 miss rate: %s (%s + %s )\n", buf1, buf2,buf3);
1633-
1634-
VG_(percentify)( D_total.mL, D_total.a, 1, l1+1, buf1);
1635-
VG_(percentify)(Dr_total.mL, Dr_total.a, 1, l2+1, buf2);
1636-
VG_(percentify)(Dw_total.mL, Dw_total.a, 1, l3+1, buf3);
1637-
VG_(umsg)("LLd miss rate: %s (%s + %s )\n", buf1, buf2,buf3);
1627+
VG_(umsg)("D1 miss rate: %*.1f%% (%*.1f%% + %*.1f%% )\n",
1628+
l1, D_total.m1 * 100.0 / D_total.a,
1629+
l2, Dr_total.m1 * 100.0 / Dr_total.a,
1630+
l3, Dw_total.m1 * 100.0 / Dw_total.a);
1631+
VG_(umsg)("LLd miss rate: %*.1f%% (%*.1f%% + %*.1f%% )\n",
1632+
l1, D_total.mL * 100.0 / D_total.a,
1633+
l2, Dr_total.mL * 100.0 / Dr_total.a,
1634+
l3, Dw_total.mL * 100.0 / Dw_total.a);
16381635
VG_(umsg)("\n");
16391636

16401637
/* LL overall results */
@@ -1651,10 +1648,10 @@ static void cg_fini(Int exitcode)
16511648
VG_(umsg)(fmt, "LL misses: ",
16521649
LL_total_m, LL_total_mr, LL_total_mw);
16531650

1654-
VG_(percentify)(LL_total_m, (Ir_total.a + D_total.a), 1, l1+1, buf1);
1655-
VG_(percentify)(LL_total_mr, (Ir_total.a + Dr_total.a), 1, l2+1, buf2);
1656-
VG_(percentify)(LL_total_mw, Dw_total.a, 1, l3+1, buf3);
1657-
VG_(umsg)("LL miss rate: %s (%s + %s )\n", buf1, buf2,buf3);
1651+
VG_(umsg)("LL miss rate: %*.1f%% (%*.1f%% + %*.1f%% )\n",
1652+
l1, LL_total_m * 100.0 / (Ir_total.a + D_total.a),
1653+
l2, LL_total_mr * 100.0 / (Ir_total.a + Dr_total.a),
1654+
l3, LL_total_mw * 100.0 / Dw_total.a);
16581655
}
16591656

16601657
/* If branch profiling is enabled, show branch overall results. */
@@ -1675,11 +1672,10 @@ static void cg_fini(Int exitcode)
16751672
VG_(umsg)(fmt, "Mispredicts: ",
16761673
B_total.mp, Bc_total.mp, Bi_total.mp);
16771674

1678-
VG_(percentify)(B_total.mp, B_total.b, 1, l1+1, buf1);
1679-
VG_(percentify)(Bc_total.mp, Bc_total.b, 1, l2+1, buf2);
1680-
VG_(percentify)(Bi_total.mp, Bi_total.b, 1, l3+1, buf3);
1681-
1682-
VG_(umsg)("Mispred rate: %s (%s + %s )\n", buf1, buf2,buf3);
1675+
VG_(umsg)("Mispred rate: %*.1f%% (%*.1f%% + %*.1f%% )\n",
1676+
l1, B_total.mp * 100.0 / B_total.b,
1677+
l2, Bc_total.mp * 100.0 / Bc_total.b,
1678+
l3, Bi_total.mp * 100.0 / Bi_total.b);
16831679
}
16841680

16851681
// Various stats
@@ -1695,18 +1691,14 @@ static void cg_fini(Int exitcode)
16951691
VG_(dmsg)("cachegrind: distinct instrs Gen: %d\n", distinct_instrsGen);
16961692
VG_(dmsg)("cachegrind: debug lookups : %d\n", debug_lookups);
16971693

1698-
VG_(percentify)(full_debugs, debug_lookups, 1, 6, buf1);
1699-
VG_(percentify)(file_line_debugs, debug_lookups, 1, 6, buf2);
1700-
VG_(percentify)(fn_debugs, debug_lookups, 1, 6, buf3);
1701-
VG_(percentify)(no_debugs, debug_lookups, 1, 6, buf4);
1702-
VG_(dmsg)("cachegrind: with full info:%s (%d)\n",
1703-
buf1, full_debugs);
1704-
VG_(dmsg)("cachegrind: with file/line info:%s (%d)\n",
1705-
buf2, file_line_debugs);
1706-
VG_(dmsg)("cachegrind: with fn name info:%s (%d)\n",
1707-
buf3, fn_debugs);
1708-
VG_(dmsg)("cachegrind: with zero info:%s (%d)\n",
1709-
buf4, no_debugs);
1694+
VG_(dmsg)("cachegrind: with full info:%6.1f%% (%d)\n",
1695+
full_debugs * 100.0 / debug_lookups, full_debugs);
1696+
VG_(dmsg)("cachegrind: with file/line info:%6.1f%% (%d)\n",
1697+
file_line_debugs * 100.0 / debug_lookups, file_line_debugs);
1698+
VG_(dmsg)("cachegrind: with fn name info:%6.1f%% (%d)\n",
1699+
fn_debugs * 100.0 / debug_lookups, fn_debugs);
1700+
VG_(dmsg)("cachegrind: with zero info:%6.1f%% (%d)\n",
1701+
no_debugs * 100.0 / debug_lookups, no_debugs);
17101702

17111703
VG_(dmsg)("cachegrind: string table size: %lu\n",
17121704
VG_(OSetGen_Size)(stringTable));

callgrind/main.c

+4-6
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,6 @@ static UInt ULong_width(ULong n)
17751775
static
17761776
void branchsim_printstat(int l1, int l2, int l3)
17771777
{
1778-
static HChar buf1[128], buf2[128], buf3[128];
17791778
static HChar fmt[128]; // large enough
17801779
FullCost total;
17811780
ULong Bc_total_b, Bc_total_mp, Bi_total_b, Bi_total_mp;
@@ -1803,11 +1802,10 @@ void branchsim_printstat(int l1, int l2, int l3)
18031802
VG_(umsg)(fmt, "Mispredicts: ",
18041803
B_total_mp, Bc_total_mp, Bi_total_mp);
18051804

1806-
VG_(percentify)(B_total_mp, B_total_b, 1, l1+1, buf1);
1807-
VG_(percentify)(Bc_total_mp, Bc_total_b, 1, l2+1, buf2);
1808-
VG_(percentify)(Bi_total_mp, Bi_total_b, 1, l3+1, buf3);
1809-
1810-
VG_(umsg)("Mispred rate: %s (%s + %s )\n", buf1, buf2,buf3);
1805+
VG_(umsg)("Mispred rate: %*.1f%% (%*.1f%% + %*.1f%% )\n",
1806+
l1, B_total_mp * 100.0 / B_total_b,
1807+
l2, Bc_total_mp * 100.0 / Bc_total_b,
1808+
l3, Bi_total_mp * 100.0 / Bi_total_b);
18111809
}
18121810

18131811
static

coregrind/m_debuglog.c

+116-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* -*- mode: C; c-basic-offset: 3; -*- */
12

23
/*--------------------------------------------------------------------*/
34
/*--- Debug (not-for-user) logging; also vprintf. m_debuglog.c ---*/
@@ -730,7 +731,7 @@ VG_(debugLog_vprintf) (
730731
UInt ret = 0;
731732
Int i;
732733
Int flags;
733-
Int width;
734+
Int width, precision;
734735
Int n_ls = 0;
735736
Bool is_long, caps;
736737

@@ -758,6 +759,7 @@ VG_(debugLog_vprintf) (
758759
flags = 0;
759760
n_ls = 0;
760761
width = 0; /* length of the field. */
762+
precision = -1; /* unspecified precision */
761763
while (1) {
762764
switch (format[i]) {
763765
case '(':
@@ -787,9 +789,29 @@ VG_(debugLog_vprintf) (
787789
}
788790
parse_fieldwidth:
789791
/* Compute the field length. */
790-
while (format[i] >= '0' && format[i] <= '9') {
791-
width *= 10;
792-
width += format[i++] - '0';
792+
if (format[i] == '*') {
793+
width = va_arg(vargs, Int);
794+
++i;
795+
} else {
796+
while (format[i] >= '0' && format[i] <= '9') {
797+
width *= 10;
798+
width += format[i++] - '0';
799+
}
800+
}
801+
/* Parse precision, if any. Only meaningful for %f. For all other
802+
format specifiers the precision will be silently ignored. */
803+
if (format[i] == '.') {
804+
++i;
805+
if (format[i] == '*') {
806+
precision = va_arg(vargs, Int);
807+
++i;
808+
} else {
809+
precision = 0;
810+
while (format[i] >= '0' && format[i] <= '9') {
811+
precision *= 10;
812+
precision += format[i++] - '0';
813+
}
814+
}
793815
}
794816
while (format[i] == 'l') {
795817
i++;
@@ -888,6 +910,96 @@ VG_(debugLog_vprintf) (
888910
flags, width, str, format[i]=='S');
889911
break;
890912
}
913+
case 'f': {
914+
/* Print a floating point number in the format x.y without
915+
any exponent. Capabilities are extremely limited, basically
916+
a joke, but good enough for our needs. */
917+
Double val = va_arg (vargs, Double);
918+
Bool is_negative = False;
919+
Int cnt;
920+
921+
if (val < 0.0) {
922+
is_negative = True;
923+
val = - val;
924+
}
925+
/* If the integral part of the floating point number cannot be
926+
represented by an ULONG_MAX, print '*' characters */
927+
if (val > (Double)(~0ULL)) {
928+
if (width == 0) width = 6; // say
929+
for (cnt = 0; cnt < width; ++cnt)
930+
send('*', send_arg2);
931+
ret += width;
932+
break;
933+
}
934+
/* The integral part of the floating point number is representable
935+
by an ULong. */
936+
ULong ipval = val;
937+
Double frac = val - ipval;
938+
939+
if (precision == -1) precision = 6; // say
940+
941+
/* Silently limit the precision to 10 digits. */
942+
if (precision > 10) precision = 10;
943+
944+
/* If fracional part is not printed (precision == 0), may have to
945+
round up */
946+
if (precision == 0 && frac >= 0.5)
947+
ipval += 1;
948+
949+
/* Find out how many characters are needed to print the number */
950+
951+
/* The integral part... */
952+
UInt ipwidth, num_digit = 1; // at least one digit
953+
ULong x, old_x = 0;
954+
for (x = 10; ; old_x = x, x *= 10, ++num_digit) {
955+
if (x <= old_x) break; // overflow occurred
956+
if (ipval < x) break;
957+
}
958+
ipwidth = num_digit; // width of integral part.
959+
if (is_negative) ++num_digit;
960+
if (precision != 0)
961+
num_digit += 1 + precision;
962+
963+
// Print the number
964+
965+
// Fill in blanks on the left
966+
if (num_digit < width && (flags & VG_MSG_LJUSTIFY) == 0) {
967+
for (cnt = 0; cnt < width - num_digit; ++cnt)
968+
send(' ', send_arg2);
969+
ret += width - num_digit;
970+
}
971+
// Sign, maybe
972+
if (is_negative) {
973+
send('-', send_arg2);
974+
ret += 1;
975+
}
976+
// Integral part
977+
ret += myvprintf_int64(send, send_arg2, 0, 10, ipwidth, False,
978+
ipval);
979+
// Decimal point and fractional part
980+
if (precision != 0) {
981+
send('.', send_arg2);
982+
ret += 1;
983+
984+
// Fractional part
985+
ULong factor = 1;
986+
for (cnt = 0; cnt < precision; ++cnt)
987+
factor *= 10;
988+
ULong frval = frac * factor;
989+
if ((frac * factor - frval) > 0.5) // round up
990+
frval += 1;
991+
frval %= factor;
992+
ret += myvprintf_int64(send, send_arg2, VG_MSG_ZJUSTIFY, 10,
993+
precision, False, frval);
994+
}
995+
// Fill in blanks on the right
996+
if (num_digit < width && (flags & VG_MSG_LJUSTIFY) != 0) {
997+
for (cnt = 0; cnt < width - num_digit; ++cnt)
998+
send(' ', send_arg2);
999+
ret += width - num_digit;
1000+
}
1001+
break;
1002+
}
8911003

8921004
// case 'y': { /* %y - print symbol */
8931005
// Addr a = va_arg(vargs, Addr);

coregrind/m_libcprint.c

-52
Original file line numberDiff line numberDiff line change
@@ -362,58 +362,6 @@ void VG_(fclose)( VgFile *fp )
362362
VG_(free)(fp);
363363
}
364364

365-
/* ---------------------------------------------------------------------
366-
percentify()
367-
------------------------------------------------------------------ */
368-
369-
// Percentify n/m with d decimal places. Includes the '%' symbol at the end.
370-
// Right justifies in 'buf'.
371-
void VG_(percentify)(ULong n, ULong m, UInt d, Int n_buf, HChar buf[])
372-
{
373-
Int i, len, space;
374-
ULong p1;
375-
HChar fmt[32]; // large enough
376-
377-
if (m == 0) {
378-
// Have to generate the format string in order to be flexible about
379-
// the width of the field.
380-
VG_(sprintf)(fmt, "%%%ds", n_buf);
381-
// fmt is now "%<n_buf>s" where <d> is 1,2,3...
382-
VG_(sprintf)(buf, fmt, "--%");
383-
return;
384-
}
385-
386-
p1 = (100*n) / m;
387-
388-
if (d == 0) {
389-
VG_(sprintf)(buf, "%llu%%", p1); // FIXME: unsafe
390-
} else {
391-
ULong p2;
392-
UInt ex;
393-
switch (d) {
394-
case 1: ex = 10; break;
395-
case 2: ex = 100; break;
396-
case 3: ex = 1000; break;
397-
default: VG_(core_panic)("Currently can only handle 3 decimal places");
398-
}
399-
p2 = ((100*n*ex) / m) % ex;
400-
// Have to generate the format string in order to be flexible about
401-
// the width of the post-decimal-point part.
402-
VG_(sprintf)(fmt, "%%llu.%%0%ullu%%%%", d);
403-
// fmt is now "%llu.%0<d>llu%%" where <d> is 1,2,3...
404-
VG_(sprintf)(buf, fmt, p1, p2); // FIXME: unsafe
405-
}
406-
407-
len = VG_(strlen)(buf);
408-
space = n_buf - len;
409-
if (space < 0) space = 0; /* Allow for v. small field_width */
410-
i = len;
411-
412-
/* Right justify in field */
413-
for ( ; i >= 0; i--) buf[i + space] = buf[i];
414-
for (i = 0; i < space; i++) buf[i] = ' ';
415-
}
416-
417365

418366
/* ---------------------------------------------------------------------
419367
elapsed_wallclock_time()

0 commit comments

Comments
 (0)