tree-mudflap.c File Reference

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "hard-reg-set.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "basic-block.h"
#include "flags.h"
#include "function.h"
#include "tree-inline.h"
#include "tree-gimple.h"
#include "tree-flow.h"
#include "tree-mudflap.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "hashtab.h"
#include "diagnostic.h"
#include <demangle.h>
#include "langhooks.h"
#include "ggc.h"
#include "cgraph.h"
#include "toplev.h"
#include "gt-tree-mudflap.h"

Include dependency graph for tree-mudflap.c:

Go to the source code of this file.

Data Structures

struct  mf_xform_decls_data

Defines

#define flag_mudflap_threads   (flag_mudflap == 2)
#define build_function_type_0(rtype)   build_function_type (rtype, void_list_node)
#define build_function_type_1(rtype, arg1)   build_function_type (rtype, tree_cons (0, arg1, void_list_node))
#define build_function_type_3(rtype, arg1, arg2, arg3)
#define build_function_type_4(rtype, arg1, arg2, arg3, arg4)

Functions

static tree mf_build_string (const char *string)
static tree mf_varname_tree (tree)
static tree mf_file_function_line_tree (location_t)
static void mf_decl_cache_locals (void)
static void mf_decl_clear_locals (void)
static void mf_xform_derefs (void)
static unsigned int execute_mudflap_function_ops (void)
static void mf_xform_decls (tree, tree)
static tree mx_xfn_xform_decls (tree *, int *, void *)
static void mx_register_decls (tree, tree *)
static unsigned int execute_mudflap_function_decls (void)
static tree mf_build_string ()
static tree mf_varname_tree ()
static tree mf_file_function_line_tree ()
static tree mf_make_builtin ()
static tree mf_make_mf_cache_struct_type ()
void mudflap_init ()
static void mf_build_check_statement_for (tree base, tree limit, block_stmt_iterator *instr_bsi, location_t *locus, tree dirflag)
static int mf_decl_eligible_p ()
static void mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, location_t *locus, tree dirflag)
static void mx_register_decls ()
static tree mx_xfn_xform_decls ()
static void mf_xform_decls ()
tree mf_mark ()
int mf_marked_p ()
static VEC (tree, gc)
void mudflap_enqueue_decl ()
void mudflap_enqueue_constant ()
void mudflap_finish_file ()
static bool gate_mudflap ()

Variables

static tree mf_uintptr_type
static tree mf_cache_struct_type
static tree mf_cache_structptr_type
static tree mf_cache_array_decl
static tree mf_cache_shift_decl
static tree mf_cache_mask_decl
static tree mf_cache_shift_decl_l
static tree mf_cache_mask_decl_l
static tree mf_check_fndecl
static tree mf_register_fndecl
static tree mf_unregister_fndecl
static tree mf_init_fndecl
static tree mf_set_options_fndecl
static htab_t marked_trees = NULL
tree_opt_pass pass_mudflap_1
tree_opt_pass pass_mudflap_2


Define Documentation

#define build_function_type_0 rtype   )     build_function_type (rtype, void_list_node)
 

Definition at line 330 of file tree-mudflap.c.

Referenced by mudflap_init().

#define build_function_type_1 rtype,
arg1   )     build_function_type (rtype, tree_cons (0, arg1, void_list_node))
 

Definition at line 332 of file tree-mudflap.c.

Referenced by mudflap_init().

#define build_function_type_3 rtype,
arg1,
arg2,
arg3   ) 
 

Value:

build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2,   \
                                                             tree_cons (0, arg3, void_list_node))))

Definition at line 334 of file tree-mudflap.c.

Referenced by mudflap_init().

#define build_function_type_4 rtype,
arg1,
arg2,
arg3,
arg4   ) 
 

Value:

build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2,   \
                                                             tree_cons (0, arg3, tree_cons (0, arg4, \
                                                                                            void_list_node)))))

Definition at line 337 of file tree-mudflap.c.

Referenced by mudflap_init().

#define flag_mudflap_threads   (flag_mudflap == 2)
 

Options.   

Definition at line 53 of file tree-mudflap.c.

Referenced by execute_mudflap_function_ops(), and mf_build_check_statement_for().


Function Documentation

static unsigned int execute_mudflap_function_decls void   )  [static]
 

