summaryrefslogtreecommitdiff
path: root/gcc/compiler-probe.h
blob: c527ae83642235e2cf886f122d1836b690ef5de0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
/* Compiler probe.
   Copyright (C) 2007 Free Software Foundation, Inc.
   Contributed by Basile Starynkevitch  <basile@starynkevitch.net>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC 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 GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  */

#ifndef GCC_COMPILER_PROBE_H
#define GCC_COMPILER_PROBE_H

#define COMPROBE_PROTOCOL_NUMBER 200701

/* the compiler probe */
#if defined(ENABLE_COMPILER_PROBE) && ENABLE_COMPILER_PROBE
/* <unistd.h> and <fcntl.h> and <string.h> have already been included
   and the following includes have been checked by autoconf */
#include <sys/select.h>
#include <signal.h>

/* compiler-probe.c uses the comprobe_ prefix */

struct comprobe_whatpos_st
{
  const char *wp_what;
  const char *wp_file;
  int wp_line;
};

/* handling routine for a request (from probe to compiler) */
typedef void comprobe_requestfun_t (struct comprobe_whatpos_st *wp,
				    char *reqlin, void *data);

/****
 * the interrupt flag, its handler, and the macro to check it 
 ****/
extern volatile sig_atomic_t comprobe_interrupted;

void comprobe_handle_probe (const char *what, const char *file, int lineno);

/* this macro should be put at all the points where we want to permit
   compiler probe interaction; in the common case where
   comprobe_interrupted is cleared, this macro runs quite quickly */
#define comprobe_check(WHAT) do{ if (comprobe_interrupted) { \
      comprobe_handle_probe((WHAT),__FILE__,__LINE__); }} while(0)

/***
 * stop the compiler probe (can be called from action handler)
 ***/
void comprobe_stop (void);

/***
 * forced kill of the compiler probe
 ***/
void comprobe_forced_kill (void);

/* force probing till an integer variable is cleared or the probe ended */
void comprobe_while_probe (const char *what, const char *file, int lineno,
			   int *pvar);
#define comprobe_while(WHAT,PVAR) do{ \
    comprobe_while_probe((WHAT),__FILE__,__LINE__,(PVAR));}while(0)
/***
 * the stream for replying to the probe ; may be NULL so should be tested!
 ***/
extern FILE *comprobe_replf;
#define comprobe_printf(Fmt, ...) do{if(comprobe_replf) {	\
      fprintf(comprobe_replf, (Fmt), ##__VA_ARGS__);		\
      fflush(comprobe_replf);}}while(0)
#define comprobe_puts(S) do{if(comprobe_replf) {	\
      fputs((S), comprobe_replf);			\
      fflush(comprobe_replf);}}while(0)
#define comprobe_flush() do{if(comprobe_replf)	\
      fflush(comprobe_replf); } while(0)
