Example #1
0
static void
tree_init_edge_profiler (void)
{
    tree interval_profiler_fn_type;
    tree pow2_profiler_fn_type;
    tree one_value_profiler_fn_type;
    tree gcov_type_ptr;

    if (!gcov_type_node)
    {
        gcov_type_node = get_gcov_type ();
        gcov_type_ptr = build_pointer_type (gcov_type_node);

        /* void (*) (gcov_type *, gcov_type, int, unsigned)  */
        interval_profiler_fn_type
            = build_function_type_list (void_type_node,
                                        gcov_type_ptr, gcov_type_node,
                                        integer_type_node,
                                        unsigned_type_node, NULL_TREE);
        tree_interval_profiler_fn
            = build_fn_decl ("__gcov_interval_profiler",
                             interval_profiler_fn_type);

        /* void (*) (gcov_type *, gcov_type)  */
        pow2_profiler_fn_type
            = build_function_type_list (void_type_node,
                                        gcov_type_ptr, gcov_type_node,
                                        NULL_TREE);
        tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
                                               pow2_profiler_fn_type);

        /* void (*) (gcov_type *, gcov_type)  */
        one_value_profiler_fn_type
            = build_function_type_list (void_type_node,
                                        gcov_type_ptr, gcov_type_node,
                                        NULL_TREE);
        tree_one_value_profiler_fn
            = build_fn_decl ("__gcov_one_value_profiler",
                             one_value_profiler_fn_type);
    }
}
Example #2
0
static tree
build_function_decl (const char *name, bool external, tree function_type)
{
    tree fndecl =  build_fn_decl (name, function_type);
    SET_DECL_ASSEMBLER_NAME(fndecl, get_identifier(name));

    DECL_EXTERNAL (fndecl) = external;
    DECL_ARTIFICIAL (fndecl) = false;
    TREE_STATIC (fndecl) = !external;
    DECL_CONTEXT (fndecl) = NULL_TREE;

    return fndecl;
}
Example #3
0
static void init_decls(void)
{
    static unsigned int is_once = 0;
    tree type;

    if (is_once) return ;
    is_once = 1;

    type = build_function_type_list
           (ptr_type_node, size_type_node, NULL_TREE);
    kaapi_pushdata_aligned_decl =
        build_fn_decl("kaapi_pushdata_aligned", type);

    type = build_function_type_list
           (void_type_node, ptr_type_node, ptr_type_node, NULL_TREE);
    kaapi_pushtask_decl =
        build_fn_decl("kaapi_pushtask", type);

    type = build_function_type_list
           (void_type_node, void_type_node, NULL_TREE);
    kaapi_barrier_decl =
        build_fn_decl("kaapi_barrier", type);
}
Example #4
0
static tree
install_builtin (const char *name, tree fntype, enum built_in_function code,
                 bool publish)
{
  tree fndecl = build_fn_decl (name, fntype);
  DECL_BUILT_IN_CLASS (fndecl) = BUILT_IN_NORMAL;
  DECL_FUNCTION_CODE (fndecl) = code;
  if (publish)
    {
      tree t = lang_hooks.decls.pushdecl (fndecl);
      if (t)
        fndecl = t;
    }
  set_builtin_decl (code, fndecl, true);
  return fndecl;
}
Example #5
0
static tree build_junk_fn(unsigned id)
{
    char fnname[32] = {0};
    tree decl, resdecl, initial, proto;

    /* Func decl */
    snprintf(fnname, 31, "__func%d", id);
    proto = build_varargs_function_type_list(void_type_node, NULL_TREE);
    decl = build_fn_decl(fnname, proto);
    SET_DECL_ASSEMBLER_NAME(decl, get_identifier(fnname));
    
    printf(TAG "Creating junk function: %s\n", fnname);
   
    /* Result */ 
    resdecl=build_decl(BUILTINS_LOCATION,RESULT_DECL,NULL_TREE,void_type_node);
    DECL_ARTIFICIAL(resdecl) = 1;
    DECL_CONTEXT(resdecl) = decl;
    DECL_RESULT(decl) = resdecl;
    
    /* Initial */
    initial = make_node(BLOCK);
    TREE_USED(initial) = 1;
    DECL_INITIAL(decl) = initial;
    DECL_UNINLINABLE(decl) = 1;
    DECL_EXTERNAL(decl) = 0;
    DECL_PRESERVE_P(decl) = 1;

    /* Func decl */
    TREE_USED(decl) = 1;
    TREE_PUBLIC(decl) = 1;
    TREE_STATIC(decl) = 1;
    DECL_ARTIFICIAL(decl) = 1;

    /* Make the function */
    push_struct_function(decl);
    /* DECL_SAVED_TREE(decl) = gen_junk(); */
    cfun->function_end_locus = BUILTINS_LOCATION;
    gimplify_function_tree(decl);

    /* Update */
    cgraph_add_new_function(decl, false);
    cgraph_mark_needed_node(cgraph_node(decl));
    current_function_decl = NULL_TREE;
    pop_cfun();

    return decl;
}
// create the function call to a `record_assignment' function and insert it
// before the given statement
static void insert_instrumentation_fn(gimple curr_stmt, tree var_id,
                                      tree new_value)
{
    // build function declaration
    tree proto = build_function_type_list(
                     void_type_node,      /* return type */
                     integer_type_node,   /* first arg's type */
                     const_ptr_type_node, /* second arg's type */
                     NULL_TREE);
    tree decl = build_fn_decl("record_assignment", proto);

    // build the function call with the new value tree and the variable id tree
    // and insert it before the statement that was passed as the first argument
    gimple call = gimple_build_call(decl, 2, var_id, new_value);
    gimple_stmt_iterator gsi = gsi_for_stmt(curr_stmt);
    gsi_insert_before(&gsi, call, GSI_NEW_STMT);
}
Example #7
0
static tree create_dummy_adapter(void)
{
    /* create function type */
    static tree type = NULL;
    static tree decl = NULL;

    if (decl != NULL) return decl;

    /* create the type void fu(void)*/
    type = build_function_type_list
           (void_type_node, ptr_type_node, ptr_type_node, NULL_TREE);

    /* create the function decl */
    decl = build_fn_decl("__xkaapi_dummy_adapter", type);

    return decl;
}
Example #8
0
/* Insert call to __slimer_init to initalize things at runtime */
static void insert_slimer_init(void)
{
    int i;
    gimple stmt;
    tree decl, proto;

    proto = build_function_type_list(void_type_node, integer_type_node, NULL_TREE);
    decl = build_fn_decl("__slimer_init", proto);
    stmt = gsi_stmt(gsi_start_bb(ENTRY_BLOCK_PTR->next_bb));
    insert_call(stmt, decl);

    for (i=0; i<n_funcs; ++i)
      insert_add_fn(stmt, i);

    /* Add this fndecl to our list of things we do not process */
    VEC_safe_push(tree, gc, analyized_fns, decl);
}
Example #9
0
static tree
make_fndecl (tree return_type,
	     const char *name,
	     vec <tree> &param_types,
	     bool is_variadic = false)
{
  tree fn_type;
  if (is_variadic)
    fn_type = build_varargs_function_type_array (return_type,
						 param_types.length (),
						 param_types.address ());
  else
    fn_type = build_function_type_array (return_type,
					 param_types.length (),
					 param_types.address ());
  /* FIXME: this uses input_location: */
  tree fndecl = build_fn_decl (name, fn_type);

  return fndecl;
}
Example #10
0
/* Insert a call to the runtime function "__slimer_add_fn" which will add the
 * "junk" function created at compile-time to an array at runtime
 */