ADDR_EXPR transforms.  Perform the declaration-related mudflap tree
   transforms on the current function.

   This is the first part of the mudflap instrumentation.  It works on
   high-level GIMPLE because after lowering, all variables are moved out
   of their BIND_EXPR binding context, and we lose liveness information
   for the declarations we wish to instrument.   

Definition at line 953 of file tree-mudflap.c.

References current_function_decl, DECL_ARGUMENTS, DECL_ARTIFICIAL, DECL_SAVED_TREE, mf_marked_p(), mf_xform_decls(), pop_gimplify_context(), and push_gimplify_context().

00954 {
00955   /* Don't instrument functions such as the synthetic constructor
00956      built during mudflap_finish_file.  */
00957   if (mf_marked_p (current_function_decl) ||
00958       DECL_ARTIFICIAL (current_function_decl))
00959     return 0;
00960 
00961   push_gimplify_context ();
00962 
00963   mf_xform_decls (DECL_SAVED_TREE (current_function_decl),
00964                   DECL_ARGUMENTS (current_function_decl));
00965 
00966   pop_gimplify_context (NULL);
00967   return 0;
00968 }

static unsigned int execute_mudflap_function_ops void   )  [static]
 

Memory reference transforms. Perform the mudflap indirection-related
   tree transforms on the current function.

   This is the second part of the mudflap instrumentation.  It works on
   low-level GIMPLE using the CFG, because we want to run this pass after
   tree optimizations have been performed, but we have to preserve the CFG
   for expansion from trees to RTL.   

Definition at line 417 of file tree-mudflap.c.

References current_function_decl, DECL_ARTIFICIAL, flag_mudflap_threads, mf_decl_cache_locals(), mf_decl_clear_locals(), mf_marked_p(), mf_xform_derefs(), pop_gimplify_context(), and push_gimplify_context().

00418 {
00419   /* Don't instrument functions such as the synthetic constructor
00420      built during mudflap_finish_file.  */
00421   if (mf_marked_p (current_function_decl) ||
00422       DECL_ARTIFICIAL (current_function_decl))
00423     return 0;
00424 
00425   push_gimplify_context ();
00426 
00427   /* In multithreaded mode, don't cache the lookup cache parameters.  */
00428   if (! flag_mudflap_threads)
00429     mf_decl_cache_locals ();
00430 
00431   mf_xform_derefs ();
00432 
00433   if (! flag_mudflap_threads)
00434     mf_decl_clear_locals ();
00435 
00436   pop_gimplify_context (NULL);
00437   return 0;
00438 }

static bool gate_mudflap  )  [static]
 

Definition at line 1305 of file tree-mudflap.c.

01306 {
01307   return flag_mudflap != 0;
01308 }

static void mf_build_check_statement_for tree  base,
tree  limit,
block_stmt_iterator instr_bsi,
location_t *  locus,
tree  dirflag
[static]
 

Definition at line 497 of file tree-mudflap.c.

References bb_for_stmt(), boolean_type_node, BSI_CONTINUE_LINKING, bsi_end_p(), bsi_insert_after(), bsi_last, bsi_next(), bsi_prev(), bsi_start, bsi_stmt(), build1, build2, build3, build4, build_function_call_expr(), convert(), create_tmp_var, flag_mudflap_threads, fold_build2, gimplify_to_stmt_list(), integer_one_node, integer_type_node, mf_cache_array_decl, mf_cache_mask_decl, mf_cache_mask_decl_l, mf_cache_shift_decl, mf_cache_shift_decl_l, mf_cache_struct_type, mf_cache_structptr_type, mf_check_fndecl, mf_file_function_line_tree(), mf_uintptr_type, NULL_TREE, SET_EXPR_LOCUS, tree_block_label(), TREE_CHAIN, tree_cons, TREE_TYPE, TSI_CONTINUE_LINKING, tsi_end_p(), tsi_last(), tsi_link_after(), tsi_next(), tsi_start(), tsi_stmt(), TYPE_FIELDS, unshare_expr(), and void_type_node.

Referenced by mf_xform_derefs_1().