void comprobe_begin_big (void);
void comprobe_end_big (void);
void comprobe_outenc_string (const char *s);
#define comprobe_begin_big_printf(Fmt, ...) do{if(comprobe_replf) {	\
      comprobe_begin_big(); fprintf(comprobe_replf, (Fmt), \
				    ##__VA_ARGS__);}}while(0)
/***
 * initialize and finish. called in toplev.c 
 ****/
void comprobe_initialize (void);
void comprobe_finish (void);


/****
 * send a message to be shown
 ****/
void comprobe_show_message (const char *msg);



/***
 * return a unique positive file rank for a file path; or 0 for NULL name
 *  may send a PROB_file request to the probe
 ***/
int comprobe_file_rank (const char *filename);

/***
 * return a unique positive infopoint rank for a file rank and a line
 * number; may send a PROB_file request and a PROB_infopoint request
 * to the probe
 **/
int comprobe_infopoint_rank (int filrank, int lineno);

/***
 * return the linenumber, filerank, and filename of a given infopoint
 * or O|NULL if invalid infopoint rank
 ***/
int comprobe_line_of_infopoint (int infoptrank);
int comprobe_filerank_of_infopoint (int infoptrank);
const char *comprobe_filename_of_infopoint (int infoptrank);

/***
 * infopoint displayer routines
 ***/

/* info displayers are opaque structures managed by the compiler probe */
struct comprobe_infodisplay_st;

typedef void comprobe_infodisplay_fun_t
  (struct comprobe_whatpos_st *wp,
   struct comprobe_infodisplay_st *di,
   HOST_WIDE_INT data, HOST_WIDE_INT navig);

void comprobe_infopoint_add_display (int infoptrank,
				     comprobe_infodisplay_fun_t * dispfun,
				     const char *msg, HOST_WIDE_INT data);

/* displayer routines can add navigators */
void comprobe_display_add_navigator (struct comprobe_infodisplay_st *idi,
				     comprobe_infodisplay_fun_t * navfun,
				     const char *msg, HOST_WIDE_INT data);


/***
 * verb handler registration (the verb and data should be constant or
 * global data, or explicitly allocated at registration and freed
 * after unregistration).
 ***/
void comprobe_register (const char *verb, comprobe_requestfun_t * handler,
			void *data);
/* unregistration is not yet imlemented */
void comprobe_unregister (const char *verb);

typedef HOST_WIDE_INT comprobe_ix_t;

/***************************************************************************
 * additional tree specific routines are declared only if we know
 * about trees because this file has been included after tree.h
 *******/
#ifdef TREE_CODE		/*TREE_CODE is an important macro from tree.h */

/***
 * return true if a (GIMPLE/SSA) tree TR has a position 
 * and in that case fill the PFILENAME and PLINENO
 * if the END flag is set, return the last position
 ***/
enum { POS_START = 0, POS_END };
bool comprobe_get_position (tree tr, char **pfilename, int *plineno, int end);

/***
 * return a unique positive file rank for the location of a tree, if
 * any (else 0); may send a PROB_file request to the probe and set the
 * *plineno to the line number
 **/
int comprobe_file_rank_of_tree (tree tr, int *plineno);

/****
 * we manage a unique mapping between trees and indexes thru our hash
 * table; to get the index of a tree and vice versa the tree of an
 * index
 ***/
comprobe_ix_t comprobe_unique_index_of_tree (tree tr);
tree comprobe_tree_of_unique_index (comprobe_ix_t ix);

#endif /*TREE_CODE */




/************************************************************************
 * additional basic block specific routines are declared only if
 * we know about basic blocks because "basic-block.h" have been included
 ************************************************************************/
#ifdef BASIC_BLOCK		/* an important macro of basic-block */
/****
 * we manage a unique mapping between basic blocks and indexes thru
 * our hash table; to get the index of a basic block and vice versa
 * the basic block of an index
 ***/
comprobe_ix_t comprobe_unique_index_of_basic_block (basic_block bb);
basic_block comprobe_basic_block_of_unique_index (comprobe_ix_t ix);
#endif

#else /* compiler probe disabled */

/***************** fake stubs when probe disabled *******************/
#define comprobe_check(WHAT) do{}while(0)
#define comprobe_while(WHAT,PVAR)  do{}while(0)
#define comprobe_stop() do{}while(0)
#define comprobe_forced_kill() do{}while(0)
#define comprobe_flush() do{}while(0)
#define comprobe_replf  ((FILE*)0)
#define comprobe_show_message(M) do{if(0) puts(M);}while(0)
#define comprobe_puts(S) do[}while(0)
#define comprobe_printf(Fmt, ...) do{if(0) printf((Fmt),##__VA_ARGS__);}while(0)
#define comprobe_big_printf(Fmt, ...) do{if(0) printf((Fmt),##__VA_ARGS__);}while(0)
#define comprobe_register(Verb,Hdlr,Data) do{}while(0)
#define comprobe_unregister(Verb,Hdlr,Data) do{}while(0)
#define comprobe_begin_big()
#define comprobe_begin_big_printf(Fmt, ...) do{if(0) printf((Fmt),##__VA_ARGS__);}while(0)
#define comprobe_end_big()
#define comprobe_outenc_string(S) do{if (0 && ((S) == (char*)0));}while(0)
#define comprobe_filerank_of_tree(T,P)  (0 && (T) == (tree)0 && (P) == (int*)0)
#define comprobe_unique_index_of_tree(T) (0 && (T) == (tree)0)
#define comprobe_tree_of_unique_index(I) NULL_TREE
#define comprobe_filerank(P)  (0 && (P) == (const char*)0)
#define comprobe_get_position(T,PF,PL,E) (FALSE \
					  && (T)!=(tree)0 \
					  && (PF)!=(char**0) \
					  && (PL) != (int*)0 && (E))
#define  comprobe_infopoint_add_displayer(IRK,DMESG,DROUT,DATA) while(0 && \
  (IRK) != (int)0 && (DMESG) != (char*)0 && \
  (DROUT) != (comprobe_infoptdisplayroutine_t*)0 && (DATA) != (void*)0) {}
