1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Callgrind                                                    ---*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                     global.h ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- (C) 2004, 2005 Josef Weidendorfer                            ---*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef CLG_GLOBAL
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_GLOBAL
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_basics.h"
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_vki.h"
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_debuginfo.h"
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcbase.h"
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcassert.h"
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcfile.h"
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcprint.h"
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcproc.h"
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_machine.h"
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_mallocfree.h"
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_options.h"
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_tooliface.h"
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_xarray.h"
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_clientstate.h"
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_machine.h"      // VG_(fnptr_to_fnentry)
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "events.h" // defines CLG_ macro
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "costs.h"
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Calltree compile options                            --- */
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Enable debug output */
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_ENABLE_DEBUG 1
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Enable experimental features? */
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_EXPERIMENTAL 0
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Syscall Timing in microseconds?
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * (define to 0 if you get compile errors) */
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_MICROSYSTIME 0
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set to 1 if you want full sanity checks for JCC */
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define JCC_CHECK 0
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Command line options                                 ---*/
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEFAULT_OUTFORMAT   "callgrind.out.%p"
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _CommandLineOptions CommandLineOptions;
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _CommandLineOptions {
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Dump format options */
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  const HChar* out_format;  /* Format string for callgrind output file name */
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Bool combine_dumps;       /* Dump trace parts into same file? */
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool compress_strings;
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool compress_events;
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool compress_pos;
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool mangle_names;
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool compress_mangled;
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool dump_line;
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool dump_instr;
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool dump_bb;
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool dump_bbs;         /* Dump basic block information? */
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Dump generation options */
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong dump_every_bb;     /* Dump every xxx BBs. */
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Collection options */
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool separate_threads; /* Separate threads in dump? */
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  separate_callers; /* Separate dependent on how many callers? */
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  separate_recursions; /* Max level of recursions to separate */
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool skip_plt;         /* Skip functions in PLT section? */
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool skip_direct_recursion; /* Increment direct recursions the level? */
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool collect_atstart;  /* Start in collecting state ? */
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool collect_jumps;    /* Collect (cond.) jumps in functions ? */
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool collect_alloc;    /* Collect size of allocated memory */
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool collect_systime;  /* Collect time for system calls */
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool collect_bus;      /* Collect global bus events */
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Instrument options */
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool instrument_atstart;  /* Instrument at start? */
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool simulate_cache;      /* Call into cache simulator ? */
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool simulate_branch;     /* Call into branch prediction simulator ? */
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Call graph generation */
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool pop_on_jump;       /* Handle a jump between functions as ret+call */
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if CLG_ENABLE_DEBUG
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int   verbose;
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong verbose_start;
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Constants                                            ---*/
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* According to IA-32 Intel Architecture Software Developer's Manual: Vol 2 */
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MAX_x86_INSTR_SIZE              16
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Minimum cache line size allowed */
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MIN_LINE_SIZE   16
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Size of various buffers used for storing strings */
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FILENAME_LEN                    VKI_PATH_MAX
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define FN_NAME_LEN                    4096 /* for C++ code :-) */
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define OBJ_NAME_LEN                    256
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define COSTS_LEN                       512 /* at least 17x 64bit values */
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define BUF_LEN                         512
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define COMMIFY_BUF_LEN                 128
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RESULTS_BUF_LEN                 256
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINE_BUF_LEN                     64
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Convenience macros */
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use this only when size of sprintf args are known to fit into
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * given buffer; for strings of unknown length, use WRITE_STR below
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRITE_SPRINTF(fd, zz_buf, fmt, args...) \
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { Int len = VG_(sprintf)(zz_buf, fmt, ## args); \
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)zz_buf, len); \
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRITE_STR(fd, str) \
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { if (str) { Int len = VG_(strlen)(str); \
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)str, len); } \
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else VG_(write)(fd, "(null)", 6); \
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRITE_STR2(fd, str1, str2) \
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { if (str1) { Int len = VG_(strlen)(str1); \
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)str1, len); } \
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else VG_(write)(fd, "(null)", 6); \
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (str2) { Int len = VG_(strlen)(str2); \
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)str2, len); } \
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else VG_(write)(fd, "(null)", 6); \
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRITE_STR3(fd, str1, str2, str3) \
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { if (str1) { Int len = VG_(strlen)(str1); \
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)str1, len); } \
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else VG_(write)(fd, "(null)", 6); \
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (str2) { Int len = VG_(strlen)(str2); \
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)str2, len); } \
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else VG_(write)(fd, "(null)", 6); \
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (str3) { Int len = VG_(strlen)(str3); \
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(write)(fd, (void*)str3, len); } \
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else VG_(write)(fd, "(null)", 6); \
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Statistics                                           ---*/
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _Statistics Statistics;
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _Statistics {
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong call_counter;
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong jcnd_counter;
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong jump_counter;
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong rec_call_counter;
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong ret_counter;
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong bb_executions;
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  context_counter;
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  bb_retranslations;
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_objs;
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_files;
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_fns;
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_contexts;
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_bbs;
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_jccs;
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_bbccs;
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_instrs;
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  distinct_skips;
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  bb_hash_resizes;
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  bbcc_hash_resizes;
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  jcc_hash_resizes;
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  cxt_hash_resizes;
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  fn_array_resizes;
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  call_stack_resizes;
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  fn_stack_resizes;
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  full_debug_BBs;
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  file_line_debug_BBs;
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  fn_name_debug_BBs;
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  no_debug_BBs;
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  bbcc_lru_misses;
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  jcc_lru_misses;
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  cxt_lru_misses;
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  bbcc_clones;
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Structure declarations                               ---*/
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _Context     Context;
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _CC          CC;
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _BB          BB;
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _BBCC        BBCC;
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _jCC         jCC;
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _fCC         fCC;
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _fn_node     fn_node;
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _file_node   file_node;
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _obj_node    obj_node;
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _fn_config   fn_config;
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _call_entry  call_entry;
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _thread_info thread_info;
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Costs of event sets. Aliases to arrays of 64-bit values */
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef ULong* SimCost;  /* All events the simulator can produce */
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef ULong* UserCost;
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef ULong* FullCost; /* Simulator + User */
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* The types of control flow changes that can happen between
232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * execution of two BBs in a thread.
233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */
234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef enum {
235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  jk_None = 0,   /* no explicit change by a guest instruction */
236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  jk_Jump,       /* regular jump */
237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  jk_Call,
238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  jk_Return,
239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  jk_CondJump    /* conditional jump taken (only used as jCC type) */
240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} ClgJumpKind;
241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* JmpCall cost center
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * for subroutine call (from->bb->jmp_addr => to->bb->addr)
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Each BB has at most one CALL instruction. The list of JCC from
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * this call is a pointer to the list head (stored in BBCC), and
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * <next_from> in the JCC struct.
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * For fast lookup, JCCs are reachable with a hash table, keyed by
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the (from_bbcc,to) pair. <next_hash> is used for the JCC chain
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * of one hash table entry.
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Cost <sum> holds event counts for already returned executions.
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * <last> are the event counters at last enter of the subroutine.
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * <sum> is updated on returning from the subroutine by
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * adding the diff of <last> and current event counters to <sum>.
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * After updating, <last> is set to current event counters. Thus,
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * events are not counted twice for recursive calls (TODO: True?)
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _jCC {
264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ClgJumpKind jmpkind; /* jk_Call, jk_Jump, jk_CondJump */
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  jCC* next_hash;   /* for hash entry chain */
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  jCC* next_from;   /* next JCC from a BBCC */
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BBCC *from, *to;  /* call arc from/to this BBCC */
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt jmp;         /* jump no. in source */
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ULong call_counter; /* no wraparound with 64 bit */
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  FullCost cost; /* simulator + user counters */
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Info for one instruction of a basic block.
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _InstrInfo InstrInfo;
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _InstrInfo {
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt instr_offset;
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt instr_size;
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt cost_offset;
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  EventSet* eventset;
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Info for a side exit in a BB
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _CJmpInfo CJmpInfo;
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _CJmpInfo {
294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  UInt instr;          /* instruction index for BB.instr array */
295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ClgJumpKind jmpkind; /* jump kind when leaving BB at this side exit */
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/**
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * An instrumented basic block (BB).
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * BBs are put into a resizable hash to allow for fast detection if a
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * BB is to be retranslated but cost info is already available.
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The key for a BB is a (object, offset) tupel making it independent
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * from possibly multiple mappings of the same ELF object.
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * At the beginning of each instrumented BB,
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * a call to setup_bbcc(), specifying a pointer to the
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * according BB structure, is added.
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * As cost of a BB has to be distinguished depending on the context,
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * multiple cost centers for one BB (struct BBCC) exist and the according
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * BBCC is set by setup_bbcc.
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _BB {
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  obj_node*  obj;         /* ELF object of BB */
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PtrdiffT   offset;      /* offset of BB in ELF object file */
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BB*        next;       /* chaining for a hash entry */
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  VgSectKind sect_kind;  /* section of this BB, e.g. PLT */
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt       instr_count;
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* filled by CLG_(get_fn_node) if debug info is available */
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fn_node*   fn;          /* debug info for this BB */
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt       line;
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool       is_entry;    /* True if this BB is a function entry */
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BBCC*      bbcc_list;  /* BBCCs for same BB (see next_bbcc in BBCC) */
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BBCC*      last_bbcc;  /* Temporary: Cached for faster access (LRU) */
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* filled by CLG_(instrument) if not seen before */
332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  UInt       cjmp_count;  /* number of side exits */
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  CJmpInfo*  jmp;         /* array of info for condition jumps,
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			   * allocated directly after this struct */
335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  Bool       cjmp_inverted; /* is last side exit actually fall through? */
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt       instr_len;
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt       cost_count;
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  InstrInfo  instr[0];   /* info on instruction sizes and costs */
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/**
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Function context
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Basic blocks are always executed in the scope of a context.
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * A function context is a list of function nodes representing
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the call chain to the current context: I.e. fn[0] is the
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * function we are currently in, fn[1] has called fn[0], and so on.
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Recursion levels are used for fn[0].
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * To get a unique number for a full execution context, use
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *  rec_index = min(<fn->rec_separation>,<active>) - 1;
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *  unique_no = <number> + rec_index
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * For each Context, recursion index and BB, there can be a BBCC.
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _Context {
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    UInt size;        // number of function dependencies
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    UInt base_number; // for context compression & dump array
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Context* next;    // entry chaining for hash
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    UWord hash;       // for faster lookup...
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    fn_node* fn[0];
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Cost info for a side exits from a BB
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _JmpData JmpData;
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _JmpData {
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ULong ecounter; /* number of times the BB was left at this exit */
374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    jCC*  jcc_list; /* JCCs used for this exit */
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Basic Block Cost Center
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * On demand, multiple BBCCs will be created for the same BB
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * dependend on command line options and:
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - current function (it's possible that a BB is executed in the
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *   context of different functions, e.g. in manual assembler/PLT)
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - current thread ID
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - position where current function is called from
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - recursion level of current function
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The cost centres for the instructions of a basic block are
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * stored in a contiguous array.
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * They are distinguishable by their tag field.
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _BBCC {
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    BB*      bb;           /* BB for this cost center */
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Context* cxt;          /* execution context of this BBCC */
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ThreadId tid;          /* only for assertion check purpose */
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    UInt     rec_index;    /* Recursion index in rec->bbcc for this bbcc */
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    BBCC**   rec_array;    /* Variable sized array of pointers to
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    * recursion BBCCs. Shared. */
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ULong    ret_counter;  /* how often returned from jccs of this bbcc;
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    * used to check if a dump for this BBCC is needed */
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    BBCC*    next_bbcc;    /* Chain of BBCCs for same BB */
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    BBCC*    lru_next_bbcc; /* BBCC executed next the last time */
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    jCC*     lru_from_jcc; /* Temporary: Cached for faster access (LRU) */
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    jCC*     lru_to_jcc;   /* Temporary: Cached for faster access (LRU) */
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    FullCost skipped;      /* cost for skipped functions called from
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    * jmp_addr. Allocated lazy */
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    BBCC*    next;         /* entry chain in hash */
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ULong*   cost;         /* start of 64bit costs for this BBCC */
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ULong    ecounter_sum; /* execution counter for first instruction of BB */
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    JmpData  jmp[0];
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* the <number> of fn_node, file_node and obj_node are for compressed dumping
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * and a index into the dump boolean table and fn_info_table
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _fn_node {
424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  HChar*     name;
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt       number;
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Context*   last_cxt; /* LRU info */
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Context*   pure_cxt; /* the context with only the function itself */
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  file_node* file;     /* reverse mapping for 2nd hash */
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fn_node* next;
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool dump_before :1;
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool dump_after :1;
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool zero_before :1;
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool toggle_collect :1;
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool skip :1;
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool pop_on_jump : 1;
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool is_malloc :1;
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool is_realloc :1;
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool is_free :1;
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  group;
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  separate_callers;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  separate_recursions;
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if CLG_ENABLE_DEBUG
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int  verbosity; /* Stores old verbosity level while in function */
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Quite arbitrary fixed hash sizes */
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define   N_OBJ_ENTRIES         47
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define  N_FILE_ENTRIES         53
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define    N_FN_ENTRIES         87
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_BBCC2_ENTRIES         37
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _file_node {
458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HChar*     name;
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fn_node*   fns[N_FN_ENTRIES];
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt       number;
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   obj_node*  obj;
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   file_node* next;
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If an object is dlopened multiple times, we hope that <name> is unique;
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * <start> and <offset> can change with each dlopen, and <start> is
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * zero when object is unmapped (possible at dump time).
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _obj_node {
470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const HChar* name;
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt       last_slash_pos;
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr       start;  /* Start address of text segment mapping */
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT      size;   /* Length of mapping */
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT   offset; /* Offset between symbol address and file offset */
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   file_node* files[N_FILE_ENTRIES];
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt       number;
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   obj_node*  next;
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* an entry in the callstack
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * <nonskipped> is 0 if the function called is not skipped (usual case).
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Otherwise, it is the last non-skipped BBCC. This one gets all
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the calls to non-skipped functions and all costs in skipped
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * instructions.
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _call_entry {
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    jCC* jcc;           /* jCC for this call */
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    FullCost enter_cost; /* cost event counters at entering frame */
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Addr sp;            /* stack pointer directly after call */
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Addr ret_addr;      /* address to which to return to
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 * is 0 on a simulated call */
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    BBCC* nonskipped;   /* see above */
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Context* cxt;       /* context before call */
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Int fn_sp;          /* function stack index before call */
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Execution state of main thread or a running signal handler in
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * a thread while interrupted by another signal handler.
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * As there's no scheduling among running signal handlers of one thread,
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * we only need a subset of a full thread state:
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - event counter
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - collect state
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - last BB, last jump kind, last nonskipped BB
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - callstack pointer for sanity checking and correct unwinding
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *   after exit
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _exec_state exec_state;
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _exec_state {
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* the signum of the handler, 0 for main thread context
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int sig;
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* the old call stack pointer at entering the signal handler */
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int orig_sp;
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  FullCost cost;
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Bool     collect;
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Context* cxt;
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  /* number of conditional jumps passed in last BB */
527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Int   jmps_passed;
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BBCC* bbcc;      /* last BB executed */
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BBCC* nonskipped;
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int call_stack_bottom; /* Index into fn_stack */
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Global state structures */
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _bb_hash bb_hash;
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _bb_hash {
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size, entries;
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BB** table;
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _cxt_hash cxt_hash;
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _cxt_hash {
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size, entries;
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Context** table;
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Thread specific state structures, i.e. parts of a thread state.
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * There are variables for the current state of each part,
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * on which a thread state is copied at thread switch.
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _bbcc_hash bbcc_hash;
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _bbcc_hash {
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size, entries;
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  BBCC** table;
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _jcc_hash jcc_hash;
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _jcc_hash {
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size, entries;
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  jCC** table;
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  jCC* spontaneous;
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _fn_array fn_array;
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _fn_array {
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size;
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt* array;
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _call_stack call_stack;
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _call_stack {
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size;
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int sp;
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  call_entry* entry;
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _fn_stack fn_stack;
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _fn_stack {
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UInt size;
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fn_node **bottom, **top;
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The maximum number of simultaneous running signal handlers per thread.
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * This is the number of execution states storable in a thread.
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MAX_SIGHANDLERS 10
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _exec_stack exec_stack;
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _exec_stack {
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int sp; /* > 0 if a handler is running */
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  exec_state* entry[MAX_SIGHANDLERS];
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Thread State
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * This structure stores thread specific info while a thread is *not*
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * running. See function switch_thread() for save/restore on thread switch.
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If --separate-threads=no, BBCCs and JCCs can be shared by all threads, i.e.
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * only structures of thread 1 are used.
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * This involves variables fn_info_table, bbcc_table and jcc_table.
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _thread_info {
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* state */
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fn_stack fns;       /* function stack */
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  call_stack calls;   /* context call arc stack */
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  exec_stack states;  /* execution states interrupted by signals */
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* dump statistics */
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  FullCost lastdump_cost;    /* Cost at last dump */
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  FullCost sighandler_cost;
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* thread specific data structure containers */
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fn_array fn_active;
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  jcc_hash jccs;
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  bbcc_hash bbccs;
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Structs used for dumping */
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Address position inside of a BBCC:
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * This includes
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - the address offset from the BB start address
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - file/line from debug info for that address (can change inside a BB)
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _AddrPos AddrPos;
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _AddrPos {
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Addr addr;
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Addr bb_addr;
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    file_node* file;
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    UInt line;
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* a simulator cost entity that can be written out in one line */
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _AddrCost AddrCost;
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _AddrCost {
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    AddrPos p;
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    SimCost cost;
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A function in an execution context */
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _FnPos FnPos;
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _FnPos {
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    file_node* file;
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    fn_node* fn;
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    obj_node* obj;
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Context* cxt;
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    int rec_index;
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    UInt line;
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Cache simulator interface                            ---*/
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct cachesim_if
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*print_opts)(void);
660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    Bool (*parse_opt)(const HChar* arg);
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*post_clo_init)(void);
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*clear)(void);
663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    void (*getdesc)(HChar* buf);
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*printstat)(Int,Int,Int);
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*add_icost)(SimCost, BBCC*, InstrInfo*, ULong);
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*finish)(void);
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_1I0D)(InstrInfo*) VG_REGPARM(1);
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_2I0D)(InstrInfo*, InstrInfo*) VG_REGPARM(2);
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_3I0D)(InstrInfo*, InstrInfo*, InstrInfo*) VG_REGPARM(3);
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_1I1Dr)(InstrInfo*, Addr, Word) VG_REGPARM(3);
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_1I1Dw)(InstrInfo*, Addr, Word) VG_REGPARM(3);
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_0I1Dr)(InstrInfo*, Addr, Word) VG_REGPARM(3);
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    void (*log_0I1Dw)(InstrInfo*, Addr, Word) VG_REGPARM(3);
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // function names of helpers (for debugging generated code)
679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    const HChar *log_1I0D_name, *log_2I0D_name, *log_3I0D_name;
680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    const HChar *log_1I1Dr_name, *log_1I1Dw_name;
681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    const HChar *log_0I1Dr_name, *log_0I1Dw_name;
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// set by setup_bbcc at start of every BB, and needed by log_* helpers
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Addr   CLG_(bb_base);
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern ULong* CLG_(cost_base);
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Event groups
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_USE   0
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_IR    1
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_DR    2
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_DW    3
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_BC    4
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_BI    5
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_BUS   6
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_ALLOC 7
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define EG_SYS   8
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct event_sets {
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    EventSet *base, *full;
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern struct event_sets CLG_(sets);
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define fullOffset(group) (CLG_(sets).full->offset[group])
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Functions                                            ---*/
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from clo.c */
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_clo_defaults)(void);
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(update_fn_config)(fn_node*);
715436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovBool CLG_(process_cmd_line_option)(const HChar*);
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_usage)(void);
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_debug_usage)(void);
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from sim.c */
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern struct cachesim_if CLG_(cachesim);
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_eventsets)(void);
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from main.c */
724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovBool CLG_(get_debug_info)(Addr, HChar filename[FILENAME_LEN],
725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov			 HChar fn_name[FN_NAME_LEN], UInt*, DebugInfo**);
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(collectBlockInfo)(IRSB* bbIn, UInt*, UInt*, Bool*);
727436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid CLG_(set_instrument_state)(const HChar*,Bool);
728436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid CLG_(dump_profile)(const HChar* trigger,Bool only_current_thread);
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(zero_all_cost)(Bool only_current_thread);
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownInt CLG_(get_dump_counter)(void);
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(fini)(Int exitcode);
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from bb.c */
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_bb_hash)(void);
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbb_hash* CLG_(get_bb_hash)(void);
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBB*  CLG_(get_bb)(Addr addr, IRSB* bb_in, Bool *seen_before);
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(delete_bb)(Addr addr);
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ Addr bb_addr(BB* bb)
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { return bb->offset + bb->obj->offset; }
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ Addr bb_jmpaddr(BB* bb)
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { UInt off = (bb->instr_count > 0) ? bb->instr[bb->instr_count-1].instr_offset : 0;
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return off + bb->offset + bb->obj->offset; }
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from fn.c */
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_fn_array)(fn_array*);
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(copy_current_fn_array)(fn_array* dst);
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfn_array* CLG_(get_current_fn_array)(void);
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_current_fn_array)(fn_array*);
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUInt* CLG_(get_fn_entry)(Int n);
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid      CLG_(init_obj_table)(void);
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownobj_node* CLG_(get_obj_node)(DebugInfo* si);
754436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovfile_node* CLG_(get_file_node)(obj_node*, HChar* filename);
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfn_node*  CLG_(get_fn_node)(BB* bb);
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from bbcc.c */
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_bbcc_hash)(bbcc_hash* bbccs);
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(copy_current_bbcc_hash)(bbcc_hash* dst);
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbbcc_hash* CLG_(get_current_bbcc_hash)(void);
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_current_bbcc_hash)(bbcc_hash*);
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(forall_bbccs)(void (*func)(BBCC*));
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(zero_bbcc)(BBCC* bbcc);
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBBCC* CLG_(get_bbcc)(BB* bb);
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBBCC* CLG_(clone_bbcc)(BBCC* orig, Context* cxt, Int rec_index);
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(setup_bbcc)(BB* bb) VG_REGPARM(1);
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from jumps.c */
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_jcc_hash)(jcc_hash*);
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(copy_current_jcc_hash)(jcc_hash* dst);
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownjcc_hash* CLG_(get_current_jcc_hash)(void);
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_current_jcc_hash)(jcc_hash*);
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownjCC* CLG_(get_jcc)(BBCC* from, UInt, BBCC* to);
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from callstack.c */
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_call_stack)(call_stack*);
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(copy_current_call_stack)(call_stack* dst);
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_current_call_stack)(call_stack*);
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncall_entry* CLG_(get_call_entry)(Int n);
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(push_call_stack)(BBCC* from, UInt jmp, BBCC* to, Addr sp, Bool skip);
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(pop_call_stack)(void);
784f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootInt CLG_(unwind_call_stack)(Addr sp, Int);
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from context.c */
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_fn_stack)(fn_stack*);
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(copy_current_fn_stack)(fn_stack*);
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfn_stack* CLG_(get_current_fn_stack)(void);
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_current_fn_stack)(fn_stack*);
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_cxt_table)(void);
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncxt_hash* CLG_(get_cxt_hash)(void);
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownContext* CLG_(get_cxt)(fn_node** fn);
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(push_cxt)(fn_node* fn);
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from threads.c */
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_threads)(void);
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthread_info** CLG_(get_threads)(void);
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthread_info* CLG_(get_current_thread)(void);
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(switch_thread)(ThreadId tid);
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(forall_threads)(void (*func)(thread_info*));
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(run_thread)(ThreadId tid);
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_exec_state)(exec_state* es);
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_exec_stack)(exec_stack*);
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(copy_current_exec_stack)(exec_stack*);
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(set_current_exec_stack)(exec_stack*);
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(pre_signal)(ThreadId tid, Int sigNum, Bool alt_stack);
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(post_signal)(ThreadId tid, Int sigNum);
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(run_post_signal_on_call_stack_bottom)(void);
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from dump.c */
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern FullCost CLG_(total_cost);
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_dumps)(void);
816436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovHChar* CLG_(get_out_file)(void);
817436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovHChar* CLG_(get_out_directory)(void);
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Exported global variables                            ---*/
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern CommandLineOptions CLG_(clo);
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Statistics CLG_(stat);
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern EventMapping* CLG_(dumpmap);
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Function active counter array, indexed by function number */
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern UInt* CLG_(fn_active_array);
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Bool CLG_(instrument_state);
830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* min of L1 and LL cache line sizes */
831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern Int CLG_(min_line_size);
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern call_stack CLG_(current_call_stack);
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern fn_stack   CLG_(current_fn_stack);
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern exec_state CLG_(current_state);
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern ThreadId   CLG_(current_tid);
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Debug output                                         ---*/
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if CLG_ENABLE_DEBUG
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_DEBUGIF(x) \
846436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  if (UNLIKELY( (CLG_(clo).verbose >x) && \
847436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                (CLG_(stat).bb_executions >= CLG_(clo).verbose_start)))
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_DEBUG(x,format,args...)   \
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    CLG_DEBUGIF(x) {                  \
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CLG_(print_bbno)();	      \
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)(format,##args);     \
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_ASSERT(cond)              \
856436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (UNLIKELY(!(cond))) {          \
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CLG_(print_context)();          \
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CLG_(print_bbno)();	      \
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tl_assert(cond);                \
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     }
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_DEBUGIF(x) if (0)
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_DEBUG(x...) {}
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_ASSERT(cond) tl_assert(cond);
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* from debug.c */
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_bbno)(void);
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_context)(void);
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_jcc)(int s, jCC* jcc);
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_bbcc)(int s, BBCC* bbcc);
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_bbcc_fn)(BBCC* bbcc);
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_execstate)(int s, exec_state* es);
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_eventset)(int s, EventSet* es);
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_cost)(int s, EventSet*, ULong* cost);
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_bb)(int s, BB* bb);
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_bbcc_cost)(int s, BBCC*);
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_cxt)(int s, Context* cxt, int rec_index);
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_short_jcc)(jCC* jcc);
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_stackentry)(int s, int sp);
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_addr)(Addr addr);
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(print_addr_ln)(Addr addr);
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
885436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid* CLG_(malloc)(const HChar* cc, UWord s, const HChar* f);
886436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid* CLG_(free)(void* p, const HChar* f);
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_MALLOC(_cc,x) CLG_(malloc)((_cc),x,__FUNCTION__)
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_FREE(p)       CLG_(free)(p,__FUNCTION__)
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_MALLOC(_cc,x) VG_(malloc)((_cc),x)
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CLG_FREE(p)       VG_(free)(p)
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* CLG_GLOBAL */
896