calls.c (alloca_call_p): New global function.
* calls.c (alloca_call_p): New global function. * tree.h (alloca_call_p): New. * tree-inline.c (inlinable_function_p): Do not inline when function calls alloca. (find_alloca_call, find_alloca_call_1): New functions. From-SVN: r59228
This commit is contained in:
parent
5602b49d69
commit
c986baf631
@ -1,3 +1,11 @@
|
|||||||
|
Sun Nov 17 00:01:28 CET 2002 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
* calls.c (alloca_call_p): New global function.
|
||||||
|
* tree.h (alloca_call_p): New.
|
||||||
|
* tree-inline.c (inlinable_function_p): Do not inline when
|
||||||
|
function calls alloca.
|
||||||
|
(find_alloca_call, find_alloca_call_1): New functions.
|
||||||
|
|
||||||
2002-11-18 Kazu Hirata <kazu@cs.umass.edu>
|
2002-11-18 Kazu Hirata <kazu@cs.umass.edu>
|
||||||
|
|
||||||
* config/h8300/h8300.md (*andorqi3): Use bor between bld and
|
* config/h8300/h8300.md (*andorqi3): Use bor between bld and
|
||||||
|
15
gcc/calls.c
15
gcc/calls.c
@ -801,6 +801,21 @@ setjmp_call_p (fndecl)
|
|||||||
return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
|
return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true when exp contains alloca call. */
|
||||||
|
bool
|
||||||
|
alloca_call_p (exp)
|
||||||
|
tree exp;
|
||||||
|
{
|
||||||
|
if (TREE_CODE (exp) == CALL_EXPR
|
||||||
|
&& TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
|
||||||
|
&& (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
|
||||||
|
== FUNCTION_DECL)
|
||||||
|
&& (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
|
||||||
|
0) & ECF_MAY_BE_ALLOCA))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Detect flags (function attributes) from the function decl or type node. */
|
/* Detect flags (function attributes) from the function decl or type node. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -122,6 +122,8 @@ static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *));
|
|||||||
static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree, tree));
|
static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree, tree));
|
||||||
static void remap_block PARAMS ((tree *, tree, inline_data *));
|
static void remap_block PARAMS ((tree *, tree, inline_data *));
|
||||||
static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
|
static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
|
||||||
|
static tree find_alloca_call_1 PARAMS ((tree *, int *, void *));
|
||||||
|
static tree find_alloca_call PARAMS ((tree));
|
||||||
#endif /* INLINER_FOR_JAVA */
|
#endif /* INLINER_FOR_JAVA */
|
||||||
|
|
||||||
/* The approximate number of instructions per statement. This number
|
/* The approximate number of instructions per statement. This number
|
||||||
@ -857,6 +859,27 @@ tree_inlinable_function_p (fn)
|
|||||||
return inlinable_function_p (fn, NULL);
|
return inlinable_function_p (fn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if *TP is possibly call to alloca, return nonzero. */
|
||||||
|
static tree
|
||||||
|
find_alloca_call_1 (tp, walk_subtrees, data)
|
||||||
|
tree *tp;
|
||||||
|
int *walk_subtrees ATTRIBUTE_UNUSED;
|
||||||
|
void *data ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
if (alloca_call_p (*tp))
|
||||||
|
return *tp;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return subexpression representing possible alloca call,
|
||||||
|
if any. */
|
||||||
|
static tree
|
||||||
|
find_alloca_call (exp)
|
||||||
|
tree exp;
|
||||||
|
{
|
||||||
|
return walk_tree (&exp, find_alloca_call_1, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns nonzero if FN is a function that can be inlined into the
|
/* Returns nonzero if FN is a function that can be inlined into the
|
||||||
inlining context ID_. If ID_ is NULL, check whether the function
|
inlining context ID_. If ID_ is NULL, check whether the function
|
||||||
can be inlined at all. */
|
can be inlined at all. */
|
||||||
@ -897,6 +920,13 @@ inlinable_function_p (fn, id)
|
|||||||
else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
|
else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
|
||||||
&& currfn_insns > MAX_INLINE_INSNS_SINGLE)
|
&& currfn_insns > MAX_INLINE_INSNS_SINGLE)
|
||||||
;
|
;
|
||||||
|
/* Refuse to inline alloca call unless user explicitly forced so as this may
|
||||||
|
change program's memory overhead drastically when the function using alloca
|
||||||
|
is called in loop. In GCC present in SPEC2000 inlining into schedule_block
|
||||||
|
cause it to require 2GB of ram instead of 256MB. */
|
||||||
|
else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL
|
||||||
|
&& find_alloca_call (DECL_SAVED_TREE (fn)))
|
||||||
|
;
|
||||||
/* All is well. We can inline this function. Traditionally, GCC
|
/* All is well. We can inline this function. Traditionally, GCC
|
||||||
has refused to inline functions using alloca, or functions whose
|
has refused to inline functions using alloca, or functions whose
|
||||||
values are returned in a PARALLEL, and a few other such obscure
|
values are returned in a PARALLEL, and a few other such obscure
|
||||||
|
@ -3018,6 +3018,7 @@ extern rtx emit_line_note PARAMS ((const char *, int));
|
|||||||
/* In calls.c */
|
/* In calls.c */
|
||||||
|
|
||||||
extern int setjmp_call_p PARAMS ((tree));
|
extern int setjmp_call_p PARAMS ((tree));
|
||||||
|
extern bool alloca_call_p PARAMS ((tree));
|
||||||
|
|
||||||
/* In attribs.c. */
|
/* In attribs.c. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user