#endif /*ENABLE_COMPILER_PROBE */

#endif /*GCC_COMPILER_PROBE_H */
/* Compiler probe.
   Copyright (C) 2007 Free Software Foundation, Inc.
   Contributed by Basile Starynkevitch  <basile@starynkevitch.net>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC 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 GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  */

#ifndef GCC_COMPILER_PROBE_H
#define GCC_COMPILER_PROBE_H

#define COMPROBE_PROTOCOL_NUMBER 200701

/* the compiler probe */
#if defined(ENABLE_COMPILER_PROBE) && ENABLE_COMPILER_PROBE
/* <unistd.h> and <fcntl.h> and <string.h> have already been included
   and the following includes have been checked by autoconf */
#include <sys/select.h>
#include <signal.h>

/* compiler-probe.c uses the comprobe_ prefix */

struct comprobe_whatpos_st
{
  const char *wp_what;
  const char *wp_file;
  int wp_line;
};

/* handling routine for a request (from probe to compiler) */
typedef void comprobe_requestfun_t (struct comprobe_whatpos_st *wp,
				    char *reqlin, void *data);

/****
 * the interrupt flag, its handler, and the macro to check it 
 ****/
extern volatile sig_atomic_t comprobe_interrupted;

void comprobe_handle_probe (const char *what, const char *file, int lineno);

/* this macro should be put at all the points where we want to permit
   compiler probe interaction; in the common case where
   comprobe_interrupted is cleared, this macro runs quite quickly */
#define comprobe_check(WHAT) do{ if (comprobe_interrupted) { \
      comprobe_handle_probe((WHAT),__FILE__,__LINE__); }} while(0)

/***
 * stop the compiler probe (can be called from action handler)
 ***/
void comprobe_stop (void);

/***
 * forced kill of the compiler probe
 ***/
void comprobe_forced_kill (void);

/* force probing till an integer variable is cleared or the probe ended */
void comprobe_while_probe (const char *what, const char *file, int lineno,
			   int *pvar);
#define comprobe_while(WHAT,PVAR) do{ \
    comprobe_while_probe((WHAT),__FILE__,__LINE__,(PVAR));}while(0)
/***
 * the stream for replying to the probe ; may be NULL so should be tested!
 ***/
extern FILE *comprobe_replf;
#define comprobe_printf(Fmt, ...) do{if(comprobe_replf) {	\
      fprintf(comprobe_replf, (Fmt), ##__VA_ARGS__);		\
      fflush(comprobe_replf);}}while(0)
#define comprobe_flush() do{if(comprobe_replf)	\
      fflush(comprobe_replf); } while(0)
