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)); }
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; }
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); } }
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; }
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); }
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; }