/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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 3, 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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <stdio.h>
#include <stdlib.h>

#include "util.h"
#include "DefaultMap.h"
#include "CacheMap.h"

#include "DbeSession.h"
#include "Application.h"
#include "CallStack.h"
#include "Emsg.h"
#include "Experiment.h"
#include "Expression.h"
#include "Function.h"
#include "Histable.h"
#include "IndexObject.h"
#include "MetricList.h"
#include "Module.h"
#include "DbeView.h"
#include "Metric.h"
#include "PathTree.h"
#include "LoadObject.h"
#include "Sample.h"
#include "StringBuilder.h"
#include "Table.h"

// Define counts, rate for error warnings for statistical profiles
#define MIN_PROF_CNT    100
#define MAX_PROF_RATE   1000.

#define NUM_DESCENDANTS(nd) ((nd)->descendants ? (nd)->descendants->size() : 0)
#define IS_LEAF(nd)         ((nd)->descendants == NULL)

#ifdef DEBUG
#define DBG(__func) __func
#else
#define DBG(__func)
#endif

void
PathTree::construct (DbeView *_dbev, int _indxtype, PathTreeType _pathTreeType)
{
  dbev = _dbev;
  indxtype = _indxtype;
  pathTreeType = _pathTreeType;
  status = 0;
  nchunks = 0;
  chunks = NULL;
  nodes = 1; // don't use node 0
  nslots = 0;
  slots = NULL;
  root_idx = 0;
  root = NULL;
  depth = 1;
  dnodes = 0;
  phaseIdx = -1;
  nexps = 0;
  total_obj = NULL;
  indx_expr = NULL;
  statsq = NULL;
  warningq = NULL;
  cancel_ok = 1;
  ptree_internal = NULL;
  ftree_internal = NULL;
  ftree_needs_update = false;
  depth_map = NULL;
  init ();
}

PathTree::~PathTree ()
{
  fini ();
  for (long i = 0; i < nchunks; i++)
    delete[] chunks[i];
  delete[] chunks;
}

void
PathTree::init ()
{
  fn_map = new DefaultMap<Function*, NodeIdx>;
  stack_prop = PROP_NONE;
  desc_htable_size = 511;
  desc_htable_nelem = 0;
  descHT = new hash_node_t*[desc_htable_size];
  for (int i = 0; i < desc_htable_size; i++)
    descHT[i] = NULL;
  pathMap = new CacheMap<uint64_t, NodeIdx>;
  statsq = new Emsgqueue (NTXT ("statsq"));
  warningq = new Emsgqueue (NTXT ("warningq"));
  if (indxtype < 0)
    {
      Function *ftotal = dbeSession->get_Total_Function ();
      if (pathTreeType == PATHTREE_INTERNAL_FUNCTREE)
	total_obj = ftotal;
      else
	total_obj = ftotal->find_dbeinstr (0, 0);
      VMode view_mode = dbev->get_view_mode ();
      if (view_mode == VMODE_MACHINE)
	stack_prop = PROP_MSTACK;
      else if (view_mode == VMODE_EXPERT)
	stack_prop = PROP_XSTACK;
      else if (view_mode == VMODE_USER)
	{
	  stack_prop = PROP_USTACK;
	  if (dbeSession->is_omp_available ()
	      && pathTreeType == PATHTREE_INTERNAL_OMP)
	    stack_prop = PROP_XSTACK;
	}
    }
  else
    {
      total_obj = new IndexObject (indxtype, (uint64_t) - 2);
      total_obj->set_name (dbe_strdup (NTXT ("<Total>")));
      char *idxname = dbeSession->getIndexSpaceName (indxtype);
      if (streq (idxname, NTXT ("OMP_preg")))
	stack_prop = PROP_CPRID;
      else if (streq (idxname, NTXT ("OMP_task")))
	stack_prop = PROP_TSKID;
      else
	indx_expr = dbeSession->getIndexSpaceExpr (indxtype);
    }
  root_idx = new_Node (0, total_obj, false);
  root = NODE_IDX (root_idx);
}

void
PathTree::fini ()
{
  // For each node free its descendants vector
  // and reset the node list of its function
  for (long i = 1; i < nodes; i++)
    {
      Node *node = NODE_IDX (i);
      if (node->descendants)
	delete node->descendants;
    }
  nodes = 1; // don't use node 0

  for (int i = 0; i < nslots; i++)
    {
      int **tmp = slots[i].mvals;
      for (long j = 0; j < nchunks; j++)
	delete[] tmp[j];
      delete[] tmp;
    }
  delete[] slots;
  slots = NULL;
  nslots = 0;
  delete fn_map;
  fn_map = NULL;
  delete pathMap;
  pathMap = NULL;
  destroy (depth_map);
  depth_map = NULL;
  if (indxtype >= 0)
    delete total_obj;

  for (int i = 0; i < desc_htable_size; i++)
    {
      hash_node_t *p = descHT[i];
      while (p)
	{
	  hash_node_t *p1 = p;
	  p = p->next;
	  delete p1;
	}
    }
  delete[] descHT;
  delete statsq;
  delete warningq;
  depth = 1;
  dnodes = 0;
  phaseIdx = -1;
  nexps = 0;
  status = 0;
}

PtreePhaseStatus
PathTree::reset ()
{
  if (pathTreeType == PATHTREE_INTERNAL_FUNCTREE)
    return NORMAL; // never process reset for ftree_internal.

  if (dbeSession->is_omp_available () && dbev->get_view_mode () == VMODE_USER
      && pathTreeType == PATHTREE_MAIN && ptree_internal == NULL)
    ptree_internal = new PathTree (dbev, indxtype, PATHTREE_INTERNAL_OMP);

  if (phaseIdx != dbev->getPhaseIdx ())
    {
      fini ();
      init ();
      phaseIdx = dbev->getPhaseIdx ();
      ftree_needs_update = true;
    }
  for (; nexps < dbeSession->nexps (); nexps++)
    {
      ftree_needs_update = true;
      if (add_experiment (nexps) == CANCELED)
	return CANCELED;
    }

  // LIBRARY_VISIBILITY
  if (dbev->isNewViewMode ())
    dbev->resetNewViewMode ();
  if (dbev->isShowHideChanged ())
    dbev->resetShowHideChanged ();
  return NORMAL;
}

int
PathTree::allocate_slot (int id, ValueTag vtype)
{

  int i;
  int slot_idx = find_slot (id);
  if (slot_idx >= 0)
    {
      DBG (assert (slots[slot_idx].vtype == vtype));
      return slot_idx;
    }
  slot_idx = nslots++;

  Slot *old_slots = slots;
  slots = new Slot[nslots];
  for (i = 0; i < slot_idx; i++)
    slots[i] = old_slots[i];
  delete[] old_slots;

  slots[slot_idx].id = id;
  slots[slot_idx].vtype = vtype;
  int **ip = new int*[nchunks];
  for (i = 0; i < nchunks; i++)
    ip[i] = NULL;
  slots[slot_idx].mvals = ip;

  return slot_idx;
}

void
PathTree::allocate_slots (Slot *new_slots, int new_nslots)
{
  // duplicates new_slots

  // if previously had more slots than currently requested, delete the data from those slots.
  for (int i = new_nslots; i < nslots; i++)
    {
      int **tmp = slots[i].mvals;
      for (long j = 0; j < nchunks; j++)
	delete tmp[j];
      delete tmp;
    }
  if (new_nslots == 0)
    {
      nslots = new_nslots;
      delete[] slots;
      slots = NULL;
      return;
    }

  Slot *old_slots = slots;
  slots = new Slot[new_nslots];
  for (int i = 0; i < new_nslots; i++)
    {
      slots[i] = new_slots[i]; // pick up id and vtype
      if (i < nslots)
	slots[i].mvals = old_slots[i].mvals;
      else
	{
	  if (nchunks == 0)
	    slots[i].mvals = NULL;
	  else
	    {
	      int **ip = new int*[nchunks];
	      for (long j = 0; j < nchunks; j++)
		ip[j] = NULL;
	      slots[i].mvals = ip;
	    }
	}
    }
  nslots = new_nslots;
  delete old_slots;
}

int
PathTree::find_slot (int id)
{
  for (int i = 0; i < nslots; i++)
    if (slots[i].id == id)
      return i;
  return -1;
}

PathTree::NodeIdx
PathTree::new_Node (NodeIdx anc, Histable *instr, bool leaf)
{
  if (nodes >= nchunks * CHUNKSZ)
    {
      long idx = nchunks++;

      // Reallocate Node chunk array
      Node **old_chunks = chunks;
      chunks = new Node*[nchunks];
      for (long k = 0; k < idx; k++)
	chunks[k] = old_chunks[k];
      delete[] old_chunks;

      // Reallocate metric value chunk arrays.
      for (int i = 0; i < nslots; i++)
	{
	  int **mvals = new int*[nchunks];
	  for (long k = 0; k < idx; k++)
	    {
	      mvals[k] = slots[i].mvals[k];
	    }
	  delete[] slots[i].mvals;
	  slots[i].mvals = mvals;
	  slots[i].mvals[idx] = NULL;
	}

      // Allocate new chunk for nodes.
      // Note that we don't need to allocate new chunks
      // for metric values at this point as we rely on
      // lazy allocation.
      //
      allocate_chunk (chunks, idx);
    }
  NodeIdx node_idx = nodes++;
  Node *node = NODE_IDX (node_idx);
  node->ancestor = anc;
  node->descendants = leaf ? (Vector<NodeIdx>*)NULL : new Vector<NodeIdx>(2);
  node->instr = instr;
  Function *func = (Function*) (instr->convertto (Histable::FUNCTION));
  node->funclist = fn_map->get (func);
  fn_map->put (func, node_idx);
  return node_idx;
}

PathTree::NodeIdx
PathTree::find_path (Experiment *exp, DataView *dview, long recIdx)
{
  if (indx_expr != NULL)
    {
      Expression::Context ctx (dbev, exp, dview, recIdx);
      uint64_t idx = indx_expr->eval (&ctx);
      Histable *cur_obj = dbeSession->createIndexObject (indxtype, idx);
      cur_obj->set_name_from_context (&ctx);
      NodeIdx dsc_idx = find_in_desc_htable (root_idx, cur_obj, true);
      depth = 2;
      return dsc_idx;
    }

  bool showAll = dbev->isShowAll ();
  int t_stack_prop = stack_prop;
  void *stackId = dview->getObjValue (t_stack_prop, recIdx);
  NodeIdx node_idx;
  if (stackId != NULL)
    {
      // pathMap does not work with NULL key
      node_idx = pathMap->get ((uint64_t) stackId);
      if (node_idx != 0)
	return node_idx;
    }
  Vector<Histable*> *stack = (Vector<Histable*>*)CallStack::getStackPCs (stackId, !showAll);
  int stack_size = stack->size ();
  if (stack_size == 0)
    return root_idx;

  node_idx = root_idx;
  int thisdepth = 1;

  for (int i = stack_size - 1; i >= 0; i--)
    {
      bool leaf = (i == 0);
      Histable *cur_addr = stack->fetch (i);

      // bail out of loop if load object API-only is set
      // and this is not the top frame
      // This is now done in HSTACK if hide is set

      Function *func = (Function*) cur_addr->convertto (Histable::FUNCTION);
      if (func != NULL)
	{
	  Module *mod = func->module;
	  LoadObject *lo = mod->loadobject;
	  int segx = lo->seg_idx;
	  if (showAll && dbev->get_lo_expand (segx) == LIBEX_API
	      && i != stack_size - 1)
	    leaf = true;
	}

      NodeIdx dsc_idx = find_desc_node (node_idx, cur_addr, leaf);
      thisdepth++;
      node_idx = dsc_idx;

      // LIBEX_API processing might have set leaf to true
      if (leaf)
	break;
    }
  if (thisdepth > depth)
    depth = thisdepth;
  delete stack;
  pathMap->put ((uint64_t) stackId, node_idx);
  return node_idx;
}

static int
desc_node_comp (const void *s1, const void *s2, const void *ptree)
{
  PathTree::NodeIdx t1, t2;
  t1 = *(PathTree::NodeIdx *)s1;
  t2 = *(PathTree::NodeIdx *)s2;
  PathTree* Ptree = (PathTree *) ptree;
  PathTree::Node *n1 = Ptree->NODE_IDX (t1);
  PathTree::Node *n2 = Ptree->NODE_IDX (t2);
  Histable *d1 = n1->instr;
  Histable *d2 = n2->instr;
  if (d1->id < d2->id)
    return -1;
  else if (d1->id > d2->id)
    return +1;
  else
    return 0;
}

PathTree::NodeIdx
PathTree::find_in_desc_htable (NodeIdx node_idx, Histable *instr, bool leaf)
{
  unsigned int hash_code = (unsigned int) instr->id % desc_htable_size;
  Node *node = NODE_IDX (node_idx);
  hash_node_t *p = NULL;
  for (p = descHT[hash_code]; p; p = p->next)
    {
      Node *dsc = NODE_IDX (p->nd);
      Histable *dinstr = dsc->instr;
      if (dinstr->id == instr->id && leaf == IS_LEAF (dsc))
	return p->nd;
    }
  // Not found
  NodeIdx dsc_idx = new_Node (node_idx, instr, leaf);
  node->descendants->append (dsc_idx);
  p = new hash_node_t ();
  p->nd = dsc_idx;
  p->next = descHT[hash_code];
  descHT[hash_code] = p;
  desc_htable_nelem++;

  // time to resize
  if (desc_htable_nelem == desc_htable_size)
    {
      int old_htable_size = desc_htable_size;
      desc_htable_size = old_htable_size * 2 + 1;
      hash_node_t **old_htable = descHT;
      descHT = new hash_node_t*[desc_htable_size];
      for (int i = 0; i < desc_htable_size; i++)
	descHT[i] = NULL;

      for (int i = 0; i < old_htable_size; i++)
	if (old_htable[i] != NULL)
	  {
	    hash_node *old_p;
	    hash_node_t *hash_p = old_htable[i];
	    while (hash_p != NULL)
	      {
		hash_node_t *new_p = new hash_node_t ();
		new_p->nd = hash_p->nd;
		Node *dnode = NODE_IDX (hash_p->nd);
		Histable *dnode_instr = dnode->instr;
		hash_code = (unsigned int) dnode_instr->id % desc_htable_size;
		new_p->next = descHT[hash_code];
		descHT[hash_code] = new_p;
		old_p = hash_p;
		hash_p = hash_p->next;
		delete old_p;
	      }
	  }
      delete[] old_htable;
    }
  return dsc_idx;
}

PathTree::NodeIdx
PathTree::find_desc_node (NodeIdx node_idx, Histable *instr, bool leaf)
{
  // Binary search. All nodes are ordered by Histable::id.

  // We have a special case when two nodes with the same
  //	id value may co-exist: one representing a leaf node and
  //	another one representing a call site.
  Node *node = NODE_IDX (node_idx);
  int left = 0;
  int right = NUM_DESCENDANTS (node) - 1;
  while (left <= right)
    {
      int index = (left + right) / 2;
      NodeIdx dsc_idx = node->descendants->fetch (index);
      Node *dsc = NODE_IDX (dsc_idx);
      Histable *dinstr = dsc->instr;
      if (instr->id < dinstr->id)
	right = index - 1;
      else if (instr->id > dinstr->id)
	left = index + 1;
      else if (leaf == IS_LEAF (dsc))
	return dsc_idx;
      else if (leaf)
	right = index - 1;
      else
	left = index + 1;
    }

  // None was found. Create one.
  NodeIdx dsc_idx = new_Node (node_idx, instr, leaf);
  node->descendants->insert (left, dsc_idx);
  return dsc_idx;
}

PtreePhaseStatus
PathTree::process_packets (Experiment *exp, DataView *packets, int data_type)
{
  Expression::Context ctx (dbev, exp);
  char *progress_bar_msg = NULL;
  int progress_bar_percent = -1;

  Vector<BaseMetric*> *mlist = dbev->get_all_reg_metrics ();
  Vector<BaseMetric*> mlist2;
  StringBuilder stb;
  for (int midx = 0, mlist_sz = mlist->size (); midx < mlist_sz; ++midx)
    {
      BaseMetric *mtr = mlist->fetch (midx);
      if (mtr->get_packet_type () == data_type &&
	  (mtr->get_expr () == NULL || mtr->get_expr ()->passes (&ctx)))
	{
	  Hwcentry *hwc = mtr->get_hw_ctr ();
	  if (hwc)
	    {
	      stb.setLength (0);
	      // XXX this should be done at metric registration
	      Collection_params *col_params = exp->get_params ();
	      for (int i = 0; i < MAX_HWCOUNT; i++)
		{
		  // We may have duplicate counters in col_params,
		  // check for all (see 5081284).
		  if (dbe_strcmp (hwc->name, col_params->hw_aux_name[i]) == 0)
		    {
		      if (stb.length () != 0)
			stb.append (NTXT ("||"));
		      stb.append (NTXT ("HWCTAG=="));
		      stb.append (i);
		    }
		}
	      if (stb.length () == 0)
		continue;
	      stb.append (NTXT ("&& ((HWCINT & "));
	      stb.append ((long long) HWCVAL_ERR_FLAG);
	      stb.append (NTXT (")==0)"));
	      char *s = stb.toString ();
	      mtr->set_cond_spec (s);
	      free (s);
	    }
	  ValueTag vtype = mtr->get_vtype ();
	  switch (vtype)
	    {
	    case VT_INT:
	    case VT_ULLONG:
	    case VT_LLONG:
	      break; // nothing to do
	    default:
	      vtype = VT_ULLONG; // ym: not sure when this would happen
	      break;
	    }
	  allocate_slot (mtr->get_id (), vtype);
	  mlist2.append (mtr);
	}
    }

  Slot **mslots = new Slot*[mlist2.size ()];
  for (int midx = 0, mlist_sz = mlist2.size (); midx < mlist_sz; ++midx)
    {
      BaseMetric *mtr = mlist2.fetch (midx);
      int id = mtr->get_id ();
      int slot_ind = find_slot (id);
      mslots[midx] = SLOT_IDX (slot_ind);
    }

  for (long i = 0, packets_sz = packets->getSize (); i < packets_sz; ++i)
    {
      if (dbeSession->is_interactive ())
	{
	  if (NULL == progress_bar_msg)
	    progress_bar_msg = dbe_sprintf (GTXT ("Processing Experiment: %s"),
					  get_basename (exp->get_expt_name ()));
	  int val = (int) (100 * i / packets_sz);
	  if (val > progress_bar_percent)
	    {
	      progress_bar_percent += 10;
	      if (theApplication->set_progress (val, progress_bar_msg)
		  && cancel_ok)
		{
		  delete[] mslots;
		  return CANCELED;
		}
	    }
	}

      NodeIdx path_idx = 0;
      ctx.put (packets, i);

      for (int midx = 0, mlist_sz = mlist2.size (); midx < mlist_sz; ++midx)
	{
	  BaseMetric *mtr = mlist2.fetch (midx);
	  if (mtr->get_cond () != NULL && !mtr->get_cond ()->passes (&ctx))
	    continue;

	  int64_t mval = mtr->get_val ()->eval (&ctx);
	  if (mval == 0)
	    continue;
	  if (path_idx == 0)
	    path_idx = find_path (exp, packets, i);
	  NodeIdx node_idx = path_idx;
	  Slot *mslot = mslots[midx];
	  while (node_idx)
	    {
	      INCREMENT_METRIC (mslot, node_idx, mval);
	      node_idx = NODE_IDX (node_idx)->ancestor;
	    }
	}
    }
  if (dbeSession->is_interactive ())
    free (progress_bar_msg);
  delete[] mslots;
  if (indx_expr != NULL)
    root->descendants->sort ((CompareFunc) desc_node_comp, this);
  return NORMAL;
}

DataView *
PathTree::get_filtered_events (int exp_index, int data_type)
{
  if (indx_expr != NULL)
    {
      IndexObjType_t *indexObj = dbeSession->getIndexSpace (indxtype);
      if (indexObj->memObj && data_type != DATA_HWC)
	return NULL;
    }
  return dbev->get_filtered_events (exp_index, data_type);
}

PtreePhaseStatus
PathTree::add_experiment (int exp_index)
{
  StringBuilder sb;
  char *expt_name;
  char *base_name;
  Emsg *m;
  Experiment *experiment = dbeSession->get_exp (exp_index);
  if (experiment->broken != 0)
    return NORMAL;
  status = 0;
  expt_name = experiment->get_expt_name ();
  base_name = get_basename (expt_name);

  hrtime_t starttime = gethrtime ();
  hrtime_t startvtime = gethrvtime ();

  // Experiment::getEndTime was initially implemented as
  // returning exp->last_event. To preserve the semantics
  // new Experiment::getLastEvent() is used here.
  hrtime_t tot_time = experiment->getLastEvent () - experiment->getStartTime ();

  if (!dbev->isShowAll () && (dbev->isShowHideChanged ()
			      || dbev->isNewViewMode ()))
    experiment->resetShowHideStack ();

  // To report experiment index to the user,
  // start numeration from 1, not 0
  sb.sprintf (GTXT ("PathTree processing experiment %d (`%s'); duration %lld.%06lld"),
	      exp_index + 1, base_name,
	      tot_time / NANOSEC, (tot_time % NANOSEC / 1000));
  m = new Emsg (CMSG_COMMENT, sb);
  statsq->append (m);

  DataView *prof_packet = get_filtered_events (exp_index, DATA_CLOCK);
  if (prof_packet && prof_packet->getSize () > 0)
    {
      if (process_packets (experiment, prof_packet, DATA_CLOCK) == CANCELED)
	return CANCELED;
      long clock_cnt = prof_packet->getSize ();
      double clock_rate;
      if (tot_time != 0)
	clock_rate = (double) clock_cnt / (double) tot_time * (double) NANOSEC;
      else
	clock_rate = (double) 0.;
      if (experiment->timelineavail)
	sb.sprintf (GTXT ("  Processed %ld clock-profile events (%3.2f/sec.)"),
		    clock_cnt, clock_rate);
      else
	sb.sprintf (GTXT ("  Processed %ld clock-profile events"), clock_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);

      // check for statistical validity
      if ((experiment->timelineavail == true)
	   && !dbev->get_filter_active () && (clock_cnt < MIN_PROF_CNT))
	{
	  sb.sprintf (GTXT ("WARNING: too few clock-profile events (%ld) in experiment %d (`%s') for statistical validity"),
		      clock_cnt, exp_index + 1, base_name);
	  m = new Emsg (CMSG_COMMENT, sb);
	  statsq->append (m);
	}
    }

  DataView *sync_packet = get_filtered_events (exp_index, DATA_SYNCH);
  if (sync_packet && sync_packet->getSize () > 0)
    {
      if (process_packets (experiment, sync_packet, DATA_SYNCH) == CANCELED)
	return CANCELED;
      long sync_cnt = sync_packet->getSize ();
      sb.sprintf (GTXT ("  Processed %ld synctrace events"), sync_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);
    }

  DataView *iotrace_packet = get_filtered_events (exp_index, DATA_IOTRACE);
  if (iotrace_packet && iotrace_packet->getSize () > 0)
    {
      if (process_packets (experiment, iotrace_packet, DATA_IOTRACE) == CANCELED)
	return CANCELED;
      long iotrace_cnt = iotrace_packet->getSize ();
      sb.sprintf (GTXT ("  Processed %ld IO trace events"), iotrace_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);
    }

  DataView *hwc_packet = get_filtered_events (exp_index, DATA_HWC);
  if (hwc_packet && hwc_packet->getSize () > 0)
    {
      if (process_packets (experiment, hwc_packet, DATA_HWC) == CANCELED)
	return CANCELED;
      long hwc_cnt = hwc_packet->getSize ();
      double hwc_rate = (double) hwc_cnt / (double) tot_time * (double) NANOSEC;
      if (experiment->timelineavail)
	sb.sprintf (GTXT ("  Processed %ld hwc-profile events (%3.2f/sec.)"),
		    hwc_cnt, hwc_rate);
      else
	sb.sprintf (GTXT ("  Processed %ld hwc-profile events"), hwc_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);

      // check for statistical validity
      if (experiment->timelineavail && !dbev->get_filter_active () && (hwc_cnt < MIN_PROF_CNT))
	{
	  sb.sprintf (GTXT ("WARNING: too few HW counter profile events (%ld) in experiment %d (`%s') for statistical validity"),
		      hwc_cnt, exp_index + 1, base_name);
	  m = new Emsg (CMSG_COMMENT, sb);
	  statsq->append (m);
	}
    }

  DataView *heap_packet = get_filtered_events (exp_index, DATA_HEAP);
  if (heap_packet && heap_packet->getSize () > 0)
    {
      if (process_packets (experiment, heap_packet, DATA_HEAP) == CANCELED)
	return CANCELED;
      long heap_cnt = heap_packet->getSize ();
      sb.sprintf (GTXT ("  Processed %ld heaptrace events"), heap_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);
    }

  DataView *race_packet = get_filtered_events (exp_index, DATA_RACE);
  if (race_packet && race_packet->getSize () > 0)
    {
      if (process_packets (experiment, race_packet, DATA_RACE) == CANCELED)
	return CANCELED;
      long race_cnt = race_packet->getSize ();
      sb.sprintf (GTXT ("  Processed %ld race access events"), race_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);
    }

  DataView *deadlock_packet = get_filtered_events (exp_index, DATA_DLCK);
  if (deadlock_packet && deadlock_packet->getSize () > 0)
    {
      if (process_packets (experiment, deadlock_packet, DATA_DLCK) == CANCELED)
	return CANCELED;
      long race_cnt = deadlock_packet->getSize ();
      sb.sprintf (GTXT ("  Processed %ld race access events"), race_cnt);
      m = new Emsg (CMSG_COMMENT, sb);
      statsq->append (m);
    }

  hrtime_t pathtime = gethrtime () - starttime;
  hrtime_t pathvtime = gethrvtime () - startvtime;
  sb.sprintf (GTXT ("PathTree time = %lld.%06lld CPU-time %lld.%06lld\n"),
	      pathtime / NANOSEC, (pathtime % NANOSEC) / 1000,
	      pathvtime / NANOSEC, (pathvtime % NANOSEC) / 1000);
  m = new Emsg (CMSG_COMMENT, sb);
  statsq->append (m);
  return NORMAL;
}

