static void
pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
{
  /* For normal/md builtins we only write the class and code, so they
     should never be handled here.  */
  gcc_assert (!streamer_handle_as_builtin_p (expr));

  bp_pack_enum (bp, built_in_class, BUILT_IN_LAST,
		DECL_BUILT_IN_CLASS (expr));
  bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1);
  bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1);
  bp_pack_value (bp, DECL_UNINLINABLE (expr), 1);
  bp_pack_value (bp, DECL_POSSIBLY_INLINED (expr), 1);
  bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
  bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
  bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
  bp_pack_value (bp, DECL_IS_OPERATOR_NEW (expr), 1);
  bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
  bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
  bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
  bp_pack_value (bp, DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr), 1);
  bp_pack_value (bp, DECL_NO_LIMIT_STACK (expr), 1);
  bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
  bp_pack_value (bp, DECL_PURE_P (expr), 1);
  bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
  if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
    bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 11);
  if (DECL_STATIC_DESTRUCTOR (expr))
    bp_pack_var_len_unsigned (bp, DECL_FINI_PRIORITY (expr));
}
Exemple #2
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;
}
Exemple #3
0
static tree
create_cilk_helper_decl (struct wrapper_data *wd)
{
  char name[20];
  if (wd->type == CILK_BLOCK_FOR)
    sprintf (name, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
  else if (wd->type == CILK_BLOCK_SPAWN)
    sprintf (name, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
  else
    gcc_unreachable (); 
  
  clean_symbol_name (name);

  tree fndecl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
			    FUNCTION_DECL, get_identifier (name), wd->fntype);

  TREE_PUBLIC (fndecl) = 0;
  TREE_STATIC (fndecl) = 1;
  TREE_USED (fndecl) = 1;
  DECL_ARTIFICIAL (fndecl) = 0;
  DECL_IGNORED_P (fndecl) = 0;
  DECL_EXTERNAL (fndecl) = 0;

  DECL_CONTEXT (fndecl) = wd->context; 
  tree block = make_node (BLOCK);
  DECL_INITIAL (fndecl) = block;
  TREE_USED (block) = 1;
  BLOCK_SUPERCONTEXT (block) = fndecl;
  gcc_assert (!DECL_SAVED_TREE (fndecl));

  /* Inlining would defeat the purpose of this wrapper.
     Either it secretly switches stack frames or it allocates
     a stable stack frame to hold function arguments even if
     the parent stack frame is stolen.  */
  DECL_UNINLINABLE (fndecl) = 1;

  tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, 
				 void_type_node);
  DECL_ARTIFICIAL (result_decl) = 0;
  DECL_IGNORED_P (result_decl) = 1;
  DECL_CONTEXT (result_decl) = fndecl;
  DECL_RESULT (fndecl) = result_decl;
  
  return fndecl;
}
static void
unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
{
  DECL_BUILT_IN_CLASS (expr) = bp_unpack_enum (bp, built_in_class,
					       BUILT_IN_LAST);
  DECL_STATIC_CONSTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_STATIC_DESTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_UNINLINABLE (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_POSSIBLY_INLINED (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_NOVOPS (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_RETURNS_TWICE (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_MALLOC (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_OPERATOR_NEW (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_DECLARED_INLINE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_STATIC_CHAIN (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_NO_INLINE_WARNING_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr)
    			= (unsigned) bp_unpack_value (bp, 1);
  DECL_NO_LIMIT_STACK (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
    {
      DECL_FUNCTION_CODE (expr) = (enum built_in_function) bp_unpack_value (bp,
	                                                                    11);
      if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL
	  && DECL_FUNCTION_CODE (expr) >= END_BUILTINS)
	fatal_error ("machine independent builtin code out of range");
      else if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD)
	{
          tree result = targetm.builtin_decl (DECL_FUNCTION_CODE (expr), true);
	  if (!result || result == error_mark_node)
	    fatal_error ("target specific builtin not available");
	}
    }
  if (DECL_STATIC_DESTRUCTOR (expr))
    {
      priority_type p;
      p = (priority_type) bp_unpack_var_len_unsigned (bp);
      SET_DECL_FINI_PRIORITY (expr, p);
    }
}
Exemple #5
0
int
c_cannot_inline_tree_fn (tree *fnp)
{
  tree fn = *fnp;
  bool do_warning = (warn_inline
                     && DECL_INLINE (fn)
                     && DECL_DECLARED_INLINE_P (fn)
                     && !DECL_IN_SYSTEM_HEADER (fn));

  if (flag_really_no_inline
      && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
    {
      if (do_warning)
        warning (OPT_Winline, "function %q+F can never be inlined because it "
                 "is suppressed using -fno-inline", fn);
      goto cannot_inline;
    }

  /* Don't auto-inline anything that might not be bound within
     this unit of translation.  */
  if (!DECL_DECLARED_INLINE_P (fn) && !targetm.binds_local_p (fn))
    {
      if (do_warning)
        warning (OPT_Winline, "function %q+F can never be inlined because it "
                 "might not be bound within this unit of translation", fn);
      goto cannot_inline;
    }

  if (!function_attribute_inlinable_p (fn))
    {
      if (do_warning)
        warning (OPT_Winline, "function %q+F can never be inlined because it "
                 "uses attributes conflicting with inlining", fn);
      goto cannot_inline;
    }

  return 0;

 cannot_inline:
  DECL_UNINLINABLE (fn) = 1;
  return 1;
}
Exemple #6
0
static void
pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
{
  bp_pack_enum (bp, built_in_class, BUILT_IN_LAST,
		DECL_BUILT_IN_CLASS (expr));
  bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1);
  bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1);
  bp_pack_value (bp, DECL_UNINLINABLE (expr), 1);
  bp_pack_value (bp, DECL_POSSIBLY_INLINED (expr), 1);
  bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
  bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
  bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
  bp_pack_value (bp, DECL_IS_OPERATOR_NEW (expr), 1);
  bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
  bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
  bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
  bp_pack_value (bp, DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr), 1);
  bp_pack_value (bp, DECL_NO_LIMIT_STACK (expr), 1);
  bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
  bp_pack_value (bp, DECL_PURE_P (expr), 1);
  bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
  if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
    bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 12);
}
Exemple #7
0
int
c_cannot_inline_tree_fn (tree *fnp)
{
  tree fn = *fnp;
  tree t;
  bool do_warning = (warn_inline
		     && DECL_INLINE (fn)
		     && DECL_DECLARED_INLINE_P (fn)
		     && !DECL_IN_SYSTEM_HEADER (fn));

  if (flag_really_no_inline
      && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
    {
      if (do_warning)
	warning ("%Jfunction '%F' can never be inlined because it "
		 "is suppressed using -fno-inline", fn, fn);
      goto cannot_inline;
    }

  /* Don't auto-inline anything that might not be bound within
     this unit of translation.  */
  if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
    {
      if (do_warning)
	warning ("%Jfunction '%F' can never be inlined because it might not "
		 "be bound within this unit of translation", fn, fn);
      goto cannot_inline;
    }

  if (! function_attribute_inlinable_p (fn))
    {
      if (do_warning)
	warning ("%Jfunction '%F' can never be inlined because it uses "
		 "attributes conflicting with inlining", fn, fn);
      goto cannot_inline;
    }

  /* If a function has pending sizes, we must not defer its
     compilation, and we can't inline it as a tree.  */
  if (fn == current_function_decl)
    {
      t = get_pending_sizes ();
      put_pending_sizes (t);

      if (t)
	{
	  if (do_warning)
	    warning ("%Jfunction '%F' can never be inlined because it has "
		     "pending sizes", fn, fn);
	  goto cannot_inline;
	}
    }

  if (! DECL_FILE_SCOPE_P (fn))
    {
      /* If a nested function has pending sizes, we may have already
         saved them.  */
      if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
	{
	  if (do_warning)
	    warning ("%Jnested function '%F' can never be inlined because it "
		     "has possibly saved pending sizes", fn, fn);
	  goto cannot_inline;
	}
    }

  return 0;

 cannot_inline:
  DECL_UNINLINABLE (fn) = 1;
  return 1;
}