00500 {
00501   tree_stmt_iterator head, tsi;
00502   block_stmt_iterator bsi;
00503   basic_block cond_bb, then_bb, join_bb;
00504   edge e;
00505   tree cond, t, u, v;
00506   tree mf_base;
00507   tree mf_elem;
00508   tree mf_limit;
00509 
00510   /* We first need to split the current basic block, and start altering
00511      the CFG.  This allows us to insert the statements we're about to
00512      construct into the right basic blocks.  */
00513 
00514   cond_bb = bb_for_stmt (bsi_stmt (*instr_bsi));
00515   bsi = *instr_bsi;
00516   bsi_prev (&bsi);
00517   if (! bsi_end_p (bsi))
00518     e = split_block (cond_bb, bsi_stmt (bsi));
00519   else
00520     e = split_block_after_labels (cond_bb);
00521   cond_bb = e->src;
00522   join_bb = e->dest;
00523 
00524   /* A recap at this point: join_bb is the basic block at whose head
00525      is the gimple statement for which this check expression is being
00526      built.  cond_bb is the (possibly new, synthetic) basic block the
00527      end of which will contain the cache-lookup code, and a
00528      conditional that jumps to the cache-miss code or, much more
00529      likely, over to join_bb.  */
00530 
00531   /* Create the bb that contains the cache-miss fallback block (mf_check).  */
00532   then_bb = create_empty_bb (cond_bb);
00533   make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
00534   make_single_succ_edge (then_bb, join_bb, EDGE_FALLTHRU);
00535 
00536   /* Mark the pseudo-fallthrough edge from cond_bb to join_bb.  */
00537   e = find_edge (cond_bb, join_bb);
00538   e->flags = EDGE_FALSE_VALUE;
00539   e->count = cond_bb->count;
00540   e->probability = REG_BR_PROB_BASE;
00541 
00542   /* Update dominance info.  Note that bb_join's data was
00543      updated by split_block.  */
00544   if (dom_info_available_p (CDI_DOMINATORS))
00545     {
00546       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
00547       set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
00548     }
00549 
00550   /* Build our local variables.  */
00551   mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem");
00552   mf_base = create_tmp_var (mf_uintptr_type, "__mf_base");
00553   mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit");
00554 
00555   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
00556   t = build2 (MODIFY_EXPR, void_type_node, mf_base,
00557               convert (mf_uintptr_type, unshare_expr (base)));
00558   SET_EXPR_LOCUS (t, locus);
00559   gimplify_to_stmt_list (&t);
00560   head = tsi_start (t);
00561   tsi = tsi_last (t);
00562 
00563   /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
00564   t = build2 (MODIFY_EXPR, void_type_node, mf_limit,
00565               convert (mf_uintptr_type, unshare_expr (limit)));
00566   SET_EXPR_LOCUS (t, locus);
00567   gimplify_to_stmt_list (&t);
00568   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
00569 
00570   /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
00571                                             & __mf_mask].  */
00572   t = build2 (RSHIFT_EXPR, mf_uintptr_type, mf_base,
00573               (flag_mudflap_threads ? mf_cache_shift_decl : mf_cache_shift_decl_l));
00574   t = build2 (BIT_AND_EXPR, mf_uintptr_type, t,
00575               (flag_mudflap_threads ? mf_cache_mask_decl : mf_cache_mask_decl_l));
00576   t = build4 (ARRAY_REF,
00577               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
00578               mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
00579   t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
00580   t = build2 (MODIFY_EXPR, void_type_node, mf_elem, t);
00581   SET_EXPR_LOCUS (t, locus);
00582   gimplify_to_stmt_list (&t);
00583   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
00584 
00585   /* Quick validity check.
00586 
00587      if (__mf_elem->low > __mf_base
00588          || (__mf_elem_high < __mf_limit))
00589         {
00590           __mf_check ();
00591           ... and only if single-threaded:
00592           __mf_lookup_shift_1 = f...;
00593           __mf_lookup_mask_l = ...;
00594         }
00595 
00596      It is expected that this body of code is rarely executed so we mark
00597      the edge to the THEN clause of the conditional jump as unlikely.  */
00598 
00599   /* Construct t <-- '__mf_elem->low  > __mf_base'.  */
00600   t = build3 (COMPONENT_REF, mf_uintptr_type,
00601               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
00602               TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
00603   t = build2 (GT_EXPR, boolean_type_node, t, mf_base);
00604 
00605   /* Construct '__mf_elem->high < __mf_limit'.
00606 
00607      First build:
00608         1) u <--  '__mf_elem->high'
00609         2) v <--  '__mf_limit'.
00610 
00611      Then build 'u <-- (u < v).  */
00612 
00613   u = build3 (COMPONENT_REF, mf_uintptr_type,
00614               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
00615               TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
00616 
00617   v = mf_limit;
00618 
00619   u = build2 (LT_EXPR, boolean_type_node, u, v);
00620 
00621   /* Build the composed conditional: t <-- 't || u'.  Then store the
00622      result of the evaluation of 't' in a temporary variable which we
00623      can use as the condition for the conditional jump.  */
00624   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
00625   cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
00626   t = build2 (MODIFY_EXPR, boolean_type_node, cond, t);
00627   gimplify_to_stmt_list (&t);
00628   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
00629 
00630   /* Build the conditional jump.  'cond' is just a temporary so we can
00631      simply build a void COND_EXPR.  We do need labels in both arms though.  */
00632   t = build3 (COND_EXPR, void_type_node, cond,
00633               build1 (GOTO_EXPR, void_type_node, tree_block_label (then_bb)),
00634               build1 (GOTO_EXPR, void_type_node, tree_block_label (join_bb)));
00635   SET_EXPR_LOCUS (t, locus);
00636   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
00637 
00638   /* At this point, after so much hard work, we have only constructed
00639      the conditional jump,
00640 
00641      if (__mf_elem->low > __mf_base
00642          || (__mf_elem_high < __mf_limit))
00643 
00644      The lowered GIMPLE tree representing this code is in the statement
00645      list starting at 'head'.
00646 
00647      We can insert this now in the current basic block, i.e. the one that
00648      the statement we're instrumenting was originally in.  */
00649   bsi = bsi_last (cond_bb);
00650   for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
00651     bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
00652 
00653   /*  Now build up the body of the cache-miss handling:
00654 
00655      __mf_check();
00656      refresh *_l vars.
00657 
00658      This is the body of the conditional.  */
00659   
00660   u = tree_cons (NULL_TREE,
00661                  mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION
00662                                              : *locus),
00663                  NULL_TREE);
00664   u = tree_cons (NULL_TREE, dirflag, u);
00665   /* NB: we pass the overall [base..limit] range to mf_check.  */
00666   u = tree_cons (NULL_TREE, 
00667                  fold_build2 (PLUS_EXPR, integer_type_node,
00668                               fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
00669                               integer_one_node),
00670                  u);
00671   u = tree_cons (NULL_TREE, mf_base, u);
00672   t = build_function_call_expr (mf_check_fndecl, u);
00673   gimplify_to_stmt_list (&t);
00674   head = tsi_start (t);
00675   tsi = tsi_last (t);
00676 
00677   if (! flag_mudflap_threads)
00678     {
00679       t = build2 (MODIFY_EXPR, void_type_node,
00680                   mf_cache_shift_decl_l, mf_cache_shift_decl);
00681       tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
00682 
00683       t = build2 (MODIFY_EXPR, void_type_node,
00684                   mf_cache_mask_decl_l, mf_cache_mask_decl);
00685       tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
00686     }
00687 
00688   /* Insert the check code in the THEN block.  */
00689   bsi = bsi_start (then_bb);
00690   for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
00691     bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
00692 
00693   *instr_bsi = bsi_start (join_bb);
00694   bsi_next (instr_bsi);
00695 }

static tree mf_build_string  )  [static]
 

