OSDN Git Service

* df.h: Include "timevar.h".
[pf3gnuchains/gcc-fork.git] / gcc / tree-mudflap.c
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4    Contributed by Frank Ch. Eigler <fche@redhat.com>
5    and Graydon Hoare <graydon@redhat.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "hard-reg-set.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "tm_p.h"
32 #include "basic-block.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "tree-inline.h"
36 #include "gimple.h"
37 #include "tree-iterator.h"
38 #include "tree-flow.h"
39 #include "tree-mudflap.h"
40 #include "tree-dump.h"
41 #include "tree-pass.h"
42 #include "hashtab.h"
43 #include "diagnostic.h"
44 #include <demangle.h>
45 #include "langhooks.h"
46 #include "ggc.h"
47 #include "cgraph.h"
48 #include "toplev.h"
49 #include "gimple.h"
50
51 /* Internal function decls */
52
53
54 /* Options.  */
55 #define flag_mudflap_threads (flag_mudflap == 2)
56
57 /* Helpers.  */
58 static tree mf_build_string (const char *string);
59 static tree mf_varname_tree (tree);
60 static tree mf_file_function_line_tree (location_t);
61
62 /* Indirection-related instrumentation.  */
63 static void mf_decl_cache_locals (void);
64 static void mf_decl_clear_locals (void);
65 static void mf_xform_derefs (void);
66 static unsigned int execute_mudflap_function_ops (void);
67
68 /* Addressable variables instrumentation.  */
69 static void mf_xform_decls (gimple_seq, tree);
70 static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *,
71                                 struct walk_stmt_info *);
72 static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
73 static unsigned int execute_mudflap_function_decls (void);
74
75
76 /* ------------------------------------------------------------------------ */
77 /* Some generally helpful functions for mudflap instrumentation.  */
78
79 /* Build a reference to a literal string.  */
80 static tree
81 mf_build_string (const char *string)
82 {
83   size_t len = strlen (string);
84   tree result = mf_mark (build_string (len + 1, string));
85
86   TREE_TYPE (result) = build_array_type
87     (char_type_node, build_index_type (build_int_cst (NULL_TREE, len)));
88   TREE_CONSTANT (result) = 1;
89   TREE_READONLY (result) = 1;
90   TREE_STATIC (result) = 1;
91
92   result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);
93
94   return mf_mark (result);
95 }
96
97 /* Create a properly typed STRING_CST node that describes the given
98    declaration.  It will be used as an argument for __mf_register().
99    Try to construct a helpful string, including file/function/variable
100    name.  */
101
102 static tree
103 mf_varname_tree (tree decl)
104 {
105   static pretty_printer buf_rec;
106   static int initialized = 0;
107   pretty_printer *buf = & buf_rec;
108   const char *buf_contents;
109   tree result;
110
111   gcc_assert (decl);
112
113   if (!initialized)
114     {
115       pp_construct (buf, /* prefix */ NULL, /* line-width */ 0);
116       initialized = 1;
117     }
118   pp_clear_output_area (buf);
119
120   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
121   {
122     expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl));
123     const char *sourcefile;
124     unsigned sourceline = xloc.line;
125     unsigned sourcecolumn = 0;
126     sourcecolumn = xloc.column;
127     sourcefile = xloc.file;
128     if (sourcefile == NULL && current_function_decl != NULL_TREE)
129       sourcefile = DECL_SOURCE_FILE (current_function_decl);
130     if (sourcefile == NULL)
131       sourcefile = "<unknown file>";
132
133     pp_string (buf, sourcefile);
134
135     if (sourceline != 0)
136       {
137         pp_string (buf, ":");
138         pp_decimal_int (buf, sourceline);
139
140         if (sourcecolumn != 0)
141           {
142             pp_string (buf, ":");
143             pp_decimal_int (buf, sourcecolumn);
144           }
145       }
146   }
147
148   if (current_function_decl != NULL_TREE)
149     {
150       /* Add (FUNCTION) */
151       pp_string (buf, " (");
152       {
153         const char *funcname = NULL;
154         if (DECL_NAME (current_function_decl))
155           funcname = lang_hooks.decl_printable_name (current_function_decl, 1);
156         if (funcname == NULL)
157           funcname = "anonymous fn";
158
159         pp_string (buf, funcname);
160       }
161       pp_string (buf, ") ");
162     }
163   else
164     pp_string (buf, " ");
165
166   /* Add <variable-declaration>, possibly demangled.  */
167   {
168     const char *declname = NULL;
169
170     if (DECL_NAME (decl) != NULL)
171       {
172         if (strcmp ("GNU C++", lang_hooks.name) == 0)
173           {
174             /* The gcc/cp decl_printable_name hook doesn't do as good a job as
175                the libiberty demangler.  */
176             declname = cplus_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)),
177                                        DMGL_AUTO | DMGL_VERBOSE);
178           }
179         if (declname == NULL)
180           declname = lang_hooks.decl_printable_name (decl, 3);
181       }
182     if (declname == NULL)
183       declname = "<unnamed variable>";
184
185     pp_string (buf, declname);
186   }
187
188   /* Return the lot as a new STRING_CST.  */
189   buf_contents = pp_base_formatted_text (buf);
190   result = mf_build_string (buf_contents);
191   pp_clear_output_area (buf);
192
193   return result;
194 }
195
196
197 /* And another friend, for producing a simpler message.  */
198
199 static tree
200 mf_file_function_line_tree (location_t location)
201 {
202   expanded_location xloc = expand_location (location);
203   const char *file = NULL, *colon, *line, *op, *name, *cp;
204   char linecolbuf[30]; /* Enough for two decimal numbers plus a colon.  */
205   char *string;
206   tree result;
207
208   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
209   file = xloc.file;
210   if (file == NULL && current_function_decl != NULL_TREE)
211     file = DECL_SOURCE_FILE (current_function_decl);
212   if (file == NULL)
213     file = "<unknown file>";
214
215   if (xloc.line > 0)
216     {
217       if (xloc.column > 0)
218         sprintf (linecolbuf, "%d:%d", xloc.line, xloc.column);
219       else
220         sprintf (linecolbuf, "%d", xloc.line);
221       colon = ":";
222       line = linecolbuf;
223     }
224   else
225     colon = line = "";
226
227   /* Add (FUNCTION).  */
228   name = lang_hooks.decl_printable_name (current_function_decl, 1);
229   if (name)
230     {
231       op = " (";
232       cp = ")";
233     }
234   else
235     op = name = cp = "";
236
237   string = concat (file, colon, line, op, name, cp, NULL);
238   result = mf_build_string (string);
239   free (string);
240
241   return result;
242 }
243
244
245 /* global tree nodes */
246
247 /* Global tree objects for global variables and functions exported by
248    mudflap runtime library.  mf_init_extern_trees must be called
249    before using these.  */
250
251 /* uintptr_t (usually "unsigned long") */
252 static GTY (()) tree mf_uintptr_type;
253
254 /* struct __mf_cache { uintptr_t low; uintptr_t high; }; */
255 static GTY (()) tree mf_cache_struct_type;
256
257 /* struct __mf_cache * const */
258 static GTY (()) tree mf_cache_structptr_type;
259
260 /* extern struct __mf_cache __mf_lookup_cache []; */
261 static GTY (()) tree mf_cache_array_decl;
262
263 /* extern unsigned char __mf_lc_shift; */
264 static GTY (()) tree mf_cache_shift_decl;
265
266 /* extern uintptr_t __mf_lc_mask; */
267 static GTY (()) tree mf_cache_mask_decl;
268
269 /* Their function-scope local shadows, used in single-threaded mode only.  */
270
271 /* auto const unsigned char __mf_lc_shift_l; */
272 static GTY (()) tree mf_cache_shift_decl_l;
273
274 /* auto const uintptr_t __mf_lc_mask_l; */
275 static GTY (()) tree mf_cache_mask_decl_l;
276
277 /* extern void __mf_check (void *ptr, size_t sz, int type, const char *); */
278 static GTY (()) tree mf_check_fndecl;
279
280 /* extern void __mf_register (void *ptr, size_t sz, int type, const char *); */
281 static GTY (()) tree mf_register_fndecl;
282
283 /* extern void __mf_unregister (void *ptr, size_t sz, int type); */
284 static GTY (()) tree mf_unregister_fndecl;
285
286 /* extern void __mf_init (); */
287 static GTY (()) tree mf_init_fndecl;
288
289 /* extern int __mf_set_options (const char*); */
290 static GTY (()) tree mf_set_options_fndecl;
291
292
293 /* Helper for mudflap_init: construct a decl with the given category,
294    name, and type, mark it an external reference, and pushdecl it.  */
295 static inline tree
296 mf_make_builtin (enum tree_code category, const char *name, tree type)
297 {
298   tree decl = mf_mark (build_decl (category, get_identifier (name), type));
299   TREE_PUBLIC (decl) = 1;
300   DECL_EXTERNAL (decl) = 1;
301   lang_hooks.decls.pushdecl (decl);
302   /* The decl was declared by the compiler.  */
303   DECL_ARTIFICIAL (decl) = 1;
304   /* And we don't want debug info for it.  */
305   DECL_IGNORED_P (decl) = 1;
306   return decl;
307 }
308
309 /* Helper for mudflap_init: construct a tree corresponding to the type
310      struct __mf_cache { uintptr_t low; uintptr_t high; };
311      where uintptr_t is the FIELD_TYPE argument.  */
312 static inline tree
313 mf_make_mf_cache_struct_type (tree field_type)
314 {
315   /* There is, abominably, no language-independent way to construct a
316      RECORD_TYPE.  So we have to call the basic type construction
317      primitives by hand.  */
318   tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type);
319   tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type);
320
321   tree struct_type = make_node (RECORD_TYPE);
322   DECL_CONTEXT (fieldlo) = struct_type;
323   DECL_CONTEXT (fieldhi) = struct_type;
324   TREE_CHAIN (fieldlo) = fieldhi;
325   TYPE_FIELDS (struct_type) = fieldlo;
326   TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
327   layout_type (struct_type);
328
329   return struct_type;
330 }
331
332 #define build_function_type_0(rtype)                                    \
333   build_function_type (rtype, void_list_node)
334 #define build_function_type_1(rtype, arg1)                              \
335   build_function_type (rtype, tree_cons (0, arg1, void_list_node))
336 #define build_function_type_3(rtype, arg1, arg2, arg3)                  \
337   build_function_type (rtype,                                           \
338                        tree_cons (0, arg1,                              \
339                                   tree_cons (0, arg2,                   \
340                                               tree_cons (0, arg3,       \
341                                                          void_list_node))))
342 #define build_function_type_4(rtype, arg1, arg2, arg3, arg4)            \
343   build_function_type (rtype,                                           \
344                        tree_cons (0, arg1,                              \
345                                   tree_cons (0, arg2,                   \
346                                              tree_cons (0, arg3,        \
347                                                         tree_cons (0, arg4, \
348                                                                    void_list_node)))))
349
350 /* Initialize the global tree nodes that correspond to mf-runtime.h
351    declarations.  */
352 void
353 mudflap_init (void)
354 {
355   static bool done = false;
356   tree mf_const_string_type;
357   tree mf_cache_array_type;
358   tree mf_check_register_fntype;
359   tree mf_unregister_fntype;
360   tree mf_init_fntype;
361   tree mf_set_options_fntype;
362
363   if (done)
364     return;
365   done = true;
366
367   mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode,
368                                                     /*unsignedp=*/true);
369   mf_const_string_type
370     = build_pointer_type (build_qualified_type
371                           (char_type_node, TYPE_QUAL_CONST));
372
373   mf_cache_struct_type = mf_make_mf_cache_struct_type (mf_uintptr_type);
374   mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
375   mf_cache_array_type = build_array_type (mf_cache_struct_type, 0);
376   mf_check_register_fntype =
377     build_function_type_4 (void_type_node, ptr_type_node, size_type_node,
378                            integer_type_node, mf_const_string_type);
379   mf_unregister_fntype =
380     build_function_type_3 (void_type_node, ptr_type_node, size_type_node,
381                            integer_type_node);
382   mf_init_fntype =
383     build_function_type_0 (void_type_node);
384   mf_set_options_fntype =
385     build_function_type_1 (integer_type_node, mf_const_string_type);
386
387   mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache",
388                                          mf_cache_array_type);
389   mf_cache_shift_decl = mf_make_builtin (VAR_DECL, "__mf_lc_shift",
390                                          unsigned_char_type_node);
391   mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask",
392                                         mf_uintptr_type);
393   /* Don't process these in mudflap_enqueue_decl, should they come by
394      there for some reason.  */
395   mf_mark (mf_cache_array_decl);
396   mf_mark (mf_cache_shift_decl);
397   mf_mark (mf_cache_mask_decl);
398   mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check",
399                                      mf_check_register_fntype);
400   mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register",
401                                         mf_check_register_fntype);
402   mf_unregister_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_unregister",
403                                           mf_unregister_fntype);
404   mf_init_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_init",
405                                     mf_init_fntype);
406   mf_set_options_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_set_options",
407                                            mf_set_options_fntype);
408 }
409 #undef build_function_type_4
410 #undef build_function_type_3
411 #undef build_function_type_1
412 #undef build_function_type_0
413
414
415 /* ------------------------------------------------------------------------ */
416 /* Memory reference transforms. Perform the mudflap indirection-related
417    tree transforms on the current function.
418
419    This is the second part of the mudflap instrumentation.  It works on
420    low-level GIMPLE using the CFG, because we want to run this pass after
421    tree optimizations have been performed, but we have to preserve the CFG
422    for expansion from trees to RTL.  */
423
424 static unsigned int
425 execute_mudflap_function_ops (void)
426 {
427   struct gimplify_ctx gctx;
428
429   /* Don't instrument functions such as the synthetic constructor
430      built during mudflap_finish_file.  */
431   if (mf_marked_p (current_function_decl) ||
432       DECL_ARTIFICIAL (current_function_decl))
433     return 0;
434
435   push_gimplify_context (&gctx);
436
437   /* In multithreaded mode, don't cache the lookup cache parameters.  */
438   if (! flag_mudflap_threads)
439     mf_decl_cache_locals ();
440
441   mf_xform_derefs ();
442
443   if (! flag_mudflap_threads)
444     mf_decl_clear_locals ();
445
446   pop_gimplify_context (NULL);
447   return 0;
448 }
449
450 /* Create and initialize local shadow variables for the lookup cache
451    globals.  Put their decls in the *_l globals for use by
452    mf_build_check_statement_for.  */
453
454 static void
455 mf_decl_cache_locals (void)
456 {
457   gimple g;
458   gimple_seq seq = gimple_seq_alloc ();
459
460   /* Build the cache vars.  */
461   mf_cache_shift_decl_l
462     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl),
463                                "__mf_lookup_shift_l"));
464
465   mf_cache_mask_decl_l
466     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl),
467                                "__mf_lookup_mask_l"));
468
469   /* Build initialization nodes for the cache vars.  We just load the
470      globals into the cache variables.  */
471   g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
472   gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
473   gimple_seq_add_stmt (&seq, g);
474
475   g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
476   gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
477   gimple_seq_add_stmt (&seq, g);
478
479   insert_edge_copies_seq (seq, ENTRY_BLOCK_PTR);
480
481   gsi_commit_edge_inserts ();
482 }
483
484
485 static void
486 mf_decl_clear_locals (void)
487 {
488   /* Unset local shadows.  */
489   mf_cache_shift_decl_l = NULL_TREE;
490   mf_cache_mask_decl_l = NULL_TREE;
491 }
492
493 static void
494 mf_build_check_statement_for (tree base, tree limit,
495                               gimple_stmt_iterator *instr_gsi,
496                               location_t location, tree dirflag)
497 {
498   gimple_stmt_iterator gsi;
499   basic_block cond_bb, then_bb, join_bb;
500   edge e;
501   tree cond, t, u, v;
502   tree mf_base;
503   tree mf_elem;
504   tree mf_limit;
505   gimple g;
506   gimple_seq seq, stmts;
507
508   /* We first need to split the current basic block, and start altering
509      the CFG.  This allows us to insert the statements we're about to
510      construct into the right basic blocks.  */
511
512   cond_bb = gimple_bb (gsi_stmt (*instr_gsi));
513   gsi = *instr_gsi;
514   gsi_prev (&gsi);
515   if (! gsi_end_p (gsi))
516     e = split_block (cond_bb, gsi_stmt (gsi));
517   else
518     e = split_block_after_labels (cond_bb);
519   cond_bb = e->src;
520   join_bb = e->dest;
521
522   /* A recap at this point: join_bb is the basic block at whose head
523      is the gimple statement for which this check expression is being
524      built.  cond_bb is the (possibly new, synthetic) basic block the
525      end of which will contain the cache-lookup code, and a
526      conditional that jumps to the cache-miss code or, much more
527      likely, over to join_bb.  */
528
529   /* Create the bb that contains the cache-miss fallback block (mf_check).  */
530   then_bb = create_empty_bb (cond_bb);
531   make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
532   make_single_succ_edge (then_bb, join_bb, EDGE_FALLTHRU);
533
534   /* Mark the pseudo-fallthrough edge from cond_bb to join_bb.  */
535   e = find_edge (cond_bb, join_bb);
536   e->flags = EDGE_FALSE_VALUE;
537   e->count = cond_bb->count;
538   e->probability = REG_BR_PROB_BASE;
539
540   /* Update dominance info.  Note that bb_join's data was
541      updated by split_block.  */
542   if (dom_info_available_p (CDI_DOMINATORS))
543     {
544       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
545       set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
546     }
547
548   /* Build our local variables.  */
549   mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem");
550   mf_base = create_tmp_var (mf_uintptr_type, "__mf_base");
551   mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit");
552
553   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
554   seq = gimple_seq_alloc ();
555   t = fold_convert (mf_uintptr_type, unshare_expr (base));
556   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
557   gimple_seq_add_seq (&seq, stmts);
558   g = gimple_build_assign (mf_base, t);
559   gimple_set_location (g, location);
560   gimple_seq_add_stmt (&seq, g);
561
562   /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
563   t = fold_convert (mf_uintptr_type, unshare_expr (limit));
564   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
565   gimple_seq_add_seq (&seq, stmts);
566   g = gimple_build_assign (mf_limit, t);
567   gimple_set_location (g, location);
568   gimple_seq_add_stmt (&seq, g);
569
570   /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
571                                             & __mf_mask].  */
572   t = build2 (RSHIFT_EXPR, mf_uintptr_type, mf_base,
573               flag_mudflap_threads ? mf_cache_shift_decl
574                : mf_cache_shift_decl_l);
575   t = build2 (BIT_AND_EXPR, mf_uintptr_type, t,
576               flag_mudflap_threads ? mf_cache_mask_decl
577                : mf_cache_mask_decl_l);
578   t = build4 (ARRAY_REF,
579               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
580               mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
581   t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
582   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
583   gimple_seq_add_seq (&seq, stmts);
584   g = gimple_build_assign (mf_elem, t);
585   gimple_set_location (g, location);
586   gimple_seq_add_stmt (&seq, g);
587
588   /* Quick validity check.
589
590      if (__mf_elem->low > __mf_base
591          || (__mf_elem_high < __mf_limit))
592         {
593           __mf_check ();
594           ... and only if single-threaded:
595           __mf_lookup_shift_1 = f...;
596           __mf_lookup_mask_l = ...;
597         }
598
599      It is expected that this body of code is rarely executed so we mark
600      the edge to the THEN clause of the conditional jump as unlikely.  */
601
602   /* Construct t <-- '__mf_elem->low  > __mf_base'.  */
603   t = build3 (COMPONENT_REF, mf_uintptr_type,
604               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
605               TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
606   t = build2 (GT_EXPR, boolean_type_node, t, mf_base);
607
608   /* Construct '__mf_elem->high < __mf_limit'.
609
610      First build:
611         1) u <--  '__mf_elem->high'
612         2) v <--  '__mf_limit'.
613
614      Then build 'u <-- (u < v).  */
615
616   u = build3 (COMPONENT_REF, mf_uintptr_type,
617               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
618               TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
619
620   v = mf_limit;
621
622   u = build2 (LT_EXPR, boolean_type_node, u, v);
623
624   /* Build the composed conditional: t <-- 't || u'.  Then store the
625      result of the evaluation of 't' in a temporary variable which we
626      can use as the condition for the conditional jump.  */
627   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
628   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
629   gimple_seq_add_seq (&seq, stmts);
630   cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
631   g = gimple_build_assign  (cond, t);
632   gimple_set_location (g, location);
633   gimple_seq_add_stmt (&seq, g);
634
635   /* Build the conditional jump.  'cond' is just a temporary so we can
636      simply build a void COND_EXPR.  We do need labels in both arms though.  */
637   g = gimple_build_cond (NE_EXPR, cond, boolean_false_node, NULL_TREE,
638                          NULL_TREE);
639   gimple_set_location (g, location);
640   gimple_seq_add_stmt (&seq, g);
641
642   /* At this point, after so much hard work, we have only constructed
643      the conditional jump,
644
645      if (__mf_elem->low > __mf_base
646          || (__mf_elem_high < __mf_limit))
647
648      The lowered GIMPLE tree representing this code is in the statement
649      list starting at 'head'.
650
651      We can insert this now in the current basic block, i.e. the one that
652      the statement we're instrumenting was originally in.  */
653   gsi = gsi_last_bb (cond_bb);
654   gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
655
656   /*  Now build up the body of the cache-miss handling:
657
658      __mf_check();
659      refresh *_l vars.
660
661      This is the body of the conditional.  */
662
663   seq = gimple_seq_alloc ();
664   /* u is a string, so it is already a gimple value.  */
665   u = mf_file_function_line_tree (location);
666   /* NB: we pass the overall [base..limit] range to mf_check.  */
667   v = fold_build2 (PLUS_EXPR, mf_uintptr_type,
668                    fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
669                    build_int_cst (mf_uintptr_type, 1));
670   v = force_gimple_operand (v, &stmts, true, NULL_TREE);
671   gimple_seq_add_seq (&seq, stmts);
672   g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
673   gimple_seq_add_stmt (&seq, g);
674
675   if (! flag_mudflap_threads)
676     {
677       if (stmt_ends_bb_p (g))
678         {
679           gsi = gsi_start_bb (then_bb);
680           gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
681           e = split_block (then_bb, g);
682           then_bb = e->dest;
683           seq = gimple_seq_alloc ();
684         }
685
686       g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
687       gimple_seq_add_stmt (&seq, g);
688
689       g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
690       gimple_seq_add_stmt (&seq, g);
691     }
692
693   /* Insert the check code in the THEN block.  */
694   gsi = gsi_start_bb (then_bb);
695   gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
696
697   *instr_gsi = gsi_start_bb (join_bb);
698 }
699
700
701 /* Check whether the given decl, generally a VAR_DECL or PARM_DECL, is
702    eligible for instrumentation.  For the mudflap1 pass, this implies
703    that it should be registered with the libmudflap runtime.  For the
704    mudflap2 pass this means instrumenting an indirection operation with
705    respect to the object.
706 */
707 static int
708 mf_decl_eligible_p (tree decl)
709 {
710   return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
711           /* The decl must have its address taken.  In the case of
712              arrays, this flag is also set if the indexes are not
713              compile-time known valid constants.  */
714           /* XXX: not sufficient: return-by-value structs! */
715           && TREE_ADDRESSABLE (decl)
716           /* The type of the variable must be complete.  */
717           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
718           /* The decl hasn't been decomposed somehow.  */
719           && !DECL_HAS_VALUE_EXPR_P (decl));
720 }
721
722
723 static void
724 mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
725                    location_t location, tree dirflag)
726 {
727   tree type, base, limit, addr, size, t;
728
729   /* Don't instrument read operations.  */
730   if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
731     return;
732
733   /* Don't instrument marked nodes.  */
734   if (mf_marked_p (*tp))
735     return;
736
737   t = *tp;
738   type = TREE_TYPE (t);
739
740   if (type == error_mark_node)
741     return;
742
743   size = TYPE_SIZE_UNIT (type);
744
745   switch (TREE_CODE (t))
746     {
747     case ARRAY_REF:
748     case COMPONENT_REF:
749       {
750         /* This is trickier than it may first appear.  The reason is
751            that we are looking at expressions from the "inside out" at
752            this point.  We may have a complex nested aggregate/array
753            expression (e.g. "a.b[i].c"), maybe with an indirection as
754            the leftmost operator ("p->a.b.d"), where instrumentation
755            is necessary.  Or we may have an innocent "a.b.c"
756            expression that must not be instrumented.  We need to
757            recurse all the way down the nesting structure to figure it
758            out: looking just at the outer node is not enough.  */          
759         tree var;
760         int component_ref_only = (TREE_CODE (t) == COMPONENT_REF);
761         /* If we have a bitfield component reference, we must note the
762            innermost addressable object in ELT, from which we will
763            construct the byte-addressable bounds of the bitfield.  */
764         tree elt = NULL_TREE;
765         int bitfield_ref_p = (TREE_CODE (t) == COMPONENT_REF
766                               && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)));
767
768         /* Iterate to the top of the ARRAY_REF/COMPONENT_REF
769            containment hierarchy to find the outermost VAR_DECL.  */
770         var = TREE_OPERAND (t, 0);
771         while (1)
772           {
773             if (bitfield_ref_p && elt == NULL_TREE
774                 && (TREE_CODE (var) == ARRAY_REF
775                     || TREE_CODE (var) == COMPONENT_REF))
776               elt = var;
777         
778             if (TREE_CODE (var) == ARRAY_REF)
779               {
780                 component_ref_only = 0;
781                 var = TREE_OPERAND (var, 0);
782               }
783             else if (TREE_CODE (var) == COMPONENT_REF)
784               var = TREE_OPERAND (var, 0);
785             else if (INDIRECT_REF_P (var))
786               {
787                 base = TREE_OPERAND (var, 0);
788                 break;
789               }
790             else if (TREE_CODE (var) == VIEW_CONVERT_EXPR)
791               {
792                 var = TREE_OPERAND (var, 0);
793                 if (CONSTANT_CLASS_P (var)
794                     && TREE_CODE (var) != STRING_CST)
795                   return;
796               }
797             else 
798               {
799                 gcc_assert (TREE_CODE (var) == VAR_DECL 
800                             || TREE_CODE (var) == PARM_DECL
801                             || TREE_CODE (var) == RESULT_DECL
802                             || TREE_CODE (var) == STRING_CST);
803                 /* Don't instrument this access if the underlying
804                    variable is not "eligible".  This test matches
805                    those arrays that have only known-valid indexes,
806                    and thus are not labeled TREE_ADDRESSABLE.  */
807                 if (! mf_decl_eligible_p (var) || component_ref_only)
808                   return;
809                 else
810                   {
811                     base = build1 (ADDR_EXPR,
812                                    build_pointer_type (TREE_TYPE (var)), var);
813                     break;
814                   }
815               }
816           }
817
818         /* Handle the case of ordinary non-indirection structure
819            accesses.  These have only nested COMPONENT_REF nodes (no
820            INDIRECT_REF), but pass through the above filter loop.
821            Note that it's possible for such a struct variable to match
822            the eligible_p test because someone else might take its
823            address sometime.  */
824
825         /* We need special processing for bitfield components, because
826            their addresses cannot be taken.  */
827         if (bitfield_ref_p)
828           {
829             tree field = TREE_OPERAND (t, 1);
830
831             if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
832               size = DECL_SIZE_UNIT (field);
833             
834             if (elt)
835               elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)),
836                             elt);
837             addr = fold_convert (ptr_type_node, elt ? elt : base);
838             addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
839                                 addr, fold_convert (sizetype,
840                                                     byte_position (field)));
841           }
842         else
843           addr = build1 (ADDR_EXPR, build_pointer_type (type), t);
844
845         limit = fold_build2 (MINUS_EXPR, mf_uintptr_type,
846                              fold_build2 (PLUS_EXPR, mf_uintptr_type,
847                                           convert (mf_uintptr_type, addr),
848                                           size),
849                              integer_one_node);
850       }
851       break;
852
853     case INDIRECT_REF:
854       addr = TREE_OPERAND (t, 0);
855       base = addr;
856       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
857                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
858                                         size),
859                            size_int (-1));
860       break;
861
862     case TARGET_MEM_REF:
863       addr = tree_mem_ref_addr (ptr_type_node, t);
864       base = addr;
865       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
866                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
867                                         size),
868                            size_int (-1));
869       break;
870
871     case ARRAY_RANGE_REF:
872       warning (OPT_Wmudflap,
873                "mudflap checking not yet implemented for ARRAY_RANGE_REF");
874       return;
875
876     case BIT_FIELD_REF:
877       /* ??? merge with COMPONENT_REF code above? */
878       {
879         tree ofs, rem, bpu;
880
881         /* If we're not dereferencing something, then the access
882            must be ok.  */
883         if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
884           return;
885
886         bpu = bitsize_int (BITS_PER_UNIT);
887         ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
888         rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
889         ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu));
890
891         size = convert (bitsizetype, TREE_OPERAND (t, 1));
892         size = size_binop (PLUS_EXPR, size, rem);
893         size = size_binop (CEIL_DIV_EXPR, size, bpu);
894         size = convert (sizetype, size);
895
896         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
897         addr = convert (ptr_type_node, addr);
898         addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs);
899
900         base = addr;
901         limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
902                              fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
903                                            base, size),
904                              size_int (-1));
905       }
906       break;
907
908     default:
909       return;
910     }
911
912   mf_build_check_statement_for (base, limit, iter, location, dirflag);
913 }
914
915 static void
916 mf_xform_derefs (void)
917 {
918   basic_block bb, next;
919   gimple_stmt_iterator i;
920   int saved_last_basic_block = last_basic_block;
921   enum gimple_rhs_class grhs_class;
922
923   bb = ENTRY_BLOCK_PTR ->next_bb;
924   do
925     {
926       next = bb->next_bb;
927       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
928         {
929           gimple s = gsi_stmt (i);
930
931           /* Only a few GIMPLE statements can reference memory.  */
932           switch (gimple_code (s))
933             {
934             case GIMPLE_ASSIGN:
935               mf_xform_derefs_1 (&i, gimple_assign_lhs_ptr (s),
936                                  gimple_location (s), integer_one_node);
937               mf_xform_derefs_1 (&i, gimple_assign_rhs1_ptr (s),
938                                  gimple_location (s), integer_zero_node);
939               grhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (s));
940               if (grhs_class == GIMPLE_BINARY_RHS)
941                 mf_xform_derefs_1 (&i, gimple_assign_rhs2_ptr (s),
942                                    gimple_location (s), integer_zero_node);
943               break;
944
945             case GIMPLE_RETURN:
946               if (gimple_return_retval (s) != NULL_TREE)
947                 {
948                   mf_xform_derefs_1 (&i, gimple_return_retval_ptr (s),
949                                      gimple_location (s),
950                                      integer_zero_node);
951                 }
952               break;
953
954             default:
955               ;
956             }
957         }
958       bb = next;
959     }
960   while (bb && bb->index <= saved_last_basic_block);
961 }
962
963 /* ------------------------------------------------------------------------ */
964 /* ADDR_EXPR transforms.  Perform the declaration-related mudflap tree
965    transforms on the current function.
966
967    This is the first part of the mudflap instrumentation.  It works on
968    high-level GIMPLE because after lowering, all variables are moved out
969    of their BIND_EXPR binding context, and we lose liveness information
970    for the declarations we wish to instrument.  */
971
972 static unsigned int
973 execute_mudflap_function_decls (void)
974 {
975   struct gimplify_ctx gctx;
976
977   /* Don't instrument functions such as the synthetic constructor
978      built during mudflap_finish_file.  */
979   if (mf_marked_p (current_function_decl) ||
980       DECL_ARTIFICIAL (current_function_decl))
981     return 0;
982
983   push_gimplify_context (&gctx);
984
985   mf_xform_decls (gimple_body (current_function_decl),
986                   DECL_ARGUMENTS (current_function_decl));
987
988   pop_gimplify_context (NULL);
989   return 0;
990 }
991
992 /* This struct is passed between mf_xform_decls to store state needed
993    during the traversal searching for objects that have their
994    addresses taken.  */
995 struct mf_xform_decls_data
996 {
997   tree param_decls;
998 };
999
1000
1001 /* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
1002    _DECLs if appropriate.  Arrange to call the __mf_register function
1003    now, and the __mf_unregister function later for each.  Return the
1004    gimple sequence after synthesis.  */
1005 gimple_seq
1006 mx_register_decls (tree decl, gimple_seq seq, location_t location)
1007 {
1008   gimple_seq finally_stmts = NULL;
1009   gimple_stmt_iterator initially_stmts = gsi_start (seq);
1010
1011   while (decl != NULL_TREE)
1012     {
1013       if (mf_decl_eligible_p (decl) 
1014           /* Not already processed.  */
1015           && ! mf_marked_p (decl)
1016           /* Automatic variable.  */
1017           && ! DECL_EXTERNAL (decl)
1018           && ! TREE_STATIC (decl))
1019         {
1020           tree size = NULL_TREE, variable_name;
1021           gimple unregister_fncall, register_fncall;
1022           tree unregister_fncall_param, register_fncall_param;
1023
1024           /* Variable-sized objects should have sizes already been
1025              gimplified when we got here. */
1026           size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
1027           gcc_assert (is_gimple_val (size));
1028         
1029
1030           unregister_fncall_param =
1031             mf_mark (build1 (ADDR_EXPR,
1032                              build_pointer_type (TREE_TYPE (decl)),
1033                              decl));
1034           /* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
1035           unregister_fncall = gimple_build_call (mf_unregister_fndecl, 3,
1036                                                  unregister_fncall_param,
1037                                                  size,
1038                                                  build_int_cst (NULL_TREE, 3));
1039
1040
1041           variable_name = mf_varname_tree (decl);
1042           register_fncall_param =
1043             mf_mark (build1 (ADDR_EXPR,
1044                              build_pointer_type (TREE_TYPE (decl)),
1045                              decl));
1046           /* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK,
1047                             "name") */
1048           register_fncall = gimple_build_call (mf_register_fndecl, 4,
1049                                                register_fncall_param,
1050                                                size,
1051                                                build_int_cst (NULL_TREE, 3),
1052                                                variable_name);
1053           
1054
1055           /* Accumulate the two calls.  */
1056           gimple_set_location (register_fncall, location);
1057           gimple_set_location (unregister_fncall, location);
1058
1059           /* Add the __mf_register call at the current appending point.  */
1060           if (gsi_end_p (initially_stmts))
1061             {
1062               if (!DECL_ARTIFICIAL (decl))
1063                 warning (OPT_Wmudflap,
1064                          "mudflap cannot track %qs in stub function",
1065                          IDENTIFIER_POINTER (DECL_NAME (decl)));
1066             }
1067           else
1068             {
1069               gsi_insert_before (&initially_stmts, register_fncall,
1070                                  GSI_SAME_STMT);
1071
1072               /* Accumulate the FINALLY piece.  */
1073               gimple_seq_add_stmt (&finally_stmts, unregister_fncall);
1074             }
1075           mf_mark (decl);
1076         }
1077
1078       decl = TREE_CHAIN (decl);
1079     }
1080
1081   /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
1082   if (finally_stmts != NULL)
1083     {
1084       gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY);
1085       gimple_seq new_seq = gimple_seq_alloc ();
1086
1087       gimple_seq_add_stmt (&new_seq, stmt);
1088       return new_seq;
1089     }
1090    else
1091     return seq;
1092 }
1093
1094
1095 /* Process every variable mentioned in BIND_EXPRs.  */
1096 static tree
1097 mx_xfn_xform_decls (gimple_stmt_iterator *gsi,
1098                     bool *handled_operands_p ATTRIBUTE_UNUSED,
1099                     struct walk_stmt_info *wi)
1100 {
1101   struct mf_xform_decls_data *d = (struct mf_xform_decls_data *) wi->info;
1102   gimple stmt = gsi_stmt (*gsi);
1103
1104   switch (gimple_code (stmt))
1105     {
1106     case GIMPLE_BIND:
1107       {
1108         /* Process function parameters now (but only once).  */
1109         if (d->param_decls)
1110           {
1111             gimple_bind_set_body (stmt,
1112                                   mx_register_decls (d->param_decls,
1113                                                      gimple_bind_body (stmt),
1114                                                      gimple_location (stmt)));
1115             d->param_decls = NULL_TREE;
1116           }
1117
1118         gimple_bind_set_body (stmt,
1119                               mx_register_decls (gimple_bind_vars (stmt),
1120                                                  gimple_bind_body (stmt),
1121                                                  gimple_location (stmt)));
1122       }
1123       break;
1124
1125     default:
1126       break;
1127     }
1128
1129   return NULL_TREE;
1130 }
1131
1132 /* Perform the object lifetime tracking mudflap transform on the given function
1133    tree.  The tree is mutated in place, with possibly copied subtree nodes.
1134
1135    For every auto variable declared, if its address is ever taken
1136    within the function, then supply its lifetime to the mudflap
1137    runtime with the __mf_register and __mf_unregister calls.
1138 */
1139
1140 static void
1141 mf_xform_decls (gimple_seq fnbody, tree fnparams)
1142 {
1143   struct mf_xform_decls_data d;
1144   struct walk_stmt_info wi;
1145   struct pointer_set_t *pset = pointer_set_create ();
1146
1147   d.param_decls = fnparams;
1148   memset (&wi, 0, sizeof (wi));
1149   wi.info = (void*) &d;
1150   wi.pset = pset;
1151   walk_gimple_seq (fnbody, mx_xfn_xform_decls, NULL, &wi);
1152   pointer_set_destroy (pset);
1153 }
1154
1155
1156 /* ------------------------------------------------------------------------ */
1157 /* Externally visible mudflap functions.  */
1158
1159
1160 /* Mark and return the given tree node to prevent further mudflap
1161    transforms.  */
1162 static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
1163
1164 tree
1165 mf_mark (tree t)
1166 {
1167   void **slot;
1168
1169   if (marked_trees == NULL)
1170     marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer,
1171                                     NULL);
1172
1173   slot = htab_find_slot (marked_trees, t, INSERT);
1174   *slot = t;
1175   return t;
1176 }
1177
1178 int
1179 mf_marked_p (tree t)
1180 {
1181   void *entry;
1182
1183   if (marked_trees == NULL)
1184     return 0;
1185
1186   entry = htab_find (marked_trees, t);
1187   return (entry != NULL);
1188 }
1189
1190 /* Remember given node as a static of some kind: global data,
1191    function-scope static, or an anonymous constant.  Its assembler
1192    label is given.  */
1193
1194 /* A list of globals whose incomplete declarations we encountered.
1195    Instead of emitting the __mf_register call for them here, it's
1196    delayed until program finish time.  If they're still incomplete by
1197    then, warnings are emitted.  */
1198
1199 static GTY (()) VEC(tree,gc) *deferred_static_decls;
1200
1201 /* A list of statements for calling __mf_register() at startup time.  */
1202 static GTY (()) tree enqueued_call_stmt_chain;
1203
1204 static void
1205 mudflap_register_call (tree obj, tree object_size, tree varname)
1206 {
1207   tree arg, call_stmt;
1208
1209   arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
1210   arg = convert (ptr_type_node, arg);
1211
1212   call_stmt = build_call_expr (mf_register_fndecl, 4,
1213                                arg,
1214                                convert (size_type_node, object_size),
1215                                /* __MF_TYPE_STATIC */
1216                                build_int_cst (NULL_TREE, 4), 
1217                                varname);
1218
1219   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
1220 }
1221
1222 void
1223 mudflap_enqueue_decl (tree obj)
1224 {
1225   if (mf_marked_p (obj))
1226     return;
1227
1228   /* We don't need to process variable decls that are internally
1229      generated extern.  If we did, we'd end up with warnings for them
1230      during mudflap_finish_file ().  That would confuse the user,
1231      since the text would refer to variables that don't show up in the
1232      user's source code.  */
1233   if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
1234     return;
1235
1236   VEC_safe_push (tree, gc, deferred_static_decls, obj);
1237 }
1238
1239
1240 void
1241 mudflap_enqueue_constant (tree obj)
1242 {
1243   tree object_size, varname;
1244
1245   if (mf_marked_p (obj))
1246     return;
1247
1248   if (TREE_CODE (obj) == STRING_CST)
1249     object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj));
1250   else
1251     object_size = size_in_bytes (TREE_TYPE (obj));
1252
1253   if (TREE_CODE (obj) == STRING_CST)
1254     varname = mf_build_string ("string literal");
1255   else
1256     varname = mf_build_string ("constant");
1257
1258   mudflap_register_call (obj, object_size, varname);
1259 }
1260
1261
1262 /* Emit any file-wide instrumentation.  */
1263 void
1264 mudflap_finish_file (void)
1265 {
1266   tree ctor_statements = NULL_TREE;
1267
1268   /* No need to continue when there were errors.  */
1269   if (errorcount != 0 || sorrycount != 0)
1270     return;
1271
1272   /* Insert a call to __mf_init.  */
1273   {
1274     tree call2_stmt = build_call_expr (mf_init_fndecl, 0);
1275     append_to_statement_list (call2_stmt, &ctor_statements);
1276   }
1277   
1278   /* If appropriate, call __mf_set_options to pass along read-ignore mode.  */
1279   if (flag_mudflap_ignore_reads)
1280     {
1281       tree arg = mf_build_string ("-ignore-reads");
1282       tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg);
1283       append_to_statement_list (call_stmt, &ctor_statements);
1284     }
1285
1286   /* Process all enqueued object decls.  */
1287   if (deferred_static_decls)
1288     {
1289       size_t i;
1290       tree obj;
1291       for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++)
1292         {
1293           gcc_assert (DECL_P (obj));
1294
1295           if (mf_marked_p (obj))
1296             continue;
1297
1298           /* Omit registration for static unaddressed objects.  NB:
1299              Perform registration for non-static objects regardless of
1300              TREE_USED or TREE_ADDRESSABLE, because they may be used
1301              from other compilation units.  */
1302           if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj))
1303             continue;
1304
1305           if (! COMPLETE_TYPE_P (TREE_TYPE (obj)))
1306             {
1307               warning (OPT_Wmudflap,
1308                        "mudflap cannot track unknown size extern %qs",
1309                        IDENTIFIER_POINTER (DECL_NAME (obj)));
1310               continue;
1311             }
1312           
1313           mudflap_register_call (obj, 
1314                                  size_in_bytes (TREE_TYPE (obj)),
1315                                  mf_varname_tree (obj));
1316         }
1317
1318       VEC_truncate (tree, deferred_static_decls, 0);
1319     }
1320
1321   /* Append all the enqueued registration calls.  */
1322   if (enqueued_call_stmt_chain)
1323     {
1324       append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements);
1325       enqueued_call_stmt_chain = NULL_TREE;
1326     }
1327
1328   cgraph_build_static_cdtor ('I', ctor_statements, 
1329                              MAX_RESERVED_INIT_PRIORITY-1);
1330 }
1331
1332
1333 static bool
1334 gate_mudflap (void)
1335 {
1336   return flag_mudflap != 0;
1337 }
1338
1339 struct gimple_opt_pass pass_mudflap_1 = 
1340 {
1341  {
1342   GIMPLE_PASS,
1343   "mudflap1",                           /* name */
1344   gate_mudflap,                         /* gate */
1345   execute_mudflap_function_decls,       /* execute */
1346   NULL,                                 /* sub */
1347   NULL,                                 /* next */
1348   0,                                    /* static_pass_number */
1349   TV_NONE,                              /* tv_id */
1350   PROP_gimple_any,                      /* properties_required */
1351   0,                                    /* properties_provided */
1352   0,                                    /* properties_destroyed */
1353   0,                                    /* todo_flags_start */
1354   TODO_dump_func                        /* todo_flags_finish */
1355  }
1356 };
1357
1358 struct gimple_opt_pass pass_mudflap_2 = 
1359 {
1360  {
1361   GIMPLE_PASS,
1362   "mudflap2",                           /* name */
1363   gate_mudflap,                         /* gate */
1364   execute_mudflap_function_ops,         /* execute */
1365   NULL,                                 /* sub */
1366   NULL,                                 /* next */
1367   0,                                    /* static_pass_number */
1368   TV_NONE,                              /* tv_id */
1369   PROP_gimple_leh,                      /* properties_required */
1370   0,                                    /* properties_provided */
1371   0,                                    /* properties_destroyed */
1372   0,                                    /* todo_flags_start */
1373   TODO_verify_flow | TODO_verify_stmts
1374   | TODO_dump_func                      /* todo_flags_finish */
1375  }
1376 };
1377
1378 #include "gt-tree-mudflap.h"