diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-09 00:31:20 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-09 00:31:20 +0000 |
commit | 309c7c521269c37881108493ac68c46d63f88812 (patch) | |
tree | 5029eb04a9f787f6958b11882444a0e5bc409cfb | |
parent | 6b039979accdac89495c0394d59753b06466ec11 (diff) | |
download | gcc-309c7c521269c37881108493ac68c46d63f88812.tar.gz |
* java-tree.h (DECL_NUM_STMTS): Rename to...
(DECL_ESTIMATED_INSNS): ... this.
* lang.c (java_estimate_num_insns, java_estimate_num_insns_1):
New static functions.
(LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Define.
* parser.y (add_stmt_to_compound): Do not account statements.
* cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
* decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
(start_function): Use DECL_ESTIMATED_INSNS.
* optimize.c (maybe_clone_body): Use DECL_ESTIMATED_INSNS.
* decl2.c (maybe_emit_vtables): Fix marking vtables as needed in
unit-at-a-time
* c-common.c (c_estimate_num_insns_1): New static function.
(c_estimate_num_insns): New global function.
* c-common.h (DECL_NUM_STMTS): Rename to...
(DECL_ESTIMATED_INSNS): ... this.
(c_estimate_num_insns): Declare.
* c-decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
* c-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
* c-semantics.c (add_stmt): Do not account statements.
* langhooks-def.h (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS):
New.
* langhooks.h (lang_hooks_for_tree_inlining): Add
estimate_num_insns
* params.def (max-inline-insns-auto, max-inline-insns-auto): set
to 100.
(max-inline-insns): set to 300.
(min-inline-insns): set to 10.
* tree-inline.c (struct inline_data): Rename inlined_stmts to
inlined-insns.
(INSNS_PER_STMT): Kill.
(inlinable_function_p): Compute and store body size.
(expand_call_inline): Likewise.
(optimize_inline_calls): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69113 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/c-common.c | 110 | ||||
-rw-r--r-- | gcc/c-common.h | 3 | ||||
-rw-r--r-- | gcc/c-decl.c | 2 | ||||
-rw-r--r-- | gcc/c-lang.c | 2 | ||||
-rw-r--r-- | gcc/c-objc-common.c | 3 | ||||
-rw-r--r-- | gcc/c-semantics.c | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 7 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 2 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 8 | ||||
-rw-r--r-- | gcc/java/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 4 | ||||
-rw-r--r-- | gcc/java/lang.c | 107 | ||||
-rw-r--r-- | gcc/java/parse.y | 4 | ||||
-rw-r--r-- | gcc/langhooks-def.h | 5 | ||||
-rw-r--r-- | gcc/langhooks.h | 1 | ||||
-rw-r--r-- | gcc/params.def | 14 | ||||
-rw-r--r-- | gcc/tree-inline.c | 28 |
21 files changed, 309 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 194c807de5a..261d8c78683 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +Wed Jul 9 02:25:39 CEST 2003 Jan Hubicka <jh@suse.cz> + + * c-common.c (c_estimate_num_insns_1): New static function. + (c_estimate_num_insns): New global function. + * c-common.h (DECL_NUM_STMTS): Rename to... + (DECL_ESTIMATED_INSNS): ... this. + (c_estimate_num_insns): Declare. + * c-decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS. + * c-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New. + * c-semantics.c (add_stmt): Do not account statements. + * langhooks-def.h (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): + New. + * langhooks.h (lang_hooks_for_tree_inlining): Add + estimate_num_insns + * params.def (max-inline-insns-auto, max-inline-insns-auto): set + to 100. + (max-inline-insns): set to 300. + (min-inline-insns): set to 10. + * tree-inline.c (struct inline_data): Rename inlined_stmts to + inlined-insns. + (INSNS_PER_STMT): Kill. + (inlinable_function_p): Compute and store body size. + (expand_call_inline): Likewise. + (optimize_inline_calls): Likewise. + 2003-07-08 James E Wilson <wilson@tuliptree.org> PR target/10021 diff --git a/gcc/c-common.c b/gcc/c-common.c index 341018c0e5b..49ff8707e27 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -5881,4 +5881,114 @@ check_function_arguments_recurse (void (*callback) (*callback) (ctx, param, param_num); } +/* Used by estimate_num_insns. Estimate number of instructions seen + by given statement. */ +static tree +c_estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) +{ + int *count = data; + tree x = *tp; + + if (TYPE_P (x) || DECL_P (x)) + { + *walk_subtrees = 0; + return NULL; + } + /* Assume that constants and references counts nothing. These should + be majorized by amount of operations amoung them we count later + and are common target of CSE and similar optimizations. */ + if (TREE_CODE_CLASS (TREE_CODE (x)) == 'c' + || TREE_CODE_CLASS (TREE_CODE (x)) == 'r') + return NULL; + switch (TREE_CODE (x)) + { + /* Reconginze assignments of large structures and constructors of + big arrays. */ + case MODIFY_EXPR: + case CONSTRUCTOR: + { + int size = int_size_in_bytes (TREE_TYPE (x)); + + if (!size || size > MOVE_MAX_PIECES) + *count += 10; + else + *count += 2 * (size + MOVE_MAX - 1) / MOVE_MAX; + return NULL; + } + break; + /* Few special cases of expensive operations. This is usefull + to avoid inlining on functions having too many of these. */ + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case TRUNC_MOD_EXPR: + case CEIL_MOD_EXPR: + case FLOOR_MOD_EXPR: + case ROUND_MOD_EXPR: + case RDIV_EXPR: + case CALL_EXPR: + case METHOD_CALL_EXPR: + *count += 10; + break; + /* Various containers that will produce no code themselves. */ + case INIT_EXPR: + case TARGET_EXPR: + case BIND_EXPR: + case BLOCK: + case TREE_LIST: + case TREE_VEC: + case IDENTIFIER_NODE: + case PLACEHOLDER_EXPR: + case WITH_CLEANUP_EXPR: + case CLEANUP_POINT_EXPR: + case NOP_EXPR: + case VIEW_CONVERT_EXPR: + case SAVE_EXPR: + case UNSAVE_EXPR: + case COMPLEX_EXPR: + case REALPART_EXPR: + case IMAGPART_EXPR: + case TRY_CATCH_EXPR: + case TRY_FINALLY_EXPR: + case LABEL_EXPR: + case EXIT_EXPR: + case LABELED_BLOCK_EXPR: + case EXIT_BLOCK_EXPR: + case EXPR_WITH_FILE_LOCATION: + + case EXPR_STMT: + case COMPOUND_STMT: + case RETURN_STMT: + case LABEL_STMT: + case SCOPE_STMT: + case FILE_STMT: + case CASE_LABEL: + case STMT_EXPR: + case CLEANUP_STMT: + + case SIZEOF_EXPR: + case ARROW_EXPR: + case ALIGNOF_EXPR: + break; + case DECL_STMT: + /* Do not account static initializers. */ + if (TREE_STATIC (TREE_OPERAND (x, 0))) + *walk_subtrees = 0; + break; + default: + (*count)++; + } + return NULL; +} + +/* Estimate number of instructions that will be created by expanding the body. */ +int +c_estimate_num_insns (tree decl) +{ + int num = 0; + walk_tree_without_duplicates (&DECL_SAVED_TREE (decl), c_estimate_num_insns_1, &num); + return num; +} + #include "gt-c-common.h" diff --git a/gcc/c-common.h b/gcc/c-common.h index bafe8570900..7fdd80969b9 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -357,7 +357,7 @@ struct c_lang_decl GTY(()) { the approximate number of statements in this function. There is no need for this number to be exact; it is only used in various heuristics regarding optimization. */ -#define DECL_NUM_STMTS(NODE) \ +#define DECL_ESTIMATED_INSNS(NODE) \ (FUNCTION_DECL_CHECK (NODE)->decl.u1.i) /* Nonzero if we can read a PCH file now. */ @@ -1296,6 +1296,7 @@ extern void c_common_write_pch (void); extern void builtin_define_with_value (const char *, const char *, int); extern void c_stddef_cpp_builtins (void); extern void fe_file_change (const struct line_map *); +extern int c_estimate_num_insns (tree decl); /* In c-ppoutput.c */ extern void init_pp_output (FILE *); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c199f6d0954..fbe0b02a810 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1471,7 +1471,7 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); - DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl); + DECL_ESTIMATED_INSNS (newdecl) = DECL_ESTIMATED_INSNS (olddecl); DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); /* Set DECL_INLINE on the declaration if we've got a body diff --git a/gcc/c-lang.c b/gcc/c-lang.c index 99b01ec82a2..815a72f1a20 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -102,6 +102,8 @@ enum c_language_kind c_language = clk_c; #undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \ c_convert_parm_for_inlining +#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS +#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c index e0a99a3ae87..438b3fba808 100644 --- a/gcc/c-objc-common.c +++ b/gcc/c-objc-common.c @@ -211,8 +211,7 @@ c_cannot_inline_tree_fn (tree *fnp) return 0; } - if (walk_tree_without_duplicates (&DECL_SAVED_TREE (fn), - inline_forbidden_p, fn)) + if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL)) goto cannot_inline; return 0; diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index 9ecfc96faa2..933ed50f27f 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -102,10 +102,6 @@ add_stmt (tree t) statements are full-expressions. We record that fact here. */ STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p (); - /* Keep track of the number of statements in this function. */ - if (current_function_decl) - ++DECL_NUM_STMTS (current_function_decl); - return t; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ae4a83ce6f0..a4b9aea4535 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +Wed Jul 9 02:28:39 CEST 2003 Jan Hubicka <jh@suse.cz> + + * cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New. + * decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS. + (start_function): Use DECL_ESTIMATED_INSNS. + * optimize.c (maybe_clone_body): Use DECL_ESTIMATED_INSNS. + + * decl2.c (maybe_emit_vtables): Fix marking vtables as needed in + unit-at-a-time + 2003-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> PR c++/11030 diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index affc9646640..741a0cc7747 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -144,6 +144,8 @@ static bool cp_var_mod_type_p (tree); #define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining #undef LANG_HOOKS_TREE_INLINING_END_INLINING #define LANG_HOOKS_TREE_INLINING_END_INLINING cp_end_inlining +#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS +#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree #undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f0aef38513f..4534a7622b9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3530,7 +3530,7 @@ duplicate_decls (tree newdecl, tree olddecl) SET_DECL_RTL (newdecl, DECL_RTL (olddecl)); } else - DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl); + DECL_ESTIMATED_INSNS (newdecl) = DECL_ESTIMATED_INSNS (olddecl); DECL_RESULT (newdecl) = DECL_RESULT (olddecl); /* Don't clear out the arguments if we're redefining a function. */ @@ -13518,7 +13518,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) begin_stmt_tree (&DECL_SAVED_TREE (decl1)); /* Don't double-count statements in templates. */ - DECL_NUM_STMTS (decl1) = 0; + DECL_ESTIMATED_INSNS (decl1) = 0; /* Let the user know we're compiling this function. */ announce_function (decl1); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7158f102147..7a2399a6016 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1634,6 +1634,7 @@ maybe_emit_vtables (tree ctype) { tree vtbl; tree primary_vtbl; + bool needed = false; /* If the vtables for this class have already been emitted there is nothing more to do. */ @@ -1651,7 +1652,6 @@ maybe_emit_vtables (tree ctype) for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) if (!DECL_EXTERNAL (vtbl) && DECL_NEEDED_P (vtbl)) break; - if (!vtbl) { /* If the references to this class' vtables are optimized away, @@ -1662,6 +1662,9 @@ maybe_emit_vtables (tree ctype) note_debug_info_needed (ctype); return false; } + else if (TREE_PUBLIC (vtbl) && !DECL_COMDAT (vtbl)) + needed = true; + /* The ABI requires that we emit all of the vtables if we emit any of them. */ @@ -1672,7 +1675,7 @@ maybe_emit_vtables (tree ctype) mark_vtable_entries (vtbl); /* If we know that DECL is needed, mark it as such for the varpool. */ - if (CLASSTYPE_EXPLICIT_INSTANTIATION (ctype)) + if (needed) cgraph_varpool_mark_needed_node (cgraph_varpool_node (vtbl)); if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0) diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 4be829e818b..c52970fd4b6 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -254,7 +254,7 @@ maybe_clone_body (tree fn) /* There are as many statements in the clone as in the original. */ - DECL_NUM_STMTS (clone) = DECL_NUM_STMTS (fn); + DECL_ESTIMATED_INSNS (clone) = DECL_ESTIMATED_INSNS (fn); /* Clean up. */ splay_tree_delete (decl_map); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 2f612282451..ade4e1f6b5e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -4532,7 +4532,7 @@ This number sets the maximum number of instructions (counted in gcc's internal representation) in a single function that the tree inliner will consider for inlining. This only affects functions declared inline and methods implemented in a class declaration (C++). -The default value is 300. +The default value is 100. @item max-inline-insns-auto When you use @option{-finline-functions} (included in @option{-O3}), @@ -4540,7 +4540,7 @@ a lot of functions that would otherwise not be considered for inlining by the compiler will be investigated. To those functions, a different (more restrictive) limit compared to functions declared inline can be applied. -The default value is 300. +The default value is 100. @item max-inline-insns The tree inliner does decrease the allowable size for single functions @@ -4551,7 +4551,7 @@ Higher numbers result in better runtime performance, but incur higher compile-time resource (CPU time, memory) requirements and result in larger binaries. Very high values are not advisable, as too large binaries may adversely affect runtime performance. -The default value is 600. +The default value is 200. @item max-inline-slope After exceeding the maximum number of inlined instructions by repeated @@ -4565,7 +4565,7 @@ The repeated inlining is throttled more and more by the linear function after exceeding the limit. To avoid too much throttling, a minimum for this function is specified here to allow repeated inlining for very small functions even when a lot of repeated inlining already has been done. -The default value is 130. +The default value is 10. @item max-inline-insns-rtl For languages that use the RTL inliner (this happens at a later stage diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index e00ec4bb533..fba4f04110b 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,12 @@ +Wed Jul 9 02:29:15 CEST 2003 Jan Hubicka <jh@suse.cz> + + * java-tree.h (DECL_NUM_STMTS): Rename to... + (DECL_ESTIMATED_INSNS): ... this. + * lang.c (java_estimate_num_insns, java_estimate_num_insns_1): + New static functions. + (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Define. + * parser.y (add_stmt_to_compound): Do not account statements. + 2003-07-08 Mark Wielaard <mark@klomp.org> * gcj.texi: CNI now expands to Compiled Native Interface. diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index f4764e7c3e8..357f3493170 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -922,10 +922,10 @@ union lang_tree_node #define DECL_FIELD_FINAL_WFL(NODE) \ (DECL_LANG_SPECIFIC(NODE)->u.v.wfl) /* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is - the approximate number of statements in this function. There is + the approximate number of instructions in this function. There is no need for this number to be exact; it is only used in various heuristics regarding optimization. */ -#define DECL_NUM_STMTS(NODE) \ +#define DECL_ESTIMATED_INSNS(NODE) \ (FUNCTION_DECL_CHECK (NODE)->decl.u1.i) /* True if NODE is a local variable final. */ #define LOCAL_FINAL_P(NODE) (DECL_LANG_SPECIFIC (NODE) && DECL_FINAL (NODE)) diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 7402ab7f086..1f9470627fa 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -66,6 +66,7 @@ static bool java_can_use_bit_fields_p (void); static bool java_dump_tree (void *, tree); static void dump_compound_expr (dump_info_p, tree); static bool java_decl_ok_for_sibcall (tree); +static int java_estimate_num_insns (tree); #ifndef TARGET_OBJECT_SUFFIX # define TARGET_OBJECT_SUFFIX ".o" @@ -249,6 +250,9 @@ struct language_function GTY(()) #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees +#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS +#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS java_estimate_num_insns + #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree @@ -1076,4 +1080,107 @@ java_decl_ok_for_sibcall (tree decl) return decl != NULL && DECL_CONTEXT (decl) == current_class; } +/* Used by estimate_num_insns. Estimate number of instructions seen + by given statement. */ +static tree +java_estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) +{ + int *count = data; + tree x = *tp; + + if (TYPE_P (x) || DECL_P (x)) + { + *walk_subtrees = 0; + return NULL; + } + /* Assume that constants and references counts nothing. These should + be majorized by amount of operations amoung them we count later + and are common target of CSE and similar optimizations. */ + if (TREE_CODE_CLASS (TREE_CODE (x)) == 'c' + || TREE_CODE_CLASS (TREE_CODE (x)) == 'r') + return NULL; + switch (TREE_CODE (x)) + { + /* Reconginze assignments of large structures and constructors of + big arrays. */ + case MODIFY_EXPR: + case CONSTRUCTOR: + { + int size = int_size_in_bytes (TREE_TYPE (x)); + + if (!size || size > MOVE_MAX_PIECES) + *count += 10; + else + *count += 2 * (size + MOVE_MAX - 1) / MOVE_MAX; + return NULL; + } + break; + /* Few special cases of expensive operations. This is usefull + to avoid inlining on functions having too many of these. */ + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case TRUNC_MOD_EXPR: + case CEIL_MOD_EXPR: + case FLOOR_MOD_EXPR: + case ROUND_MOD_EXPR: + case RDIV_EXPR: + case CALL_EXPR: + case METHOD_CALL_EXPR: + + case NEW_ARRAY_EXPR: + case NEW_ANONYMOUS_ARRAY_EXPR: + case NEW_CLASS_EXPR: + *count += 10; + break; + /* Various containers that will produce no code themselves. */ + case INIT_EXPR: + case TARGET_EXPR: + case BIND_EXPR: + case BLOCK: + case TREE_LIST: + case TREE_VEC: + case IDENTIFIER_NODE: + case PLACEHOLDER_EXPR: + case WITH_CLEANUP_EXPR: + case CLEANUP_POINT_EXPR: + case NOP_EXPR: + case VIEW_CONVERT_EXPR: + case SAVE_EXPR: + case UNSAVE_EXPR: + case COMPLEX_EXPR: + case REALPART_EXPR: + case IMAGPART_EXPR: + case TRY_CATCH_EXPR: + case TRY_FINALLY_EXPR: + case LABEL_EXPR: + case EXIT_EXPR: + case LABELED_BLOCK_EXPR: + case EXIT_BLOCK_EXPR: + case EXPR_WITH_FILE_LOCATION: + case UNARY_PLUS_EXPR: + case THIS_EXPR: + case DEFAULT_EXPR: + case TRY_EXPR: + + break; + case CLASS_LITERAL: + *walk_subtrees = 0; + break; + default: + (*count)++; + } + return NULL; +} + +/* Estimate number of instructions that will be created by expanding the body. */ +static int +java_estimate_num_insns (tree decl) +{ + int num = 0; + walk_tree (&DECL_SAVED_TREE (decl), java_estimate_num_insns_1, &num, NULL); + return num; +} + #include "gt-java-lang.h" diff --git a/gcc/java/parse.y b/gcc/java/parse.y index a156be1ccfd..cbb4297f962 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -7429,10 +7429,6 @@ add_stmt_to_block (tree b, tree type, tree stmt) static tree add_stmt_to_compound (tree existing, tree type, tree stmt) { - /* Keep track of this for inlining. */ - if (current_function_decl) - ++DECL_NUM_STMTS (current_function_decl); - if (existing) return build (COMPOUND_EXPR, type, existing, stmt); else diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index a598c05114e..12da91c5c45 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -152,6 +152,8 @@ extern void write_global_declarations (void); lhd_tree_inlining_end_inlining #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \ lhd_tree_inlining_convert_parm_for_inlining +#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \ + NULL #define LANG_HOOKS_TREE_INLINING_INITIALIZER { \ LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \ @@ -165,7 +167,8 @@ extern void write_global_declarations (void); LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P, \ LANG_HOOKS_TREE_INLINING_START_INLINING, \ LANG_HOOKS_TREE_INLINING_END_INLINING, \ - LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \ + LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING, \ + LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \ } \ #define LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION NULL diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 1ba3bfe3743..0ab10e05cbc 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -53,6 +53,7 @@ struct lang_hooks_for_tree_inlining union tree_node *(*convert_parm_for_inlining) (union tree_node *, union tree_node *, union tree_node *); + int (*estimate_num_insns) (union tree_node *); }; struct lang_hooks_for_callgraph diff --git a/gcc/params.def b/gcc/params.def index 9d9d973ec0b..3f1d94b6bea 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -39,7 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA of a function counted in internal gcc instructions (not in real machine instructions) that is eligible for inlining by the tree inliner. - The default value is 300. + The default value is 100. Only functions marked inline (or methods defined in the class definition for C++) are affected by this, unless you set the -finline-functions (included in -O3) compiler option. @@ -51,7 +51,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, "max-inline-insns-single", "The maximum number of instructions in a single function eligible for inlining", - 300) + 100) /* The single function inlining limit for functions that are inlined by virtue of -finline-functions (-O3). @@ -59,11 +59,11 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, that is applied to functions marked inlined (or defined in the class declaration in C++) given by the "max-inline-insns-single" parameter. - The default value is 300. */ + The default value is 100. */ DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, "max-inline-insns-auto", "The maximum number of instructions when automatically inlining", - 300) + 100) /* The repeated inlining limit. After this number of instructions (in the internal gcc representation, not real machine instructions) @@ -74,7 +74,7 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, could otherwise become very high. It is recommended to set this value to twice the value of the single function limit (set by the "max-inline-insns-single" parameter) or - higher. The default value is 600. + higher. The default value is 200. Higher values mean that more inlining is done, resulting in better performance of the code, at the expense of higher compile-time resource (time, memory) requirements and larger @@ -82,7 +82,7 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, DEFPARAM (PARAM_MAX_INLINE_INSNS, "max-inline-insns", "The maximum number of instructions by repeated inlining before gcc starts to throttle inlining", - 600) + 200) /* After the repeated inline limit has been exceeded (see "max-inline-insns" parameter), a linear function is used to @@ -108,7 +108,7 @@ DEFPARAM (PARAM_MAX_INLINE_SLOPE, DEFPARAM (PARAM_MIN_INLINE_INSNS, "min-inline-insns", "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining", - 130) + 10) /* For languages that (still) use the RTL inliner, we can specify limits for the RTL inliner separately. diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index c41ccea5e83..3e68983fe3f 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -93,9 +93,9 @@ typedef struct inline_data int in_target_cleanup_p; /* A list of the functions current function has inlined. */ varray_type inlined_fns; - /* The approximate number of statements we have inlined in the + /* The approximate number of instructions we have inlined in the current call stack. */ - int inlined_stmts; + int inlined_insns; /* We use the same mechanism to build clones that we do to perform inlining. However, there are a few places where we need to distinguish between those two situations. This flag is true if @@ -131,11 +131,6 @@ static tree find_alloca_call (tree); static tree find_builtin_longjmp_call_1 (tree *, int *, void *); static tree find_builtin_longjmp_call (tree); -/* The approximate number of instructions per statement. This number - need not be particularly accurate; it is used only to make - decisions about when a function is too big to inline. */ -#define INSNS_PER_STMT (10) - /* Remap DECL during the copying of the BLOCK tree for the function. */ static tree @@ -939,7 +934,7 @@ static int inlinable_function_p (tree fn, inline_data *id, int nolimit) { int inlinable; - int currfn_insns; + int currfn_insns = 0; int max_inline_insns_single = MAX_INLINE_INSNS_SINGLE; /* If we've already decided this function shouldn't be inlined, @@ -959,7 +954,10 @@ inlinable_function_p (tree fn, inline_data *id, int nolimit) max_inline_insns_single = MAX_INLINE_INSNS_AUTO; /* The number of instructions (estimated) of current function. */ - currfn_insns = DECL_NUM_STMTS (fn) * INSNS_PER_STMT; + if (!nolimit && !DECL_ESTIMATED_INSNS (fn)) + DECL_ESTIMATED_INSNS (fn) + = (*lang_hooks.tree_inlining.estimate_num_insns) (fn); + currfn_insns = DECL_ESTIMATED_INSNS (fn); /* If we're not inlining things, then nothing is inlinable. */ if (! flag_inline_trees) @@ -1008,8 +1006,7 @@ inlinable_function_p (tree fn, inline_data *id, int nolimit) if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) && inlinable && !nolimit) { - int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT - + currfn_insns; + int sum_insns = (id ? id->inlined_insns : 0) + currfn_insns; /* In the extreme case that we have exceeded the recursive inlining limit by a huge factor (128), we just say no. Should not happen in real life. */ @@ -1394,9 +1391,9 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data) TREE_USED (*tp) = 1; /* Our function now has more statements than it did before. */ - DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn); + DECL_ESTIMATED_INSNS (VARRAY_TREE (id->fns, 0)) += DECL_ESTIMATED_INSNS (fn); /* For accounting, subtract one for the saved call/ret. */ - id->inlined_stmts += DECL_NUM_STMTS (fn) - 1; + id->inlined_insns += DECL_ESTIMATED_INSNS (fn) - 1; /* Update callgraph if needed. */ if (id->decl && flag_unit_at_a_time) @@ -1412,7 +1409,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data) /* If we've returned to the top level, clear out the record of how much inlining has been done. */ if (VARRAY_ACTIVE_SIZE (id->fns) == id->first_inlined_fn) - id->inlined_stmts = 0; + id->inlined_insns = 0; /* Don't walk into subtrees. We've already handled them above. */ *walk_subtrees = 0; @@ -1452,6 +1449,9 @@ optimize_inline_calls (tree fn) /* Don't allow recursion into FN. */ VARRAY_TREE_INIT (id.fns, 32, "fns"); VARRAY_PUSH_TREE (id.fns, fn); + if (!DECL_ESTIMATED_INSNS (fn)) + DECL_ESTIMATED_INSNS (fn) + = (*lang_hooks.tree_inlining.estimate_num_insns) (fn); /* Or any functions that aren't finished yet. */ prev_fn = NULL_TREE; if (current_function_decl) |