Build a reference to a literal string.   

Definition at line 78 of file tree-mudflap.c.

References build1, build_array_type(), build_index_type(), build_int_cst(), build_pointer_type(), build_string(), char_type_node, mf_mark(), NULL_TREE, TREE_CONSTANT, TREE_INVARIANT, TREE_READONLY, TREE_STATIC, and TREE_TYPE.

00079 {
00080   size_t len = strlen (string);
00081   tree result = mf_mark (build_string (len + 1, string));
00082 
00083   TREE_TYPE (result) = build_array_type
00084     (char_type_node, build_index_type (build_int_cst (NULL_TREE, len)));
00085   TREE_CONSTANT (result) = 1;
00086   TREE_INVARIANT (result) = 1;
00087   TREE_READONLY (result) = 1;
00088   TREE_STATIC (result) = 1;
00089 
00090   result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);
00091 
00092   return mf_mark (result);
00093 }

static tree mf_build_string const char *  string  )  [static]
 

Helpers.   

Referenced by mf_file_function_line_tree(), mf_varname_tree(), mudflap_enqueue_constant(), and mudflap_finish_file().

static void mf_decl_cache_locals void   )  [static]
 

Create and initialize local shadow variables for the lookup cache
   globals.  Put their decls in the *_l globals for use by
   mf_build_check_statement_for.   

