diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-12-06 13:25:37 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-12-06 13:25:37 +0000 |
commit | 8a58ed0af38bbe49d77d45122f8fc503d14ea055 (patch) | |
tree | cef18ea9cceaa7495e72439b79c224d9d6d77889 /gcc/tree-ssa-ccp.c | |
parent | 326f0dc4ce53c5bbf7bbbb2b946629a58530096c (diff) | |
download | gcc-8a58ed0af38bbe49d77d45122f8fc503d14ea055.tar.gz |
PR middle-end/20983
* tree-ssa-ccp.c (optimize_stdarg_builtin): New function.
(execute_fold_all_builtins): Call it for BUILT_IN_VA_START,
BUILT_IN_VA_COPY and BUILT_IN_VA_END.
* target.h (struct ggc_target): Add expand_builtin_va_start
hook.
* target-def.h (TARGET_EXPAND_BUILTIN_VA_START): Define.
(TARGET_INITIALIZER): Add it.
* builtins.c (expand_builtin_va_start): Use
targetm.expand_builtin_va_start hook instead of
EXPAND_BUILTIN_VA_START macro.
* alpha/alpha.c (alpha_va_start): Made static.
(override_options): Clear targetm.expand_builtin_va_start if
TARGET_UNICOSMK.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* alpha/unicosmk.h (EXPAND_BUILTIN_VA_START): Remove.
* alpha/alpha.h (EXPAND_BUILTIN_VA_START): Remove.
* alpha/alpha-protos.h (alpha_va_start): Remove prototype.
* xtensa/xtensa.h (EXPAND_BUILTIN_VA_START): Remove.
* xtensa/xtensa.c (TARGET_EXPAND_BUILTIN_VA_START): Define.
(xtensa_va_start): Made static.
* xtensa/xtensa-protos.h (xtensa_va_start): Remove prototype.
* pa/pa-protos.h (hppa_va_start): Remove prototype.
* pa/pa.h (EXPAND_BUILTIN_VA_START): Remove.
* pa/pa.c (hppa_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* frv/frv.c (frv_expand_builtin_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* frv/frv-protos.h (frv_expand_builtin_va_start): Remove prototype.
* frv/frv.h (EXPAND_BUILTIN_VA_START): Remove.
* i386/i386.c (override_options): Clear
targetm.expand_builtin_va_start if -m32 or 64-bit MS ABI.
(ix86_va_start): Made static.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* i386/i386.h (EXPAND_BUILTIN_VA_START): Remove.
* i386/i386-protos.h (ix86_va_start, ix86_va_arg): Remove prototypes.
* iq2000/iq2000-protos.h (iq2000_va_start): Remove prototype.
* iq2000/iq2000.h (EXPAND_BUILTIN_VA_START): Remove.
* iq2000/iq2000.c (iq2000_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* rs6000/rs6000-protos.h (rs6000_va_start): Remove prototype.
* rs6000/rs6000.c (rs6000_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
(rs6000_override_options): Clear targetm.expand_builtin_va_start if
DEFAULT_ABI != ABI_V4.
* rs6000/rs6000.h (EXPAND_BUILTIN_VA_START): Remove.
* spu/spu.c (spu_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* spu/spu.h (EXPAND_BUILTIN_VA_START): Remove.
* spu/spu-protos.h spu_va_start): Remove prototype.
* stormy16/stormy16.h (EXPAND_BUILTIN_VA_START): Remove.
* stormy16/stormy16-protos.h (xstormy16_expand_builtin_va_start):
Remove prototype.
* stormy16/stormy16.c (xstormy16_expand_builtin_va_start): Made
static.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* s390/s390-protos.h (s390_va_start): Remove prototype.
* s390/s390.c (s390_va_start): Made static.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* s390/s390.h (EXPAND_BUILTIN_VA_START): Remove.
* mn10300/mn10300.h (EXPAND_BUILTIN_VA_START): Remove.
* mn10300/mn10300-protos.h (mn10300_va_start): Remove prototype.
* mn10300/mn10300.c (mn10300_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* arc/arc.c (arc_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* arc/arc.h (EXPAND_BUILTIN_VA_START): Remove.
* arc/arc-protos.h (arc_va_start): Remove prototype.
* mt/mt-protos.h (mt_va_start): Remove prototype.
* sparc/sparc.c (sparc_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* sparc/sparc-protos.h (sparc_va_start): Remove prototype.
* sparc/sparc.h (EXPAND_BUILTIN_VA_START): Remove.
* sh/sh.c (sh_va_start): Made static, add prototype.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
* sh/sh-protos.h (sh_va_start): Remove prototype.
* sh/sh.h (EXPAND_BUILTIN_VA_START): Remove.
* mips/mips-protos.h (mips_va_start): Remove prototype.
* mips/mips.h (EXPAND_BUILTIN_VA_START): Remove.
* mips/mips.c (mips_va_start): Made static.
(TARGET_EXPAND_BUILTIN_VA_START): Define.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130650 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 19d82563a81..15f14c4c608 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2708,6 +2708,78 @@ optimize_stack_restore (basic_block bb, tree call, block_stmt_iterator i) return integer_zero_node; } +/* If va_list type is a simple pointer and nothing special is needed, + optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0), + __builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple + pointer assignment. */ + +static tree +optimize_stdarg_builtin (tree call) +{ + tree callee, lhs, rhs; + bool va_list_simple_ptr; + + if (TREE_CODE (call) != CALL_EXPR) + return NULL_TREE; + + va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node) + && (TREE_TYPE (va_list_type_node) == void_type_node + || TREE_TYPE (va_list_type_node) == char_type_node); + + callee = get_callee_fndecl (call); + switch (DECL_FUNCTION_CODE (callee)) + { + case BUILT_IN_VA_START: + if (!va_list_simple_ptr + || targetm.expand_builtin_va_start != NULL + || built_in_decls[BUILT_IN_NEXT_ARG] == NULL) + return NULL_TREE; + + if (call_expr_nargs (call) != 2) + return NULL_TREE; + + lhs = CALL_EXPR_ARG (call, 0); + if (!POINTER_TYPE_P (TREE_TYPE (lhs)) + || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs))) + != TYPE_MAIN_VARIANT (va_list_type_node)) + return NULL_TREE; + + lhs = build_fold_indirect_ref (lhs); + rhs = build_call_expr (built_in_decls[BUILT_IN_NEXT_ARG], + 1, integer_zero_node); + rhs = fold_convert (TREE_TYPE (lhs), rhs); + return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs); + + case BUILT_IN_VA_COPY: + if (!va_list_simple_ptr) + return NULL_TREE; + + if (call_expr_nargs (call) != 2) + return NULL_TREE; + + lhs = CALL_EXPR_ARG (call, 0); + if (!POINTER_TYPE_P (TREE_TYPE (lhs)) + || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs))) + != TYPE_MAIN_VARIANT (va_list_type_node)) + return NULL_TREE; + + lhs = build_fold_indirect_ref (lhs); + rhs = CALL_EXPR_ARG (call, 1); + if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs)) + != TYPE_MAIN_VARIANT (va_list_type_node)) + return NULL_TREE; + + rhs = fold_convert (TREE_TYPE (lhs), rhs); + return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs); + + case BUILT_IN_VA_END: + return integer_zero_node; + + default: + gcc_unreachable (); + } +} + /* Convert EXPR into a GIMPLE value suitable for substitution on the RHS of an assignment. Insert the necessary statements before iterator *SI_P. @@ -2796,6 +2868,16 @@ execute_fold_all_builtins (void) result = optimize_stack_restore (bb, *stmtp, i); if (result) break; + bsi_next (&i); + continue; + + case BUILT_IN_VA_START: + case BUILT_IN_VA_END: + case BUILT_IN_VA_COPY: + /* These shouldn't be folded before pass_stdarg. */ + result = optimize_stdarg_builtin (*stmtp); + if (result) + break; /* FALLTHRU */ default: |