diff options
Diffstat (limited to 'gcc/java/lang.c')
-rw-r--r-- | gcc/java/lang.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 7402ab7..1f94706 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" |