Definition at line 445 of file tree-mudflap.c.

References bsi_commit_edge_inserts(), build2, create_tmp_var, current_function_decl, DECL_SOURCE_LOCATION, gimplify_to_stmt_list(), insert_edge_copies(), mf_cache_mask_decl, mf_cache_mask_decl_l, mf_cache_shift_decl, mf_cache_shift_decl_l, mf_mark(), SET_EXPR_LOCATION, TREE_TYPE, tsi_end_p(), tsi_next(), tsi_start(), and tsi_stmt().

Referenced by execute_mudflap_function_ops().

00446 {
00447   tree t, shift_init_stmts, mask_init_stmts;
00448   tree_stmt_iterator tsi;
00449 
00450   /* Build the cache vars.  */
00451   mf_cache_shift_decl_l
00452     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl),
00453                                "__mf_lookup_shift_l"));
00454 
00455   mf_cache_mask_decl_l
00456     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl),
00457                                "__mf_lookup_mask_l"));
00458 
00459   /* Build initialization nodes for the cache vars.  We just load the
00460      globals into the cache variables.  */
00461   t = build2 (MODIFY_EXPR, TREE_TYPE (mf_cache_shift_decl_l),
00462               mf_cache_shift_decl_l, mf_cache_shift_decl);
00463   SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
00464   gimplify_to_stmt_list (&t);
00465   shift_init_stmts = t;
00466 
00467   t = build2 (MODIFY_EXPR, TREE_TYPE (mf_cache_mask_decl_l),
00468               mf_cache_mask_decl_l, mf_cache_mask_decl);
00469   SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
00470   gimplify_to_stmt_list (&t);
00471   mask_init_stmts = t;
00472 
00473   /* Anticipating multiple entry points, we insert the cache vars
00474      initializers in each successor of the ENTRY_BLOCK_PTR.  */
00475   for (tsi = tsi_start (shift_init_stmts);
00476        ! tsi_end_p (tsi);
00477        tsi_next (&tsi))
00478     insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
00479 
00480   for (tsi = tsi_start (mask_init_stmts);
00481        ! tsi_end_p (tsi);
00482        tsi_next (&tsi))
00483     insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
00484   bsi_commit_edge_inserts ();
00485 }

static void mf_decl_clear_locals void   )  [static]
 

Definition at line 489 of file tree-mudflap.c.

References mf_cache_mask_decl_l, mf_cache_shift_decl_l, and NULL_TREE.

Referenced by execute_mudflap_function_ops().

00490 {
00491   /* Unset local shadows.  */
00492   mf_cache_shift_decl_l = NULL_TREE;
00493   mf_cache_mask_decl_l = NULL_TREE;
00494 }

static int mf_decl_eligible_p  )  [static]
 

Check whether the given decl, generally a VAR_DECL or PARM_DECL, is
   eligible for instrumentation.  For the mudflap1 pass, this implies
   that it should be registered with the libmudflap runtime.  For the
   mudflap2 pass this means instrumenting an indirection operation with
   respect to the object.
 

Definition at line 705 of file tree-mudflap.c.

References COMPLETE_OR_VOID_TYPE_P, DECL_HAS_VALUE_EXPR_P, TREE_ADDRESSABLE, TREE_CODE, and TREE_TYPE.

Referenced by mf_xform_derefs_1(), and mx_register_decls().

00706 {
00707   return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
00708           /* The decl must have its address taken.  In the case of
00709              arrays, this flag is also set if the indexes are not
00710              compile-time known valid constants.  */
00711           && TREE_ADDRESSABLE (decl)    /* XXX: not sufficient: return-by-value structs! */
00712           /* The type of the variable must be complete.  */
00713           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
00714           /* The decl hasn't been decomposed somehow.  */
00715           && !DECL_HAS_VALUE_EXPR_P (decl));
00716 }