Hist_data *
PathTree::compute_metrics (MetricList *mlist, Histable::Type type,
			   Hist_data::Mode mode, Vector<Histable*> *objs,
			   Histable *context, Vector<Histable*> *sel_objs,
			   PtreeComputeOption computeOpt)
{
  VMode view_mode = dbev->get_view_mode ();

  // For displaying disassembly correctly in user mode with openmp
  if (ptree_internal != NULL &&
      (view_mode == VMODE_EXPERT ||
       (view_mode == VMODE_USER && (type == Histable::INSTR
				    || (dbev->isOmpDisMode ()
					&& type == Histable::FUNCTION
					&& mode == Hist_data::CALLEES
					&& computeOpt == COMPUTEOPT_OMP_CALLEE))
				    )))
    return ptree_internal->compute_metrics (mlist, type, mode, objs, context,
					    sel_objs);

  PtreePhaseStatus resetStatus = reset ();

  hist_data = new Hist_data (mlist, type, mode);
  int nmetrics = mlist->get_items ()->size ();
  int sort_ind = -1;
  Hist_data::HistItem *hi;
  int index;

  if (status != 0 || resetStatus == CANCELED)
    return hist_data;

  hist_data->set_status (Hist_data::SUCCESS);
  if (dbeSession->is_interactive () && mode != Hist_data::CALLEES)
    theApplication->set_progress (0, GTXT ("Constructing Metrics"));

  xlate = new int[nmetrics];
  for (int mind = 0; mind < nmetrics; mind++)
    {
      Metric *mtr = mlist->get (mind);
      xlate[mind] = find_slot (mtr->get_id ());
    }

  // Compute dynamic metrics
  obj_list = new Histable*[depth];
  if ((type == Histable::LINE || type == Histable::INSTR)
      && mode == Hist_data::CALLERS)
    node_list = new Node*[depth];
  percent = 0;
  ndone = 0;
  if (mode == Hist_data::MODL)
    {
      Histable *obj = objs && objs->size () > 0 ? objs->fetch (0) : NULL;
      if (obj != NULL)
	{
	  switch (obj->get_type ())
	    {
	    case Histable::FUNCTION:
	      {
		Vector<Function*> *funclist = new Vector<Function*>;
		funclist->append ((Function*) obj);
		get_metrics (funclist, context);
		delete funclist;
		break;
	      }
	    case Histable::MODULE:
	      {
		Vector<Histable*> *comparableModules = obj->get_comparable_objs ();
		if (comparableModules != NULL)
		  {
		    Vector<Function*> *functions = new Vector<Function*>;
		    for (int i = 0; i < comparableModules->size (); i++)
		      {
			Module *mod = (Module*) comparableModules->fetch (i);
			if (mod)
			  {
			    bool found = false;
			    for (int i1 = 0; i1 < i; i1++)
			      {
				if (mod == comparableModules->fetch (i1))
				  {
				    found = true;
				    break;
				  }
			      }
			    if (!found)
			      functions->addAll (mod->functions);
			  }
		      }
		    get_metrics (functions, context);
		    delete functions;
		  }
		else
		  get_metrics (((Module*) obj)->functions, context);
		break;
	      }
	    case Histable::SOURCEFILE:
	      get_metrics (((SourceFile *) obj)->get_functions (), context);
	      break;
	    default:
	      DBG (assert (0));
	    }
	}
    }
  else if (mode == Hist_data::CALLERS)
    {
      if (objs && objs->size () > 0)
	get_clr_metrics (objs);
    }
  else if (mode == Hist_data::CALLEES)
    {
      if (objs && objs->size () > 0)
	get_cle_metrics (objs);
      else   // Special case: get root
	get_cle_metrics (NULL);
    }
  else if (mode == Hist_data::SELF)
    {
      if (objs->size () == 1)
	{
	  Histable *obj = objs->fetch (0);
	  if (obj != NULL)
	    {
	      if (obj->get_type () == Histable::LINE)
		{
		  Vector<Function*> *funclist = new Vector<Function*>;
		  for (DbeLine *dl = (DbeLine*) obj->convertto (Histable::LINE);
			  dl; dl = dl->dbeline_func_next)
		    if (dl->func)
		      funclist->append (dl->func);

		  get_self_metrics (obj, funclist, sel_objs);
		  delete funclist;
		}
	      else if (obj->get_type () == Histable::FUNCTION
		       || obj->get_type () == Histable::INSTR)
		{
		  // Use shortcut for functions and oth.
		  if (context)
		    {
		      Vector<Function*> *funclist = NULL;
		      if (context->get_type () == Histable::MODULE)
			funclist = ((Module*) context)->functions->copy ();
		      else
			{
			  funclist = new Vector<Function*>;
			  funclist->append ((Function*) context);
			}
		      get_self_metrics (obj, funclist, sel_objs);
		      delete funclist;
		    }
		  else
		    get_self_metrics (objs);
		}
	      else
		get_self_metrics (objs);
	    }
	}
      else
	get_self_metrics (objs);
    }
  else   // Hist_data::ALL
    get_metrics (root_idx, 0);

  delete[] obj_list;
  if ((type == Histable::LINE || type == Histable::INSTR)
      && mode == Hist_data::CALLERS)
    delete[] node_list;

  // Postprocess; find total
  for (long mind = 0, sz = mlist->get_items ()->size (); mind < sz; mind++)
    {
      Metric *mtr = mlist->get_items ()->get (mind);
      Metric::SubType subtype = mtr->get_subtype ();
      ValueTag vtype = mtr->get_vtype ();
      hist_data->total->value[mind].tag = vtype;

      switch (vtype)
	{
	  // ignoring the following cases (why?)
	case VT_SHORT:
	case VT_FLOAT:
	case VT_HRTIME:
	case VT_LABEL:
	case VT_ADDRESS:
	case VT_OFFSET:
	  break;

	case VT_INT:
	  // Calculate total as the sum of all values in hist_data for
	  // ATTRIBUTED metrics only. For all others, use root node values.
	  //
	  if ((mode == Hist_data::CALLERS || mode == Hist_data::CALLEES)
	      && subtype == Metric::ATTRIBUTED)
	    {
	      hist_data->total->value[mind].i = 0;
	      Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	      {
		hist_data->total->value[mind].i += hi->value[mind].i;
	      }
	      if (mode == Hist_data::CALLEES)
		hist_data->total->value[mind].i += hist_data->gprof_item->value[mind].i;
	    }
	  else if (xlate[mind] != -1)
	    ASN_METRIC_VAL (hist_data->total->value[mind], slots[xlate[mind]],
			    root_idx);
	  break;

	case VT_LLONG:
	  Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	  {
	    hi->value[mind].tag = vtype;
	  }

	  if ((mode == Hist_data::CALLERS || mode == Hist_data::CALLEES)
	      && subtype == Metric::ATTRIBUTED)
	    {
	      hist_data->total->value[mind].ll = 0;
	      Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	      {
		hist_data->total->value[mind].ll += hi->value[mind].ll;
	      }
	      if (mode == Hist_data::CALLEES)
		hist_data->total->value[mind].ll += hist_data->gprof_item->value[mind].ll;
	    }
	  else if (xlate[mind] != -1)
	    ASN_METRIC_VAL (hist_data->total->value[mind], slots[xlate[mind]], root_idx);
	  break;

	case VT_ULLONG:
	  Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	  {
	    hi->value[mind].tag = vtype;
	  }
	  if ((mode == Hist_data::CALLERS || mode == Hist_data::CALLEES)
	      && subtype == Metric::ATTRIBUTED)
	    {
	      hist_data->total->value[mind].ull = 0;
	      Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	      {
		hist_data->total->value[mind].ull += hi->value[mind].ull;
	      }
	      if (mode == Hist_data::CALLEES)
		hist_data->total->value[mind].ull += hist_data->gprof_item->value[mind].ull;
	    }
	  else if (xlate[mind] != -1)
	    ASN_METRIC_VAL (hist_data->total->value[mind], slots[xlate[mind]], root_idx);
	  break;

	case VT_DOUBLE:
	  double prec = mtr->get_precision ();
	  ValueTag vt = (xlate[mind] != -1) ? slots[xlate[mind]].vtype : VT_INT;
	  Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	  {
	    double val = (vt == VT_LLONG ? hi->value[mind].ll :
			  (vt == VT_ULLONG ? hi->value[mind].ull
			   : hi->value[mind].i));
	    hi->value[mind].tag = vtype;
	    hi->value[mind].d = val / prec;
	  }

	  if ((mode == Hist_data::CALLERS || mode == Hist_data::CALLEES)
	       && subtype == Metric::ATTRIBUTED)
	    {
	      hist_data->total->value[mind].d = 0.0;
	      Vec_loop (Hist_data::HistItem*, hist_data->hist_items, index, hi)
	      {
		hist_data->total->value[mind].d += hi->value[mind].d;
	      }
	      if (mode == Hist_data::CALLEES)
		hist_data->total->value[mind].d +=
		      (double) (vt == VT_LLONG ? hist_data->gprof_item->value[mind].ll :
				(vt == VT_ULLONG ? hist_data->gprof_item->value[mind].ull :
				 hist_data->gprof_item->value[mind].i)) / prec;
	    }
	  else if (xlate[mind] != -1)
	    {
	      TValue& total = hist_data->total->value[mind];
	      ASN_METRIC_VAL (total, slots[xlate[mind]], root_idx);
	      double val = (vt == VT_LLONG ? total.ll :
			    (vt == VT_ULLONG ? total.ll : total.i));
	      total.d = val / prec;
	    }
	  break;
	}
    }
  delete[] xlate;

  // Determine by which metric to sort if any
  bool rev_sort = mlist->get_sort_rev ();
  for (long mind = 0, sz = mlist->get_items ()->size (); mind < sz; mind++)
    {
      Metric *mtr = mlist->get_items ()->get (mind);
      if (mlist->get_sort_ref_index () == mind)
	sort_ind = mind;

      switch (mtr->get_type ())
	{
	case BaseMetric::SIZES:
	  Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
	  {
	    Histable *h = mtr->get_comparable_obj (hi->obj);
	    hi->value[mind].tag = VT_LLONG;
	    hi->value[mind].ll = h ? h->get_size () : 0;
	  }
	  break;
	case BaseMetric::ADDRESS:
	  Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
	  {
	    Histable *h = mtr->get_comparable_obj (hi->obj);
	    hi->value[mind].tag = VT_ADDRESS;
	    hi->value[mind].ll = h ? h->get_addr () : 0;
	  }
	  break;
	case BaseMetric::DERIVED:
	  {
	    Definition *def = mtr->get_definition ();
	    long *map = def->get_map ();
	    for (long i1 = 0, sz1 = hist_data->hist_items->size (); i1 < sz1; i1++)
	      {
		/* Hist_data::HistItem * */hi = hist_data->hist_items->get (i1);
		hi->value[mind].tag = VT_DOUBLE;
		hi->value[mind].d = def->eval (map, hi->value);
	      }
	    hist_data->total->value[mind].tag = VT_DOUBLE;
	    hist_data->total->value[mind].d = def->eval (map, hist_data->total->value);
	  }
	  break;
	default:
	  break;
	}
    }

  hist_data->sort (sort_ind, rev_sort);
  hist_data->compute_minmax ();
  if (dbeSession->is_interactive () && mode != Hist_data::CALLERS)
    theApplication->set_progress (0, GTXT (""));

#if DEBUG_FTREE
  if (ftree_hist_data)
    {
      bool matches = ftree_debug_match_hist_data (hist_data, ftree_hist_data);
      if (!matches)
	assert (false);
      delete hist_data;
      hist_data = ftree_hist_data; // return the debug version
    }
#endif
  return hist_data;
}

#if DEBUG_FTREE
bool
PathTree::ftree_debug_match_hist_data (Hist_data *data /* ref */,
				       Hist_data *data_tmp)
{
  if (data->get_status () != Hist_data::SUCCESS)
    {
      DBG (assert (false));
      return false;
    }
  if (data == NULL && data != data_tmp)
    {
      DBG (assert (false));
      return false;
    }

  MetricList *mlist;
  mlist = data->get_metric_list ();
  MetricList *mlist_tmp;
  mlist_tmp = data_tmp->get_metric_list ();
  if (mlist->size () != mlist_tmp->size ())
    {
      DBG (assert (false));
      return false;
    }

  // Get table size: count visible metrics
  int nitems = data->size ();
  if (data->size () != data_tmp->size ())
    {
      DBG (assert (false));
      return false;
    }

  for (int i = 0; i < nitems; ++i)
    {
      Hist_data::HistItem *item = data->fetch (i);
      Hist_data::HistItem *item_tmp = data_tmp->fetch (i);
      if (item->obj->id != item_tmp->obj->id)
	{
	  DBG (assert (false));
	  return false;
	}
    }

  for (long i = 0, sz = mlist->size (); i < sz; i++)
    {
      long met_ind = i;
      Metric *mitem = mlist->get (i);
      Metric *mitem_tmp = mlist_tmp->get (i);

      if (mitem->get_id () != mitem_tmp->get_id ())
	{
	  DBG (assert (false));
	  return false;
	}
      if (mitem->get_visbits () != mitem_tmp->get_visbits ())
	{
	  DBG (assert (false));
	  return false;
	}
      if (mitem->get_vtype () != mitem_tmp->get_vtype ())
	{
	  DBG (assert (false));
	  return false;
	}

      if (!mitem->is_visible () && !mitem->is_tvisible ()
	  && !mitem->is_pvisible ())
	continue;
      // table->append(dbeGetTableDataOneColumn(data, i));
      for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	{
	  Metric *m = mitem;
	  TValue res;
	  TValue res_tmp;
	  TValue *v = data->get_value (&res, met_ind, row);
	  TValue *v_tmp = data_tmp->get_value (&res_tmp, met_ind, row);
	  if ((m->get_visbits () & VAL_RATIO) != 0)
	    {
	      if (v->tag != VT_LABEL)
		{
		  if (v->to_double () != v_tmp->to_double ())
		    {
		      DBG (assert (false));
		      return false;
		    }
		}
	      continue;
	    }
	  switch (m->get_vtype ())
	    {
	    case VT_DOUBLE:
	      {
		double diff = v->d - v_tmp->d;
		if (diff < 0) diff = -diff;
		if (diff > 0.0001)
		  {
		    DBG (assert (false));
		    return false;
		  }
		else
		  DBG (assert (true));
		break;
	      }
	    case VT_INT:
	      if (v->i != v_tmp->i)
		{
		  DBG (assert (false));
		  return false;
		}
	      break;
	    case VT_ULLONG:
	    case VT_LLONG:
	    case VT_ADDRESS:
	      if (v->ll != v_tmp->ll)
		{
		  DBG (assert (false));
		  return false;
		}
	      break;

	    case VT_LABEL:
	      if (dbe_strcmp (v->l, v_tmp->l))
		{
		  DBG (assert (false));
		  return false;
		}
	      break;
	    default:
	      DBG (assert (false));
	      return false;
	    }
	}
    }
  return true;
}
#endif

