diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-11 13:40:14 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-11 13:40:14 +0000 |
commit | 4e1d7ea46e9e60154f976a52a62b115ce5a0803a (patch) | |
tree | 79484e03a465253f9b84c8b8966f361bbe454ca5 /gcc/tree-inline.c | |
parent | c50ab07115770a13ea245b18969cffcc09a295c8 (diff) | |
download | gcc-4e1d7ea46e9e60154f976a52a62b115ce5a0803a.tar.gz |
* builtins.def (BUILT_IN_VA_ARG_PACK_LEN): New builtin.
* builtins.c (expand_builtin) <case BUILT_IN_VA_ARG_PACK_LEN>: Issue
error if __builtin_va_arg_pack_len () wasn't optimized out during
inlining.
* tree-inline.c (copy_bb): Replace __builtin_va_arg_pack_len ()
with the number of inline's anonymous arguments.
* doc/extend.texi: Document __builtin_va_arg_pack_len ().
* gcc.dg/va-arg-pack-len-1.c: New test.
* g++.dg/va-arg-pack-len-1.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128376 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index d49c3c8c490..d50b2c754ef 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -867,6 +867,33 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal stmt = *stmtp; update_stmt (stmt); } + else if (call + && id->call_expr + && (decl = get_callee_fndecl (call)) + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (decl) + == BUILT_IN_VA_ARG_PACK_LEN) + { + /* __builtin_va_arg_pack_len () should be replaced by + the number of anonymous arguments. */ + int nargs = call_expr_nargs (id->call_expr); + tree count, *call_ptr, p; + + for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p)) + nargs--; + + count = build_int_cst (integer_type_node, nargs); + call_ptr = stmtp; + if (TREE_CODE (*call_ptr) == GIMPLE_MODIFY_STMT) + call_ptr = &GIMPLE_STMT_OPERAND (*call_ptr, 1); + if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR) + call_ptr = &TREE_OPERAND (*call_ptr, 0); + gcc_assert (*call_ptr == call && call_ptr != stmtp); + *call_ptr = count; + stmt = *stmtp; + update_stmt (stmt); + call = NULL_TREE; + } /* Statements produced by inlining can be unfolded, especially when we constant propagated some operands. We can't fold |