diff options
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 0f5ab59158f..5e645e1bb81 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -125,6 +125,8 @@ static tree add_stmt_to_compound PARAMS ((tree, tree, tree)); #endif /* INLINER_FOR_JAVA */ static tree find_alloca_call_1 PARAMS ((tree *, int *, void *)); static tree find_alloca_call PARAMS ((tree)); +static tree find_builtin_longjmp_call_1 PARAMS ((tree *, int *, void *)); +static tree find_builtin_longjmp_call PARAMS ((tree)); /* The approximate number of instructions per statement. This number need not be particularly accurate; it is used only to make @@ -661,6 +663,10 @@ initialize_inlined_parameters (id, args, fn, block) if (DECL_P (value)) value = build1 (NOP_EXPR, TREE_TYPE (value), value); + /* If this is a constant, make sure it has the right type. */ + else if (TREE_TYPE (value) != TREE_TYPE (p)) + value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value)); + splay_tree_insert (id->decl_map, (splay_tree_key) p, (splay_tree_value) value); @@ -871,7 +877,7 @@ tree_inlinable_function_p (fn) return inlinable_function_p (fn, NULL); } -/* if *TP is possibly call to alloca, return nonzero. */ +/* If *TP is possibly call to alloca, return nonzero. */ static tree find_alloca_call_1 (tp, walk_subtrees, data) tree *tp; @@ -883,8 +889,7 @@ find_alloca_call_1 (tp, walk_subtrees, data) return NULL; } -/* Return subexpression representing possible alloca call, - if any. */ +/* Return subexpression representing possible alloca call, if any. */ static tree find_alloca_call (exp) tree exp; @@ -892,6 +897,32 @@ find_alloca_call (exp) return walk_tree (&exp, find_alloca_call_1, NULL, NULL); } +static tree +find_builtin_longjmp_call_1 (tp, walk_subtrees, data) + tree *tp; + int *walk_subtrees ATTRIBUTE_UNUSED; + void *data ATTRIBUTE_UNUSED; +{ + tree exp = *tp, decl; + + if (TREE_CODE (exp) == CALL_EXPR + && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR + && (decl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0), + TREE_CODE (decl) == FUNCTION_DECL) + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (decl) == BUILT_IN_LONGJMP) + return decl; + + return NULL; +} + +static tree +find_builtin_longjmp_call (exp) + tree exp; +{ + return walk_tree (&exp, find_builtin_longjmp_call_1, NULL, NULL); +} + /* Returns nonzero if FN is a function that can be inlined into the inlining context ID_. If ID_ is NULL, check whether the function can be inlined at all. */ @@ -903,6 +934,7 @@ inlinable_function_p (fn, id) { int inlinable; int currfn_insns; + int max_inline_insns_single = MAX_INLINE_INSNS_SINGLE; /* If we've already decided this function shouldn't be inlined, there's no need to check again. */ @@ -911,7 +943,13 @@ inlinable_function_p (fn, id) /* Assume it is not inlinable. */ inlinable = 0; - + + /* We may be here either because fn is declared inline or because + we use -finline-functions. For the second case, we are more + restrictive. */ + if (DID_INLINE_FUNC (fn)) + 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; @@ -930,7 +968,15 @@ inlinable_function_p (fn, id) function to be of MAX_INLINE_INSNS_SINGLE size. Make special allowance for extern inline functions, though. */ else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) - && currfn_insns > MAX_INLINE_INSNS_SINGLE) + && currfn_insns > max_inline_insns_single) + ; + /* We can't inline functions that call __builtin_longjmp at all. + The non-local goto machenery really requires the destination + be in a different function. If we allow the function calling + __builtin_longjmp to be inlined into the function calling + __builtin_setjmp, Things will Go Awry. */ + /* ??? Need front end help to identify "regular" non-local goto. */ + else if (find_builtin_longjmp_call (DECL_SAVED_TREE (fn))) ; /* Refuse to inline alloca call unless user explicitly forced so as this may change program's memory overhead drastically when the function using alloca @@ -1492,10 +1538,9 @@ walk_tree (tp, func, data, htab_) /* Don't walk the same tree twice, if the user has requested that we avoid doing so. */ - if (htab_find (htab, *tp)) - return NULL_TREE; - /* If we haven't already seen this node, add it to the table. */ slot = htab_find_slot (htab, *tp, INSERT); + if (*slot) + return NULL_TREE; *slot = *tp; } @@ -1617,6 +1662,7 @@ walk_tree (tp, func, data, htab_) case ENUMERAL_TYPE: case BLOCK: case RECORD_TYPE: + case CHAR_TYPE: /* None of thse have subtrees other than those already walked above. */ break; |