Histable *
PathTree::get_hist_func_obj (Node *node)
{
  LoadObject *lo;
  Function *func;
  func = (Function*) (node->instr->convertto (Histable::FUNCTION));
  // LIBRARY VISIBILITY
  lo = func->module->loadobject;
  if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
    return lo->get_hide_function ();
  return get_compare_obj (func);
}

Histable *
PathTree::get_hist_obj (Node *node, Histable* context)
{
  LoadObject *lo;
  Function *func;
  switch (hist_data->type)
    {
    case Histable::INSTR:
      if (hist_data->mode == Hist_data::MODL)
	{
	  if (node->instr->get_type () != Histable::INSTR)
	    return NULL;
	}
      else
	{
	  // LIBRARY VISIBILITY
	  func = (Function*) (node->instr->convertto (Histable::FUNCTION));
	  lo = func->module->loadobject;
	  if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
	    return lo->get_hide_function ();
	}
      return node->instr;

    case Histable::LINE:
      if (hist_data->mode != Hist_data::MODL)
	{
	  func = (Function*) (node->instr->convertto (Histable::FUNCTION));
	  lo = func->module->loadobject;
	  // LIBRARY VISIBILITY
	  if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
	    return lo->get_hide_function ();
	}
      // For openmp user mode - the stack is already made with dbelines,
      // no need to convert it
      if (node->instr->get_type () == Histable::LINE)
	return node->instr;
      return node->instr->convertto (Histable::LINE, context);

    case Histable::FUNCTION:
      if (pathTreeType == PATHTREE_INTERNAL_FUNCTREE && node->ancestor != 0)
	func = (Function*) node->instr;
      else
	func = (Function*) (node->instr->convertto (Histable::FUNCTION));
      lo = func->module->loadobject;
      // LIBRARY VISIBILITY
      if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
	return lo->get_hide_function ();
      return get_compare_obj (func);
    case Histable::MODULE:
      func = (Function*) (node->instr->convertto (Histable::FUNCTION));
      return func->module;
    case Histable::LOADOBJECT:
      func = (Function*) (node->instr->convertto (Histable::FUNCTION));
      return func->module->loadobject;
    case Histable::INDEXOBJ:
    case Histable::MEMOBJ:
      return node->instr;
    default:
      DBG (assert (0));
    }
  return NULL;
}

Histable *
PathTree::get_compare_obj (Histable *obj)
{
  if (obj && dbev->comparingExperiments ())
    obj = dbev->get_compare_obj (obj);
  return obj;
}

void
PathTree::get_metrics (NodeIdx node_idx, int dpth)
{
  Node *node = NODE_IDX (node_idx);
  Histable *cur_obj = get_hist_obj (node);
  obj_list[dpth] = cur_obj;

  // Check for recursion (inclusive metrics)
  int incl_ok = 1;
  for (int i = dpth - 1; i >= 0; i--)
    if (cur_obj == obj_list[i])
      {
	incl_ok = 0;
	break;
      }

  // Check for leaf nodes (exclusive metrics)
  int excl_ok = 0;
  if (IS_LEAF (node) || node == NODE_IDX (root_idx))
    excl_ok = 1;

  // We shouldn't eliminate empty subtrees here because
  // we create the list of hist items dynamically and want
  // one for each object in the tree.
  cur_obj = get_compare_obj (cur_obj);
  Hist_data::HistItem *hi = hist_data->append_hist_item (cur_obj);
  DBG (assert (hi != NULL));

  MetricList *mlist = hist_data->get_metric_list ();
  for (long ind = 0, sz = mlist->size (); ind < sz; ind++)
    {
      if (xlate[ind] == -1)
	continue;
      Metric *mtr = mlist->get (ind);
      Metric::SubType subtype = mtr->get_subtype ();
      if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
	continue;

      switch (subtype)
	{
	case Metric::INCLUSIVE:
	  if (incl_ok && hi)
	    ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	  break;
	case Metric::EXCLUSIVE:
	  if (excl_ok && hi)
	    ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	  break;
	  // ignoring the following cases (why?)
	case Metric::STATIC:
	case Metric::ATTRIBUTED:
	  break;
	case Metric::DATASPACE:
	  if (hi)
	    ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	  break;
	}
    }

  if (dbeSession->is_interactive ())
    {
      ndone++;
      int new_percent = 95 * ndone / nodes;
      if (new_percent > percent)
	{
	  percent = new_percent;
	  theApplication->set_progress (percent, NULL);
	}
    }

  // Recursively process all descendants
  int index;
  int dsize = NUM_DESCENDANTS (node);
  for (index = 0; index < dsize; index++)
    get_metrics (node->descendants->fetch (index), dpth + 1);
}

void
PathTree::get_clr_metrics (Vector<Histable*> *objs, NodeIdx node_idx,
			   int pmatch, int dpth)
{
  Node *node = NODE_IDX (node_idx);
  Histable *cur_obj;
  if (hist_data->type == Histable::LINE || hist_data->type == Histable::INSTR)
    {
      cur_obj = get_hist_func_obj (node);
      node_list[dpth] = node;
    }
  else
    cur_obj = get_hist_obj (node);
  obj_list[dpth] = cur_obj;

  bool match = false;
  int nobj = objs->size ();
  if (dpth + 1 >= nobj)
    {
      match = true;
      for (int i = 0; i < nobj; ++i)
	{
	  if (objs->fetch (i) != obj_list[dpth - nobj + 1 + i])
	    {
	      match = false;
	      break;
	    }
	}
    }

  Hist_data::HistItem *hi = NULL;
  Hist_data::HistItem *hi_adj = NULL;
  if (match && dpth >= nobj)
    {
      if (hist_data->type == Histable::LINE
	  || hist_data->type == Histable::INSTR)
	hi = hist_data->append_hist_item (get_hist_obj (node_list[dpth - nobj]));
      else
	hi = hist_data->append_hist_item (obj_list[dpth - nobj]);

      if (pmatch >= 0 && pmatch >= nobj)
	{
	  if (hist_data->type == Histable::LINE
	      || hist_data->type == Histable::INSTR)
	    hi_adj = hist_data->append_hist_item (get_hist_obj (
						    node_list[pmatch - nobj]));
	  else
	    hi_adj = hist_data->append_hist_item (obj_list[pmatch - nobj]);
	}
    }

  if (hi != NULL)
    {
      MetricList *mlist = hist_data->get_metric_list ();
      for (long ind = 0, sz = mlist->size (); ind < sz; ind++)
	{
	  if (xlate[ind] == -1)
	    continue;
	  if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
	    continue;
	  Metric *mtr = mlist->get (ind);
	  Metric::SubType subtype = mtr->get_subtype ();

	  switch (subtype)
	    {
	    case Metric::ATTRIBUTED:
	      if (hi)
		ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	      if (hi_adj)
		SUB_METRIC_VAL (hi_adj->value[ind], slots[xlate[ind]], node_idx);
	      break;
	    case Metric::STATIC:
	    case Metric::EXCLUSIVE:
	    case Metric::INCLUSIVE:
	    case Metric::DATASPACE:
	      break;
	    }
	}
    }

  // Recursively process all descendants
  int dsize = NUM_DESCENDANTS (node);
  for (int index = 0; index < dsize; index++)
    get_clr_metrics (objs, node->descendants->fetch (index),
		     match ? dpth : pmatch, dpth + 1);
}

void
PathTree::get_clr_metrics (Vector<Histable*> *objs)
{
  get_clr_metrics (objs, root_idx, -1, 0);
}

void
PathTree::get_cle_metrics (Vector<Histable*> *objs, NodeIdx node_idx, int pcle,
			   int pmatch, int dpth)
{
  Node *node = NODE_IDX (node_idx);
  Histable *cur_obj = get_hist_obj (node);
  obj_list[dpth] = cur_obj;

  bool match = false;
  int nobj = objs->size ();
  if (dpth + 1 >= nobj)
    {
      match = true;
      for (int i = 0; i < nobj; ++i)
	if (objs->fetch (i) != obj_list[dpth - nobj + 1 + i])
	  {
	    match = false;
	    break;
	  }
    }

  Hist_data::HistItem *hi = NULL;
  Hist_data::HistItem *hi_adj = NULL;
  if (pmatch >= 0 && dpth == pmatch + 1)
    hi = hist_data->append_hist_item (cur_obj);
  if (match && IS_LEAF (node))
    hi = hist_data->gprof_item;
  if (pcle >= 0)
    hi_adj = hist_data->append_hist_item (obj_list[pcle]);

  if (hi != NULL)
    {
      MetricList *mlist = hist_data->get_metric_list ();
      for (long ind = 0, sz = mlist->size (); ind < sz; ind++)
	{
	  if (xlate[ind] == -1)
	    continue;
	  if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
	    continue;
	  Metric *mtr = mlist->get (ind);
	  Metric::SubType subtype = mtr->get_subtype ();
	  if (subtype == Metric::ATTRIBUTED)
	    {
	      ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	      if (hi_adj)
		SUB_METRIC_VAL (hi_adj->value[ind], slots[xlate[ind]], node_idx);
	    }
	}
    }

  // Recursively process all descendants
  int dsize = NUM_DESCENDANTS (node);
  for (int index = 0; index < dsize; index++)
    get_cle_metrics (objs, node->descendants->fetch (index),
		     pmatch >= 0 && dpth == pmatch + 1 ? dpth : pcle,
		     match ? dpth : pmatch, dpth + 1);
}