static void insert_add_fn(gimple stmt, int index)
{
    tree fn;
    gimple call;
    gimple_stmt_iterator gsi;
    static tree decl, proto, idx;

    if (!decl || !proto)
    {
        proto = build_function_type_list(void_type_node, ptr_type_node,
                                         integer_type_node, NULL_TREE);
        decl = build_fn_decl("__slimer_add_fn", proto);
    
        /* Add this fndecl to our list of things we do not process */
        VEC_safe_push(tree, gc, analyized_fns, decl);
    }

    /* Create a constant value and pointer to the function we are to add */
    idx = build_int_cst(integer_type_node, index);
    fn = build_addr(VEC_index(tree, fakes, index), NULL_TREE);
    call = gimple_build_call(decl, 2, fn, idx);
    gsi = gsi_for_stmt(stmt);
    gsi_insert_before(&gsi, call, GSI_NEW_STMT);
}
Example #11
0
void
gimple_init_edge_profiler (void)
{
  tree interval_profiler_fn_type;
  tree pow2_profiler_fn_type;
  tree one_value_profiler_fn_type;
  tree gcov_type_ptr;
  tree ic_profiler_fn_type;
  tree average_profiler_fn_type;
  tree time_profiler_fn_type;

  if (!gcov_type_node)
    {
      gcov_type_node = get_gcov_type ();
      gcov_type_ptr = build_pointer_type (gcov_type_node);

      /* void (*) (gcov_type *, gcov_type, int, unsigned)  */
      interval_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node,
					  integer_type_node,
					  unsigned_type_node, NULL_TREE);
      tree_interval_profiler_fn
	      = build_fn_decl ("__gcov_interval_profiler",
				     interval_profiler_fn_type);
      TREE_NOTHROW (tree_interval_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_interval_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_interval_profiler_fn));

      /* void (*) (gcov_type *, gcov_type)  */
      pow2_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node,
					  NULL_TREE);
      tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
						   pow2_profiler_fn_type);
      TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_pow2_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_pow2_profiler_fn));

      /* void (*) (gcov_type *, gcov_type)  */
      one_value_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node,
					  NULL_TREE);
      tree_one_value_profiler_fn
	      = build_fn_decl ("__gcov_one_value_profiler",
				     one_value_profiler_fn_type);
      TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_one_value_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_one_value_profiler_fn));

      init_ic_make_global_vars ();

      /* void (*) (gcov_type, void *)  */
      ic_profiler_fn_type
	       = build_function_type_list (void_type_node,
					  gcov_type_node,
					  ptr_void,
					  NULL_TREE);
      tree_indirect_call_profiler_fn
	      = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
				 "__gcov_indirect_call_topn_profiler":
				 "__gcov_indirect_call_profiler_v2"),
			       ic_profiler_fn_type);

      TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));

      /* void (*) (gcov_type *, gcov_type, void *)  */
      time_profiler_fn_type
	       = build_function_type_list (void_type_node,
					  gcov_type_ptr, NULL_TREE);
      tree_time_profiler_fn
	      = build_fn_decl ("__gcov_time_profiler",
				     time_profiler_fn_type);
      TREE_NOTHROW (tree_time_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_time_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_time_profiler_fn));

      /* void (*) (gcov_type *, gcov_type)  */
      average_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node, NULL_TREE);
      tree_average_profiler_fn
	      = build_fn_decl ("__gcov_average_profiler",
				     average_profiler_fn_type);
      TREE_NOTHROW (tree_average_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_average_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_average_profiler_fn));
      tree_ior_profiler_fn
	      = build_fn_decl ("__gcov_ior_profiler",
				     average_profiler_fn_type);
      TREE_NOTHROW (tree_ior_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_ior_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_ior_profiler_fn));

      /* LTO streamer needs assembler names.  Because we create these decls
         late, we need to initialize them by hand.  */
      DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
    }
}
Example #12
0
void
gimple_init_edge_profiler (void)
{
  tree interval_profiler_fn_type;
  tree pow2_profiler_fn_type;
  tree one_value_profiler_fn_type;
  tree gcov_type_ptr;
  tree ic_profiler_fn_type;
  tree average_profiler_fn_type;
  tree time_profiler_fn_type;

  if (!gcov_type_node)
    {
      gcov_type_node = get_gcov_type ();
      gcov_type_ptr = build_pointer_type (gcov_type_node);

      /* void (*) (gcov_type *, gcov_type, int, unsigned)  */
      interval_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node,
					  integer_type_node,
					  unsigned_type_node, NULL_TREE);
      tree_interval_profiler_fn
	      = build_fn_decl ("__gcov_interval_profiler",
				     interval_profiler_fn_type);
      TREE_NOTHROW (tree_interval_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_interval_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_interval_profiler_fn));

      /* void (*) (gcov_type *, gcov_type)  */
      pow2_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node,
					  NULL_TREE);
      tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
						   pow2_profiler_fn_type);
      TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_pow2_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_pow2_profiler_fn));

      /* void (*) (gcov_type *, gcov_type)  */
      one_value_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node,
					  NULL_TREE);
      tree_one_value_profiler_fn
	      = build_fn_decl ("__gcov_one_value_profiler",
				     one_value_profiler_fn_type);
      TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_one_value_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_one_value_profiler_fn));

      init_ic_make_global_vars ();

      /* Workaround for binutils bug 14342.  Once it is fixed, remove lto path.  */
      if (flag_lto)
        {
	  /* void (*) (gcov_type, void *)  */
	  ic_profiler_fn_type
		   = build_function_type_list (void_type_node,
					      gcov_type_ptr, gcov_type_node,
					      ptr_void, ptr_void,
					      NULL_TREE);
	  tree_indirect_call_profiler_fn
		  = build_fn_decl ("__gcov_indirect_call_profiler",
					 ic_profiler_fn_type);
        }
      else
        {
	  /* void (*) (gcov_type, void *)  */
	  ic_profiler_fn_type
		   = build_function_type_list (void_type_node,
					      gcov_type_node,
					      ptr_void,
					      NULL_TREE);
	  tree_indirect_call_profiler_fn
		  = build_fn_decl ("__gcov_indirect_call_profiler_v2",
					 ic_profiler_fn_type);
        }
      TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));

      /* void (*) (gcov_type *, gcov_type, void *)  */
      time_profiler_fn_type
	       = build_function_type_list (void_type_node,
					  gcov_type_ptr, NULL_TREE);
      tree_time_profiler_fn
	      = build_fn_decl ("__gcov_time_profiler",
				     time_profiler_fn_type);
      TREE_NOTHROW (tree_time_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_time_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_time_profiler_fn));

      /* void (*) (gcov_type *, gcov_type)  */
      average_profiler_fn_type
	      = build_function_type_list (void_type_node,
					  gcov_type_ptr, gcov_type_node, NULL_TREE);
      tree_average_profiler_fn
	      = build_fn_decl ("__gcov_average_profiler",
				     average_profiler_fn_type);
      TREE_NOTHROW (tree_average_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_average_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_average_profiler_fn));
      tree_ior_profiler_fn
	      = build_fn_decl ("__gcov_ior_profiler",
				     average_profiler_fn_type);
      TREE_NOTHROW (tree_ior_profiler_fn) = 1;
      DECL_ATTRIBUTES (tree_ior_profiler_fn)
	= tree_cons (get_identifier ("leaf"), NULL,
		     DECL_ATTRIBUTES (tree_ior_profiler_fn));

      /* LTO streamer needs assembler names.  Because we create these decls
         late, we need to initialize them by hand.  */
      DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
      DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
    }
}
Example #13
0
static void insert_call_to_junk_fn(gimple stmt)
{
    tree tv, rv, fn, rhs, tmp;
    gimple gimp;
    gimple_stmt_iterator gsi;
    static bool has_initted;
    static tree decl, proto, decl_get_funcs, proto_get_funcs, fn_ptr_type;
    
    printf("slimer: Inserting junk function call at line: %d\n",
            gimple_lineno(stmt));

    /* Get random value modulo n_funcs for index into runtime __funcs array of
     * junk functions:
     *     rv = time % n_funcs;
     *     fn = __funcs + rv;
     *     call fn
     */

    /* Build instances */
    if (!has_initted)
    {
        proto = build_function_type_list(
            uint64_type_node, ptr_type_node, NULL_TREE);
        decl = build_fn_decl("time", proto);
        DECL_EXTERNAL(decl) = 1;

        proto_get_funcs = build_function_type_list(ptr_type_node, NULL_TREE);
        decl_get_funcs = build_fn_decl("__slimer_get_funcs", proto_get_funcs);

        fn_ptr_type = build_function_type_list(
            void_type_node, void_type_node, NULL_TREE);

        has_initted = true;
    }

    /* time_tmp = time(NULL); */
    tv = create_tmp_var(uint64_type_node, "time_tmp");
    tv = make_ssa_name(tv, NULL);
    gimp = gimple_build_call(decl, 1, null_pointer_node);
    gimple_set_lhs(gimp, tv);
    gsi = gsi_for_stmt(stmt);
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

    /* rv_tmp = time_temp % n_funcs */
    rv = create_tmp_var(uint64_type_node, "rv_tmp");
    rv = make_ssa_name(rv, NULL);
    rhs = build_int_cst(integer_type_node, n_funcs);
    gimp = gimple_build_assign_with_ops(TRUNC_MOD_EXPR, rv, tv, rhs);
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

    /* tmp = __slimer_get_funcs(); TODO: Get rid of __slimer_get_funcs()
     * rv = rv * sizeof(void *)
     * fn_tmp = tmp + rv
     */
    tree pp_type = build_pointer_type(ptr_type_node);
    tmp = create_tmp_var(pp_type, "tmp");
    tmp = make_ssa_name(tmp, NULL);
    gimp = gimple_build_call(decl_get_funcs, 0);
    gimple_set_lhs(gimp, tmp);
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

    /* rv = rv * sizeof(void *))
     * FIXME: THIS IS NOT SUFFICIENT FOR CROSS COMPILING FOR ARCHITECTURES THAT
     * HAVE ADDRESS SIZES sizeof(void *)
     */
    tree addr_size = build_int_cst(integer_type_node, sizeof(void *));
    gimp = gimple_build_assign_with_ops(MULT_EXPR, rv, rv, addr_size);
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

    fn = create_tmp_var(pp_type, "fn_tmp");
    fn = make_ssa_name(fn, NULL);
    gimp = gimple_build_assign_with_ops(PLUS_EXPR, fn, tmp, rv);
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

    /* the_fn = *fn */
    tree f = build_pointer_type(fn_ptr_type); 
    tree the_fn = create_tmp_var(f, "the_func_ptr");
    the_fn = make_ssa_name(the_fn, NULL);
    gimp = gimple_build_assign(the_fn, build_simple_mem_ref(fn));
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

    /* call the_fn */
    gimp = gimple_build_call(the_fn, 0);
    gsi_insert_before(&gsi, gimp, GSI_SAME_STMT);

#ifdef GOAT_DEBUG
    debug_function(cfun->decl, 0);
#endif
}