if (!CLG_(clo).simulate_cache) {
/* update Ir cost */
int instr_count = last_bb->jmp[passed].instr+1;
- CLG_(current_state).cost[CLG_(sets).off_full_Ir] += instr_count;
+ CLG_(current_state).cost[ fullOffset(EG_IR) ] += instr_count;
}
}
void CLG_(print_eventset)(int s, EventSet* es)
{
- int i;
+ int i, j;
+ UInt mask;
+ EventGroup* eg;
- if (s<0) {
- s = -s;
- print_indent(s);
- }
+ if (s<0) {
+ s = -s;
+ print_indent(s);
+ }
- if (!es) {
- VG_(printf)("(EventSet not set)\n");
- return;
- }
+ if (!es) {
+ VG_(printf)("(EventSet not set)\n");
+ return;
+ }
- VG_(printf)("%5s (Size/Cap %d/%d): ",
- es->name, es->size, es->capacity);
-
- if (es->size == 0)
- VG_(printf)("-");
- else {
- for(i=0; i< es->size; i++) {
- if (i>0) {
- VG_(printf)(" ");
- if (es->e[i-1].nextTop == i)
- VG_(printf)("| ");
- }
- VG_(printf)("%s", es->e[i].type->name);
+ VG_(printf)("EventSet %d (%d groups, size %d):",
+ es->mask, es->count, es->size);
+
+ if (es->count == 0) {
+ VG_(printf)("-\n");
+ return;
}
- }
- VG_(printf)("\n");
+
+ for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
+ if ((es->mask & mask)==0) continue;
+ eg = CLG_(get_event_group)(i);
+ if (!eg) continue;
+ VG_(printf)(" (%d: %s", i, eg->name[0]);
+ for(j=1; j<eg->size; j++)
+ VG_(printf)(" %s", eg->name[j]);
+ VG_(printf)(")");
+ }
+ VG_(printf)("\n");
}
void CLG_(print_cost)(int s, EventSet* es, ULong* c)
{
- Int i, pos;
+ Int i, j, pos, off;
+ UInt mask;
+ EventGroup* eg;
if (s<0) {
s = -s;
return;
}
if (!c) {
- VG_(printf)("Cost (Null, EventSet %s)\n", es->name);
+ VG_(printf)("Cost (Null, EventSet %d)\n", es->mask);
return;
}
if (es->size == 0) {
- VG_(printf)("Cost (Nothing, EventSet %s with len 0)\n", es->name);
+ VG_(printf)("Cost (Nothing, EventSet with len 0)\n");
return;
}
pos = s;
- pos += VG_(printf)("Cost %s [%p]: %s %llu", es->name, c, es->e[0].type->name, c[0]);
-
- i = 1;
- while(i<es->size) {
- if (pos > 70) {
- VG_(printf)(",\n");
- print_indent(s+5);
- pos = s+5;
- }
- else
- pos += VG_(printf)(", ");
- pos += VG_(printf)("%s %llu", es->e[i].type->name, c[i]);
- i++;
+ pos += VG_(printf)("Cost [%p]: ", c);
+ off = 0;
+ for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
+ if ((es->mask & mask)==0) continue;
+ eg = CLG_(get_event_group)(i);
+ if (!eg) continue;
+ for(j=0; j<eg->size; j++) {
+
+ if (off>0) {
+ if (pos > 70) {
+ VG_(printf)(",\n");
+ print_indent(s+5);
+ pos = s+5;
+ }
+ else
+ pos += VG_(printf)(", ");
+ }
+
+ pos += VG_(printf)("%s %llu", eg->name[j], c[off++]);
+ }
}
VG_(printf)("\n");
}
void CLG_(print_short_jcc)(jCC* jcc)
{
if (jcc)
- VG_(printf)("%#lx => %#lx [%llu/%llu,%llu,%llu]",
+ VG_(printf)("%#lx => %#lx [calls %llu/Ir %llu, Dr %llu, Dw %llu]",
bb_jmpaddr(jcc->from->bb),
bb_addr(jcc->to->bb),
jcc->call_counter,
- jcc->cost ? jcc->cost[CLG_(sets).off_full_Ir]:0,
- jcc->cost ? jcc->cost[CLG_(sets).off_full_Dr]:0,
- jcc->cost ? jcc->cost[CLG_(sets).off_full_Dw]:0);
+ jcc->cost ? jcc->cost[fullOffset(EG_IR)]:0,
+ jcc->cost ? jcc->cost[fullOffset(EG_DR)]:0,
+ jcc->cost ? jcc->cost[fullOffset(EG_DW)]:0);
else
VG_(printf)("[Skipped JCC]");
}
#include "global.h"
-#define MAX_EVENTTYPE 20
+/* This should be 2**MAX_EVENTGROUP_COUNT */
+#define MAX_EVENTSET_COUNT 1024
-static EventType eventtype[MAX_EVENTTYPE];
-static Int eventtype_count = 0;
+static EventGroup* eventGroup[MAX_EVENTGROUP_COUNT];
+static EventSet* eventSetTable[MAX_EVENTSET_COUNT];
+static Bool eventSets_initialized = 0;
-EventType* CLG_(register_eventtype)(Char* name)
+static
+void initialize_event_sets(void)
{
- EventType* et;
+ Int i;
- if (eventtype_count == MAX_EVENTTYPE) {
- VG_(printf)("\nMore than %d event types used!\n"
- "Increase MAX_EVENTTYPE in ct_events.c and recomile this tool!\n",
- MAX_EVENTTYPE);
- VG_(tool_panic)("Too many event types requested.");
- }
+ if (eventSets_initialized) return;
- et = &(eventtype[eventtype_count]);
- et->id = eventtype_count;
- et->name = (UChar*) VG_(strdup)("cl.events.re.1", name);
- et->description = 0;
+ for(i=0; i< MAX_EVENTGROUP_COUNT; i++)
+ eventGroup[i] = 0;
- eventtype_count++;
-
- return et;
-}
+ for(i=0; i< MAX_EVENTSET_COUNT; i++)
+ eventSetTable[i] = 0;
+ eventSets_initialized = 1;
+ }
-EventType* CLG_(get_eventtype)(Char* name)
+static
+EventGroup* new_event_group(int id, int n)
{
- Int i;
+ EventGroup* eg;
+
+ initialize_event_sets();
- for(i=0;i<eventtype_count;i++)
- if (VG_(strcmp)(eventtype[i].name, name) == 0)
- return eventtype+i;
- return 0;
+ CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
+ CLG_ASSERT(eventGroup[id]==0);
+
+ eg = (EventGroup*) CLG_MALLOC("cl.events.group.1",
+ sizeof(EventGroup) + n * sizeof(Char*));
+ eg->size = n;
+ eventGroup[id] = eg;
+ return eg;
}
-EventType* CLG_(get_eventtype_byindex)(Int id)
+EventGroup* CLG_(register_event_group) (int id, Char* n1)
{
- if ((id >= 0) && (id < eventtype_count))
- return eventtype+id;
- return 0;
+ EventGroup* eg = new_event_group(id, 1);
+ eg->name[0] = n1;
+
+ return eg;
}
-/* Allocate space for an event set */
-EventSet* CLG_(get_eventset)(Char* n, Int capacity)
+EventGroup* CLG_(register_event_group2)(int id, Char* n1, Char* n2)
{
- EventSet* es;
+ EventGroup* eg = new_event_group(id, 2);
+ eg->name[0] = n1;
+ eg->name[1] = n2;
- es = (EventSet*) CLG_MALLOC("cl.events.geSet.1",
- sizeof(EventSet) +
- capacity * sizeof(EventSetEntry));
- es->capacity = capacity;
- es->size = 0;
- es->name = n;
-
- return es;
+ return eg;
}
-/* Incorporate a event type into a set, get start offset */
-Int CLG_(add_eventtype)(EventSet* es, EventType* t)
+EventGroup* CLG_(register_event_group3)(int id, Char* n1, Char* n2, Char* n3)
{
- Int offset = es->size;
- if (es->capacity - offset < 1) return -1;
-
- es->size++;
- es->e[offset].type = t;
- es->e[offset].nextTop = es->size;
+ EventGroup* eg = new_event_group(id, 3);
+ eg->name[0] = n1;
+ eg->name[1] = n2;
+ eg->name[2] = n3;
- return offset;
+ return eg;
}
-/* Incorporate one event set into another, get start offset */
-Int CLG_(add_eventset)(EventSet* dst, EventSet* src)
+EventGroup* CLG_(register_event_group4)(int id,
+ Char* n1, Char* n2, Char* n3, Char* n4)
{
- Int offset = dst->size, i;
- if (!src || (src->size == 0)) return offset;
+ EventGroup* eg = new_event_group(id, 4);
+ eg->name[0] = n1;
+ eg->name[1] = n2;
+ eg->name[2] = n3;
+ eg->name[3] = n4;
- if (dst->capacity - offset < src->size) return -1;
-
- for(i=0;i<src->size;i++) {
- dst->e[offset+i].type = src->e[i].type;
- dst->e[offset+i].nextTop = src->e[i].nextTop + offset;
- }
- dst->size += src->size;
+ return eg;
+}
- return offset;
+EventGroup* CLG_(get_event_group)(int id)
+{
+ CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
+
+ return eventGroup[id];
}
-/* Incorporate two event types into a set, with second < first */
-Int CLG_(add_dep_event2)(EventSet* es, EventType* e1, EventType* e2)
+
+static
+EventSet* eventset_from_mask(UInt mask)
{
- Int offset = es->size;
+ EventSet* es;
+ Int i, count, offset;
- if (es->capacity - offset < 2) return -1;
+ if (mask >= MAX_EVENTSET_COUNT) return 0;
- es->size += 2;
- es->e[offset].type = e1;
- es->e[offset].nextTop = es->size;
- es->e[offset+1].type = e2;
- es->e[offset+1].nextTop = es->size;
-
- return offset;
+ initialize_event_sets();
+ if (eventSetTable[mask]) return eventSetTable[mask];
+
+ es = (EventSet*) CLG_MALLOC("cl.events.eventset.1", sizeof(EventSet));
+ es->mask = mask;
+
+ offset = 0;
+ count = 0;
+ for(i=0;i<MAX_EVENTGROUP_COUNT;i++) {
+ es->offset[i] = offset;
+ if ( ((mask & (1u<<i))==0) || (eventGroup[i]==0))
+ continue;
+
+ offset += eventGroup[i]->size;
+ count++;
+ }
+ es->size = offset;
+ es->count = count;
+
+ eventSetTable[mask] = es;
+ return es;
}
-/* Incorporate 3 event types into a set, with third < second < first */
-Int CLG_(add_dep_event3)(EventSet* es,
- EventType* e1, EventType* e2, EventType* e3)
+EventSet* CLG_(get_event_set)(Int id)
{
- Int offset = es->size;
+ CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
+ return eventset_from_mask(1u << id);
+}
- if (es->capacity - offset < 3) return -1;
+EventSet* CLG_(get_event_set2)(Int id1, Int id2)
+{
+ CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
+ CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
+ return eventset_from_mask((1u << id1) | (1u << id2));
+}
- es->size += 3;
- es->e[offset].type = e1;
- es->e[offset].nextTop = es->size;
- es->e[offset+1].type = e2;
- es->e[offset+1].nextTop = es->size;
- es->e[offset+2].type = e3;
- es->e[offset+2].nextTop = es->size;
-
- return offset;
+EventSet* CLG_(get_event_set3)(Int id1, Int id2, Int id3)
+{
+ CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
+ CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
+ CLG_ASSERT(id3>=0 && id3<MAX_EVENTGROUP_COUNT);
+ return eventset_from_mask((1u << id1) | (1u << id2) | (1u << id3));
}
-Int CLG_(add_dep_event4)(EventSet* es,
- EventType* e1, EventType* e2,
- EventType* e3, EventType* e4)
+EventSet* CLG_(add_event_group)(EventSet* es, Int id)
{
- Int offset = es->size;
+ CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
+ if (!es) es = eventset_from_mask(0);
+ return eventset_from_mask(es->mask | (1u << id));
+}
- if (es->capacity - offset < 4) return -1;
+EventSet* CLG_(add_event_group2)(EventSet* es, Int id1, Int id2)
+{
+ CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
+ CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
+ if (!es) es = eventset_from_mask(0);
+ return eventset_from_mask(es->mask | (1u << id1) | (1u << id2));
+}
- es->size += 4;
- es->e[offset].type = e1;
- es->e[offset].nextTop = es->size;
- es->e[offset+1].type = e2;
- es->e[offset+1].nextTop = es->size;
- es->e[offset+2].type = e3;
- es->e[offset+2].nextTop = es->size;
- es->e[offset+3].type = e4;
- es->e[offset+3].nextTop = es->size;
-
- return offset;
+EventSet* CLG_(add_event_set)(EventSet* es1, EventSet* es2)
+{
+ if (!es1) es1 = eventset_from_mask(0);
+ if (!es2) es2 = eventset_from_mask(0);
+ return eventset_from_mask(es1->mask | es2->mask);
}
-/* Returns number of characters written */
Int CLG_(sprint_eventset)(Char* buf, EventSet* es)
{
- Int i, pos = 0;
-
- for(i=0; i< es->size; i++) {
- if (pos>0) buf[pos++] = ' ';
- pos += VG_(sprintf)(buf + pos, "%s", es->e[i].type->name);
- }
- buf[pos] = 0;
+ Int i, j, pos;
+ UInt mask;
+ EventGroup* eg;
+
+
+ CLG_ASSERT(es->size >0);
+ pos = 0;
+ for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
+ if ((es->mask & mask)==0) continue;
+ if (eventGroup[i] ==0) continue;
+
+ eg = eventGroup[i];
+ for(j=0; j<eg->size; j++) {
+ if (pos>0) buf[pos++] = ' ';
+ pos += VG_(sprintf)(buf + pos, "%s", eg->name[j]);
+ }
+ }
+ buf[pos] = 0;
- return pos;
+ return pos;
}
+
/* Get cost array for an event set */
ULong* CLG_(get_eventset_cost)(EventSet* es)
{
- return CLG_(get_costarray)(es->capacity);
+ return CLG_(get_costarray)(es->size);
}
/* Set all costs of an event set to zero */
void CLG_(init_cost)(EventSet* es, ULong* cost)
{
- Int i;
+ Int i;
- if (!cost) return;
+ if (!cost) return;
- for(i=0;i<es->capacity;i++)
- cost[i] = 0;
+ for(i=0; i<es->size; i++)
+ cost[i] = 0;
}
/* Set all costs of an event set to zero */
void CLG_(init_cost_lz)(EventSet* es, ULong** cost)
{
- Int i;
+ Int i;
- CLG_ASSERT(cost != 0);
- if (!(*cost))
- *cost = CLG_(get_eventset_cost)(es);
+ CLG_ASSERT(cost != 0);
+ if (!(*cost))
+ *cost = CLG_(get_eventset_cost)(es);
- for(i=0;i<es->capacity;i++)
- (*cost)[i] = 0;
+ for(i=0; i<es->size; i++)
+ (*cost)[i] = 0;
}
void CLG_(zero_cost)(EventSet* es, ULong* cost)
{
- Int i;
+ Int i;
- if (!cost) return;
+ if (!cost) return;
- for(i=0;i<es->size;i++)
- cost[i] = 0;
+ for(i=0;i<es->size;i++)
+ cost[i] = 0;
}
Bool CLG_(is_zero_cost)(EventSet* es, ULong* cost)
{
- Int i = 0;
+ Int i;
- if (!cost) return True;
+ if (!cost) return True;
- while(i<es->size) {
- if (cost[i] != 0) return False;
- i = es->e[i].nextTop;
- }
- return True;
+ for(i=0; i<es->size; i++)
+ if (cost[i] != 0) return False;
+
+ return True;
}
Bool CLG_(is_equal_cost)(EventSet* es, ULong* c1, ULong* c2)
{
- Int i = 0;
+ Int i;
- if (!c1) return CLG_(is_zero_cost)(es,c2);
- if (!c2) return CLG_(is_zero_cost)(es,c1);
+ if (!c1) return CLG_(is_zero_cost)(es, c2);
+ if (!c2) return CLG_(is_zero_cost)(es, c1);
- while(i<es->size) {
- if (c1[i] != c2[i]) return False;
- if (c1[i] == 0)
- i = es->e[i].nextTop;
- else
- i++;
- }
- return True;
+ for(i=0; i<es->size; i++)
+ if (c1[i] != c2[i]) return False;
+
+ return True;
}
void CLG_(copy_cost)(EventSet* es, ULong* dst, ULong* src)
{
- Int i;
+ Int i;
- if (!src) {
- CLG_(zero_cost)(es, dst);
- return;
- }
- CLG_ASSERT(dst != 0);
+ if (!src) {
+ CLG_(zero_cost)(es, dst);
+ return;
+ }
+ CLG_ASSERT(dst != 0);
- for(i=0;i<es->size;i++)
- dst[i] = src[i];
+ for(i=0;i<es->size;i++)
+ dst[i] = src[i];
}
void CLG_(copy_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
{
- Int i;
- ULong* dst;
+ Int i;
+ ULong* dst;
- CLG_ASSERT(pdst != 0);
+ CLG_ASSERT(pdst != 0);
- if (!src) {
- CLG_(zero_cost)(es, *pdst);
- return;
- }
- dst = *pdst;
- if (!dst)
- dst = *pdst = CLG_(get_eventset_cost)(es);
+ if (!src) {
+ CLG_(zero_cost)(es, *pdst);
+ return;
+ }
+ dst = *pdst;
+ if (!dst)
+ dst = *pdst = CLG_(get_eventset_cost)(es);
- for(i=0;i<es->size;i++)
- dst[i] = src[i];
+ for(i=0;i<es->size;i++)
+ dst[i] = src[i];
}
void CLG_(add_cost)(EventSet* es, ULong* dst, ULong* src)
{
- Int i = 0;
+ Int i;
- if (!src) return;
- CLG_ASSERT(dst != 0);
+ if (!src) return;
+ CLG_ASSERT(dst != 0);
- while(i<es->size) {
- if (src[i] == 0)
- i = es->e[i].nextTop;
- else {
- dst[i] += src[i];
- i++;
- }
- }
+ for(i=0; i<es->size; i++)
+ dst[i] += src[i];
}
void CLG_(add_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
{
- Int i;
- ULong* dst;
-
- if (!src) return;
- CLG_ASSERT(pdst != 0);
-
- dst = *pdst;
- if (!dst) {
- dst = *pdst = CLG_(get_eventset_cost)(es);
- CLG_(copy_cost)(es,dst,src);
- return;
- }
-
- i = 0;
- while(i<es->size) {
- if (src[i] == 0)
- i = es->e[i].nextTop;
- else {
- dst[i] += src[i];
- i++;
+ Int i;
+ ULong* dst;
+
+ if (!src) return;
+ CLG_ASSERT(pdst != 0);
+
+ dst = *pdst;
+ if (!dst) {
+ dst = *pdst = CLG_(get_eventset_cost)(es);
+ CLG_(copy_cost)(es, dst, src);
+ return;
}
- }
+
+ for(i=0; i<es->size; i++)
+ dst[i] += src[i];
}
/* Adds src to dst and zeros src. Returns false if nothing changed */
Bool CLG_(add_and_zero_cost)(EventSet* es, ULong* dst, ULong* src)
{
- Int i = 0, j = 0;
-
- CLG_DEBUGIF(6) {
- CLG_DEBUG(6, " add_and_zero_cost(%s, dst %p, src %p)\n", es->name, dst, src);
- CLG_(print_cost)(-5, es, src);
- }
+ Int i;
+ Bool is_nonzero = False;
- if (!es || !src) return False;
+ CLG_ASSERT((es != 0) && (dst != 0));
+ if (!src) return False;
- while(i<es->size) {
- if (src[i] == 0)
- i = es->e[i].nextTop;
- else {
- dst[i] += src[i];
- src[i] = 0;
- i++;
- j++;
+ for(i=0; i<es->size; i++) {
+ if (src[i]==0) continue;
+ dst[i] += src[i];
+ src[i] = 0;
+ is_nonzero = True;
}
- }
- return (j>0);
+ return is_nonzero;
}
/* Adds src to dst and zeros src. Returns false if nothing changed */
-Bool CLG_(add_and_zero_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
-{
- Int i;
- ULong* dst;
-
- if (!src) return False;
-
- i = 0;
- while(1) {
- if (i >= es->size) return False;
- if (src[i] != 0) break;
- i = es->e[i].nextTop;
- }
-
- CLG_ASSERT(pdst != 0);
- dst = *pdst;
- if (!dst) {
- dst = *pdst = CLG_(get_eventset_cost)(es);
- CLG_(copy_cost)(es,dst,src);
- CLG_(zero_cost)(es,src);
- return True;
- }
-
- dst[i] += src[i];
- src[i] = 0;
- i++;
-
- while(i<es->size) {
- if (src[i] == 0)
- i = es->e[i].nextTop;
- else {
- dst[i] += src[i];
- src[i] = 0;
+Bool CLG_(add_and_zero_cost2)(EventSet* esDst, ULong* dst,
+ EventSet* esSrc, ULong* src)
+{
+ Int i,j;
+ Bool is_nonzero = False;
+ UInt mask;
+ EventGroup *eg;
+ ULong *egDst, *egSrc;
+
+ CLG_ASSERT((esDst != 0) && (dst != 0) && (esSrc != 0));
+ if (!src) return False;
+
+ for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
+ if ((esSrc->mask & mask)==0) continue;
+ if (eventGroup[i] ==0) continue;
+
+ /* if src has a subset, dst must have, too */
+ CLG_ASSERT((esDst->mask & mask)>0);
+ eg = eventGroup[i];
+ egSrc = src + esSrc->offset[i];
+ egDst = dst + esDst->offset[i];
+ for(j=0; j<eg->size; j++) {
+ if (egSrc[j]==0) continue;
+ egDst[j] += egSrc[j];
+ egSrc[j] = 0;
+ is_nonzero = True;
+ }
}
- }
- return True;
+ return is_nonzero;
}
+
+
/* Adds difference of new and old to dst, and set old to new.
* Returns false if nothing changed */
Bool CLG_(add_diff_cost)(EventSet* es, ULong* dst, ULong* old, ULong* new_cost)
{
- Int i = 0, j = 0;
+ Int i;
+ Bool is_nonzero = False;
- while(i<es->size) {
- if (new_cost[i] == old[i])
- i = es->e[i].nextTop;
- else {
- dst[i] += new_cost[i] - old[i];
- old[i] = new_cost[i];
- i++;
- j++;
+ CLG_ASSERT((es != 0) && (dst != 0));
+ CLG_ASSERT(old && new_cost);
+
+ for(i=0; i<es->size; i++) {
+ if (new_cost[i] == old[i]) continue;
+ dst[i] += new_cost[i] - old[i];
+ old[i] = new_cost[i];
+ is_nonzero = True;
}
- }
- return (j>0);
+ return is_nonzero;
}
-/* Adds difference of new and old to dst, and set old to new.
- * Returns false if nothing changed */
-Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst,
- ULong* old, ULong* new_cost)
-{
- Int i;
- ULong* dst;
-
- if (!old && !new_cost) return False;
- CLG_ASSERT(old && new_cost);
-
- i = 0;
- while(1) {
- if (i >= es->size) return False;
- if (old[i] != new_cost[i]) break;
- i = es->e[i].nextTop;
- }
-
- CLG_ASSERT(pdst != 0);
- dst = *pdst;
- if (!dst) {
- dst = *pdst = CLG_(get_eventset_cost)(es);
- CLG_(zero_cost)(es,dst);
- }
-
- dst[i] += new_cost[i] - old[i];
- old[i] = new_cost[i];
- i++;
-
- while(i<es->size) {
- if (new_cost[i] == old[i])
- i = es->e[i].nextTop;
- else {
- dst[i] += new_cost[i] - old[i];
- old[i] = new_cost[i];
- i++;
+Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst, ULong* old, ULong* new_cost)
+{
+ Int i;
+ ULong* dst;
+ Bool is_nonzero = False;
+
+ CLG_ASSERT((es != 0) && (pdst != 0));
+ CLG_ASSERT(old && new_cost);
+
+ dst = *pdst;
+ if (!dst) {
+ dst = *pdst = CLG_(get_eventset_cost)(es);
+ CLG_(zero_cost)(es, dst);
}
- }
- return True;
+ for(i=0; i<es->size; i++) {
+ if (new_cost[i] == old[i]) continue;
+ dst[i] += new_cost[i] - old[i];
+ old[i] = new_cost[i];
+ is_nonzero = True;
+ }
+
+ return is_nonzero;
}
+
/* Returns number of characters written */
Int CLG_(sprint_cost)(Char* buf, EventSet* es, ULong* c)
{
- Int i, pos, skipped = 0;
+ Int i, pos, skipped = 0;
- if (!c || es->size==0) return 0;
+ if (!c || es->size==0) return 0;
- /* At least one entry */
- pos = VG_(sprintf)(buf, "%llu", c[0]);
- i = 1;
-
- while(i<es->size) {
- if (c[i] == 0) {
- skipped += es->e[i].nextTop - i;
- i = es->e[i].nextTop;
- }
- else {
- while(skipped>0) {
+ /* At least one entry */
+ pos = VG_(sprintf)(buf, "%llu", c[0]);
+ for(i=1; i<es->size; i++) {
+ if (c[i] == 0) {
+ skipped++;
+ continue;
+ }
+ while(skipped>0) {
+ buf[pos++] = ' ';
+ buf[pos++] = '0';
+ skipped--;
+ }
buf[pos++] = ' ';
- buf[pos++] = '0';
- skipped--;
- }
- buf[pos++] = ' ';
- pos += VG_(sprintf)(buf+pos, "%llu", c[i]);
- i++;
+ pos += VG_(sprintf)(buf+pos, "%llu", c[i]);
}
- }
- return pos;
+ return pos;
}
/* Allocate space for an event mapping */
EventMapping* CLG_(get_eventmapping)(EventSet* es)
{
- EventMapping* em;
+ EventMapping* em;
- CLG_ASSERT(es != 0);
+ CLG_ASSERT(es != 0);
- em = (EventMapping*) CLG_MALLOC("cl.events.geMapping.1",
- sizeof(EventMapping) +
- es->capacity * sizeof(Int));
- em->capacity = es->capacity;
- em->size = 0;
- em->set = es;
+ em = (EventMapping*) CLG_MALLOC("cl.events.geMapping.1",
+ sizeof(EventMapping) +
+ sizeof(struct EventMappingEntry) *
+ es->size);
+ em->capacity = es->size;
+ em->size = 0;
+ em->es = es;
- return em;
+ return em;
}
void CLG_(append_event)(EventMapping* em, Char* n)
{
- Int i;
-
- CLG_ASSERT(em != 0);
-
- for(i=0; i<em->set->size; i++)
- if (VG_(strcmp)(n, em->set->e[i].type->name)==0)
- break;
-
- if (i == em->set->size) return;
-
- CLG_ASSERT(em->capacity > em->size);
-
- em->index[em->size] = i;
- em->size++;
+ Int i, j, offset = 0;
+ UInt mask;
+ EventGroup* eg;
+
+ CLG_ASSERT(em != 0);
+ for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
+ if ((em->es->mask & mask)==0) continue;
+ if (eventGroup[i] ==0) continue;
+
+ eg = eventGroup[i];
+ for(j=0; j<eg->size; j++, offset++) {
+ if (VG_(strcmp)(n, eg->name[j])!=0)
+ continue;
+
+ CLG_ASSERT(em->capacity > em->size);
+ em->entry[em->size].group = i;
+ em->entry[em->size].index = j;
+ em->entry[em->size].offset = offset;
+ em->size++;
+ return;
+ }
+ }
}
/* Returns number of characters written */
Int CLG_(sprint_eventmapping)(Char* buf, EventMapping* em)
{
- Int i, pos = 0;
+ Int i, pos = 0;
+ EventGroup* eg;
- CLG_ASSERT(em != 0);
+ CLG_ASSERT(em != 0);
- for(i=0; i< em->size; i++) {
- if (pos>0) buf[pos++] = ' ';
- pos += VG_(sprintf)(buf + pos, "%s", em->set->e[em->index[i]].type->name);
- }
- buf[pos] = 0;
+ for(i=0; i< em->size; i++) {
+ if (pos>0) buf[pos++] = ' ';
+ eg = eventGroup[em->entry[i].group];
+ CLG_ASSERT(eg != 0);
+ pos += VG_(sprintf)(buf + pos, "%s", eg->name[em->entry[i].index]);
+ }
+ buf[pos] = 0;
- return pos;
+ return pos;
}
/* Returns number of characters written */
Int CLG_(sprint_mappingcost)(Char* buf, EventMapping* em, ULong* c)
{
- Int i, pos, skipped = 0;
+ Int i, pos, skipped = 0;
- if (!c || em->size==0) return 0;
+ if (!c || em->size==0) return 0;
/* At least one entry */
- pos = VG_(sprintf)(buf, "%llu", c[em->index[0]]);
- i = 1;
-
- while(i<em->size) {
- if (c[em->index[i]] == 0) {
- skipped++;
- i++;
- }
- else {
- while(skipped>0) {
+ pos = VG_(sprintf)(buf, "%llu", c[em->entry[0].offset]);
+
+ for(i=1; i<em->size; i++) {
+ if (c[em->entry[i].offset] == 0) {
+ skipped++;
+ continue;
+ }
+ while(skipped>0) {
+ buf[pos++] = ' ';
+ buf[pos++] = '0';
+ skipped--;
+ }
buf[pos++] = ' ';
- buf[pos++] = '0';
- skipped--;
- }
- buf[pos++] = ' ';
- pos += VG_(sprintf)(buf+pos, "%llu", c[em->index[i]]);
- i++;
+ pos += VG_(sprintf)(buf+pos, "%llu", c[em->entry[i].offset]);
}
- }
- return pos;
+ return pos;
}
/*--------------------------------------------------------------------*/
/*--- Callgrind ---*/
/*--- events.h ---*/
-/*--- (C) 2004-2005, Josef Weidendorfer ---*/
/*--------------------------------------------------------------------*/
+/*
+ This file is part of Callgrind, a Valgrind tool for call tracing.
+
+ Copyright (C) 2002-2010, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
/* Abstractions for 64-bit cost lists (events.h) */
-#ifndef CG_EVENTS
-#define CG_EVENTS
+#ifndef CLG_EVENTS
+#define CLG_EVENTS
#include "pub_tool_basics.h"
#define CLG_(str) VGAPPEND(vgCallgrind_,str)
-/* An event type */
-typedef struct _EventType EventType;
-struct _EventType {
- Char* name;
- Char* description;
- Int id;
-};
+/* Event groups consist of one or more named event types.
+ * Event sets are constructed from such event groups.
+ *
+ * Event groups have to be registered globally with a unique ID
+ * before they can be used in an event set.
+ * A group can appear at most once in a event set.
+ */
-EventType* CLG_(register_eventtype)(Char*);
-EventType* CLG_(get_eventtype)(Char*);
-EventType* CLG_(get_eventtype_byindex)(Int id);
+#define MAX_EVENTGROUP_COUNT 10
-/* An event set is a ordered list of event types, which comes down
- * to some description for ordered lists of costs.
- * Often, costs of 2 event types are related, e.g. one is always smaller
- * than the other. This is useful to speed up arithmetics on cost lists:
- * Each event type in the set has a <nextTop>. All indexes before are
- * promised to hold smaller values than the current.
- */
-typedef struct _EventSetEntry EventSetEntry;
-struct _EventSetEntry {
- EventType* type;
- Int nextTop;
-};
-typedef struct _EventSet EventSet;
-struct _EventSet {
- Char* name;
- Int size;
- Int capacity;
- EventSetEntry e[0];
+typedef struct _EventGroup EventGroup;
+struct _EventGroup {
+ Int size;
+ Char* name[0];
};
+/* return 0 if event group can not be registered */
+EventGroup* CLG_(register_event_group) (int id, Char*);
+EventGroup* CLG_(register_event_group2)(int id, Char*, Char*);
+EventGroup* CLG_(register_event_group3)(int id, Char*, Char*, Char*);
+EventGroup* CLG_(register_event_group4)(int id, Char*, Char*, Char*, Char*);
+EventGroup* CLG_(get_event_group)(int id);
-/* Some events out of an event set.
- * Used to print out part of an EventSet, or in another order.
- */
-typedef struct _EventMapping EventMapping;
-struct _EventMapping {
- EventSet* set;
- Int size;
- Int capacity;
- Int index[0];
-};
+/* Event sets are defined by event groups they consist of. */
-
-/* Allocate space for an event set */
-EventSet* CLG_(get_eventset)(Char* n, Int capacity);
-/* Incorporate a event type into a set, get start offset */
-Int CLG_(add_eventtype)(EventSet* dst, EventType*);
-/* Incorporate event types into a set, with ... < second < first */
-Int CLG_(add_dep_event2)(EventSet* dst, EventType* e1, EventType* e2);
-Int CLG_(add_dep_event3)(EventSet* dst,
- EventType* e1, EventType* e2, EventType* e3);
-Int CLG_(add_dep_event4)(EventSet* dst,
- EventType* e1, EventType* e2, EventType* e3,
- EventType* e4);
-/* Incorporate one event set into another, get start offset */
-Int CLG_(add_eventset)(EventSet* dst, EventSet* src);
-/* Returns number of characters written */
+typedef struct _EventSet EventSet;
+struct _EventSet {
+ /* if subset with ID x is in the set, then bit x is set */
+ UInt mask;
+ Int count;
+ Int size;
+ Int offset[MAX_EVENTGROUP_COUNT];
+ };
+
+/* Same event set is returned when requesting same event groups */
+EventSet* CLG_(get_event_set)(Int id);
+EventSet* CLG_(get_event_set2)(Int id1, Int id2);
+EventSet* CLG_(get_event_set3)(Int id1, Int id2, Int id3);
+EventSet* CLG_(add_event_group)(EventSet*, Int id);
+EventSet* CLG_(add_event_group2)(EventSet*, Int id1, Int id2);
+EventSet* CLG_(add_event_set)(EventSet*, EventSet*);
+/* Writes event names into buf. Returns number of characters written */
Int CLG_(sprint_eventset)(Char* buf, EventSet*);
-/* Allocate cost array for an event set */
-ULong* CLG_(get_eventset_cost)(EventSet*);
+
/* Operations on costs. A cost pointer of 0 means zero cost.
- * Functions ending in _lz allocate costs lazy if needed
+ * Functions ending in _lz allocate cost arrays only when needed
*/
-/* Set costs according full capacity of event set to 0 */
+ULong* CLG_(get_eventset_cost)(EventSet*);
+/* Set costs of event set to 0 */
void CLG_(init_cost)(EventSet*,ULong*);
/* This always allocates counter and sets them to 0 */
void CLG_(init_cost_lz)(EventSet*,ULong**);
void CLG_(add_cost_lz)(EventSet*,ULong** pdst, ULong* src);
/* Adds src to dst and zeros src. Returns false if nothing changed */
Bool CLG_(add_and_zero_cost)(EventSet*,ULong* dst, ULong* src);
-Bool CLG_(add_and_zero_cost_lz)(EventSet*,ULong** pdst, ULong* src);
+Bool CLG_(add_and_zero_cost2)(EventSet*,ULong* dst,EventSet*,ULong* src);
/* Adds difference of new and old to to dst, and set old to new.
* Returns false if nothing changed */
Bool CLG_(add_diff_cost)(EventSet*,ULong* dst, ULong* old, ULong* new_cost);
/* Returns number of characters written */
Int CLG_(sprint_cost)(Char* buf, EventSet*, ULong*);
+/* EventMapping: An ordered subset of events from an event set.
+ * This is used to print out part of an EventSet, or in another order.
+ */
+struct EventMappingEntry {
+ Int group;
+ Int index;
+ Int offset;
+};
+typedef struct _EventMapping EventMapping;
+struct _EventMapping {
+ EventSet* es;
+ Int size;
+ Int capacity;
+ struct EventMappingEntry entry[0];
+};
+
/* Allocate space for an event mapping */
EventMapping* CLG_(get_eventmapping)(EventSet*);
void CLG_(append_event)(EventMapping*, Char*);
/* Returns number of characters written */
Int CLG_(sprint_mappingcost)(Char* buf, EventMapping*, ULong*);
-#endif /* CG_EVENTS */
+#endif /* CLG_EVENTS */
Char *log_0I1Dr_name, *log_0I1Dw_name;
};
+// Event groups
+#define EG_USE 0
+#define EG_IR 1
+#define EG_DR 2
+#define EG_DW 3
+#define EG_ALLOC 4
+#define EG_SYS 5
+
+struct event_sets {
+ EventSet *base, *full;
+};
+extern struct event_sets CLG_(sets);
+
+#define fullOffset(group) (CLG_(sets).full->offset[group])
+
/*------------------------------------------------------------*/
/*--- Functions ---*/
void CLG_(print_debug_usage)(void);
/* from sim.c */
-struct event_sets {
- EventSet *Use, *Ir, *Dr, *Dw;
- EventSet *UIr, *UIrDr, *UIrDrDw, *UIrDw, *UIrDwDr;
- EventSet *full;
-
- /* offsets into eventsets */
- Int off_full_Ir, off_full_Dr, off_full_Dw;
- Int off_full_alloc, off_full_systime;
-};
-
-extern struct event_sets CLG_(sets);
extern struct cachesim_if CLG_(cachesim);
-
-void CLG_(init_eventsets)(Int user);
+void CLG_(init_eventsets)(void);
/* from main.c */
Bool CLG_(get_debug_info)(Addr, Char filename[FILENAME_LEN],
case Ev_Ir:
// Ir event always is first for a guest instruction
CLG_ASSERT(ev->inode->eventset == 0);
- ev->inode->eventset = CLG_(sets).UIr;
+ ev->inode->eventset = CLG_(sets).base;
break;
case Ev_Dr:
// extend event set by Dr counter
- if ((ev->inode->eventset == CLG_(sets).UIrDr) ||
- (ev->inode->eventset == CLG_(sets).UIrDrDw) ||
- (ev->inode->eventset == CLG_(sets).UIrDwDr))
- break;
- if (ev->inode->eventset == CLG_(sets).UIrDw) {
- ev->inode->eventset = CLG_(sets).UIrDwDr;
- break;
- }
- CLG_ASSERT(ev->inode->eventset == CLG_(sets).UIr);
- ev->inode->eventset = CLG_(sets).UIrDr;
+ ev->inode->eventset = CLG_(add_event_group)(ev->inode->eventset,
+ EG_DR);
break;
case Ev_Dw:
case Ev_Dm:
// extend event set by Dw counter
- if ((ev->inode->eventset == CLG_(sets).UIrDw) ||
- (ev->inode->eventset == CLG_(sets).UIrDwDr) ||
- (ev->inode->eventset == CLG_(sets).UIrDrDw))
- break;
- if (ev->inode->eventset == CLG_(sets).UIrDr) {
- ev->inode->eventset = CLG_(sets).UIrDrDw;
- break;
- }
- CLG_ASSERT(ev->inode->eventset == CLG_(sets).UIr);
- ev->inode->eventset = CLG_(sets).UIrDw;
+ ev->inode->eventset = CLG_(add_event_group)(ev->inode->eventset,
+ EG_DW);
break;
default:
tl_assert(0);
{
if (CLG_(clo).collect_systime &&
CLG_(current_state).bbcc) {
- Int o = CLG_(sets).off_full_systime;
+ Int o;
#if CLG_MICROSYSTIME
struct vki_timeval tv_now;
ULong diff;
#else
UInt diff = VG_(read_millisecond_timer)() - syscalltime[tid];
#endif
-
+
+ /* offset o is for "SysCount", o+1 for "SysTime" */
+ o = fullOffset(EG_SYS);
+ CLG_ASSERT(o>=0);
CLG_DEBUG(0," Time (Off %d) for Syscall %d: %ull\n", o, syscallno, diff);
- if (o<0) return;
-
CLG_(current_state).cost[o] ++;
CLG_(current_state).cost[o+1] += diff;
if (!CLG_(current_state).bbcc->skipped)
(*CLG_(cachesim).post_clo_init)();
- CLG_(init_eventsets)(0);
+ CLG_(init_eventsets)();
CLG_(init_statistics)(& CLG_(stat));
CLG_(init_cost_lz)( CLG_(sets).full, &CLG_(total_cost) );
-
/*--------------------------------------------------------------------*/
/*--- Cache simulation. ---*/
/*--- sim.c ---*/
This file is part of Callgrind, a Valgrind tool for call graph
profiling programs.
- Copyright (C) 2003-2005, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
+ Copyright (C) 2003-2010, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
This tool is derived from and contains code from Cachegrind
Copyright (C) 2002-2010 Nicholas Nethercote (njn@valgrind.org)
* - BBCC* nonskipped (only != 0 when in a function not skipped)
*/
-/* Offset to events in event set, used in log_* functions
- * <off_EventSet_BasicEventSet>: offset where basic set is found
- */
-static Int off_UIr_Ir;
-static Int off_UIrDr_Ir, off_UIrDr_Dr;
-static Int off_UIrDrDw_Ir, off_UIrDrDw_Dr, off_UIrDrDw_Dw;
-static Int off_UIrDw_Ir, off_UIrDw_Dw;
-static Int off_UIrDwDr_Ir, off_UIrDwDr_Dr, off_UIrDwDr_Dw;
-
static Addr bb_base;
static ULong* cost_base;
static InstrInfo* current_ii;
ULong* cost_Ir;
if (CLG_(current_state).nonskipped)
- cost_Ir = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Ir;
+ cost_Ir = CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR);
else
- cost_Ir = cost_base + ii->cost_offset + off_UIr_Ir;
+ cost_Ir = cost_base + ii->cost_offset + ii->eventset->offset[EG_IR];
inc_costs(IrRes, cost_Ir,
- CLG_(current_state).cost + CLG_(sets).off_full_Ir );
+ CLG_(current_state).cost + fullOffset(EG_IR) );
}
}
if (!CLG_(current_state).collect) return;
- global_cost_Ir = CLG_(current_state).cost + CLG_(sets).off_full_Ir;
+ global_cost_Ir = CLG_(current_state).cost + fullOffset(EG_IR);
if (CLG_(current_state).nonskipped) {
- ULong* skipped_cost_Ir = CLG_(current_state).nonskipped->skipped +
- CLG_(sets).off_full_Ir;
+ ULong* skipped_cost_Ir =
+ CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR);
+
inc_costs(Ir1Res, global_cost_Ir, skipped_cost_Ir);
inc_costs(Ir2Res, global_cost_Ir, skipped_cost_Ir);
return;
}
- inc_costs(Ir1Res, global_cost_Ir, cost_base + ii1->cost_offset + off_UIr_Ir);
- inc_costs(Ir2Res, global_cost_Ir, cost_base + ii2->cost_offset + off_UIr_Ir);
+ inc_costs(Ir1Res, global_cost_Ir,
+ cost_base + ii1->cost_offset + ii1->eventset->offset[EG_IR]);
+ inc_costs(Ir2Res, global_cost_Ir,
+ cost_base + ii2->cost_offset + ii2->eventset->offset[EG_IR]);
}
VG_REGPARM(3)
if (!CLG_(current_state).collect) return;
- global_cost_Ir = CLG_(current_state).cost + CLG_(sets).off_full_Ir;
+ global_cost_Ir = CLG_(current_state).cost + fullOffset(EG_IR);
if (CLG_(current_state).nonskipped) {
- ULong* skipped_cost_Ir = CLG_(current_state).nonskipped->skipped +
- CLG_(sets).off_full_Ir;
+ ULong* skipped_cost_Ir =
+ CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR);
inc_costs(Ir1Res, global_cost_Ir, skipped_cost_Ir);
inc_costs(Ir2Res, global_cost_Ir, skipped_cost_Ir);
inc_costs(Ir3Res, global_cost_Ir, skipped_cost_Ir);
return;
}
- inc_costs(Ir1Res, global_cost_Ir, cost_base + ii1->cost_offset + off_UIr_Ir);
- inc_costs(Ir2Res, global_cost_Ir, cost_base + ii2->cost_offset + off_UIr_Ir);
- inc_costs(Ir3Res, global_cost_Ir, cost_base + ii3->cost_offset + off_UIr_Ir);
+ inc_costs(Ir1Res, global_cost_Ir,
+ cost_base + ii1->cost_offset + ii1->eventset->offset[EG_IR]);
+ inc_costs(Ir2Res, global_cost_Ir,
+ cost_base + ii2->cost_offset + ii2->eventset->offset[EG_IR]);
+ inc_costs(Ir3Res, global_cost_Ir,
+ cost_base + ii3->cost_offset + ii3->eventset->offset[EG_IR]);
}
/* Instruction doing a read access */
ULong *cost_Ir, *cost_Dr;
if (CLG_(current_state).nonskipped) {
- cost_Ir = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Ir;
- cost_Dr = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Dr;
+ cost_Ir = CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR);
+ cost_Dr = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DR);
}
else {
- // event set must be UIrDr or extension
- CLG_ASSERT((ii->eventset == CLG_(sets).UIrDr) ||
- (ii->eventset == CLG_(sets).UIrDrDw));
- cost_Ir = cost_base + ii->cost_offset + off_UIrDr_Ir;
- cost_Dr = cost_base + ii->cost_offset + off_UIrDr_Dr;
+ cost_Ir = cost_base + ii->cost_offset + ii->eventset->offset[EG_IR];
+ cost_Dr = cost_base + ii->cost_offset + ii->eventset->offset[EG_DR];
}
inc_costs(IrRes, cost_Ir,
- CLG_(current_state).cost + CLG_(sets).off_full_Ir );
+ CLG_(current_state).cost + fullOffset(EG_IR) );
inc_costs(DrRes, cost_Dr,
- CLG_(current_state).cost + CLG_(sets).off_full_Dr );
+ CLG_(current_state).cost + fullOffset(EG_DR) );
}
}
if (CLG_(current_state).collect) {
ULong *cost_Dr;
- if (CLG_(current_state).nonskipped) {
- cost_Dr = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Dr;
- }
- else {
- Int off_Dr;
- if (ii->eventset == CLG_(sets).UIrDr) off_Dr = off_UIrDr_Dr;
- else if (ii->eventset == CLG_(sets).UIrDrDw) off_Dr = off_UIrDrDw_Dr;
- else if (ii->eventset == CLG_(sets).UIrDwDr) off_Dr = off_UIrDwDr_Dr;
- else CLG_ASSERT(0);
-
- cost_Dr = cost_base + ii->cost_offset + off_Dr;
- }
+ if (CLG_(current_state).nonskipped)
+ cost_Dr = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DR);
+ else
+ cost_Dr = cost_base + ii->cost_offset + ii->eventset->offset[EG_DR];
inc_costs(DrRes, cost_Dr,
- CLG_(current_state).cost + CLG_(sets).off_full_Dr );
+ CLG_(current_state).cost + fullOffset(EG_DR) );
}
}
ULong *cost_Ir, *cost_Dw;
if (CLG_(current_state).nonskipped) {
- cost_Ir = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Ir;
- cost_Dw = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Dw;
+ cost_Ir = CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR);
+ cost_Dw = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DW);
}
else {
- // This helper is called when a Dr event follows Ir;
- // Event set must be UIrDw or extension
- CLG_ASSERT((ii->eventset == CLG_(sets).UIrDw) ||
- (ii->eventset == CLG_(sets).UIrDwDr));
- cost_Ir = cost_base + ii->cost_offset + off_UIrDw_Ir;
- cost_Dw = cost_base + ii->cost_offset + off_UIrDw_Dw;
+ cost_Ir = cost_base + ii->cost_offset + ii->eventset->offset[EG_IR];
+ cost_Dw = cost_base + ii->cost_offset + ii->eventset->offset[EG_DW];
}
inc_costs(IrRes, cost_Ir,
- CLG_(current_state).cost + CLG_(sets).off_full_Ir );
+ CLG_(current_state).cost + fullOffset(EG_IR) );
inc_costs(DwRes, cost_Dw,
- CLG_(current_state).cost + CLG_(sets).off_full_Dw );
+ CLG_(current_state).cost + fullOffset(EG_DW) );
}
}
if (CLG_(current_state).collect) {
ULong *cost_Dw;
- if (CLG_(current_state).nonskipped) {
- cost_Dw = CLG_(current_state).nonskipped->skipped + CLG_(sets).off_full_Dw;
- }
- else {
- Int off_Dw;
- if (ii->eventset == CLG_(sets).UIrDw) off_Dw = off_UIrDw_Dw;
- else if (ii->eventset == CLG_(sets).UIrDwDr) off_Dw = off_UIrDwDr_Dw;
- else if (ii->eventset == CLG_(sets).UIrDrDw) off_Dw = off_UIrDrDw_Dw;
- else CLG_ASSERT(0);
-
- cost_Dw = cost_base + ii->cost_offset + off_Dw;
- }
+ if (CLG_(current_state).nonskipped)
+ cost_Dw = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DW);
+ else
+ cost_Dw = cost_base + ii->cost_offset + ii->eventset->offset[EG_DW];
inc_costs(DwRes, cost_Dw,
- CLG_(current_state).cost + CLG_(sets).off_full_Dw );
+ CLG_(current_state).cost + fullOffset(EG_DW) );
}
}
/* I cache results. Use the I_refs value to determine the first column
* width. */
- l1 = commify(total[CLG_(sets).off_full_Ir], 0, buf1);
+ l1 = commify(total[fullOffset(EG_IR)], 0, buf1);
VG_(message)(Vg_UserMsg, "I refs: %s\n", buf1);
if (!CLG_(clo).simulate_cache) return;
- commify(total[CLG_(sets).off_full_Ir +1], l1, buf1);
+ commify(total[fullOffset(EG_IR) +1], l1, buf1);
VG_(message)(Vg_UserMsg, "I1 misses: %s\n", buf1);
- commify(total[CLG_(sets).off_full_Ir +2], l1, buf1);
+ commify(total[fullOffset(EG_IR) +2], l1, buf1);
VG_(message)(Vg_UserMsg, "L2i misses: %s\n", buf1);
p = 100;
- if (0 == total[CLG_(sets).off_full_Ir])
- total[CLG_(sets).off_full_Ir] = 1;
+ if (0 == total[fullOffset(EG_IR)])
+ total[fullOffset(EG_IR)] = 1;
- percentify(total[CLG_(sets).off_full_Ir+1] * 100 * p /
- total[CLG_(sets).off_full_Ir], p, l1+1, buf1);
+ percentify(total[fullOffset(EG_IR)+1] * 100 * p /
+ total[fullOffset(EG_IR)], p, l1+1, buf1);
VG_(message)(Vg_UserMsg, "I1 miss rate: %s\n", buf1);
- percentify(total[CLG_(sets).off_full_Ir+2] * 100 * p /
- total[CLG_(sets).off_full_Ir], p, l1+1, buf1);
+ percentify(total[fullOffset(EG_IR)+2] * 100 * p /
+ total[fullOffset(EG_IR)], p, l1+1, buf1);
VG_(message)(Vg_UserMsg, "L2i miss rate: %s\n", buf1);
VG_(message)(Vg_UserMsg, "\n");
D_total = CLG_(get_eventset_cost)( CLG_(sets).full );
CLG_(init_cost)( CLG_(sets).full, D_total);
- CLG_(copy_cost)( CLG_(sets).Dr, D_total, total + CLG_(sets).off_full_Dr );
- CLG_(add_cost) ( CLG_(sets).Dw, D_total, total + CLG_(sets).off_full_Dw );
+ // we only use the first 3 values of D_total, adding up Dr and Dw costs
+ CLG_(copy_cost)( CLG_(get_event_set)(EG_DR), D_total, total + fullOffset(EG_DR) );
+ CLG_(add_cost) ( CLG_(get_event_set)(EG_DW), D_total, total + fullOffset(EG_DW) );
commify( D_total[0], l1, buf1);
- l2 = commify(total[CLG_(sets).off_full_Dr], 0, buf2);
- l3 = commify(total[CLG_(sets).off_full_Dw], 0, buf3);
+ l2 = commify(total[fullOffset(EG_DR)], 0, buf2);
+ l3 = commify(total[fullOffset(EG_DW)], 0, buf3);
VG_(message)(Vg_UserMsg, "D refs: %s (%s rd + %s wr)\n",
buf1, buf2, buf3);
commify( D_total[1], l1, buf1);
- commify(total[CLG_(sets).off_full_Dr+1], l2, buf2);
- commify(total[CLG_(sets).off_full_Dw+1], l3, buf3);
+ commify(total[fullOffset(EG_DR)+1], l2, buf2);
+ commify(total[fullOffset(EG_DW)+1], l3, buf3);
VG_(message)(Vg_UserMsg, "D1 misses: %s (%s rd + %s wr)\n",
buf1, buf2, buf3);
commify( D_total[2], l1, buf1);
- commify(total[CLG_(sets).off_full_Dr+2], l2, buf2);
- commify(total[CLG_(sets).off_full_Dw+2], l3, buf3);
+ commify(total[fullOffset(EG_DR)+2], l2, buf2);
+ commify(total[fullOffset(EG_DW)+2], l3, buf3);
VG_(message)(Vg_UserMsg, "L2d misses: %s (%s rd + %s wr)\n",
buf1, buf2, buf3);
p = 10;
if (0 == D_total[0]) D_total[0] = 1;
- if (0 == total[CLG_(sets).off_full_Dr]) total[CLG_(sets).off_full_Dr] = 1;
- if (0 == total[CLG_(sets).off_full_Dw]) total[CLG_(sets).off_full_Dw] = 1;
+ if (0 == total[fullOffset(EG_DR)]) total[fullOffset(EG_DR)] = 1;
+ if (0 == total[fullOffset(EG_DW)]) total[fullOffset(EG_DW)] = 1;
percentify( D_total[1] * 100 * p / D_total[0], p, l1+1, buf1);
- percentify(total[CLG_(sets).off_full_Dr+1] * 100 * p /
- total[CLG_(sets).off_full_Dr], p, l2+1, buf2);
- percentify(total[CLG_(sets).off_full_Dw+1] * 100 * p /
- total[CLG_(sets).off_full_Dw], p, l3+1, buf3);
+ percentify(total[fullOffset(EG_DR)+1] * 100 * p /
+ total[fullOffset(EG_DR)], p, l2+1, buf2);
+ percentify(total[fullOffset(EG_DW)+1] * 100 * p /
+ total[fullOffset(EG_DW)], p, l3+1, buf3);
VG_(message)(Vg_UserMsg, "D1 miss rate: %s (%s + %s )\n",
buf1, buf2,buf3);
percentify( D_total[2] * 100 * p / D_total[0], p, l1+1, buf1);
- percentify(total[CLG_(sets).off_full_Dr+2] * 100 * p /
- total[CLG_(sets).off_full_Dr], p, l2+1, buf2);
- percentify(total[CLG_(sets).off_full_Dw+2] * 100 * p /
- total[CLG_(sets).off_full_Dw], p, l3+1, buf3);
+ percentify(total[fullOffset(EG_DR)+2] * 100 * p /
+ total[fullOffset(EG_DR)], p, l2+1, buf2);
+ percentify(total[fullOffset(EG_DW)+2] * 100 * p /
+ total[fullOffset(EG_DW)], p, l3+1, buf3);
VG_(message)(Vg_UserMsg, "L2d miss rate: %s (%s + %s )\n",
buf1, buf2,buf3);
VG_(message)(Vg_UserMsg, "\n");
/* L2 overall results */
L2_total =
- total[CLG_(sets).off_full_Dr +1] +
- total[CLG_(sets).off_full_Dw +1] +
- total[CLG_(sets).off_full_Ir +1];
+ total[fullOffset(EG_DR) +1] +
+ total[fullOffset(EG_DW) +1] +
+ total[fullOffset(EG_IR) +1];
L2_total_r =
- total[CLG_(sets).off_full_Dr +1] +
- total[CLG_(sets).off_full_Ir +1];
- L2_total_w = total[CLG_(sets).off_full_Dw +1];
+ total[fullOffset(EG_DR) +1] +
+ total[fullOffset(EG_IR) +1];
+ L2_total_w = total[fullOffset(EG_DW) +1];
commify(L2_total, l1, buf1);
commify(L2_total_r, l2, buf2);
commify(L2_total_w, l3, buf3);
buf1, buf2, buf3);
L2_total_m =
- total[CLG_(sets).off_full_Dr +2] +
- total[CLG_(sets).off_full_Dw +2] +
- total[CLG_(sets).off_full_Ir +2];
+ total[fullOffset(EG_DR) +2] +
+ total[fullOffset(EG_DW) +2] +
+ total[fullOffset(EG_IR) +2];
L2_total_mr =
- total[CLG_(sets).off_full_Dr +2] +
- total[CLG_(sets).off_full_Ir +2];
- L2_total_mw = total[CLG_(sets).off_full_Dw +2];
+ total[fullOffset(EG_DR) +2] +
+ total[fullOffset(EG_IR) +2];
+ L2_total_mw = total[fullOffset(EG_DW) +2];
commify(L2_total_m, l1, buf1);
commify(L2_total_mr, l2, buf2);
commify(L2_total_mw, l3, buf3);
buf1, buf2, buf3);
percentify(L2_total_m * 100 * p /
- (total[CLG_(sets).off_full_Ir] + D_total[0]), p, l1+1, buf1);
+ (total[fullOffset(EG_IR)] + D_total[0]), p, l1+1, buf1);
percentify(L2_total_mr * 100 * p /
- (total[CLG_(sets).off_full_Ir] + total[CLG_(sets).off_full_Dr]),
+ (total[fullOffset(EG_IR)] + total[fullOffset(EG_DR)]),
p, l2+1, buf2);
percentify(L2_total_mw * 100 * p /
- total[CLG_(sets).off_full_Dw], p, l3+1, buf3);
+ total[fullOffset(EG_DW)], p, l3+1, buf3);
VG_(message)(Vg_UserMsg, "L2 miss rate: %s (%s + %s )\n",
buf1, buf2,buf3);
}
struct event_sets CLG_(sets);
-void CLG_(init_eventsets)(Int max_user)
+void CLG_(init_eventsets)()
{
- EventType * e1, *e2, *e3, *e4;
- // Basic event sets from which others are composed
- EventSet *Use, *Ir, *Dr, *Dw;
- // Compositions of basic sets used for per-instruction counters
- EventSet *UIr, *UIrDr, *UIrDrDw, *UIrDw, *UIrDwDr;
- // Composition used for global counters and aggregation
- EventSet *full;
- int sizeOfUseIr;
-
- // the "Use" events types only are used with "cacheuse" simulation
- Use = CLG_(get_eventset)("Use", 4);
- if (clo_collect_cacheuse) {
- /* if TUse is 0, there was never a load, and no loss, too */
- e1 = CLG_(register_eventtype)("AcCost1");
- CLG_(add_eventtype)(Use, e1);
- e1 = CLG_(register_eventtype)("SpLoss1");
- CLG_(add_eventtype)(Use, e1);
- e1 = CLG_(register_eventtype)("AcCost2");
- CLG_(add_eventtype)(Use, e1);
- e1 = CLG_(register_eventtype)("SpLoss2");
- CLG_(add_eventtype)(Use, e1);
- }
-
- Ir = CLG_(get_eventset)("Ir", 4);
- Dr = CLG_(get_eventset)("Dr", 4);
- Dw = CLG_(get_eventset)("Dw", 4);
- if (CLG_(clo).simulate_cache) {
- e1 = CLG_(register_eventtype)("Ir");
- e2 = CLG_(register_eventtype)("I1mr");
- e3 = CLG_(register_eventtype)("I2mr");
- if (clo_simulate_writeback) {
- e4 = CLG_(register_eventtype)("I2dmr");
- CLG_(add_dep_event4)(Ir, e1,e2,e3,e4);
+ // Event groups from which the event sets are composed
+ // the "Use" group only is used with "cacheuse" simulation
+ if (clo_collect_cacheuse)
+ CLG_(register_event_group4)(EG_USE,
+ "AcCost1", "SpLoss1", "AcCost2", "SpLoss2");
+
+ if (!CLG_(clo).simulate_cache)
+ CLG_(register_event_group)(EG_IR, "Ir");
+ else if (!clo_simulate_writeback) {
+ CLG_(register_event_group3)(EG_IR, "Ir", "I1mr", "I2mr");
+ CLG_(register_event_group3)(EG_DR, "Dr", "D1mr", "D2mr");
+ CLG_(register_event_group3)(EG_DW, "Dw", "D1mw", "D2mw");
}
- else
- CLG_(add_dep_event3)(Ir, e1,e2,e3);
-
- e1 = CLG_(register_eventtype)("Dr");
- e2 = CLG_(register_eventtype)("D1mr");
- e3 = CLG_(register_eventtype)("D2mr");
- if (clo_simulate_writeback) {
- e4 = CLG_(register_eventtype)("D2dmr");
- CLG_(add_dep_event4)(Dr, e1,e2,e3,e4);
- }
- else
- CLG_(add_dep_event3)(Dr, e1,e2,e3);
-
- e1 = CLG_(register_eventtype)("Dw");
- e2 = CLG_(register_eventtype)("D1mw");
- e3 = CLG_(register_eventtype)("D2mw");
- if (clo_simulate_writeback) {
- e4 = CLG_(register_eventtype)("D2dmw");
- CLG_(add_dep_event4)(Dw, e1,e2,e3,e4);
+ else { // clo_simulate_writeback
+ CLG_(register_event_group4)(EG_IR, "Ir", "I1mr", "I2mr", "I2dmr");
+ CLG_(register_event_group4)(EG_DR, "Dr", "D1mr", "D2mr", "I2dmr");
+ CLG_(register_event_group4)(EG_DW, "Dw", "D1mw", "D2mw", "I2dmw");
}
- else
- CLG_(add_dep_event3)(Dw, e1,e2,e3);
- }
- else {
- e1 = CLG_(register_eventtype)("Ir");
- CLG_(add_eventtype)(Ir, e1);
- }
+ if (CLG_(clo).collect_alloc)
+ CLG_(register_event_group2)(EG_ALLOC, "allocCount", "allocSize");
- // Self cost event sets per guest instruction (U used only for cacheUse).
- // Each basic event set only appears once, as eg. multiple different Dr's
- // in one guest instruction are counted in the same counter.
-
- sizeOfUseIr = Use->size + Ir->size;
- UIr = CLG_(get_eventset)("UIr", sizeOfUseIr);
- CLG_(add_eventset)(UIr, Use);
- off_UIr_Ir = CLG_(add_eventset)(UIr, Ir);
-
- UIrDr = CLG_(get_eventset)("UIrDr", sizeOfUseIr + Dr->size);
- CLG_(add_eventset)(UIrDr, Use);
- off_UIrDr_Ir = CLG_(add_eventset)(UIrDr, Ir);
- off_UIrDr_Dr = CLG_(add_eventset)(UIrDr, Dr);
-
- UIrDrDw = CLG_(get_eventset)("IrDrDw", sizeOfUseIr + Dr->size + Dw->size);
- CLG_(add_eventset)(UIrDrDw, Use);
- off_UIrDrDw_Ir = CLG_(add_eventset)(UIrDrDw, Ir);
- off_UIrDrDw_Dr = CLG_(add_eventset)(UIrDrDw, Dr);
- off_UIrDrDw_Dw = CLG_(add_eventset)(UIrDrDw, Dw);
-
- UIrDw = CLG_(get_eventset)("UIrDw", sizeOfUseIr + Dw->size);
- CLG_(add_eventset)(UIrDw, Use);
- off_UIrDw_Ir = CLG_(add_eventset)(UIrDw, Ir);
- off_UIrDw_Dw = CLG_(add_eventset)(UIrDw, Dw);
-
- UIrDwDr = CLG_(get_eventset)("IrDwDr", sizeOfUseIr + Dw->size + Dr->size);
- CLG_(add_eventset)(UIrDwDr, Use);
- off_UIrDwDr_Ir = CLG_(add_eventset)(UIrDrDw, Ir);
- off_UIrDwDr_Dw = CLG_(add_eventset)(UIrDrDw, Dw);
- off_UIrDwDr_Dr = CLG_(add_eventset)(UIrDrDw, Dr);
-
-
- // the "full" event set is used as global counter and for aggregation
- if (CLG_(clo).collect_alloc) max_user += 2;
- if (CLG_(clo).collect_systime) max_user += 2;
- full = CLG_(get_eventset)("full",
- sizeOfUseIr + Dr->size + Dw->size + max_user);
- CLG_(add_eventset)(full, Use);
- CLG_(sets).off_full_Ir = CLG_(add_eventset)(full, Ir);
- CLG_(sets).off_full_Dr = CLG_(add_eventset)(full, Dr);
- CLG_(sets).off_full_Dw = CLG_(add_eventset)(full, Dw);
- if (CLG_(clo).collect_alloc) {
- e1 = CLG_(register_eventtype)("allocCount");
- e2 = CLG_(register_eventtype)("allocSize");
- CLG_(sets).off_full_alloc = CLG_(add_dep_event2)(full, e1,e2);
- }
- if (CLG_(clo).collect_systime) {
- e1 = CLG_(register_eventtype)("sysCount");
- e2 = CLG_(register_eventtype)("sysTime");
- CLG_(sets).off_full_systime = CLG_(add_dep_event2)(full, e1,e2);
- }
+ if (CLG_(clo).collect_systime)
+ CLG_(register_event_group2)(EG_SYS, "sysCount", "sysTime");
- CLG_(sets).Use = Use;
- CLG_(sets).Ir = Ir;
- CLG_(sets).Dr = Dr;
- CLG_(sets).Dw = Dw;
- CLG_(sets).UIr = UIr;
- CLG_(sets).UIrDr = UIrDr;
- CLG_(sets).UIrDrDw = UIrDrDw;
- CLG_(sets).UIrDw = UIrDw;
- CLG_(sets).UIrDwDr = UIrDwDr;
- CLG_(sets).full = full;
-
-
- CLG_DEBUGIF(1) {
- CLG_DEBUG(1, "EventSets:\n");
- CLG_(print_eventset)(-2, Use);
- CLG_(print_eventset)(-2, Ir);
- CLG_(print_eventset)(-2, Dr);
- CLG_(print_eventset)(-2, Dw);
- CLG_(print_eventset)(-2, full);
- }
+ // event set used as base for instruction self cost
+ CLG_(sets).base = CLG_(get_event_set2)(EG_USE, EG_IR);
- /* Not-existing events are silently ignored */
- CLG_(dumpmap) = CLG_(get_eventmapping)(full);
- CLG_(append_event)(CLG_(dumpmap), "Ir");
- CLG_(append_event)(CLG_(dumpmap), "Dr");
- CLG_(append_event)(CLG_(dumpmap), "Dw");
- CLG_(append_event)(CLG_(dumpmap), "I1mr");
- CLG_(append_event)(CLG_(dumpmap), "D1mr");
- CLG_(append_event)(CLG_(dumpmap), "D1mw");
- CLG_(append_event)(CLG_(dumpmap), "I2mr");
- CLG_(append_event)(CLG_(dumpmap), "D2mr");
- CLG_(append_event)(CLG_(dumpmap), "D2mw");
- CLG_(append_event)(CLG_(dumpmap), "I2dmr");
- CLG_(append_event)(CLG_(dumpmap), "D2dmr");
- CLG_(append_event)(CLG_(dumpmap), "D2dmw");
- CLG_(append_event)(CLG_(dumpmap), "AcCost1");
- CLG_(append_event)(CLG_(dumpmap), "SpLoss1");
- CLG_(append_event)(CLG_(dumpmap), "AcCost2");
- CLG_(append_event)(CLG_(dumpmap), "SpLoss2");
- CLG_(append_event)(CLG_(dumpmap), "allocCount");
- CLG_(append_event)(CLG_(dumpmap), "allocSize");
- CLG_(append_event)(CLG_(dumpmap), "sysCount");
- CLG_(append_event)(CLG_(dumpmap), "sysTime");
+ // event set comprising all event groups, used for inclusive cost
+ CLG_(sets).full = CLG_(add_event_group2)(CLG_(sets).base, EG_DR, EG_DW);
+ CLG_(sets).full = CLG_(add_event_group2)(CLG_(sets).full, EG_ALLOC, EG_SYS);
-}
-
-
-
-static
-void add_and_zero_Dx(EventSet* es, SimCost dst, ULong* cost)
-{
- /* if eventset use is defined, it is always first (hardcoded!) */
- CLG_(add_and_zero_cost)( CLG_(sets).Use, dst, cost);
+ CLG_DEBUGIF(1) {
+ CLG_DEBUG(1, "EventSets:\n");
+ CLG_(print_eventset)(-2, CLG_(sets).base);
+ CLG_(print_eventset)(-2, CLG_(sets).full);
+ }
- if (es == CLG_(sets).UIr) {
- CLG_(add_and_zero_cost)( CLG_(sets).Ir, dst + CLG_(sets).off_full_Ir,
- cost + off_UIr_Ir);
- }
- else if (es == CLG_(sets).UIrDr) {
- CLG_(add_and_zero_cost)( CLG_(sets).Ir, dst + CLG_(sets).off_full_Ir,
- cost + off_UIrDr_Ir);
- CLG_(add_and_zero_cost)( CLG_(sets).Dr, dst + CLG_(sets).off_full_Dr,
- cost + off_UIrDr_Dr);
- }
- else if (es == CLG_(sets).UIrDrDw) {
- CLG_(add_and_zero_cost)( CLG_(sets).Ir, dst + CLG_(sets).off_full_Ir,
- cost + off_UIrDrDw_Ir);
- CLG_(add_and_zero_cost)( CLG_(sets).Dr, dst + CLG_(sets).off_full_Dr,
- cost + off_UIrDrDw_Dr);
- CLG_(add_and_zero_cost)( CLG_(sets).Dw, dst + CLG_(sets).off_full_Dw,
- cost + off_UIrDrDw_Dw);
- }
- else if (es == CLG_(sets).UIrDw) {
- CLG_(add_and_zero_cost)( CLG_(sets).Ir, dst + CLG_(sets).off_full_Ir,
- cost + off_UIrDw_Ir);
- CLG_(add_and_zero_cost)( CLG_(sets).Dw, dst + CLG_(sets).off_full_Dw,
- cost + off_UIrDw_Dw);
- }
- else if (es == CLG_(sets).UIrDwDr) {
- CLG_(add_and_zero_cost)( CLG_(sets).Ir, dst + CLG_(sets).off_full_Ir,
- cost + off_UIrDwDr_Ir);
- CLG_(add_and_zero_cost)( CLG_(sets).Dw, dst + CLG_(sets).off_full_Dw,
- cost + off_UIrDwDr_Dw);
- CLG_(add_and_zero_cost)( CLG_(sets).Dr, dst + CLG_(sets).off_full_Dr,
- cost + off_UIrDwDr_Dr);
- }
- else CLG_ASSERT(0);
+ /* Not-existing events are silently ignored */
+ CLG_(dumpmap) = CLG_(get_eventmapping)(CLG_(sets).full);
+ CLG_(append_event)(CLG_(dumpmap), "Ir");
+ CLG_(append_event)(CLG_(dumpmap), "Dr");
+ CLG_(append_event)(CLG_(dumpmap), "Dw");
+ CLG_(append_event)(CLG_(dumpmap), "I1mr");
+ CLG_(append_event)(CLG_(dumpmap), "D1mr");
+ CLG_(append_event)(CLG_(dumpmap), "D1mw");
+ CLG_(append_event)(CLG_(dumpmap), "I2mr");
+ CLG_(append_event)(CLG_(dumpmap), "D2mr");
+ CLG_(append_event)(CLG_(dumpmap), "D2mw");
+ CLG_(append_event)(CLG_(dumpmap), "I2dmr");
+ CLG_(append_event)(CLG_(dumpmap), "D2dmr");
+ CLG_(append_event)(CLG_(dumpmap), "D2dmw");
+ CLG_(append_event)(CLG_(dumpmap), "AcCost1");
+ CLG_(append_event)(CLG_(dumpmap), "SpLoss1");
+ CLG_(append_event)(CLG_(dumpmap), "AcCost2");
+ CLG_(append_event)(CLG_(dumpmap), "SpLoss2");
+ CLG_(append_event)(CLG_(dumpmap), "allocCount");
+ CLG_(append_event)(CLG_(dumpmap), "allocSize");
+ CLG_(append_event)(CLG_(dumpmap), "sysCount");
+ CLG_(append_event)(CLG_(dumpmap), "sysTime");
}
+
/* this is called at dump time for every instruction executed */
static void cachesim_add_icost(SimCost cost, BBCC* bbcc,
InstrInfo* ii, ULong exe_count)
{
- if (!CLG_(clo).simulate_cache)
- cost[CLG_(sets).off_full_Ir] += exe_count;
- else {
-
-#if 0
-/* There is always a trivial case where exe_count and Ir can be
- * slightly different because ecounter is updated when executing
- * the next BB. E.g. for last BB executed, or when toggling collection
- */
- /* FIXME: Hardcoded that each eventset has Ir as first */
- if ((bbcc->cost + ii->cost_offset)[0] != exe_count) {
- VG_(printf)("==> Ir %llu, exe %llu\n",
- (bbcc->cost + ii->cost_offset)[0], exe_count);
- CLG_(print_bbcc_cost)(-2, bbcc);
- //CLG_ASSERT((bbcc->cost + ii->cost_offset)[0] == exe_count);
- }
-#endif
-
- add_and_zero_Dx(ii->eventset, cost,
- bbcc->cost + ii->cost_offset);
- }
+ if (!CLG_(clo).simulate_cache)
+ cost[ fullOffset(EG_IR) ] += exe_count;
+ else
+ CLG_(add_and_zero_cost2)( CLG_(sets).full, cost,
+ ii->eventset, bbcc->cost + ii->cost_offset);
}
static