void
PathTree::get_cle_metrics (Vector<Histable*> *objs, NodeIdx node_idx, int dpth)
{
  Node *node = NODE_IDX (node_idx);
  Histable *cur_obj = get_hist_obj (node);
  Hist_data::HistItem *hi = NULL;
  if (NULL == objs)   // Special case: get root
    hi = hist_data->append_hist_item (cur_obj);
  else
    {
      if (dpth == objs->size ())
	hi = hist_data->append_hist_item (cur_obj);
      else if (cur_obj == objs->fetch (dpth))
	{
	  // Recursively process all descendants
	  int dsize = NUM_DESCENDANTS (node);
	  for (int index = 0; index < dsize; index++)
	    get_cle_metrics (objs, node->descendants->fetch (index), dpth + 1);
	  if (dpth == objs->size () - 1 && dsize == 0)
	    hi = hist_data->gprof_item;
	}
    }

  if (hi != NULL)
    {
      MetricList *mlist = hist_data->get_metric_list ();
      for (long ind = 0, sz = mlist->size (); ind < sz; ind++)
	{
	  if (xlate[ind] == -1)
	    continue;
	  if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
	    continue;
	  Metric *mtr = mlist->get (ind);
	  Metric::SubType subtype = mtr->get_subtype ();
	  if (subtype == Metric::ATTRIBUTED)
	    ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	}
    }
}

void
PathTree::ftree_reset ()
{
  if (pathTreeType == PATHTREE_MAIN && indxtype < 0)
    {
      reset ();
      if (ftree_needs_update)
	{
	  if (ftree_internal == NULL)
	    {
	      ftree_internal = new PathTree (dbev, indxtype,
					     PATHTREE_INTERNAL_FUNCTREE);
	      if (ftree_internal == NULL)
		return;
	    }
	  ftree_internal->ftree_build (this);
	  ftree_needs_update = false;
	}
    }
}

void
PathTree::ftree_build (PathTree * mstr)
{
  fini ();
  init ();
  allocate_slots (mstr->slots, mstr->nslots);
  ftree_build (mstr, mstr->root_idx, root_idx);
  depth = mstr->depth;
  depth_map_build ();
}

#if DEBUG_FTREE // possibly TBR
void
PathTree::ftree_dump ()
{
  hrtime_t starttime, endtime;
  int nmetrics = 1;
  // int nmetrics = nslots;
  for (int kk = 0; kk < nmetrics; kk++)
    {
      int id = slots[kk].id;
      starttime = gethrtime ();
      long nodecnt = 0;
      for (int ii = 0; ii < depth; ii++)
	{
	  Vector<Vector<void*>*> *tmp = (Vector<Vector<void*>*>*)get_ftree_level
		  (id, ii);
	  if (tmp == NULL)
	    continue;
	  long sz = tmp->get (0)->size ();
	  nodecnt += sz;
#if 1
	  //   fprintf(stderr, "... finished (%ld nodes)\n", sz);
#else
	  Vector<NodeIdx> *nodeIdxList = (Vector<NodeIdx> *)tmp->get (0);
	  Vector<NodeIdx> *ancestorNodeIdxList = (Vector<NodeIdx> *)tmp->get (1);
	  Vector<uint64_t> *idList = (Vector<uint64_t> *)tmp->get (2);
	  Vector<uint64_t> *vals = (Vector<uint64_t> *)tmp->get (3);
	  for (int jj = 0; jj < sz; jj++)
	    fprintf (stderr, " ...%d:%d node=%ld, anc=%ld, id=%llu, val=%llu\n",
		     sz, jj, nodeIdxList->get (jj),
		     ancestorNodeIdxList->get (jj),
		     idList->get (jj), vals->get (jj));
#endif
	  destroy (tmp);
	}
      endtime = gethrtime ();
      fprintf (stderr, "====================== %ld nodes time=%llu\n",
	       nodecnt, (endtime - starttime) / 1000 / 1000);
    }
}
#endif

// ftree: translate mstr Histable::INSTR to Histable::FUNCTION
void
PathTree::ftree_build (PathTree *mstr, NodeIdx mstr_node_idx,
		       NodeIdx local_node_idx)
{
  // requires: slots, nslots
  Node *mstr_node = mstr->NODE_IDX (mstr_node_idx);
  int dsize = NUM_DESCENDANTS (mstr_node);

  // Add metrics
  for (int i = 0; i < nslots; i++)
    {
      if (i >= mstr->nslots)
	continue; //weird
      if (slots[i].vtype != mstr->slots[i].vtype)
	continue; //weird
      TValue val;
      val.ll = 0;
      mstr->ASN_METRIC_VAL (val, mstr->slots[i], mstr_node_idx);
      int64_t mval;
      switch (slots[i].vtype)
	{
	case VT_ULLONG:
	case VT_LLONG:
	  mval = val.ll;
	  break;
	case VT_INT:
	  mval = val.i;
	  break;
	default:
	  mval = 0;
	  break;
	}
      if (mval)
	{
	  Slot * mslot = SLOT_IDX (i);
	  if (mslot)
	    INCREMENT_METRIC (mslot, local_node_idx, mval);
	}
    }

  // Recursively process all descendants
  for (int index = 0; index < dsize; index++)
    {
      NodeIdx mstr_desc_node_idx = mstr_node->descendants->fetch (index);
      Node *mstr_desc_node = mstr->NODE_IDX (mstr_desc_node_idx);
      Function *func = (Function*) mstr_desc_node->instr->convertto (Histable::FUNCTION);
      int mstr_desc_dsize = NUM_DESCENDANTS (mstr_desc_node);
      bool leaf = (mstr_desc_dsize == 0);
      NodeIdx local_desc_node_idx = find_desc_node (local_node_idx, func, leaf);
      ftree_build (mstr, mstr_desc_node_idx, local_desc_node_idx);
    }
}

void
PathTree::depth_map_build ()
{
  destroy (depth_map);
  depth_map = new Vector<Vector<NodeIdx>*>(depth);
  if (depth)
    {
      depth_map->put (depth - 1, 0); // fill vector with nulls
      depth_map_build (root_idx, 0);
    }
}

void
PathTree::depth_map_build (NodeIdx node_idx, int dpth)
{
  Node *node = NODE_IDX (node_idx);

  Vector<NodeIdx> *node_idxs = depth_map->get (dpth);
  if (node_idxs == NULL)
    {
      node_idxs = new Vector<NodeIdx>();
      depth_map->store (dpth, node_idxs);
    }
  node_idxs->append (node_idx);

  // Recursively process all descendants
  int dsize = NUM_DESCENDANTS (node);
  for (int index = 0; index < dsize; index++)
    {
      NodeIdx desc_node_idx = node->descendants->fetch (index);
      depth_map_build (desc_node_idx, dpth + 1);
    }
}

int
PathTree::get_ftree_depth ()
{ // external use only
  ftree_reset ();
  if (!ftree_internal)
    return 0;
  return ftree_internal->get_depth ();
}

Vector<Function*>*
PathTree::get_ftree_funcs ()
{ // external use only
  ftree_reset ();
  if (!ftree_internal)
    return NULL;
  return ftree_internal->get_funcs ();
}

Vector<Function*>*
PathTree::get_funcs ()
{
  // get unique functions
  if (fn_map == NULL)
    return NULL;
  return fn_map->keySet ();
}

Vector<void*>*
PathTree::get_ftree_level (BaseMetric *bm, int dpth)
{ // external use only
  ftree_reset ();
  if (!ftree_internal)
    return NULL;
  return ftree_internal->get_level (bm, dpth);
}

Vector<void*>*
PathTree::get_level (BaseMetric *bm, int dpth)
{
  // Nodes at tree depth dpth
  if (dpth < 0 || dpth >= depth)
    return NULL;
  if (depth_map == NULL)
    return NULL;
  Vector<NodeIdx> *node_idxs = depth_map->get (dpth);
  return get_nodes (bm, node_idxs);
}

Vector<void*>*
PathTree::get_ftree_node_children (BaseMetric *bm, NodeIdx node_idx)
{ // external use only
  ftree_reset ();
  if (!ftree_internal)
    return NULL;
  return ftree_internal->get_node_children (bm, node_idx);
}

Vector<void*>*
PathTree::get_node_children (BaseMetric *bm, NodeIdx node_idx)
{
  // Nodes that are children of node_idx
  if (depth_map == NULL)
    return NULL;
  if (node_idx == 0)  // special case for root
    return get_nodes (bm, depth_map->get (0));
  if (node_idx < 0 || node_idx >= nodes)
    return NULL;
  Node *node = NODE_IDX (node_idx);
  if (node == NULL)
    return NULL;
  Vector<NodeIdx> *node_idxs = node->descendants;
  return get_nodes (bm, node_idxs);
}