void comprobe_begin_big (void);
void comprobe_end_big (void);
void comprobe_outenc_string (const char *s);
#define comprobe_begin_big_printf(Fmt, ...) do{if(comprobe_replf) {	\
      comprobe_begin_big(); fprintf(comprobe_replf, (Fmt), \
				    ##__VA_ARGS__);}}while(0)
/***
 * initialize and finish. called in toplev.c 
 ****/
void comprobe_initialize (void);
void comprobe_finish (void);


/****
 * send a message to be shown
 ****/
void comprobe_show_message (const char *msg);


extern struct tree_opt_pass pass_compiler_probe;

/***
 * return a unique positive file rank for a file path; or 0 for NULL name
 *  may send a PROB_file request to the probe
 ***/
int comprobe_file_rank (const char *filename);

/***
 * return a unique positive infopoint rank for a file rank and a line
 * number; may send a PROB_file request and a PROB_infopoint request
 * to the probe
 **/
int comprobe_infopoint_rank (int filrank, int lineno);

/***
 * return the linenumber, filerank, and filename of a given infopoint
 * or O|NULL if invalid infopoint rank
 ***/
int comprobe_line_of_infopoint (int infoptrank);
int comprobe_filerank_of_infopoint (int infoptrank);
const char *comprobe_filename_of_infopoint (int infoptrank);

/***
 * infopoint displayer routines
 ***/

/* info displayers are opaque structures managed by the compiler probe */
struct comprobe_infodisplay_st;

typedef void comprobe_infodisplay_fun_t
  (struct comprobe_whatpos_st *wp,
   struct comprobe_infodisplay_st *di,
   HOST_WIDE_INT data, HOST_WIDE_INT navig);

void comprobe_infopoint_add_display (int infoptrank,
				     comprobe_infodisplay_fun_t * dispfun,
				     const char *msg, HOST_WIDE_INT data);

/* displayer routines can add navigators */
void comprobe_display_add_navigator (struct comprobe_infodisplay_st *idi,
				     comprobe_infodisplay_fun_t * navfun,
				     const char *msg, HOST_WIDE_INT data);


/***
 * verb handler registration (the verb and data should be constant or
 * global data, or explicitly allocated at registration and freed
 * after unregistration).
 ***/
void comprobe_register (const char *verb, comprobe_requestfun_t * handler,
			void *data);
/* unregistration is not yet imlemented */
void comprobe_unregister (const char *verb);

typedef HOST_WIDE_INT comprobe_ix_t;

/***************************************************************************
 * additional tree specific routines are declared only if we know
 * about trees because this file has been included after tree.h
 *******/
#ifdef TREE_CODE		/*TREE_CODE is an important macro from tree.h */

/***
 * return true if a (GIMPLE/SSA) tree TR has a position 
 * and in that case fill the PFILENAME and PLINENO
 * if the END flag is set, return the last position
 ***/
enum { POS_START = 0, POS_END };
bool comprobe_get_position (tree tr, char **pfilename, int *plineno, int end);

/***
 * return a unique positive file rank for the location of a tree, if
 * any (else 0); may send a PROB_file request to the probe and set the
 * *plineno to the line number
 **/
int comprobe_file_rank_of_tree (tree tr, int *plineno);

/****
 * we manage a unique mapping between trees and indexes thru our hash
 * table; to get the index of a tree and vice versa the tree of an
 * index
 ***/
comprobe_ix_t comprobe_unique_index_of_tree (tree tr);
tree comprobe_tree_of_unique_index (comprobe_ix_t ix);

#endif /*TREE_CODE */




/************************************************************************
 * additional basic block specific routines are declared only if
 * we know about basic blocks because "basic-block.h" have been included
 ************************************************************************/
#ifdef BASIC_BLOCK		/* an important macro of basic-block */
/****
 * we manage a unique mapping between basic blocks and indexes thru
 * our hash table; to get the index of a basic block and vice versa
 * the basic block of an index
 ***/
comprobe_ix_t comprobe_unique_index_of_basic_block (basic_block bb);
basic_block comprobe_basic_block_of_unique_index (comprobe_ix_t ix);
#endif

#else /* compiler probe disabled */

/***************** fake stubs when probe disabled *******************/
#define comprobe_check(WHAT) do{}while(0)
#define comprobe_while(WHAT,PVAR)  do{}while(0)
#define comprobe_stop() do{}while(0)
#define comprobe_forced_kill() do{}while(0)
#define comprobe_flush() do{}while(0)
#define comprobe_replf  ((FILE*)0)
#define comprobe_show_message(M) do{if(0) puts(M);}while(0)
#define comprobe_printf(Fmt, ...) do{if(0) printf((Fmt),##__VA_ARGS__);}while(0)
#define comprobe_big_printf(Fmt, ...) do{if(0) printf((Fmt),##__VA_ARGS__);}while(0)
#define comprobe_register(Verb,Hdlr,Data) do{}while(0)
#define comprobe_unregister(Verb,Hdlr,Data) do{}while(0)
#define comprobe_begin_big()
#define comprobe_begin_big_printf(Fmt, ...) do{if(0) printf((Fmt),##__VA_ARGS__);}while(0)
#define comprobe_end_big()
#define comprobe_outenc_string(S) do{if (0 && ((S) == (char*)0));}while(0)
#define comprobe_filerank_of_tree(T,P)  (0 && (T) == (tree)0 && (P) == (int*)0)
#define comprobe_unique_index_of_tree(T) (0 && (T) == (tree)0)
#define comprobe_tree_of_unique_index(I) NULL_TREE
#define comprobe_filerank(P)  (0 && (P) == (const char*)0)
#define comprobe_get_position(T,PF,PL,E) (FALSE \
					  && (T)!=(tree)0 \
					  && (PF)!=(char**0) \
					  && (PL) != (int*)0 && (E))
#define  comprobe_infopoint_add_displayer(IRK,DMESG,DROUT,DATA) while(0 && \
  (IRK) != (int)0 && (DMESG) != (char*)0 && \
  (DROUT) != (comprobe_infoptdisplayroutine_t*)0 && (DATA) != (void*)0) {}
#endif /*ENABLE_COMPILER_PROBE */

#endif /*GCC_COMPILER_PROBE_H */