blob: a3925e9e7c3ea1b0f603933d63c2f77075711e78 [file] [log] [blame]
weidendoa17f2a32006-03-20 10:27:30 +00001/*--------------------------------------------------------------------*/
2/*--- Callgrind ---*/
3/*--- events.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Callgrind, a Valgrind tool for call tracing.
8
Elliott Hughesed398002017-06-21 14:41:24 -07009 Copyright (C) 2002-2017, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
weidendoa17f2a32006-03-20 10:27:30 +000010
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 02111-1307, USA.
25
26 The GNU General Public License is contained in the file COPYING.
27*/
28
29#include "global.h"
30
weidendo5bba5252010-06-09 22:32:53 +000031/* This should be 2**MAX_EVENTGROUP_COUNT */
32#define MAX_EVENTSET_COUNT 1024
weidendoa17f2a32006-03-20 10:27:30 +000033
weidendo5bba5252010-06-09 22:32:53 +000034static EventGroup* eventGroup[MAX_EVENTGROUP_COUNT];
35static EventSet* eventSetTable[MAX_EVENTSET_COUNT];
36static Bool eventSets_initialized = 0;
weidendoa17f2a32006-03-20 10:27:30 +000037
weidendo5bba5252010-06-09 22:32:53 +000038static
39void initialize_event_sets(void)
weidendoa17f2a32006-03-20 10:27:30 +000040{
weidendo5bba5252010-06-09 22:32:53 +000041 Int i;
weidendoa17f2a32006-03-20 10:27:30 +000042
weidendo5bba5252010-06-09 22:32:53 +000043 if (eventSets_initialized) return;
weidendoa17f2a32006-03-20 10:27:30 +000044
weidendo5bba5252010-06-09 22:32:53 +000045 for(i=0; i< MAX_EVENTGROUP_COUNT; i++)
46 eventGroup[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +000047
weidendo5bba5252010-06-09 22:32:53 +000048 for(i=0; i< MAX_EVENTSET_COUNT; i++)
florian19f91bb2012-11-10 22:29:54 +000049 eventSetTable[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +000050
weidendo5bba5252010-06-09 22:32:53 +000051 eventSets_initialized = 1;
52 }
53
54static
55EventGroup* new_event_group(int id, int n)
56{
57 EventGroup* eg;
58
59 initialize_event_sets();
60
61 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
62 CLG_ASSERT(eventGroup[id]==0);
63
64 eg = (EventGroup*) CLG_MALLOC("cl.events.group.1",
florian19f91bb2012-11-10 22:29:54 +000065 sizeof(EventGroup) + n * sizeof(HChar*));
weidendo5bba5252010-06-09 22:32:53 +000066 eg->size = n;
67 eventGroup[id] = eg;
68 return eg;
69}
70
florian25f6c572012-10-21 02:55:56 +000071EventGroup* CLG_(register_event_group) (int id, const HChar* n1)
weidendo5bba5252010-06-09 22:32:53 +000072{
73 EventGroup* eg = new_event_group(id, 1);
74 eg->name[0] = n1;
75
76 return eg;
77}
78
florian25f6c572012-10-21 02:55:56 +000079EventGroup* CLG_(register_event_group2)(int id, const HChar* n1,
80 const HChar* n2)
weidendo5bba5252010-06-09 22:32:53 +000081{
82 EventGroup* eg = new_event_group(id, 2);
83 eg->name[0] = n1;
84 eg->name[1] = n2;
85
86 return eg;
87}
88
florian25f6c572012-10-21 02:55:56 +000089EventGroup* CLG_(register_event_group3)(int id, const HChar* n1,
90 const HChar* n2, const HChar* n3)
weidendo5bba5252010-06-09 22:32:53 +000091{
92 EventGroup* eg = new_event_group(id, 3);
93 eg->name[0] = n1;
94 eg->name[1] = n2;
95 eg->name[2] = n3;
96
97 return eg;
98}
99
florian25f6c572012-10-21 02:55:56 +0000100EventGroup* CLG_(register_event_group4)(int id, const HChar* n1,
101 const HChar* n2, const HChar* n3,
102 const HChar* n4)
weidendo5bba5252010-06-09 22:32:53 +0000103{
104 EventGroup* eg = new_event_group(id, 4);
105 eg->name[0] = n1;
106 eg->name[1] = n2;
107 eg->name[2] = n3;
108 eg->name[3] = n4;
109
110 return eg;
111}
112
113EventGroup* CLG_(get_event_group)(int id)
114{
115 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
116
117 return eventGroup[id];
weidendoa17f2a32006-03-20 10:27:30 +0000118}
119
120
weidendo5bba5252010-06-09 22:32:53 +0000121static
122EventSet* eventset_from_mask(UInt mask)
weidendoa17f2a32006-03-20 10:27:30 +0000123{
weidendo5bba5252010-06-09 22:32:53 +0000124 EventSet* es;
125 Int i, count, offset;
weidendoa17f2a32006-03-20 10:27:30 +0000126
weidendo5bba5252010-06-09 22:32:53 +0000127 if (mask >= MAX_EVENTSET_COUNT) return 0;
128
129 initialize_event_sets();
130 if (eventSetTable[mask]) return eventSetTable[mask];
131
132 es = (EventSet*) CLG_MALLOC("cl.events.eventset.1", sizeof(EventSet));
133 es->mask = mask;
134
135 offset = 0;
136 count = 0;
137 for(i=0;i<MAX_EVENTGROUP_COUNT;i++) {
138 es->offset[i] = offset;
139 if ( ((mask & (1u<<i))==0) || (eventGroup[i]==0))
140 continue;
141
142 offset += eventGroup[i]->size;
143 count++;
144 }
145 es->size = offset;
146 es->count = count;
147
148 eventSetTable[mask] = es;
149 return es;
weidendoa17f2a32006-03-20 10:27:30 +0000150}
151
weidendo5bba5252010-06-09 22:32:53 +0000152EventSet* CLG_(get_event_set)(Int id)
weidendoa17f2a32006-03-20 10:27:30 +0000153{
weidendo5bba5252010-06-09 22:32:53 +0000154 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
155 return eventset_from_mask(1u << id);
weidendoa17f2a32006-03-20 10:27:30 +0000156}
157
weidendo5bba5252010-06-09 22:32:53 +0000158EventSet* CLG_(get_event_set2)(Int id1, Int id2)
weidendoa17f2a32006-03-20 10:27:30 +0000159{
weidendo5bba5252010-06-09 22:32:53 +0000160 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
161 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
162 return eventset_from_mask((1u << id1) | (1u << id2));
weidendoa17f2a32006-03-20 10:27:30 +0000163}
164
weidendo5bba5252010-06-09 22:32:53 +0000165EventSet* CLG_(add_event_group)(EventSet* es, Int id)
weidendoa17f2a32006-03-20 10:27:30 +0000166{
weidendo5bba5252010-06-09 22:32:53 +0000167 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
168 if (!es) es = eventset_from_mask(0);
169 return eventset_from_mask(es->mask | (1u << id));
weidendoa17f2a32006-03-20 10:27:30 +0000170}
171
weidendo5bba5252010-06-09 22:32:53 +0000172EventSet* CLG_(add_event_group2)(EventSet* es, Int id1, Int id2)
weidendoa17f2a32006-03-20 10:27:30 +0000173{
weidendo5bba5252010-06-09 22:32:53 +0000174 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
175 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
176 if (!es) es = eventset_from_mask(0);
177 return eventset_from_mask(es->mask | (1u << id1) | (1u << id2));
weidendoa17f2a32006-03-20 10:27:30 +0000178}
179
weidendo5bba5252010-06-09 22:32:53 +0000180EventSet* CLG_(add_event_set)(EventSet* es1, EventSet* es2)
weidendoa17f2a32006-03-20 10:27:30 +0000181{
weidendo5bba5252010-06-09 22:32:53 +0000182 if (!es1) es1 = eventset_from_mask(0);
183 if (!es2) es2 = eventset_from_mask(0);
184 return eventset_from_mask(es1->mask | es2->mask);
weidendoa17f2a32006-03-20 10:27:30 +0000185}
186
weidendo5bba5252010-06-09 22:32:53 +0000187
weidendoa17f2a32006-03-20 10:27:30 +0000188/* Get cost array for an event set */
189ULong* CLG_(get_eventset_cost)(EventSet* es)
190{
weidendo5bba5252010-06-09 22:32:53 +0000191 return CLG_(get_costarray)(es->size);
weidendoa17f2a32006-03-20 10:27:30 +0000192}
193
194/* Set all costs of an event set to zero */
195void CLG_(init_cost)(EventSet* es, ULong* cost)
196{
weidendo5bba5252010-06-09 22:32:53 +0000197 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000198
weidendo5bba5252010-06-09 22:32:53 +0000199 if (!cost) return;
weidendoa17f2a32006-03-20 10:27:30 +0000200
weidendo5bba5252010-06-09 22:32:53 +0000201 for(i=0; i<es->size; i++)
202 cost[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000203}
204
205/* Set all costs of an event set to zero */
206void CLG_(init_cost_lz)(EventSet* es, ULong** cost)
207{
weidendo5bba5252010-06-09 22:32:53 +0000208 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000209
weidendo5bba5252010-06-09 22:32:53 +0000210 CLG_ASSERT(cost != 0);
211 if (!(*cost))
212 *cost = CLG_(get_eventset_cost)(es);
weidendoa17f2a32006-03-20 10:27:30 +0000213
weidendo5bba5252010-06-09 22:32:53 +0000214 for(i=0; i<es->size; i++)
215 (*cost)[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000216}
217
218void CLG_(zero_cost)(EventSet* es, ULong* cost)
219{
weidendo5bba5252010-06-09 22:32:53 +0000220 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000221
weidendo5bba5252010-06-09 22:32:53 +0000222 if (!cost) return;
weidendoa17f2a32006-03-20 10:27:30 +0000223
weidendo5bba5252010-06-09 22:32:53 +0000224 for(i=0;i<es->size;i++)
225 cost[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000226}
227
228Bool CLG_(is_zero_cost)(EventSet* es, ULong* cost)
229{
weidendo5bba5252010-06-09 22:32:53 +0000230 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000231
weidendo5bba5252010-06-09 22:32:53 +0000232 if (!cost) return True;
weidendoa17f2a32006-03-20 10:27:30 +0000233
weidendo5bba5252010-06-09 22:32:53 +0000234 for(i=0; i<es->size; i++)
235 if (cost[i] != 0) return False;
236
237 return True;
weidendoa17f2a32006-03-20 10:27:30 +0000238}
239
weidendoa17f2a32006-03-20 10:27:30 +0000240void CLG_(copy_cost)(EventSet* es, ULong* dst, ULong* src)
241{
weidendo5bba5252010-06-09 22:32:53 +0000242 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000243
weidendo5bba5252010-06-09 22:32:53 +0000244 if (!src) {
245 CLG_(zero_cost)(es, dst);
246 return;
247 }
248 CLG_ASSERT(dst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000249
weidendo5bba5252010-06-09 22:32:53 +0000250 for(i=0;i<es->size;i++)
251 dst[i] = src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000252}
253
254void CLG_(copy_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
255{
weidendo5bba5252010-06-09 22:32:53 +0000256 Int i;
257 ULong* dst;
weidendoa17f2a32006-03-20 10:27:30 +0000258
weidendo5bba5252010-06-09 22:32:53 +0000259 CLG_ASSERT(pdst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000260
weidendo5bba5252010-06-09 22:32:53 +0000261 if (!src) {
262 CLG_(zero_cost)(es, *pdst);
263 return;
264 }
265 dst = *pdst;
266 if (!dst)
267 dst = *pdst = CLG_(get_eventset_cost)(es);
weidendoa17f2a32006-03-20 10:27:30 +0000268
weidendo5bba5252010-06-09 22:32:53 +0000269 for(i=0;i<es->size;i++)
270 dst[i] = src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000271}
272
273void CLG_(add_cost)(EventSet* es, ULong* dst, ULong* src)
274{
weidendo5bba5252010-06-09 22:32:53 +0000275 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000276
weidendo5bba5252010-06-09 22:32:53 +0000277 if (!src) return;
278 CLG_ASSERT(dst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000279
weidendo5bba5252010-06-09 22:32:53 +0000280 for(i=0; i<es->size; i++)
281 dst[i] += src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000282}
283
284void CLG_(add_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
285{
weidendo5bba5252010-06-09 22:32:53 +0000286 Int i;
287 ULong* dst;
weidendoa17f2a32006-03-20 10:27:30 +0000288
weidendo5bba5252010-06-09 22:32:53 +0000289 if (!src) return;
290 CLG_ASSERT(pdst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000291
weidendo5bba5252010-06-09 22:32:53 +0000292 dst = *pdst;
293 if (!dst) {
294 dst = *pdst = CLG_(get_eventset_cost)(es);
295 CLG_(copy_cost)(es, dst, src);
296 return;
weidendoa17f2a32006-03-20 10:27:30 +0000297 }
weidendo5bba5252010-06-09 22:32:53 +0000298
299 for(i=0; i<es->size; i++)
300 dst[i] += src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000301}
302
303/* Adds src to dst and zeros src. Returns false if nothing changed */
304Bool CLG_(add_and_zero_cost)(EventSet* es, ULong* dst, ULong* src)
305{
weidendo5bba5252010-06-09 22:32:53 +0000306 Int i;
307 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000308
weidendo5bba5252010-06-09 22:32:53 +0000309 CLG_ASSERT((es != 0) && (dst != 0));
310 if (!src) return False;
weidendoa17f2a32006-03-20 10:27:30 +0000311
weidendo5bba5252010-06-09 22:32:53 +0000312 for(i=0; i<es->size; i++) {
313 if (src[i]==0) continue;
314 dst[i] += src[i];
315 src[i] = 0;
316 is_nonzero = True;
weidendoa17f2a32006-03-20 10:27:30 +0000317 }
weidendoa17f2a32006-03-20 10:27:30 +0000318
weidendo5bba5252010-06-09 22:32:53 +0000319 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000320}
321
322/* Adds src to dst and zeros src. Returns false if nothing changed */
weidendo5bba5252010-06-09 22:32:53 +0000323Bool CLG_(add_and_zero_cost2)(EventSet* esDst, ULong* dst,
324 EventSet* esSrc, ULong* src)
weidendoa17f2a32006-03-20 10:27:30 +0000325{
weidendo5bba5252010-06-09 22:32:53 +0000326 Int i,j;
327 Bool is_nonzero = False;
328 UInt mask;
329 EventGroup *eg;
330 ULong *egDst, *egSrc;
weidendoa17f2a32006-03-20 10:27:30 +0000331
weidendo5bba5252010-06-09 22:32:53 +0000332 CLG_ASSERT((esDst != 0) && (dst != 0) && (esSrc != 0));
333 if (!src) return False;
weidendoa17f2a32006-03-20 10:27:30 +0000334
weidendo5bba5252010-06-09 22:32:53 +0000335 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
336 if ((esSrc->mask & mask)==0) continue;
337 if (eventGroup[i] ==0) continue;
weidendoa17f2a32006-03-20 10:27:30 +0000338
weidendo5bba5252010-06-09 22:32:53 +0000339 /* if src has a subset, dst must have, too */
340 CLG_ASSERT((esDst->mask & mask)>0);
341 eg = eventGroup[i];
342 egSrc = src + esSrc->offset[i];
343 egDst = dst + esDst->offset[i];
344 for(j=0; j<eg->size; j++) {
345 if (egSrc[j]==0) continue;
346 egDst[j] += egSrc[j];
347 egSrc[j] = 0;
348 is_nonzero = True;
349 }
weidendoa17f2a32006-03-20 10:27:30 +0000350 }
weidendoa17f2a32006-03-20 10:27:30 +0000351
weidendo5bba5252010-06-09 22:32:53 +0000352 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000353}
354
weidendo5bba5252010-06-09 22:32:53 +0000355
356
weidendoa17f2a32006-03-20 10:27:30 +0000357/* Adds difference of new and old to dst, and set old to new.
358 * Returns false if nothing changed */
weidendo0b23d6e2009-06-15 00:16:32 +0000359Bool CLG_(add_diff_cost)(EventSet* es, ULong* dst, ULong* old, ULong* new_cost)
weidendoa17f2a32006-03-20 10:27:30 +0000360{
weidendo5bba5252010-06-09 22:32:53 +0000361 Int i;
362 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000363
weidendo5bba5252010-06-09 22:32:53 +0000364 CLG_ASSERT((es != 0) && (dst != 0));
365 CLG_ASSERT(old && new_cost);
366
367 for(i=0; i<es->size; i++) {
368 if (new_cost[i] == old[i]) continue;
369 dst[i] += new_cost[i] - old[i];
370 old[i] = new_cost[i];
371 is_nonzero = True;
weidendoa17f2a32006-03-20 10:27:30 +0000372 }
weidendoa17f2a32006-03-20 10:27:30 +0000373
weidendo5bba5252010-06-09 22:32:53 +0000374 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000375}
376
weidendo5bba5252010-06-09 22:32:53 +0000377Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst, ULong* old, ULong* new_cost)
weidendoa17f2a32006-03-20 10:27:30 +0000378{
weidendo5bba5252010-06-09 22:32:53 +0000379 Int i;
380 ULong* dst;
381 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000382
weidendo5bba5252010-06-09 22:32:53 +0000383 CLG_ASSERT((es != 0) && (pdst != 0));
384 CLG_ASSERT(old && new_cost);
weidendoa17f2a32006-03-20 10:27:30 +0000385
weidendo5bba5252010-06-09 22:32:53 +0000386 dst = *pdst;
387 if (!dst) {
388 dst = *pdst = CLG_(get_eventset_cost)(es);
389 CLG_(zero_cost)(es, dst);
weidendoa17f2a32006-03-20 10:27:30 +0000390 }
weidendoa17f2a32006-03-20 10:27:30 +0000391
weidendo5bba5252010-06-09 22:32:53 +0000392 for(i=0; i<es->size; i++) {
393 if (new_cost[i] == old[i]) continue;
394 dst[i] += new_cost[i] - old[i];
395 old[i] = new_cost[i];
396 is_nonzero = True;
397 }
398
399 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000400}
401
weidendo5bba5252010-06-09 22:32:53 +0000402
weidendoa17f2a32006-03-20 10:27:30 +0000403/* Allocate space for an event mapping */
404EventMapping* CLG_(get_eventmapping)(EventSet* es)
405{
weidendo5bba5252010-06-09 22:32:53 +0000406 EventMapping* em;
weidendoa17f2a32006-03-20 10:27:30 +0000407
weidendo5bba5252010-06-09 22:32:53 +0000408 CLG_ASSERT(es != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000409
weidendo5bba5252010-06-09 22:32:53 +0000410 em = (EventMapping*) CLG_MALLOC("cl.events.geMapping.1",
411 sizeof(EventMapping) +
412 sizeof(struct EventMappingEntry) *
413 es->size);
414 em->capacity = es->size;
415 em->size = 0;
416 em->es = es;
weidendoa17f2a32006-03-20 10:27:30 +0000417
weidendo5bba5252010-06-09 22:32:53 +0000418 return em;
weidendoa17f2a32006-03-20 10:27:30 +0000419}
420
florian25f6c572012-10-21 02:55:56 +0000421void CLG_(append_event)(EventMapping* em, const HChar* n)
weidendoa17f2a32006-03-20 10:27:30 +0000422{
weidendo5bba5252010-06-09 22:32:53 +0000423 Int i, j, offset = 0;
424 UInt mask;
425 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000426
weidendo5bba5252010-06-09 22:32:53 +0000427 CLG_ASSERT(em != 0);
428 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
429 if ((em->es->mask & mask)==0) continue;
430 if (eventGroup[i] ==0) continue;
weidendoa17f2a32006-03-20 10:27:30 +0000431
weidendo5bba5252010-06-09 22:32:53 +0000432 eg = eventGroup[i];
433 for(j=0; j<eg->size; j++, offset++) {
434 if (VG_(strcmp)(n, eg->name[j])!=0)
435 continue;
weidendoa17f2a32006-03-20 10:27:30 +0000436
weidendo5bba5252010-06-09 22:32:53 +0000437 CLG_ASSERT(em->capacity > em->size);
438 em->entry[em->size].group = i;
439 em->entry[em->size].index = j;
440 em->entry[em->size].offset = offset;
441 em->size++;
442 return;
443 }
444 }
weidendoa17f2a32006-03-20 10:27:30 +0000445}
446
447
florian5ee42a42014-11-06 21:43:44 +0000448/* Returns pointer to dynamically string. The string will be overwritten
449 with each invocation. */
450HChar *CLG_(eventmapping_as_string)(const EventMapping* em)
weidendoa17f2a32006-03-20 10:27:30 +0000451{
florian5ee42a42014-11-06 21:43:44 +0000452 Int i;
weidendo5bba5252010-06-09 22:32:53 +0000453 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000454
weidendo5bba5252010-06-09 22:32:53 +0000455 CLG_ASSERT(em != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000456
florian5ee42a42014-11-06 21:43:44 +0000457 XArray *xa = VG_(newXA)(VG_(malloc), "cl.events.emas", VG_(free),
458 sizeof(HChar));
459
weidendo5bba5252010-06-09 22:32:53 +0000460 for(i=0; i< em->size; i++) {
florian5ee42a42014-11-06 21:43:44 +0000461 if (i > 0) {
462 VG_(xaprintf)(xa, "%c", ' ');
463 }
weidendo5bba5252010-06-09 22:32:53 +0000464 eg = eventGroup[em->entry[i].group];
465 CLG_ASSERT(eg != 0);
florian5ee42a42014-11-06 21:43:44 +0000466 VG_(xaprintf)(xa, "%s", eg->name[em->entry[i].index]);
weidendo5bba5252010-06-09 22:32:53 +0000467 }
florian5ee42a42014-11-06 21:43:44 +0000468 VG_(xaprintf)(xa, "%c", '\0'); // zero terminate the string
weidendoa17f2a32006-03-20 10:27:30 +0000469
florian5ee42a42014-11-06 21:43:44 +0000470 HChar *buf = VG_(strdup)("cl.events.emas", VG_(indexXA)(xa, 0));
471 VG_(deleteXA)(xa);
472
473 return buf;
weidendoa17f2a32006-03-20 10:27:30 +0000474}
475
florian5ee42a42014-11-06 21:43:44 +0000476/* Returns pointer to dynamically allocated string. Caller needs to
477 VG_(free) it. */
478HChar *CLG_(mappingcost_as_string)(const EventMapping* em, const ULong* c)
weidendoa17f2a32006-03-20 10:27:30 +0000479{
florian5ee42a42014-11-06 21:43:44 +0000480 Int i, skipped = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000481
florian5ee42a42014-11-06 21:43:44 +0000482 if (!c || em->size==0) return VG_(strdup)("cl.events.mcas", "");
483
484 XArray *xa = VG_(newXA)(VG_(malloc), "cl.events.mcas", VG_(free),
485 sizeof(HChar));
weidendoa17f2a32006-03-20 10:27:30 +0000486
487 /* At least one entry */
florian5ee42a42014-11-06 21:43:44 +0000488 VG_(xaprintf)(xa, "%llu", c[em->entry[0].offset]);
weidendoa17f2a32006-03-20 10:27:30 +0000489
weidendo5bba5252010-06-09 22:32:53 +0000490 for(i=1; i<em->size; i++) {
491 if (c[em->entry[i].offset] == 0) {
492 skipped++;
493 continue;
494 }
495 while(skipped>0) {
florian5ee42a42014-11-06 21:43:44 +0000496 VG_(xaprintf)(xa, " 0");
weidendo5bba5252010-06-09 22:32:53 +0000497 skipped--;
498 }
florian5ee42a42014-11-06 21:43:44 +0000499 VG_(xaprintf)(xa, " %llu", c[em->entry[i].offset]);
weidendoa17f2a32006-03-20 10:27:30 +0000500 }
florian5ee42a42014-11-06 21:43:44 +0000501 VG_(xaprintf)(xa, "%c", '\0'); // zero terminate the string
weidendoa17f2a32006-03-20 10:27:30 +0000502
florian5ee42a42014-11-06 21:43:44 +0000503 HChar *buf = VG_(strdup)("cl.events.mas", VG_(indexXA)(xa, 0));
504 VG_(deleteXA)(xa);
505
506 return buf;
weidendoa17f2a32006-03-20 10:27:30 +0000507}