From c536a6a77a19a895e51e5e5167d266bd8ce61001 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 28 Aug 2007 09:03:59 +0000 Subject: [PATCH] tree.h (DECL_DISREGARD_INLINE_LIMITS): New. 2007-08-28 Richard Guenther * tree.h (DECL_DISREGARD_INLINE_LIMITS): New. (struct tree_function_decl): Make function_code a bitfield. Add disregard_inline_limits flag. * cgraphunit.c (cgraph_process_new_functions): Check DECL_DISREGARD_INLINE_LIMITS instead of disregard_inline_limits_p. (cgraph_preserve_function_body_p): Likewise. * ipa-inline.c (compute_inline_parameters): Likewise. * c-decl.c (finish_function): Set DECL_DISREGARD_INLINE_LIMITS for GNU C extern inline functions. (merge_decls): Merge DECL_DISREGARD_INLINE_LIMITS. * tree-inline.c (disregard_inline_limits_p): Remove. * tree-inline.h (disregard_inline_limits_p): Likewise. * c-common.c (handle_always_inline_attribute): Set DECL_DISREGARD_INLINE_LIMITS. * langhooks.c (add_builtin_function): Verify the function code fits in the bitfield. cp/ * decl.c (duplicate_decls): Merge DECL_DISREGARD_INLINE_LIMITS. From-SVN: r127851 --- gcc/ChangeLog | 19 +++++++++++++++++++ gcc/c-common.c | 5 +++-- gcc/c-decl.c | 10 ++++++++++ gcc/cgraphunit.c | 4 ++-- gcc/cp/ChangeLog | 4 ++++ gcc/cp/decl.c | 5 +++++ gcc/ipa-inline.c | 2 +- gcc/langhooks.c | 3 +++ gcc/tree-inline.c | 14 -------------- gcc/tree-inline.h | 1 - gcc/tree.h | 25 +++++++++++++++++++------ 11 files changed, 66 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b440e936605..8f8cc2d2302 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2007-08-28 Richard Guenther + + * tree.h (DECL_DISREGARD_INLINE_LIMITS): New. + (struct tree_function_decl): Make function_code a bitfield. + Add disregard_inline_limits flag. + * cgraphunit.c (cgraph_process_new_functions): Check + DECL_DISREGARD_INLINE_LIMITS instead of disregard_inline_limits_p. + (cgraph_preserve_function_body_p): Likewise. + * ipa-inline.c (compute_inline_parameters): Likewise. + * c-decl.c (finish_function): Set DECL_DISREGARD_INLINE_LIMITS + for GNU C extern inline functions. + (merge_decls): Merge DECL_DISREGARD_INLINE_LIMITS. + * tree-inline.c (disregard_inline_limits_p): Remove. + * tree-inline.h (disregard_inline_limits_p): Likewise. + * c-common.c (handle_always_inline_attribute): Set + DECL_DISREGARD_INLINE_LIMITS. + * langhooks.c (add_builtin_function): Verify the function code + fits in the bitfield. + 2007-08-28 Mircea Namolaru Vladimir Yanovsky Revital Eres diff --git a/gcc/c-common.c b/gcc/c-common.c index 30d381625b0..8e4ae22271b 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4864,8 +4864,9 @@ handle_always_inline_attribute (tree *node, tree name, { if (TREE_CODE (*node) == FUNCTION_DECL) { - /* Do nothing else, just set the attribute. We'll get at - it later with lookup_attribute. */ + /* Set the attribute and mark it for disregarding inline + limits. */ + DECL_DISREGARD_INLINE_LIMITS (*node) = 1; } else { diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 98489b13a37..714cf62ba03 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1819,6 +1819,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); + + DECL_DISREGARD_INLINE_LIMITS (newdecl) + = DECL_DISREGARD_INLINE_LIMITS (olddecl) + = (DECL_DISREGARD_INLINE_LIMITS (newdecl) + || DECL_DISREGARD_INLINE_LIMITS (olddecl)); } if (DECL_BUILT_IN (olddecl)) @@ -6771,6 +6776,11 @@ finish_function (void) /* Finalize the ELF visibility for the function. */ c_determine_visibility (fndecl); + /* For GNU C extern inline functions disregard inline limits. */ + if (DECL_EXTERNAL (fndecl) + && DECL_DECLARED_INLINE_P (fndecl)) + DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1; + /* Genericize before inlining. Delay genericizing nested functions until their parent function is genericized. Since finalizing requires GENERIC, delay that as well. */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index dddc093b5b3..accb6477d68 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -381,7 +381,7 @@ cgraph_process_new_functions (void) node->local.self_insns = estimate_num_insns (fndecl, &eni_inlining_weights); node->local.disregard_inline_limits - |= disregard_inline_limits_p (fndecl); + |= DECL_DISREGARD_INLINE_LIMITS (fndecl); /* Inlining characteristics are maintained by the cgraph_mark_inline. */ node->global.insns = node->local.self_insns; @@ -1252,7 +1252,7 @@ cgraph_preserve_function_body_p (tree decl) struct cgraph_node *node; if (!cgraph_global_info_ready) return (flag_really_no_inline - ? disregard_inline_limits_p (decl) + ? DECL_DISREGARD_INLINE_LIMITS (decl) : DECL_INLINE (decl)); /* Look if there is any clone around. */ for (node = cgraph_node (decl); node; node = node->next_clone) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0d412cedece..a6222faae7a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2007-08-28 Richard Guenther + + * decl.c (duplicate_decls): Merge DECL_DISREGARD_INLINE_LIMITS. + 2007-08-28 Gabriel Dos Reis * error.c (dump_expr): Handle COMPLEX_CST. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ef63ffd83ac..fdccb3542ad 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1954,6 +1954,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); + + DECL_DISREGARD_INLINE_LIMITS (newdecl) + = DECL_DISREGARD_INLINE_LIMITS (olddecl) + = (DECL_DISREGARD_INLINE_LIMITS (newdecl) + || DECL_DISREGARD_INLINE_LIMITS (olddecl)); } /* Preserve abstractness on cloned [cd]tors. */ diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index f74ebf8c9f1..647ec9faded 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1529,7 +1529,7 @@ compute_inline_parameters (void) &eni_inlining_weights); if (node->local.inlinable && !node->local.disregard_inline_limits) node->local.disregard_inline_limits - = disregard_inline_limits_p (current_function_decl); + = DECL_DISREGARD_INLINE_LIMITS (current_function_decl); if (flag_really_no_inline && !node->local.disregard_inline_limits) node->local.inlinable = 0; /* Inlining characteristics are maintained by the cgraph_mark_inline. */ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 2635efef6f9..b8e7aaacc27 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -480,6 +480,9 @@ add_builtin_function (const char *name, TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; DECL_BUILT_IN_CLASS (decl) = cl; + + DECL_FUNCTION_CODE (decl) = -1; + gcc_assert (DECL_FUNCTION_CODE (decl) >= function_code); DECL_FUNCTION_CODE (decl) = function_code; if (library_name) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 2b7ab9e39ac..b2b959097cd 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1936,20 +1936,6 @@ inlinable_function_p (tree fn) return inlinable; } -/* Return true if we shall disregard inlining limits for the function - FN during inlining. */ - -bool -disregard_inline_limits_p (tree fn) -{ - /* GNU extern inline functions are supposed to be cheap. */ - if (DECL_DECLARED_INLINE_P (fn) - && DECL_EXTERNAL (fn)) - return true; - - return lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL_TREE; -} - /* Estimate the cost of a memory move. Use machine dependent word size and take possible memcpy call into account. */ diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 05d921a2b6f..200a9a68fc3 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -130,7 +130,6 @@ extern void insert_decl_map (copy_body_data *, tree, tree); unsigned int optimize_inline_calls (tree); bool tree_inlinable_function_p (tree); -bool disregard_inline_limits_p (tree); tree copy_tree_r (tree *, int *, void *); void clone_body (tree, tree, void *); void save_body (tree, tree *, tree *); diff --git a/gcc/tree.h b/gcc/tree.h index 43f402146b4..b3a5955ed8e 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3273,6 +3273,13 @@ struct tree_decl_non_common GTY(()) #define DECL_DECLARED_INLINE_P(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.declared_inline_flag) +/* Nonzero in a FUNCTION_DECL that should be always inlined by the inliner + disregarding size and cost heuristics. This is equivalent to using + the always_inline attribute without the required diagnostics if the + function cannot be inlined. */ +#define DECL_DISREGARD_INLINE_LIMITS(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.disregard_inline_limits) + /* For FUNCTION_DECL, this holds a pointer to a structure ("struct function") that describes the status of this function. */ #define DECL_STRUCT_FUNCTION(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.f) @@ -3299,27 +3306,33 @@ struct tree_function_decl GTY(()) { struct tree_decl_non_common common; + struct function *f; + /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is - DECL_FUNCTION_CODE. Otherwise unused. */ - enum built_in_function function_code; + DECL_FUNCTION_CODE. Otherwise unused. + ??? The bitfield needs to be able to hold all target function + codes as well. */ + ENUM_BITFIELD(built_in_function) function_code : 10; + ENUM_BITFIELD(built_in_class) built_in_class : 2; unsigned static_ctor_flag : 1; unsigned static_dtor_flag : 1; unsigned uninlinable : 1; unsigned possibly_inlined : 1; + unsigned novops_flag : 1; unsigned returns_twice_flag : 1; unsigned malloc_flag : 1; unsigned pure_flag : 1; - unsigned declared_inline_flag : 1; unsigned regdecl_flag : 1; unsigned inline_flag : 1; unsigned no_instrument_function_entry_exit : 1; - unsigned no_limit_stack : 1; - ENUM_BITFIELD(built_in_class) built_in_class : 2; - struct function *f; + unsigned no_limit_stack : 1; + unsigned disregard_inline_limits : 1; + + /* 6 bits left */ }; /* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */