From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10431 invoked by alias); 27 Aug 2007 09:49:30 -0000 Received: (qmail 9900 invoked by uid 22791); 27 Aug 2007 09:49:26 -0000 X-Spam-Check-By: sourceware.org Received: from cantor.suse.de (HELO mx1.suse.de) (195.135.220.2) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 27 Aug 2007 09:49:20 +0000 Received: from Relay2.suse.de (mail2.suse.de [195.135.221.8]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 749BD12269 for ; Mon, 27 Aug 2007 11:49:17 +0200 (CEST) Date: Mon, 27 Aug 2007 09:54:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Restore disregarding inlining limits for extern inline functions In-Reply-To: Message-ID: References: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-08/txt/msg01781.txt.bz2 On Sun, 26 Aug 2007, Richard Guenther wrote: > On Tue, 21 Aug 2007, Richard Guenther wrote: > > > > > As $subject says. > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu. I'll apply this > > tomorrow if nobody objects. > > > > Thanks, > > Richard. > > > > 2007-08-21 Richard Guenther > > > > * tree-inline.c (inlinable_function_p): Restore disregarding > > inline limits for GNU extern inline functions. > > Unfortunately this seems to cause quite some C++ compile-time > regressions. Does anyone know which C++ construct leads to both > DECL_DECLARED_INLINE_P and DECL_EXTERNAL set (just to have a testcase)? > > I suppose the only solution is to either revert the patch, or in the > C frontend set some other flag for the GNU extern inline case. Any > ideas on what to best use here? There are bits in struct function > left, also one bit in the decl itself. I am testing the following patch. (If it makes us less nervous we can spare more bits for function_code, like for example 14) Richard. 2007-08-27 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_decl): Set DECL_DISREGARD_INLINE_LIMITS for GNU C extern inline functions. * 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. Index: tree.h =================================================================== *** tree.h.orig 2007-08-27 11:25:41.000000000 +0200 --- tree.h 2007-08-27 11:46:50.000000000 +0200 *************** struct tree_decl_non_common GTY(()) *** 3273,3278 **** --- 3273,3281 ---- #define DECL_DECLARED_INLINE_P(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.declared_inline_flag) + #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) *************** struct tree_function_decl GTY(()) *** 3299,3325 **** { struct tree_decl_non_common common; /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is ! DECL_FUNCTION_CODE. Otherwise unused. */ ! enum built_in_function function_code; 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; }; /* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */ --- 3302,3334 ---- { 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. ! ??? 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; ! unsigned disregard_inline_limits : 1; ! /* 6 bits left */ }; /* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */ Index: cgraphunit.c =================================================================== *** cgraphunit.c.orig 2007-08-27 11:25:41.000000000 +0200 --- cgraphunit.c 2007-08-27 11:26:56.000000000 +0200 *************** cgraph_process_new_functions (void) *** 381,387 **** node->local.self_insns = estimate_num_insns (fndecl, &eni_inlining_weights); node->local.disregard_inline_limits ! |= disregard_inline_limits_p (fndecl); /* Inlining characteristics are maintained by the cgraph_mark_inline. */ node->global.insns = node->local.self_insns; --- 381,387 ---- node->local.self_insns = estimate_num_insns (fndecl, &eni_inlining_weights); node->local.disregard_inline_limits ! |= DECL_DISREGARD_INLINE_LIMITS (fndecl); /* Inlining characteristics are maintained by the cgraph_mark_inline. */ node->global.insns = node->local.self_insns; *************** cgraph_preserve_function_body_p (tree de *** 1252,1258 **** struct cgraph_node *node; if (!cgraph_global_info_ready) return (flag_really_no_inline ! ? disregard_inline_limits_p (decl) : DECL_INLINE (decl)); /* Look if there is any clone around. */ for (node = cgraph_node (decl); node; node = node->next_clone) --- 1252,1258 ---- struct cgraph_node *node; if (!cgraph_global_info_ready) return (flag_really_no_inline ! ? 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) Index: ipa-inline.c =================================================================== *** ipa-inline.c.orig 2007-08-27 11:25:41.000000000 +0200 --- ipa-inline.c 2007-08-27 11:26:56.000000000 +0200 *************** compute_inline_parameters (void) *** 1529,1535 **** &eni_inlining_weights); if (node->local.inlinable && !node->local.disregard_inline_limits) node->local.disregard_inline_limits ! = disregard_inline_limits_p (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. */ --- 1529,1535 ---- &eni_inlining_weights); if (node->local.inlinable && !node->local.disregard_inline_limits) node->local.disregard_inline_limits ! = 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. */ Index: c-decl.c =================================================================== *** c-decl.c.orig 2007-08-27 11:25:41.000000000 +0200 --- c-decl.c 2007-08-27 11:26:56.000000000 +0200 *************** finish_decl (tree decl, tree init, tree *** 3517,3522 **** --- 3517,3528 ---- /* If #pragma weak was used, mark the decl weak now. */ maybe_apply_pragma_weak (decl); + /* For GNU C extern inline functions disregard inline limits. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_EXTERNAL (decl) + && DECL_DECLARED_INLINE_P (decl)) + DECL_DISREGARD_INLINE_LIMITS (decl) = 1; + /* Output the assembler code and/or RTL code for variables and functions, unless the type is an undefined structure or union. If not, it will get done when the type is completed. */ Index: tree-inline.c =================================================================== *** tree-inline.c.orig 2007-08-27 11:25:41.000000000 +0200 --- tree-inline.c 2007-08-27 11:26:56.000000000 +0200 *************** inlinable_function_p (tree fn) *** 1936,1955 **** 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. */ --- 1936,1941 ---- Index: tree-inline.h =================================================================== *** tree-inline.h.orig 2007-08-27 11:25:41.000000000 +0200 --- tree-inline.h 2007-08-27 11:26:56.000000000 +0200 *************** extern void insert_decl_map (copy_body_d *** 130,136 **** 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 *); --- 130,135 ---- Index: c-common.c =================================================================== *** c-common.c.orig 2007-08-27 11:25:41.000000000 +0200 --- c-common.c 2007-08-27 11:26:56.000000000 +0200 *************** handle_always_inline_attribute (tree *no *** 4864,4871 **** { if (TREE_CODE (*node) == FUNCTION_DECL) { ! /* Do nothing else, just set the attribute. We'll get at ! it later with lookup_attribute. */ } else { --- 4864,4872 ---- { if (TREE_CODE (*node) == FUNCTION_DECL) { ! /* Set the attribute and mark it for disregarding inline ! limits. */ ! DECL_DISREGARD_INLINE_LIMITS (*node) = 1; } else {