Vector<void*>*
PathTree::get_nodes (BaseMetric *bm, Vector<NodeIdx> *node_idxs)
{ // used for ftree
  // capture info for node_idxs:
  //   node's idx
  //   node->ancestor idx
  //   node->instr->id
  //   mind metric value // in the future, could instead accept vector of mind
  if (node_idxs == NULL)
    return NULL;
  long sz = node_idxs->size ();
  if (sz <= 0)
    return NULL;

  bool calculate_metric = false;
  ValueTag vtype;
  int slot_idx;
  double prec;
  if (bm != NULL)
    {
      int mind = bm->get_id ();
      slot_idx = find_slot (mind); // may be -1 (CPI and IPC)
      prec = bm->get_precision ();
      vtype = bm->get_vtype ();
    }
  else
    {
      slot_idx = -1;
      prec = 1.0;
      vtype = VT_INT;
    }

  if (slot_idx >= 0)
    {
      switch (vtype)
	{
	case VT_ULLONG:
	case VT_LLONG:
	case VT_INT:
	  if (slots[slot_idx].vtype == vtype)
	    calculate_metric = true;
	  else
	    DBG (assert (false));
	  break;
	case VT_DOUBLE:
	  calculate_metric = true;
	  break;
	default:
	  break;
	}
    }

  Vector<void*> *results = new Vector<void*>(4);
  if (!calculate_metric)
    results->store (3, NULL);
  else
    {
      // Code below cribbed from Dbe.cc:dbeGetTableDataV2Data.
      // TBD: possibly create an intermediate HistData and instead call that routine
      switch (vtype)
	{
	case VT_ULLONG:
	case VT_LLONG:
	  {
	    Vector<long long> *vals = new Vector<long long>(sz);
	    for (long i = 0; i < sz; i++)
	      {
		NodeIdx node_idx = node_idxs->get (i);
		TValue val;
		val.ll = 0;
		ASN_METRIC_VAL (val, slots[slot_idx], node_idx);
		vals->append (val.ll);
	      }
	    results->store (3, vals);
	    break;
	  }
	case VT_DOUBLE:
	  {
	    Vector<double> *vals = new Vector<double>(sz);
	    TValue val;
	    val.tag = slots[slot_idx].vtype; // required for to_double();
	    for (long i = 0; i < sz; i++)
	      {
		NodeIdx node_idx = node_idxs->get (i);
		val.ll = 0;
		ASN_METRIC_VAL (val, slots[slot_idx], node_idx);
		double dval = val.to_double ();
		dval /= prec;
		vals->append (dval);
	      }
	    results->store (3, vals);
	    break;
	  }
	case VT_INT:
	  {
	    Vector<int> *vals = new Vector<int>(sz);
	    for (long i = 0; i < sz; i++)
	      {
		NodeIdx node_idx = node_idxs->get (i);
		TValue val;
		val.i = 0;
		ASN_METRIC_VAL (val, slots[slot_idx], node_idx);
		vals->append (val.i);
	      }
	    results->store (3, vals);
	    break;
	  }
	default:
	  results->store (3, NULL);
	  break;
	}
    }

  Vector<int> *nodeIdxList = new Vector<int>(sz);
  Vector<int> *ancestorNodeIdxList = new Vector<int>(sz);
  Vector<uint64_t> *idList = new Vector<uint64_t>(sz);
  for (long i = 0; i < sz; i++)
    {
      NodeIdx node_idx = node_idxs->get (i);
      Node *node = NODE_IDX (node_idx);
      NodeIdx ancestor_idx = node->ancestor;
      Histable *func = node->instr;
      nodeIdxList->append (node_idx);
      ancestorNodeIdxList->append (ancestor_idx);
      idList->append (func->id);
    }

  results->store (0, nodeIdxList);
  results->store (1, ancestorNodeIdxList);
  results->store (2, idList);
  return results;
}

void
PathTree::get_cle_metrics (Vector<Histable*> *objs)
{
  if (NULL == objs || objs->fetch (0) == get_hist_obj (NODE_IDX (root_idx)))
    // Call Tree optimization
    get_cle_metrics (objs, root_idx, 0);
  else
    // General case
    get_cle_metrics (objs, root_idx, -1, -1, 0);
}

void
PathTree::get_metrics (Vector<Function*> *functions, Histable *context)
{
  Function *fitem;
  int excl_ok, incl_ok;
  NodeIdx node_idx;
  Node *node, *anc;
  int index;

  Vec_loop (Function*, functions, index, fitem)
  {
    node_idx = fn_map->get (fitem);
    for (; node_idx; node_idx = node->funclist)
      {
	node = NODE_IDX (node_idx);
	Histable *h_obj = get_hist_obj (node, context);
	if (h_obj == NULL)
	  continue;

	// Check for recursion (inclusive metrics)
	incl_ok = 1;
	for (anc = NODE_IDX (node->ancestor); anc;
		anc = NODE_IDX (anc->ancestor))
	  {
	    if (h_obj == get_hist_obj (anc, context))
	      {
		incl_ok = 0;
		break;
	      }
	  }

	// Check for leaf nodes (exclusive metrics)
	excl_ok = 0;
	if (IS_LEAF (node))
	  excl_ok = 1;

	h_obj = get_compare_obj (h_obj);
	Hist_data::HistItem *hi = hist_data->append_hist_item (h_obj);

	if (!excl_ok)
	  hist_data->get_callsite_mark ()->put (h_obj, 1);
	MetricList *mlist = hist_data->get_metric_list ();
	for (long ind = 0, sz = mlist->size (); ind < sz; ind++)
	  {
	    if (xlate[ind] == -1)
	      continue;
	    Metric *mtr = mlist->get (ind);
	    Metric::SubType subtype = mtr->get_subtype ();
	    if (subtype == Metric::INCLUSIVE && !incl_ok)
	      continue;
	    if (subtype == Metric::EXCLUSIVE && !excl_ok)
	      continue;
	    if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
	      continue;
	    ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	  }
      }
  }
}

void
PathTree::get_self_metrics (Vector<Histable*> *objs, NodeIdx node_idx,
			    bool seen, int dpth)
{
  Node *node = NODE_IDX (node_idx);
  Histable *cur_obj = get_hist_obj (node);
  obj_list[dpth] = cur_obj;

  bool match = false;
  int nobj = objs->size ();
  if (dpth + 1 >= nobj)
    {
      match = true;
      for (int i = 0; i < nobj; ++i)
	{
	  if (objs->fetch (i) != obj_list[dpth - nobj + 1 + i])
	    {
	      match = false;
	      break;
	    }
	}
    }

  if (match)
    {
      Hist_data::HistItem *hi = hist_data->append_hist_item (cur_obj);
      int incl_ok = !seen;
      int excl_ok = 0;
      if (IS_LEAF (node) || node == NODE_IDX (root_idx))
	excl_ok = 1;
      MetricList *mlist = hist_data->get_metric_list ();
      for (long ind = 0, sz = mlist->size (); ind < sz; ind++)
	{
	  if (xlate[ind] == -1)
	    continue;
	  if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
	    continue;
	  Metric *mtr = mlist->get (ind);
	  Metric::SubType subtype = mtr->get_subtype ();
	  switch (subtype)
	    {
	    case Metric::INCLUSIVE:
	      if (incl_ok && hi)
		ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	      break;
	    case Metric::EXCLUSIVE:
	    case Metric::ATTRIBUTED:
	      if (excl_ok && hi)
		ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	      break;
	    case Metric::DATASPACE:
	      if (hi)
		ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	      break;
	      // ignoring the following cases (why?)
	    case Metric::STATIC:
	      break;
	    }
	}
    }

  if (dbeSession->is_interactive ())
    {
      ndone++;
      int new_percent = 95 * ndone / nodes;
      if (new_percent > percent)
	{
	  percent = new_percent;
	  theApplication->set_progress (percent, NULL);
	}
    }

  // Recursively process all descendants
  int index;
  int dsize = NUM_DESCENDANTS (node);
  for (index = 0; index < dsize; index++)
    get_self_metrics (objs, node->descendants->fetch (index),
		      seen || match, dpth + 1);
}

void
PathTree::get_self_metrics (Vector<Histable*> *objs)
{
  get_self_metrics (objs, root_idx, false, 0);
}

void
PathTree::get_self_metrics (Histable *obj, Vector<Function*> *funclist,
			    Vector<Histable*>* sel_objs)
{
  int excl_ok, incl_ok;
  NodeIdx node_idx;
  Node *node, *anc;

  if (obj == NULL)
    return;

  SourceFile *src = NULL;
  if (obj && obj->get_type () == Histable::LINE)
    {
      DbeLine *dbeline = (DbeLine*) obj;
      src = dbeline->sourceFile;
    }

  Hist_data::HistItem *hi = hist_data->append_hist_item (obj);
  for (int i = 0, sz = funclist ? funclist->size () : 0; i < sz; i++)
    {
      Function *fitem = (Function*) get_compare_obj (funclist->fetch (i));
      node_idx = fn_map->get (fitem);
      for (; node_idx; node_idx = node->funclist)
	{
	  node = NODE_IDX (node_idx);
	  if (obj && obj->get_type () == Histable::LINE)
	    {
	      Histable *h = get_hist_obj (node, src);
	      if (h == NULL)
		continue;
	      if (h->convertto (Histable::LINE) != obj->convertto (Histable::LINE))
		continue;
	    }
	  else if (get_hist_obj (node, src) != obj)
	    continue;

	  // Check for recursion (inclusive metrics)
	  incl_ok = 1;
	  for (anc = NODE_IDX (node->ancestor); anc;
		  anc = NODE_IDX (anc->ancestor))
	    {
	      if (get_hist_obj (anc, src) == obj)
		{
		  incl_ok = 0;
		  break;
		}
	      if (sel_objs != NULL)
		for (int k = 0; k < sel_objs->size (); k++)
		  if (sel_objs->fetch (k) == get_hist_obj (anc, src))
		    {
		      incl_ok = 0;
		      break;
		    }
	    }

	  // Check for leaf nodes (exclusive metrics)
	  excl_ok = 0;
	  if (IS_LEAF (node) || node == NODE_IDX (root_idx))
	    excl_ok = 1;

	  MetricList *mlist = hist_data->get_metric_list ();
	  for (long ind = 0, ind_sz = mlist->size (); ind < ind_sz; ind++)
	    {
	      if (xlate[ind] == -1)
		continue;
	      Metric *mtr = mlist->get (ind);
	      Metric::SubType subtype = mtr->get_subtype ();
	      if (subtype == Metric::INCLUSIVE && !incl_ok)
		continue;
	      if (subtype == Metric::EXCLUSIVE && !excl_ok)
		continue;
	      if (subtype == Metric::ATTRIBUTED && !excl_ok)
		continue;
	      if (IS_MVAL_ZERO (slots[xlate[ind]], node_idx))
		continue;
	      ADD_METRIC_VAL (hi->value[ind], slots[xlate[ind]], node_idx);
	    }
	}
    }
}

Vector<Histable*> *
PathTree::get_clr_instr (Histable * func)
{
  Vector<Histable*> * instrs = NULL;
  if (func->get_type () != Histable::FUNCTION)
    return NULL;
  NodeIdx node_idx = fn_map->get ((Function*) func);
  Node *node = NODE_IDX (node_idx);
  if (node == NULL)
    return new Vector<Histable*>();
  int instr_num = 0;
  for (; node; node = NODE_IDX (node->funclist))
    instr_num++;
  instrs = new Vector<Histable*>(instr_num);
  node = NODE_IDX (node_idx);
  Histable *instr = NODE_IDX (node->ancestor)->instr;
  instr_num = 0;
  instrs->store (instr_num, instr);
  node = NODE_IDX (node->funclist);
  for (; node; node = NODE_IDX (node->funclist))
    {
      instr = NODE_IDX (node->ancestor)->instr;
      instr_num++;
      instrs->store (instr_num, instr);
    }
  return instrs;
}