static tree mf_file_function_line_tree  )  [static]
 

And another friend, for producing a simpler message.   

Definition at line 200 of file tree-mudflap.c.

References current_function_decl, DECL_SOURCE_FILE, mf_build_string(), and NULL_TREE.

00201 {
00202   expanded_location xloc = expand_location (location);
00203   const char *file = NULL, *colon, *line, *op, *name, *cp;
00204   char linecolbuf[30]; /* Enough for two decimal numbers plus a colon.  */
00205   char *string;
00206   tree result;
00207 
00208   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
00209   file = xloc.file;
00210   if (file == NULL && current_function_decl != NULL_TREE)
00211     file = DECL_SOURCE_FILE (current_function_decl);
00212   if (file == NULL)
00213     file = "<unknown file>";
00214 
00215   if (xloc.line > 0)
00216     {
00217 #ifdef USE_MAPPED_LOCATION
00218       if (xloc.column > 0)
00219         sprintf (linecolbuf, "%d:%d", xloc.line, xloc.column);
00220       else
00221 #endif
00222         sprintf (linecolbuf, "%d", xloc.line);
00223       colon = ":";
00224       line = linecolbuf;
00225     }
00226   else
00227     colon = line = "";
00228 
00229   /* Add (FUNCTION).  */
00230   name = lang_hooks.decl_printable_name (current_function_decl, 1);
00231   if (name)
00232     {
00233       op = " (";
00234       cp = ")";
00235     }
00236   else
00237     op = name = cp = "";
00238 
00239   string = concat (file, colon, line, op, name, cp, NULL);
00240   result = mf_build_string (string);
00241   free (string);
00242 
00243   return result;
00244 }

static tree mf_file_function_line_tree location_t   )  [static]
 

Referenced by mf_build_check_statement_for().

static tree mf_make_builtin  )  [inline, static]
 

Helper for mudflap_init: construct a decl with the given category,
   name, and type, mark it an external reference, and pushdecl it.   

Definition at line 298 of file tree-mudflap.c.

References build_decl, DECL_EXTERNAL, get_identifier(), mf_mark(), and TREE_PUBLIC.

Referenced by mudflap_init().

00299 {
00300   tree decl = mf_mark (build_decl (category, get_identifier (name), type));
00301   TREE_PUBLIC (decl) = 1;
00302   DECL_EXTERNAL (decl) = 1;
00303   lang_hooks.decls.pushdecl (decl);
00304   return decl;
00305 }

static tree mf_make_mf_cache_struct_type  )  [inline, static]
 

Helper for mudflap_init: construct a tree corresponding to the type
     struct __mf_cache { uintptr_t low; uintptr_t high; };
     where uintptr_t is the FIELD_TYPE argument.   

Definition at line 311 of file tree-mudflap.c.

References build_decl, DECL_CONTEXT, get_identifier(), layout_type(), make_node, TREE_CHAIN, TYPE_FIELDS, and TYPE_NAME.

Referenced by mudflap_init().

00312 {
00313   /* There is, abominably, no language-independent way to construct a
00314      RECORD_TYPE.  So we have to call the basic type construction
00315      primitives by hand.  */
00316   tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type);
00317   tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type);
00318 
00319   tree struct_type = make_node (RECORD_TYPE);
00320   DECL_CONTEXT (fieldlo) = struct_type;
00321   DECL_CONTEXT (fieldhi) = struct_type;
00322   TREE_CHAIN (fieldlo) = fieldhi;
00323   TYPE_FIELDS (struct_type) = fieldlo;
00324   TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
00325   layout_type (struct_type);
00326 
00327   return struct_type;
00328 }

tree mf_mark  ) 
 

Definition at line 1133 of file tree-mudflap.c.

Referenced by copy_tree_r(), mf_build_string(), mf_decl_cache_locals(), mf_make_builtin(), mudflap_init(), and mx_register_decls().

01134 {
01135   void **slot;
01136 
01137   if (marked_trees == NULL)
01138     marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer, NULL);
01139 
01140   slot = htab_find_slot (marked_trees, t, INSERT);
01141   *slot = t;
01142   return t;
01143 }

int mf_marked_p  ) 
 

Definition at line 1146 of file tree-mudflap.c.

