OSDN Git Service

gcc/java/
[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 (UNKNOWN_LOCATION,
299                                    category, get_identifier (name), type));
300   TREE_PUBLIC (decl) = 1;
301   DECL_EXTERNAL (decl) = 1;
302   lang_hooks.decls.pushdecl (decl);
303   /* The decl was declared by the compiler.  */
304   DECL_ARTIFICIAL (decl) = 1;
305   /* And we don't want debug info for it.  */
306   DECL_IGNORED_P (decl) = 1;
307   return decl;
308 }
309
310 /* Helper for mudflap_init: construct a tree corresponding to the type
311      struct __mf_cache { uintptr_t low; uintptr_t high; };
312      where uintptr_t is the FIELD_TYPE argument.  */
313 static inline tree
314 mf_make_mf_cache_struct_type (tree field_type)
315 {
316   /* There is, abominably, no language-independent way to construct a
317      RECORD_TYPE.  So we have to call the basic type construction
318      primitives by hand.  */
319   tree fieldlo = build_decl (UNKNOWN_LOCATION,
320                              FIELD_DECL, get_identifier ("low"), field_type);
321   tree fieldhi = build_decl (UNKNOWN_LOCATION,
322                              FIELD_DECL, get_identifier ("high"), field_type);
323
324   tree struct_type = make_node (RECORD_TYPE);
325   DECL_CONTEXT (fieldlo) = struct_type;
326   DECL_CONTEXT (fieldhi) = struct_type;
327   TREE_CHAIN (fieldlo) = fieldhi;
328   TYPE_FIELDS (struct_type) = fieldlo;
329   TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
330   layout_type (struct_type);
331
332   return struct_type;
333 }
334
335 #define build_function_type_0(rtype)                                    \
336   build_function_type (rtype, void_list_node)
337 #define build_function_type_1(rtype, arg1)                              \
338   build_function_type (rtype, tree_cons (0, arg1, void_list_node))
339 #define build_function_type_3(rtype, arg1, arg2, arg3)                  \
340   build_function_type (rtype,                                           \
341                        tree_cons (0, arg1,                              \
342                                   tree_cons (0, arg2,                   \
343                                               tree_cons (0, arg3,       \
344                                                          void_list_node))))
345 #define build_function_type_4(rtype, arg1, arg2, arg3, arg4)            \
346   build_function_type (rtype,                                           \
347                        tree_cons (0, arg1,                              \
348                                   tree_cons (0, arg2,                   \
349                                              tree_cons (0, arg3,        \
350                                                         tree_cons (0, arg4, \
351                                                                    void_list_node)))))
352
353 /* Initialize the global tree nodes that correspond to mf-runtime.h
354    declarations.  */
355 void
356 mudflap_init (void)
357 {
358   static bool done = false;
359   tree mf_const_string_type;
360   tree mf_cache_array_type;
361   tree mf_check_register_fntype;
362   tree mf_unregister_fntype;
363   tree mf_init_fntype;
364   tree mf_set_options_fntype;
365
366   if (done)
367     return;
368   done = true;
369
370   mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode,
371                                                     /*unsignedp=*/true);
372   mf_const_string_type
373     = build_pointer_type (build_qualified_type
374                           (char_type_node, TYPE_QUAL_CONST));
375
376   mf_cache_struct_type = mf_make_mf_cache_struct_type (mf_uintptr_type);
377   mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
378   mf_cache_array_type = build_array_type (mf_cache_struct_type, 0);
379   mf_check_register_fntype =
380     build_function_type_4 (void_type_node, ptr_type_node, size_type_node,
381                            integer_type_node, mf_const_string_type);
382   mf_unregister_fntype =
383     build_function_type_3 (void_type_node, ptr_type_node, size_type_node,
384                            integer_type_node);
385   mf_init_fntype =
386     build_function_type_0 (void_type_node);
387   mf_set_options_fntype =
388     build_function_type_1 (integer_type_node, mf_const_string_type);
389
390   mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache",
391                                          mf_cache_array_type);
392   mf_cache_shift_decl = mf_make_builtin (VAR_DECL, "__mf_lc_shift",
393                                          unsigned_char_type_node);
394   mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask",
395                                         mf_uintptr_type);
396   /* Don't process these in mudflap_enqueue_decl, should they come by
397      there for some reason.  */
398   mf_mark (mf_cache_array_decl);
399   mf_mark (mf_cache_shift_decl);
400   mf_mark (mf_cache_mask_decl);
401   mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check",
402                                      mf_check_register_fntype);
403   mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register",
404                                         mf_check_register_fntype);
405   mf_unregister_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_unregister",
406                                           mf_unregister_fntype);
407   mf_init_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_init",
408                                     mf_init_fntype);
409   mf_set_options_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_set_options",
410                                            mf_set_options_fntype);
411 }
412 #undef build_function_type_4
413 #undef build_function_type_3
414 #undef build_function_type_1
415 #undef build_function_type_0
416
417
418 /* ------------------------------------------------------------------------ */
419 /* Memory reference transforms. Perform the mudflap indirection-related
420    tree transforms on the current function.
421
422    This is the second part of the mudflap instrumentation.  It works on
423    low-level GIMPLE using the CFG, because we want to run this pass after
424    tree optimizations have been performed, but we have to preserve the CFG
425    for expansion from trees to RTL.  */
426
427 static unsigned int
428 execute_mudflap_function_ops (void)
429 {
430   struct gimplify_ctx gctx;
431
432   /* Don't instrument functions such as the synthetic constructor
433      built during mudflap_finish_file.  */
434   if (mf_marked_p (current_function_decl) ||
435       DECL_ARTIFICIAL (current_function_decl))
436     return 0;
437
438   push_gimplify_context (&gctx);
439
440   /* In multithreaded mode, don't cache the lookup cache parameters.  */
441   if (! flag_mudflap_threads)
442     mf_decl_cache_locals ();
443
444   mf_xform_derefs ();
445
446   if (! flag_mudflap_threads)
447     mf_decl_clear_locals ();
448
449   pop_gimplify_context (NULL);
450   return 0;
451 }
452
453 /* Insert a gimple_seq SEQ on all the outgoing edges out of BB.  Note that
454    if BB has more than one edge, STMT will be replicated for each edge.
455    Also, abnormal edges will be ignored.  */
456
457 static void
458 insert_edge_copies_seq (gimple_seq seq, basic_block bb)
459 {
460   edge e;
461   edge_iterator ei;
462   unsigned n_copies = -1;
463
464   FOR_EACH_EDGE (e, ei, bb->succs)
465     if (!(e->flags & EDGE_ABNORMAL))
466       n_copies++;
467
468   FOR_EACH_EDGE (e, ei, bb->succs)
469     if (!(e->flags & EDGE_ABNORMAL))
470       gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
471 }
472
473 /* Create and initialize local shadow variables for the lookup cache
474    globals.  Put their decls in the *_l globals for use by
475    mf_build_check_statement_for.  */
476
477 static void
478 mf_decl_cache_locals (void)
479 {
480   gimple g;
481   gimple_seq seq = gimple_seq_alloc ();
482
483   /* Build the cache vars.  */
484   mf_cache_shift_decl_l
485     = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_shift_decl),
486                                "__mf_lookup_shift_l"));
487
488   mf_cache_mask_decl_l
489     = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_mask_decl),
490                                "__mf_lookup_mask_l"));
491
492   /* Build initialization nodes for the cache vars.  We just load the
493      globals into the cache variables.  */
494   g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
495   gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
496   gimple_seq_add_stmt (&seq, g);
497
498   g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
499   gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
500   gimple_seq_add_stmt (&seq, g);
501
502   insert_edge_copies_seq (seq, ENTRY_BLOCK_PTR);
503
504   gsi_commit_edge_inserts ();
505 }
506
507
508 static void
509 mf_decl_clear_locals (void)
510 {
511   /* Unset local shadows.  */
512   mf_cache_shift_decl_l = NULL_TREE;
513   mf_cache_mask_decl_l = NULL_TREE;
514 }
515
516 static void
517 mf_build_check_statement_for (tree base, tree limit,
518                               gimple_stmt_iterator *instr_gsi,
519                               location_t location, tree dirflag)
520 {
521   gimple_stmt_iterator gsi;
522   basic_block cond_bb, then_bb, join_bb;
523   edge e;
524   tree cond, t, u, v;
525   tree mf_base;
526   tree mf_elem;
527   tree mf_limit;
528   gimple g;
529   gimple_seq seq, stmts;
530
531   /* We first need to split the current basic block, and start altering
532      the CFG.  This allows us to insert the statements we're about to
533      construct into the right basic blocks.  */
534
535   cond_bb = gimple_bb (gsi_stmt (*instr_gsi));
536   gsi = *instr_gsi;
537   gsi_prev (&gsi);
538   if (! gsi_end_p (gsi))
539     e = split_block (cond_bb, gsi_stmt (gsi));
540   else
541     e = split_block_after_labels (cond_bb);
542   cond_bb = e->src;
543   join_bb = e->dest;
544
545   /* A recap at this point: join_bb is the basic block at whose head
546      is the gimple statement for which this check expression is being
547      built.  cond_bb is the (possibly new, synthetic) basic block the
548      end of which will contain the cache-lookup code, and a
549      conditional that jumps to the cache-miss code or, much more
550      likely, over to join_bb.  */
551
552   /* Create the bb that contains the cache-miss fallback block (mf_check).  */
553   then_bb = create_empty_bb (cond_bb);
554   make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
555   make_single_succ_edge (then_bb, join_bb, EDGE_FALLTHRU);
556
557   /* Mark the pseudo-fallthrough edge from cond_bb to join_bb.  */
558   e = find_edge (cond_bb, join_bb);
559   e->flags = EDGE_FALSE_VALUE;
560   e->count = cond_bb->count;
561   e->probability = REG_BR_PROB_BASE;
562
563   /* Update dominance info.  Note that bb_join's data was
564      updated by split_block.  */
565   if (dom_info_available_p (CDI_DOMINATORS))
566     {
567       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
568       set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
569     }
570
571   /* Build our local variables.  */
572   mf_elem = make_rename_temp (mf_cache_structptr_type, "__mf_elem");
573   mf_base = make_rename_temp (mf_uintptr_type, "__mf_base");
574   mf_limit = make_rename_temp (mf_uintptr_type, "__mf_limit");
575
576   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
577   seq = gimple_seq_alloc ();
578   t = fold_convert (mf_uintptr_type, unshare_expr (base));
579   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
580   gimple_seq_add_seq (&seq, stmts);
581   g = gimple_build_assign (mf_base, t);
582   gimple_set_location (g, location);
583   gimple_seq_add_stmt (&seq, g);
584
585   /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
586   t = fold_convert (mf_uintptr_type, unshare_expr (limit));
587   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
588   gimple_seq_add_seq (&seq, stmts);
589   g = gimple_build_assign (mf_limit, t);
590   gimple_set_location (g, location);
591   gimple_seq_add_stmt (&seq, g);
592
593   /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
594                                             & __mf_mask].  */
595   t = build2 (RSHIFT_EXPR, mf_uintptr_type, mf_base,
596               flag_mudflap_threads ? mf_cache_shift_decl
597                : mf_cache_shift_decl_l);
598   t = build2 (BIT_AND_EXPR, mf_uintptr_type, t,
599               flag_mudflap_threads ? mf_cache_mask_decl
600                : mf_cache_mask_decl_l);
601   t = build4 (ARRAY_REF,
602               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
603               mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
604   t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
605   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
606   gimple_seq_add_seq (&seq, stmts);
607   g = gimple_build_assign (mf_elem, t);
608   gimple_set_location (g, location);
609   gimple_seq_add_stmt (&seq, g);
610
611   /* Quick validity check.
612
613      if (__mf_elem->low > __mf_base
614          || (__mf_elem_high < __mf_limit))
615         {
616           __mf_check ();
617           ... and only if single-threaded:
618           __mf_lookup_shift_1 = f...;
619           __mf_lookup_mask_l = ...;
620         }
621
622      It is expected that this body of code is rarely executed so we mark
623      the edge to the THEN clause of the conditional jump as unlikely.  */
624
625   /* Construct t <-- '__mf_elem->low  > __mf_base'.  */
626   t = build3 (COMPONENT_REF, mf_uintptr_type,
627               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
628               TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
629   t = build2 (GT_EXPR, boolean_type_node, t, mf_base);
630
631   /* Construct '__mf_elem->high < __mf_limit'.
632
633      First build:
634         1) u <--  '__mf_elem->high'
635         2) v <--  '__mf_limit'.
636
637      Then build 'u <-- (u < v).  */
638
639   u = build3 (COMPONENT_REF, mf_uintptr_type,
640               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
641               TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
642
643   v = mf_limit;
644
645   u = build2 (LT_EXPR, boolean_type_node, u, v);
646
647   /* Build the composed conditional: t <-- 't || u'.  Then store the
648      result of the evaluation of 't' in a temporary variable which we
649      can use as the condition for the conditional jump.  */
650   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
651   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
652   gimple_seq_add_seq (&seq, stmts);
653   cond = make_rename_temp (boolean_type_node, "__mf_unlikely_cond");
654   g = gimple_build_assign  (cond, t);
655   gimple_set_location (g, location);
656   gimple_seq_add_stmt (&seq, g);
657
658   /* Build the conditional jump.  'cond' is just a temporary so we can
659      simply build a void COND_EXPR.  We do need labels in both arms though.  */
660   g = gimple_build_cond (NE_EXPR, cond, boolean_false_node, NULL_TREE,
661                          NULL_TREE);
662   gimple_set_location (g, location);
663   gimple_seq_add_stmt (&seq, g);
664
665   /* At this point, after so much hard work, we have only constructed
666      the conditional jump,
667
668      if (__mf_elem->low > __mf_base
669          || (__mf_elem_high < __mf_limit))
670
671      The lowered GIMPLE tree representing this code is in the statement
672      list starting at 'head'.
673
674      We can insert this now in the current basic block, i.e. the one that
675      the statement we're instrumenting was originally in.  */
676   gsi = gsi_last_bb (cond_bb);
677   gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
678
679   /*  Now build up the body of the cache-miss handling:
680
681      __mf_check();
682      refresh *_l vars.
683
684      This is the body of the conditional.  */
685
686   seq = gimple_seq_alloc ();
687   /* u is a string, so it is already a gimple value.  */
688   u = mf_file_function_line_tree (location);
689   /* NB: we pass the overall [base..limit] range to mf_check.  */
690   v = fold_build2 (PLUS_EXPR, mf_uintptr_type,
691                    fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
692                    build_int_cst (mf_uintptr_type, 1));
693   v = force_gimple_operand (v, &stmts, true, NULL_TREE);
694   gimple_seq_add_seq (&seq, stmts);
695   g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
696   gimple_seq_add_stmt (&seq, g);
697
698   if (! flag_mudflap_threads)
699     {
700       if (stmt_ends_bb_p (g))
701         {
702           gsi = gsi_start_bb (then_bb);
703           gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
704           e = split_block (then_bb, g);
705           then_bb = e->dest;
706           seq = gimple_seq_alloc ();
707         }
708
709       g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
710       gimple_seq_add_stmt (&seq, g);
711
712       g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
713       gimple_seq_add_stmt (&seq, g);
714     }
715
716   /* Insert the check code in the THEN block.  */
717   gsi = gsi_start_bb (then_bb);
718   gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
719
720   *instr_gsi = gsi_start_bb (join_bb);
721 }
722
723
724 /* Check whether the given decl, generally a VAR_DECL or PARM_DECL, is
725    eligible for instrumentation.  For the mudflap1 pass, this implies
726    that it should be registered with the libmudflap runtime.  For the
727    mudflap2 pass this means instrumenting an indirection operation with
728    respect to the object.
729 */
730 static int
731 mf_decl_eligible_p (tree decl)
732 {
733   return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
734           /* The decl must have its address taken.  In the case of
735              arrays, this flag is also set if the indexes are not
736              compile-time known valid constants.  */
737           /* XXX: not sufficient: return-by-value structs! */
738           && TREE_ADDRESSABLE (decl)
739           /* The type of the variable must be complete.  */
740           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
741           /* The decl hasn't been decomposed somehow.  */
742           && !DECL_HAS_VALUE_EXPR_P (decl));
743 }
744
745
746 static void
747 mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
748                    location_t location, tree dirflag)
749 {
750   tree type, base, limit, addr, size, t;
751
752   /* Don't instrument read operations.  */
753   if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
754     return;
755
756   /* Don't instrument marked nodes.  */
757   if (mf_marked_p (*tp))
758     return;
759
760   t = *tp;
761   type = TREE_TYPE (t);
762
763   if (type == error_mark_node)
764     return;
765
766   size = TYPE_SIZE_UNIT (type);
767
768   switch (TREE_CODE (t))
769     {
770     case ARRAY_REF:
771     case COMPONENT_REF:
772       {
773         /* This is trickier than it may first appear.  The reason is
774            that we are looking at expressions from the "inside out" at
775            this point.  We may have a complex nested aggregate/array
776            expression (e.g. "a.b[i].c"), maybe with an indirection as
777            the leftmost operator ("p->a.b.d"), where instrumentation
778            is necessary.  Or we may have an innocent "a.b.c"
779            expression that must not be instrumented.  We need to
780            recurse all the way down the nesting structure to figure it
781            out: looking just at the outer node is not enough.  */          
782         tree var;
783         int component_ref_only = (TREE_CODE (t) == COMPONENT_REF);
784         /* If we have a bitfield component reference, we must note the
785            innermost addressable object in ELT, from which we will
786            construct the byte-addressable bounds of the bitfield.  */
787         tree elt = NULL_TREE;
788         int bitfield_ref_p = (TREE_CODE (t) == COMPONENT_REF
789                               && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)));
790
791         /* Iterate to the top of the ARRAY_REF/COMPONENT_REF
792            containment hierarchy to find the outermost VAR_DECL.  */
793         var = TREE_OPERAND (t, 0);
794         while (1)
795           {
796             if (bitfield_ref_p && elt == NULL_TREE
797                 && (TREE_CODE (var) == ARRAY_REF
798                     || TREE_CODE (var) == COMPONENT_REF))
799               elt = var;
800         
801             if (TREE_CODE (var) == ARRAY_REF)
802               {
803                 component_ref_only = 0;
804                 var = TREE_OPERAND (var, 0);
805               }
806             else if (TREE_CODE (var) == COMPONENT_REF)
807               var = TREE_OPERAND (var, 0);
808             else if (INDIRECT_REF_P (var))
809               {
810                 base = TREE_OPERAND (var, 0);
811                 break;
812               }
813             else if (TREE_CODE (var) == VIEW_CONVERT_EXPR)
814               {
815                 var = TREE_OPERAND (var, 0);
816                 if (CONSTANT_CLASS_P (var)
817                     && TREE_CODE (var) != STRING_CST)
818                   return;
819               }
820             else 
821               {
822                 gcc_assert (TREE_CODE (var) == VAR_DECL 
823                             || TREE_CODE (var) == PARM_DECL
824                             || TREE_CODE (var) == RESULT_DECL
825                             || TREE_CODE (var) == STRING_CST);
826                 /* Don't instrument this access if the underlying
827                    variable is not "eligible".  This test matches
828                    those arrays that have only known-valid indexes,
829                    and thus are not labeled TREE_ADDRESSABLE.  */
830                 if (! mf_decl_eligible_p (var) || component_ref_only)
831                   return;
832                 else
833                   {
834                     base = build1 (ADDR_EXPR,
835                                    build_pointer_type (TREE_TYPE (var)), var);
836                     break;
837                   }
838               }
839           }
840
841         /* Handle the case of ordinary non-indirection structure
842            accesses.  These have only nested COMPONENT_REF nodes (no
843            INDIRECT_REF), but pass through the above filter loop.
844            Note that it's possible for such a struct variable to match
845            the eligible_p test because someone else might take its
846            address sometime.  */
847
848         /* We need special processing for bitfield components, because
849            their addresses cannot be taken.  */
850         if (bitfield_ref_p)
851           {
852             tree field = TREE_OPERAND (t, 1);
853
854             if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
855               size = DECL_SIZE_UNIT (field);
856             
857             if (elt)
858               elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)),
859                             elt);
860             addr = fold_convert (ptr_type_node, elt ? elt : base);
861             addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
862                                 addr, fold_convert (sizetype,
863                                                     byte_position (field)));
864           }
865         else
866           addr = build1 (ADDR_EXPR, build_pointer_type (type), t);
867
868         limit = fold_build2 (MINUS_EXPR, mf_uintptr_type,
869                              fold_build2 (PLUS_EXPR, mf_uintptr_type,
870                                           convert (mf_uintptr_type, addr),
871                                           size),
872                              integer_one_node);
873       }
874       break;
875
876     case INDIRECT_REF:
877       addr = TREE_OPERAND (t, 0);
878       base = addr;
879       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
880                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
881                                         size),
882                            size_int (-1));
883       break;
884
885     case TARGET_MEM_REF:
886       addr = tree_mem_ref_addr (ptr_type_node, t);
887       base = addr;
888       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
889                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
890                                         size),
891                            size_int (-1));
892       break;
893
894     case ARRAY_RANGE_REF:
895       warning (OPT_Wmudflap,
896                "mudflap checking not yet implemented for ARRAY_RANGE_REF");
897       return;
898
899     case BIT_FIELD_REF:
900       /* ??? merge with COMPONENT_REF code above? */
901       {
902         tree ofs, rem, bpu;
903
904         /* If we're not dereferencing something, then the access
905            must be ok.  */
906         if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
907           return;
908
909         bpu = bitsize_int (BITS_PER_UNIT);
910         ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
911         rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
912         ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu));
913
914         size = convert (bitsizetype, TREE_OPERAND (t, 1));
915         size = size_binop (PLUS_EXPR, size, rem);
916         size = size_binop (CEIL_DIV_EXPR, size, bpu);
917         size = convert (sizetype, size);
918
919         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
920         addr = convert (ptr_type_node, addr);
921         addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs);
922
923         base = addr;
924         limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
925                              fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
926                                            base, size),
927                              size_int (-1));
928       }
929       break;
930
931     default:
932       return;
933     }
934
935   mf_build_check_statement_for (base, limit, iter, location, dirflag);
936 }
937
938 static void
939 mf_xform_derefs (void)
940 {
941   basic_block bb, next;
942   gimple_stmt_iterator i;
943   int saved_last_basic_block = last_basic_block;
944   enum gimple_rhs_class grhs_class;
945
946   bb = ENTRY_BLOCK_PTR ->next_bb;
947   do
948     {
949       next = bb->next_bb;
950       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
951         {
952           gimple s = gsi_stmt (i);
953
954           /* Only a few GIMPLE statements can reference memory.  */
955           switch (gimple_code (s))
956             {
957             case GIMPLE_ASSIGN:
958               mf_xform_derefs_1 (&i, gimple_assign_lhs_ptr (s),
959                                  gimple_location (s), integer_one_node);
960               mf_xform_derefs_1 (&i, gimple_assign_rhs1_ptr (s),
961                                  gimple_location (s), integer_zero_node);
962               grhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (s));
963               if (grhs_class == GIMPLE_BINARY_RHS)
964                 mf_xform_derefs_1 (&i, gimple_assign_rhs2_ptr (s),
965                                    gimple_location (s), integer_zero_node);
966               break;
967
968             case GIMPLE_RETURN:
969               if (gimple_return_retval (s) != NULL_TREE)
970                 {
971                   mf_xform_derefs_1 (&i, gimple_return_retval_ptr (s),
972                                      gimple_location (s),
973                                      integer_zero_node);
974                 }
975               break;
976
977             default:
978               ;
979             }
980         }
981       bb = next;
982     }
983   while (bb && bb->index <= saved_last_basic_block);
984 }
985
986 /* ------------------------------------------------------------------------ */
987 /* ADDR_EXPR transforms.  Perform the declaration-related mudflap tree
988    transforms on the current function.
989
990    This is the first part of the mudflap instrumentation.  It works on
991    high-level GIMPLE because after lowering, all variables are moved out
992    of their BIND_EXPR binding context, and we lose liveness information
993    for the declarations we wish to instrument.  */
994
995 static unsigned int
996 execute_mudflap_function_decls (void)
997 {
998   struct gimplify_ctx gctx;
999
1000   /* Don't instrument functions such as the synthetic constructor
1001      built during mudflap_finish_file.  */
1002   if (mf_marked_p (current_function_decl) ||
1003       DECL_ARTIFICIAL (current_function_decl))
1004     return 0;
1005
1006   push_gimplify_context (&gctx);
1007
1008   mf_xform_decls (gimple_body (current_function_decl),
1009                   DECL_ARGUMENTS (current_function_decl));
1010
1011   pop_gimplify_context (NULL);
1012   return 0;
1013 }
1014
1015 /* This struct is passed between mf_xform_decls to store state needed
1016    during the traversal searching for objects that have their
1017    addresses taken.  */
1018 struct mf_xform_decls_data
1019 {
1020   tree param_decls;
1021 };
1022
1023
1024 /* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
1025    _DECLs if appropriate.  Arrange to call the __mf_register function
1026    now, and the __mf_unregister function later for each.  Return the
1027    gimple sequence after synthesis.  */
1028 gimple_seq
1029 mx_register_decls (tree decl, gimple_seq seq, location_t location)
1030 {
1031   gimple_seq finally_stmts = NULL;
1032   gimple_stmt_iterator initially_stmts = gsi_start (seq);
1033
1034   while (decl != NULL_TREE)
1035     {
1036       if (mf_decl_eligible_p (decl) 
1037           /* Not already processed.  */
1038           && ! mf_marked_p (decl)
1039           /* Automatic variable.  */
1040           && ! DECL_EXTERNAL (decl)
1041           && ! TREE_STATIC (decl))
1042         {
1043           tree size = NULL_TREE, variable_name;
1044           gimple unregister_fncall, register_fncall;
1045           tree unregister_fncall_param, register_fncall_param;
1046
1047           /* Variable-sized objects should have sizes already been
1048              gimplified when we got here. */
1049           size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
1050           gcc_assert (is_gimple_val (size));
1051         
1052
1053           unregister_fncall_param =
1054             mf_mark (build1 (ADDR_EXPR,
1055                              build_pointer_type (TREE_TYPE (decl)),
1056                              decl));
1057           /* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
1058           unregister_fncall = gimple_build_call (mf_unregister_fndecl, 3,
1059                                                  unregister_fncall_param,
1060                                                  size,
1061                                                  build_int_cst (NULL_TREE, 3));
1062
1063
1064           variable_name = mf_varname_tree (decl);
1065           register_fncall_param =
1066             mf_mark (build1 (ADDR_EXPR,
1067                              build_pointer_type (TREE_TYPE (decl)),
1068                              decl));
1069           /* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK,
1070                             "name") */
1071           register_fncall = gimple_build_call (mf_register_fndecl, 4,
1072                                                register_fncall_param,
1073                                                size,
1074                                                build_int_cst (NULL_TREE, 3),
1075                                                variable_name);
1076           
1077
1078           /* Accumulate the two calls.  */
1079           gimple_set_location (register_fncall, location);
1080           gimple_set_location (unregister_fncall, location);
1081
1082           /* Add the __mf_register call at the current appending point.  */
1083           if (gsi_end_p (initially_stmts))
1084             {
1085               if (!DECL_ARTIFICIAL (decl))
1086                 warning (OPT_Wmudflap,
1087                          "mudflap cannot track %qE in stub function",
1088                          DECL_NAME (decl));
1089             }
1090           else
1091             {
1092               gsi_insert_before (&initially_stmts, register_fncall,
1093                                  GSI_SAME_STMT);
1094
1095               /* Accumulate the FINALLY piece.  */
1096               gimple_seq_add_stmt (&finally_stmts, unregister_fncall);
1097             }
1098           mf_mark (decl);
1099         }
1100
1101       decl = TREE_CHAIN (decl);
1102     }
1103
1104   /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
1105   if (finally_stmts != NULL)
1106     {
1107       gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY);
1108       gimple_seq new_seq = gimple_seq_alloc ();
1109
1110       gimple_seq_add_stmt (&new_seq, stmt);
1111       return new_seq;
1112     }
1113    else
1114     return seq;
1115 }
1116
1117
1118 /* Process every variable mentioned in BIND_EXPRs.  */
1119 static tree
1120 mx_xfn_xform_decls (gimple_stmt_iterator *gsi,
1121                     bool *handled_operands_p ATTRIBUTE_UNUSED,
1122                     struct walk_stmt_info *wi)
1123 {
1124   struct mf_xform_decls_data *d = (struct mf_xform_decls_data *) wi->info;
1125   gimple stmt = gsi_stmt (*gsi);
1126
1127   switch (gimple_code (stmt))
1128     {
1129     case GIMPLE_BIND:
1130       {
1131         /* Process function parameters now (but only once).  */
1132         if (d->param_decls)
1133           {
1134             gimple_bind_set_body (stmt,
1135                                   mx_register_decls (d->param_decls,
1136                                                      gimple_bind_body (stmt),
1137                                                      gimple_location (stmt)));
1138             d->param_decls = NULL_TREE;
1139           }
1140
1141         gimple_bind_set_body (stmt,
1142                               mx_register_decls (gimple_bind_vars (stmt),
1143                                                  gimple_bind_body (stmt),
1144                                                  gimple_location (stmt)));
1145       }
1146       break;
1147
1148     default:
1149       break;
1150     }
1151
1152   return NULL_TREE;
1153 }
1154
1155 /* Perform the object lifetime tracking mudflap transform on the given function
1156    tree.  The tree is mutated in place, with possibly copied subtree nodes.
1157
1158    For every auto variable declared, if its address is ever taken
1159    within the function, then supply its lifetime to the mudflap
1160    runtime with the __mf_register and __mf_unregister calls.
1161 */
1162
1163 static void
1164 mf_xform_decls (gimple_seq fnbody, tree fnparams)
1165 {
1166   struct mf_xform_decls_data d;
1167   struct walk_stmt_info wi;
1168   struct pointer_set_t *pset = pointer_set_create ();
1169
1170   d.param_decls = fnparams;
1171   memset (&wi, 0, sizeof (wi));
1172   wi.info = (void*) &d;
1173   wi.pset = pset;
1174   walk_gimple_seq (fnbody, mx_xfn_xform_decls, NULL, &wi);
1175   pointer_set_destroy (pset);
1176 }
1177
1178
1179 /* ------------------------------------------------------------------------ */
1180 /* Externally visible mudflap functions.  */
1181
1182
1183 /* Mark and return the given tree node to prevent further mudflap
1184    transforms.  */
1185 static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
1186
1187 tree
1188 mf_mark (tree t)
1189 {
1190   void **slot;
1191
1192   if (marked_trees == NULL)
1193     marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer,
1194                                     NULL);
1195
1196   slot = htab_find_slot (marked_trees, t, INSERT);
1197   *slot = t;
1198   return t;
1199 }
1200
1201 int
1202 mf_marked_p (tree t)
1203 {
1204   void *entry;
1205
1206   if (marked_trees == NULL)
1207     return 0;
1208
1209   entry = htab_find (marked_trees, t);
1210   return (entry != NULL);
1211 }
1212
1213 /* Remember given node as a static of some kind: global data,
1214    function-scope static, or an anonymous constant.  Its assembler
1215    label is given.  */
1216
1217 /* A list of globals whose incomplete declarations we encountered.
1218    Instead of emitting the __mf_register call for them here, it's
1219    delayed until program finish time.  If they're still incomplete by
1220    then, warnings are emitted.  */
1221
1222 static GTY (()) VEC(tree,gc) *deferred_static_decls;
1223
1224 /* A list of statements for calling __mf_register() at startup time.  */
1225 static GTY (()) tree enqueued_call_stmt_chain;
1226
1227 static void
1228 mudflap_register_call (tree obj, tree object_size, tree varname)
1229 {
1230   tree arg, call_stmt;
1231
1232   arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
1233   arg = convert (ptr_type_node, arg);
1234
1235   call_stmt = build_call_expr (mf_register_fndecl, 4,
1236                                arg,
1237                                convert (size_type_node, object_size),
1238                                /* __MF_TYPE_STATIC */
1239                                build_int_cst (NULL_TREE, 4), 
1240                                varname);
1241
1242   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
1243 }
1244
1245 void
1246 mudflap_enqueue_decl (tree obj)
1247 {
1248   if (mf_marked_p (obj))
1249     return;
1250
1251   /* We don't need to process variable decls that are internally
1252      generated extern.  If we did, we'd end up with warnings for them
1253      during mudflap_finish_file ().  That would confuse the user,
1254      since the text would refer to variables that don't show up in the
1255      user's source code.  */
1256   if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
1257     return;
1258
1259   VEC_safe_push (tree, gc, deferred_static_decls, obj);
1260 }
1261
1262
1263 void
1264 mudflap_enqueue_constant (tree obj)
1265 {
1266   tree object_size, varname;
1267
1268   if (mf_marked_p (obj))
1269     return;
1270
1271   if (TREE_CODE (obj) == STRING_CST)
1272     object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj));
1273   else
1274     object_size = size_in_bytes (TREE_TYPE (obj));
1275
1276   if (TREE_CODE (obj) == STRING_CST)
1277     varname = mf_build_string ("string literal");
1278   else
1279     varname = mf_build_string ("constant");
1280
1281   mudflap_register_call (obj, object_size, varname);
1282 }
1283
1284
1285 /* Emit any file-wide instrumentation.  */
1286 void
1287 mudflap_finish_file (void)
1288 {
1289   tree ctor_statements = NULL_TREE;
1290
1291   /* No need to continue when there were errors.  */
1292   if (errorcount != 0 || sorrycount != 0)
1293     return;
1294
1295   /* Insert a call to __mf_init.  */
1296   {
1297     tree call2_stmt = build_call_expr (mf_init_fndecl, 0);
1298     append_to_statement_list (call2_stmt, &ctor_statements);
1299   }
1300   
1301   /* If appropriate, call __mf_set_options to pass along read-ignore mode.  */
1302   if (flag_mudflap_ignore_reads)
1303     {
1304       tree arg = mf_build_string ("-ignore-reads");
1305       tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg);
1306       append_to_statement_list (call_stmt, &ctor_statements);
1307     }
1308
1309   /* Process all enqueued object decls.  */
1310   if (deferred_static_decls)
1311     {
1312       size_t i;
1313       tree obj;
1314       for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++)
1315         {
1316           gcc_assert (DECL_P (obj));
1317
1318           if (mf_marked_p (obj))
1319             continue;
1320
1321           /* Omit registration for static unaddressed objects.  NB:
1322              Perform registration for non-static objects regardless of
1323              TREE_USED or TREE_ADDRESSABLE, because they may be used
1324              from other compilation units.  */
1325           if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj))
1326             continue;
1327
1328           if (! COMPLETE_TYPE_P (TREE_TYPE (obj)))
1329             {
1330               warning (OPT_Wmudflap,
1331                        "mudflap cannot track unknown size extern %qE",
1332                        DECL_NAME (obj));
1333               continue;
1334             }
1335           
1336           mudflap_register_call (obj, 
1337                                  size_in_bytes (TREE_TYPE (obj)),
1338                                  mf_varname_tree (obj));
1339         }
1340
1341       VEC_truncate (tree, deferred_static_decls, 0);
1342     }
1343
1344   /* Append all the enqueued registration calls.  */
1345   if (enqueued_call_stmt_chain)
1346     {
1347       append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements);
1348       enqueued_call_stmt_chain = NULL_TREE;
1349     }
1350
1351   cgraph_build_static_cdtor ('I', ctor_statements, 
1352                              MAX_RESERVED_INIT_PRIORITY-1);
1353 }
1354
1355
1356 static bool
1357 gate_mudflap (void)
1358 {
1359   return flag_mudflap != 0;
1360 }
1361
1362 struct gimple_opt_pass pass_mudflap_1 = 
1363 {
1364  {
1365   GIMPLE_PASS,
1366   "mudflap1",                           /* name */
1367   gate_mudflap,                         /* gate */
1368   execute_mudflap_function_decls,       /* execute */
1369   NULL,                                 /* sub */
1370   NULL,                                 /* next */
1371   0,                                    /* static_pass_number */
1372   TV_NONE,                              /* tv_id */
1373   PROP_gimple_any,                      /* properties_required */
1374   0,                                    /* properties_provided */
1375   0,                                    /* properties_destroyed */
1376   0,                                    /* todo_flags_start */
1377   TODO_dump_func                        /* todo_flags_finish */
1378  }
1379 };
1380
1381 struct gimple_opt_pass pass_mudflap_2 = 
1382 {
1383  {
1384   GIMPLE_PASS,
1385   "mudflap2",                           /* name */
1386   gate_mudflap,                         /* gate */
1387   execute_mudflap_function_ops,         /* execute */
1388   NULL,                                 /* sub */
1389   NULL,                                 /* next */
1390   0,                                    /* static_pass_number */
1391   TV_NONE,                              /* tv_id */
1392   PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */
1393   0,                                    /* properties_provided */
1394   0,                                    /* properties_destroyed */
1395   0,                                    /* todo_flags_start */
1396   TODO_verify_flow | TODO_verify_stmts
1397   | TODO_dump_func | TODO_update_ssa    /* todo_flags_finish */
1398  }
1399 };
1400
1401 #include "gt-tree-mudflap.h"