Vector<void*> *
PathTree::get_cle_instr (Histable * func, Vector<Histable*>*&instrs)
{
  if (func->get_type () != Histable::FUNCTION)
    return NULL;
  NodeIdx node_idx = fn_map->get ((Function*) func);
  Node *node = NODE_IDX (node_idx);
  if (node == NULL)
    {
      instrs = new Vector<Histable*>();
      return new Vector<void*>();
    }
  int instr_num = 0;
  for (; node; node = NODE_IDX (node->funclist))
    instr_num++;
  instrs = new Vector<Histable*>(instr_num);
  Vector<void*> *callee_info = new Vector<void*>(instr_num);
  node = NODE_IDX (node_idx);
  Histable *instr = node->instr;
  instr_num = 0;
  instrs->store (instr_num, instr);
  int dec_num = 0;
  NodeIdx dec_idx = 0;
  if (NUM_DESCENDANTS (node) > 0)
    {
      Vector<Histable*> * callee_instrs = new Vector<Histable*>(node->descendants->size ());
      Vec_loop (NodeIdx, node->descendants, dec_num, dec_idx)
      {
	Node * dec_node = NODE_IDX (dec_idx);
	//XXXX Note: there can be more than one instrs in one leaf function
	callee_instrs->store (dec_num, dec_node->instr);
      }
      callee_info->store (instr_num, callee_instrs);
    }
  else
    callee_info->store (instr_num, NULL);
  node = NODE_IDX (node->funclist);
  for (; node; node = NODE_IDX (node->funclist))
    {
      instr = node->instr;
      instr_num++;
      instrs->store (instr_num, instr);
      if (NUM_DESCENDANTS (node) > 0)
	{
	  Vector<Histable*> * callee_instrs = new Vector<Histable*>(node->descendants->size ());
	  Vec_loop (NodeIdx, node->descendants, dec_num, dec_idx)
	  {
	    Node * dec_node = NODE_IDX (dec_idx);
	    //XXXX Note: there can be more than one instrs in one leaf function
	    callee_instrs->store (dec_num, dec_node->instr);
	  }
	  callee_info->store (instr_num, callee_instrs);
	}
      else
	callee_info->store (instr_num, NULL);
    }
  return callee_info;
}

//
//
// The following methods are used for debugging purpose only.
//
//
static int maxdepth;
static int maxwidth;

void
PathTree::print (FILE *fd)
{
  (void) reset ();
  fprintf (fd, NTXT ("n = %lld, dn = %lld, MD = %lld\n\n"),
	   (long long) nodes, (long long) dnodes, (long long) depth);
  maxdepth = 0;
  maxwidth = 0;
  print (fd, root, 0);
  fprintf (fd, NTXT ("md = %lld, mw = %lld\n"),
	   (long long) maxdepth, (long long) maxwidth);
}

void
PathTree::print (FILE *fd, PathTree::Node *node, int lvl)
{
  const char *t;
  char *n;
  if (lvl + 1 > maxdepth)
    maxdepth = lvl + 1;
  for (int i = 0; i < lvl; i++)
    fprintf (fd, NTXT ("-"));
  Histable *instr = node->instr;
  if (instr->get_type () == Histable::LINE)
    {
      t = "L";
      n = ((DbeLine *) instr)->func->get_name ();
    }
  else if (instr->get_type () == Histable::INSTR)
    {
      t = "I";
      n = ((DbeInstr *) instr)->func->get_name ();
    }
  else
    {
      t = "O";
      n = instr->get_name ();
    }
  long long addr = (long long) instr->get_addr ();
  fprintf (fd, NTXT ("%s %s (0x%08llx) -- ndesc = %lld\n"),
	   t, n, addr, (long long) (NUM_DESCENDANTS (node)));

  // Recursively process all descendants
  int dsize = NUM_DESCENDANTS (node);
  if (dsize > maxwidth)
    maxwidth = dsize;
  for (int index = 0; index < dsize; index++)
    print (fd, NODE_IDX (node->descendants->fetch (index)), lvl + 1);
}

void
PathTree::printn (FILE *fd)
{
  int n = dbg_nodes (root);
  fprintf (fd, GTXT ("Number of nodes: %d, total size: %d\n"), n, (int) (n * sizeof (Node)));
}

void
PathTree::dumpNodes (FILE *fd, Histable *obj)
{
  const char *t;
  char *n;
  NodeIdx node_idx = fn_map->get ((Function*) obj);
  Node *node = NODE_IDX (node_idx);
  if (node == NULL)
    {
      fprintf (fd, GTXT ("No nodes associated with %s\n"), obj->get_name ());
      return;
    }
  Histable *instr = node->instr;
  for (; node; node = NODE_IDX (node->funclist))
    {
      instr = node->instr;
      if (instr->get_type () == Histable::LINE)
	{
	  t = "L";
	  n = ((DbeLine *) instr)->func->get_name ();
	}
      else if (instr->get_type () == Histable::INSTR)
	{
	  t = "I";
	  n = ((DbeInstr *) instr)->func->get_name ();
	}
      else
	{
	  t = "O";
	  n = instr->get_name ();
	}
      long long addr = (long long) instr->get_addr ();
      if (addr <= 0xFFFFFFFFU)
	fprintf (fd, NTXT ("0x%08x -- %s %s\n"), (uint32_t) addr, t, n);
      else
	fprintf (fd, NTXT ("0x%016llX -- %s %s\n"), addr, t, n);
    }
}

int
PathTree::dbg_nodes (PathTree::Node *node)
{
  int res = 1;
  int dsize = NUM_DESCENDANTS (node);
  for (int index = 0; index < dsize; index++)
    res += dbg_nodes (NODE_IDX (node->descendants->fetch (index)));
  return res;
}

static int mind_g;

int
leak_alloc_comp (const void *s1, const void *s2)
{
  // See Hist_data::sort_compare() for duplicate code
  int result = 0;
  CStack_data::CStack_item *t1, *t2;
  t1 = *(CStack_data::CStack_item **)s1;
  t2 = *(CStack_data::CStack_item **)s2;

  switch (t1->value[mind_g].tag)
    {
    case VT_INT:
      if (t1->value[mind_g].i < t2->value[mind_g].i)
	result = -1;
      else if (t1->value[mind_g].i > t2->value[mind_g].i)
	result = 1;
      else
	result = 0;
      break;
    case VT_LLONG:
      if (t1->value[mind_g].ll < t2->value[mind_g].ll)
	result = -1;
      else if (t1->value[mind_g].ll > t2->value[mind_g].ll)
	result = 1;
      else
	result = 0;
      break;
    case VT_ULLONG:
      if (t1->value[mind_g].ull < t2->value[mind_g].ull)
	result = -1;
      else if (t1->value[mind_g].ull > t2->value[mind_g].ull)
	result = 1;
      else
	result = 0;
      break;
      // ignoring the following cases (why?)
    case VT_SHORT:
    case VT_FLOAT:
    case VT_DOUBLE:
    case VT_HRTIME:
    case VT_LABEL:
    case VT_ADDRESS:
    case VT_OFFSET:
      break;
    }
  // Sort in descending order
  return -result;
}

CStack_data *
PathTree::get_cstack_data (MetricList *mlist)
{
  (void) reset ();
  CStack_data *lam = new CStack_data (mlist);
  int nmetrics = mlist->get_items ()->size ();
  mind_g = -1;
  xlate = new int[nmetrics];
  for (int mind = 0; mind < nmetrics; mind++)
    {
      xlate[mind] = -1;
      Metric *mtr = mlist->get_items ()->fetch (mind);
      if (mlist->get_sort_ref_index () == mind)
	mind_g = mind;
      xlate[mind] = find_slot (mtr->get_id ());
    }

  // now fill in the actual data
  obj_list = new Histable*[depth];
  get_cstack_list (lam, root_idx, 0);
  delete[] obj_list;

  if (mind_g >= 0)
    lam->cstack_items->sort (leak_alloc_comp);
  delete[] xlate;
  return lam;
}

void
PathTree::get_cstack_list (CStack_data *lam, NodeIdx node_idx, int dpth)
{

  Node *node = NODE_IDX (node_idx);
  obj_list[dpth] = node->instr;

  CStack_data::CStack_item *item = NULL;
  if (IS_LEAF (node))
    item = lam->new_cstack_item ();
  int nmetrics = lam->metrics->get_items ()->size ();
  bool subtree_empty = true;

  for (int mind = 0; mind < nmetrics; mind++)
    {
      if (xlate[mind] == -1)
	continue;
      if (IS_MVAL_ZERO (slots[xlate[mind]], node_idx))
	continue;
      else
	subtree_empty = false;
      if (item)
	{
	  ADD_METRIC_VAL (item->value[mind], slots[xlate[mind]], node_idx);
	  ADD_METRIC_VAL (lam->total->value[mind], slots[xlate[mind]], node_idx);
	}
    }

  if (subtree_empty)
    {
      delete item;
      return;
    }

  if (item)
    {
      // Finish processing a leaf node
      item->stack = new Vector<DbeInstr*>(dpth);
      for (int i = 1; i <= dpth; i++)
	item->stack->append ((DbeInstr*) obj_list[i]);
      lam->cstack_items->append (item);
    }
  else
    {
      // Recursively process all descendants
      int dsize = NUM_DESCENDANTS (node);
      for (int index = 0; index < dsize; index++)
	get_cstack_list (lam, node->descendants->fetch (index), dpth + 1);
    }
}

Emsg *
PathTree::fetch_stats ()
{
  if (statsq == NULL)
    return NULL;
  return statsq->fetch ();
}

void
PathTree::delete_stats ()
{
  if (statsq != NULL)
    {
      delete statsq;
      statsq = new Emsgqueue (NTXT ("statsq"));
    }
}

Emsg *
PathTree::fetch_warnings ()
{
  if (warningq == NULL)
    return NULL;
  return warningq->fetch ();
}

void
PathTree::delete_warnings ()
{
  if (warningq != NULL)
    {
      delete warningq;
      warningq = new Emsgqueue (NTXT ("warningq"));
    }
}