Referenced by copy_tree_r(), execute_mudflap_function_decls(), execute_mudflap_function_ops(), mf_xform_derefs_1(), mudflap_enqueue_constant(), mudflap_enqueue_decl(), mudflap_finish_file(), and mx_register_decls().

01147 {
01148   void *entry;
01149 
01150   if (marked_trees == NULL)
01151     return 0;
01152 
01153   entry = htab_find (marked_trees, t);
01154   return (entry != NULL);
01155 }

static tree mf_varname_tree  )  [static]
 

Create a properly typed STRING_CST node that describes the given
   declaration.  It will be used as an argument for __mf_register().
   Try to construct a helpful string, including file/function/variable
   name.   

Definition at line 101 of file tree-mudflap.c.

References current_function_decl, DECL_NAME, DECL_SOURCE_FILE, DECL_SOURCE_LOCATION, IDENTIFIER_POINTER, initialized, mf_build_string(), and NULL_TREE.

00102 {
00103   static pretty_printer buf_rec;
00104   static int initialized = 0;
00105   pretty_printer *buf = & buf_rec;
00106   const char *buf_contents;
00107   tree result;
00108 
00109   gcc_assert (decl);
00110 
00111   if (!initialized)
00112     {
00113       pp_construct (buf, /* prefix */ NULL, /* line-width */ 0);
00114       initialized = 1;
00115     }
00116   pp_clear_output_area (buf);
00117 
00118   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
00119   {
00120     expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl));
00121     const char *sourcefile;
00122     unsigned sourceline = xloc.line;
00123     unsigned sourcecolumn = 0;
00124 #ifdef USE_MAPPED_LOCATION
00125     sourcecolumn = xloc.column;
00126 #endif
00127     sourcefile = xloc.file;
00128     if (sourcefile == NULL && current_function_decl != NULL_TREE)
00129       sourcefile = DECL_SOURCE_FILE (current_function_decl);
00130     if (sourcefile == NULL)
00131       sourcefile = "<unknown file>";
00132 
00133     pp_string (buf, sourcefile);
00134 
00135     if (sourceline != 0)
00136       {
00137         pp_string (buf, ":");
00138         pp_decimal_int (buf, sourceline);
00139 
00140         if (sourcecolumn != 0)
00141           {
00142             pp_string (buf, ":");
00143             pp_decimal_int (buf, sourcecolumn);
00144           }
00145       }
00146   }
00147 
00148   if (current_function_decl != NULL_TREE)
00149     {
00150       /* Add (FUNCTION) */
00151       pp_string (buf, " (");
00152       {
00153         const char *funcname = NULL;
00154         if (DECL_NAME (current_function_decl))
00155           funcname = lang_hooks.decl_printable_name (current_function_decl, 1);
00156         if (funcname == NULL)
00157           funcname = "anonymous fn";
00158 
00159         pp_string (buf, funcname);
00160       }
00161       pp_string (buf, ") ");
00162     }
00163   else
00164     pp_string (buf, " ");
00165 
00166   /* Add <variable-declaration>, possibly demangled.  */
00167   {
00168     const char *declname = NULL;
00169 
00170     if (DECL_NAME (decl) != NULL)
00171       {
00172         if (strcmp ("GNU C++", lang_hooks.name) == 0)
00173           {
00174             /* The gcc/cp decl_printable_name hook doesn't do as good a job as
00175                the libiberty demangler.  */
00176             declname = cplus_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)),
00177                                        DMGL_AUTO | DMGL_VERBOSE);
00178           }
00179         if (declname == NULL)
00180           declname = lang_hooks.decl_printable_name (decl, 3);
00181       }
00182     if (declname == NULL)
00183       declname = "<unnamed variable>";
00184 
00185     pp_string (buf, declname);
00186   }
00187 
00188   /* Return the lot as a new STRING_CST.  */
00189   buf_contents = pp_base_formatted_text (buf);
00190   result = mf_build_string (buf_contents);
00191   pp_clear_output_area (buf);
00192 
00193   return result;
00194 }

static tree mf_varname_tree tree   )  [static]
 

Referenced by mudflap_finish_file(), and mx_register_decls().

static void mf_xform_decls  )  [static]
 

