/*--------------------------------------------------------------------*/
/*--- Callgrind                                                    ---*/
/*---                                                     events.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Callgrind, a Valgrind tool for call tracing.

   Copyright (C) 2002-2013, 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.
*/

#include "global.h"

/* This should be 2**MAX_EVENTGROUP_COUNT */
#define MAX_EVENTSET_COUNT 1024

static EventGroup* eventGroup[MAX_EVENTGROUP_COUNT];
static EventSet* eventSetTable[MAX_EVENTSET_COUNT];
static Bool eventSets_initialized = 0;

static
void initialize_event_sets(void)
{
    Int i;

    if (eventSets_initialized) return;

    for(i=0; i< MAX_EVENTGROUP_COUNT; i++)
	eventGroup[i] = 0;

    for(i=0; i< MAX_EVENTSET_COUNT; i++)
	eventSetTable[i] = 0; 

    eventSets_initialized = 1;
 }

static
EventGroup* new_event_group(int id, int n)
{
    EventGroup* eg;

    initialize_event_sets();

    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(HChar*));
    eg->size = n;
    eventGroup[id] = eg;
    return eg;
}

EventGroup* CLG_(register_event_group) (int id, const HChar* n1)
{
    EventGroup* eg = new_event_group(id, 1);
    eg->name[0] = n1;

    return eg;
}

EventGroup* CLG_(register_event_group2)(int id, const HChar* n1,
                                        const HChar* n2)
{
    EventGroup* eg = new_event_group(id, 2);
    eg->name[0] = n1;
    eg->name[1] = n2;

    return eg;
}

EventGroup* CLG_(register_event_group3)(int id, const HChar* n1,
                                        const HChar* n2, const HChar* n3)
{
    EventGroup* eg = new_event_group(id, 3);
    eg->name[0] = n1;
    eg->name[1] = n2;
    eg->name[2] = n3;

    return eg;
}

EventGroup* CLG_(register_event_group4)(int id, const HChar* n1,
                                        const HChar* n2, const HChar* n3,
                                        const HChar* n4)
{
    EventGroup* eg = new_event_group(id, 4);
    eg->name[0] = n1;
    eg->name[1] = n2;
    eg->name[2] = n3;
    eg->name[3] = n4;

    return eg;
}

EventGroup* CLG_(get_event_group)(int id)
{
    CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);

    return eventGroup[id];
}


static
EventSet* eventset_from_mask(UInt mask)
{
    EventSet* es;
    Int i, count, offset;

    if (mask >= MAX_EVENTSET_COUNT) return 0;

    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;
}

EventSet* CLG_(get_event_set)(Int id)
{
    CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
    return eventset_from_mask(1u << id);
}

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));
}

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));
}

EventSet* CLG_(add_event_group)(EventSet* es, Int id)
{
    CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
    if (!es) es = eventset_from_mask(0);
    return eventset_from_mask(es->mask | (1u << id));
}

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));
}

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);
}

Int CLG_(sprint_eventset)(HChar* buf, EventSet* es)
{
    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;
}


/* Get cost array for an event set */
ULong* CLG_(get_eventset_cost)(EventSet* es)
{
    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;

    if (!cost) return;

    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;

    CLG_ASSERT(cost != 0);
    if (!(*cost))
	*cost = CLG_(get_eventset_cost)(es);

    for(i=0; i<es->size; i++)
	(*cost)[i] = 0;
}

void CLG_(zero_cost)(EventSet* es, ULong* cost)
{
    Int i;

    if (!cost) return;

    for(i=0;i<es->size;i++)
	cost[i] = 0;
}
  
Bool CLG_(is_zero_cost)(EventSet* es, ULong* cost)
{
    Int i;

    if (!cost) 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;

    if (!c1) return CLG_(is_zero_cost)(es, c2);
    if (!c2) return CLG_(is_zero_cost)(es, c1);

    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;

    if (!src) {
	CLG_(zero_cost)(es, dst);
	return;
    }
    CLG_ASSERT(dst != 0);
  
    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;

    CLG_ASSERT(pdst != 0);

    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];
}

void CLG_(add_cost)(EventSet* es, ULong* dst, ULong* src)
{
    Int i;

    if (!src) return;
    CLG_ASSERT(dst != 0);

    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;
    }

    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;
    Bool is_nonzero = False;

    CLG_ASSERT((es != 0) && (dst != 0));
    if (!src) return False;

    for(i=0; i<es->size; i++) {
	if (src[i]==0) continue;
	dst[i] += src[i];
	src[i] = 0;
	is_nonzero = True;
    }

    return is_nonzero;
}

/* Adds src to dst and zeros src. Returns false if nothing changed */
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 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;
    Bool is_nonzero = False;

    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 is_nonzero;
}

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);
    }

    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)(HChar* buf, EventSet* es, ULong* c)
{
    Int i, pos, skipped = 0;

    if (!c || es->size==0) return 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++] = ' ';
	pos += VG_(sprintf)(buf+pos, "%llu", c[i]);
    }

    return pos;
}


/* Allocate space for an event mapping */
EventMapping* CLG_(get_eventmapping)(EventSet* es)
{
    EventMapping* em;

    CLG_ASSERT(es != 0);

    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;
}

void CLG_(append_event)(EventMapping* em, const HChar* n)
{
    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)(HChar* buf, EventMapping* em)
{
    Int i, pos = 0;
    EventGroup* eg;

    CLG_ASSERT(em != 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;
}

/* Returns number of characters written */
Int CLG_(sprint_mappingcost)(HChar* buf, EventMapping* em, ULong* c)
{
    Int i, pos, skipped = 0;

    if (!c || em->size==0) return 0;

    /* At least one entry */
    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++] = ' ';
	pos += VG_(sprintf)(buf+pos, "%llu", c[em->entry[i].offset]);
    }

    return pos;
}