Perform the object lifetime tracking mudflap transform on the given function
   tree.  The tree is mutated in place, with possibly copied subtree nodes.

   For every auto variable declared, if its address is ever taken
   within the function, then supply its lifetime to the mudflap
   runtime with the __mf_register and __mf_unregister calls.
 

Definition at line 1116 of file tree-mudflap.c.

References mx_xfn_xform_decls(), mf_xform_decls_data::param_decls, and walk_tree_without_duplicates().

01117 {
01118   struct mf_xform_decls_data d;
01119   d.param_decls = fnparams;
01120   walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d);
01121 }

static void mf_xform_decls tree  ,
tree 
[static]
 

Addressable variables instrumentation.   

Referenced by execute_mudflap_function_decls().

static void mf_xform_derefs void   )  [static]
 

Definition at line 898 of file tree-mudflap.c.

References bsi_end_p(), bsi_next(), bsi_start, bsi_stmt(), EXPR_LOCUS, integer_one_node, integer_zero_node, mf_xform_derefs_1(), NULL_TREE, TREE_CODE, and TREE_OPERAND.

Referenced by execute_mudflap_function_ops().

00899 {
00900   basic_block bb, next;
00901   block_stmt_iterator i;
00902   int saved_last_basic_block = last_basic_block;
00903 
00904   bb = ENTRY_BLOCK_PTR ->next_bb;
00905   do
00906     {
00907       next = bb->next_bb;
00908       for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
00909         {
00910           tree s = bsi_stmt (i);
00911 
00912           /* Only a few GIMPLE statements can reference memory.  */
00913           switch (TREE_CODE (s))
00914             {
00915             case MODIFY_EXPR:
00916               mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
00917                                  integer_one_node);
00918               mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 1), EXPR_LOCUS (s),
00919                                  integer_zero_node);
00920               break;
00921 
00922             case RETURN_EXPR:
00923               if (TREE_OPERAND (s, 0) != NULL_TREE)
00924                 {
00925                   if (TREE_CODE (TREE_OPERAND (s, 0)) == MODIFY_EXPR)
00926                     mf_xform_derefs_1 (&i, &TREE_OPERAND (TREE_OPERAND (s, 0), 1),
00927                                        EXPR_LOCUS (s), integer_zero_node);
00928                   else
00929                     mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
00930                                        integer_zero_node);
00931                 }
00932               break;
00933 
00934             default:
00935               ;
00936             }
00937         }
00938       bb = next;
00939     }
00940   while (bb && bb->index <= saved_last_basic_block);
00941 }

static void mf_xform_derefs_1 block_stmt_iterator iter,
tree *  tp,
location_t *  locus,
tree  dirflag
[static]
 

Definition at line 720 of file tree-mudflap.c.

References bitsize_int, bitsizetype, build1, build_int_cst(), build_pointer_type(), byte_position(), convert(), DECL_BIT_FIELD_TYPE, DECL_SIZE_UNIT, error_mark_node, fold_build2, fold_convert(), INDIRECT_REF_P, integer_one_node, integer_zero_node, mf_build_check_statement_for(), mf_decl_eligible_p(), mf_marked_p(), mf_uintptr_type, NULL_TREE, ptr_type_node, size_binop(), sizetype, TREE_CODE, tree_mem_ref_addr(), TREE_OPERAND, TREE_TYPE, and TYPE_SIZE_UNIT.

Referenced by mf_xform_derefs().

00722 {
00723   tree type, base, limit, addr, size, t;
00724 
00725   /* Don't instrument read operations.  */
00726   if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
00727     return;
00728 
00729   /* Don't instrument marked nodes.  */
00730   if (mf_marked_p (*tp))
00731     return;
00732 
00733   t = *tp;
00734   type = TREE_TYPE (t);
00735 
00736   if (type == error_mark_node)
00737     return;
00738 
00739   size = TYPE_SIZE_UNIT (type);
00740 
00741   switch (TREE_CODE (t))
00742     {
00743     case ARRAY_REF:
00744     case COMPONENT_REF:
00745       {
00746         /* This is trickier than it may first appear.  The reason is
00747            that we are looking at expressions from the "inside out" at
00748            this point.  We may have a complex nested aggregate/array
00749            expression (e.g. "a.b[i].c"), maybe with an indirection as
00750            the leftmost operator ("p->a.b.d"), where