diff mbox series

Use more DECL_BUILT_IN_P macro.

Message ID 91c10cf9-2873-3136-a667-645ed2554e05@suse.cz
State New
Headers show
Series Use more DECL_BUILT_IN_P macro. | expand

Commit Message

Martin Liška Aug. 14, 2018, 9:06 a.m. UTC
Hi.

The patch adds more usages of the new macro. I hope it improves
readability of code.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin

gcc/ChangeLog:

2018-08-10  Martin Liska  <mliska@suse.cz>

	* tree.h (DECL_BUILT_IN_P): Add also check
        for TREE_CODE (NODE) == FUNCTION_DECL.
	* builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
	(fold_builtin_call_array): Likewise.
	* cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
	(cgraph_edge::verify_corresponds_to_fndecl): Likewise.
	(cgraph_node::verify_node): Likewise.
	* cgraphclones.c (cgraph_node::create_clone): Likewise.
	* dse.c (scan_insn): Likewise.
	* fold-const.c (fold_binary_loc): Likewise.
	* gimple-pretty-print.c (dump_gimple_call): Likewise.
	* gimple.c (gimple_call_builtin_p): Likewise.
	* gimplify.c (gimplify_call_expr): Likewise.
	(gimple_boolify): Likewise.
	(gimplify_modify_expr): Likewise.
	* ipa-fnsummary.c (compute_fn_summary): Likewise.
	* omp-low.c (setjmp_or_longjmp_p): Likewise.
	* trans-mem.c (is_tm_irrevocable): Likewise.
	(is_tm_abort): Likewise.
	* tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
	* tree-inline.c (copy_bb): Likewise.
	* tree-sra.c (scan_function): Likewise.
	* tree-ssa-ccp.c (optimize_stack_restore): Likewise.
	(pass_fold_builtins::execute): Likewise.
	* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
	* tree-ssa-loop-im.c (stmt_cost): Likewise.
	* tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.

gcc/c/ChangeLog:

2018-08-10  Martin Liska  <mliska@suse.cz>

	* c-parser.c (c_parser_postfix_expression_after_primary):
        Use DECL_BUILT_IN_P macro.

gcc/cp/ChangeLog:

2018-08-10  Martin Liska  <mliska@suse.cz>

	* constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
	(cxx_eval_builtin_function_call): Likewise.
	* cp-gimplify.c (cp_gimplify_expr): Likewise.
	(cp_fold): Likewise.
	* semantics.c (finish_call_expr): Likewise.
	* tree.c (builtin_valid_in_constant_expr_p): Likewise.
---
 gcc/builtins.c            | 10 ++--------
 gcc/c/c-parser.c          |  9 +++------
 gcc/cgraph.c              | 13 ++++++-------
 gcc/cgraphclones.c        |  4 ++--
 gcc/cp/constexpr.c        | 12 +++++-------
 gcc/cp/cp-gimplify.c      | 12 ++++--------
 gcc/cp/semantics.c        |  4 +---
 gcc/cp/tree.c             |  5 ++---
 gcc/dse.c                 |  5 ++---
 gcc/fold-const.c          |  4 +---
 gcc/gimple-pretty-print.c |  4 +---
 gcc/gimple.c              |  3 +--
 gcc/gimplify.c            | 14 ++++----------
 gcc/ipa-fnsummary.c       |  8 ++++----
 gcc/omp-low.c             |  5 ++---
 gcc/trans-mem.c           |  8 ++------
 gcc/tree-cfg.c            |  3 +--
 gcc/tree-inline.c         |  4 ++--
 gcc/tree-sra.c            |  4 ++--
 gcc/tree-ssa-ccp.c        |  8 ++------
 gcc/tree-ssa-dom.c        |  4 +---
 gcc/tree-ssa-loop-im.c    |  4 +---
 gcc/tree-stdarg.c         |  6 ++----
 gcc/tree.h                |  4 +++-
 24 files changed, 56 insertions(+), 101 deletions(-)

Comments

Martin Sebor Aug. 14, 2018, 4:02 p.m. UTC | #1
On 08/14/2018 03:06 AM, Martin Liška wrote:
> Hi.
>
> The patch adds more usages of the new macro. I hope it improves
> readability of code.

I think it does :)  I see that most invocations of it in your
patch are with BUILT_IN_NORMAL as the second argument.  Is
the argument implied by the last argument?  E.g., in

   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)

is there a way to determine that BUILT_IN_VA_ARG_PACK implies
DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
be eliminated?  (Both to make the invocation less verbose and
to avoid the mistake of using the macro with the wrong class.)

If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
to omit it.

Martin

>
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>
> Ready to be installed?
> Martin
>
> gcc/ChangeLog:
>
> 2018-08-10  Martin Liska  <mliska@suse.cz>
>
> 	* tree.h (DECL_BUILT_IN_P): Add also check
>         for TREE_CODE (NODE) == FUNCTION_DECL.
> 	* builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
> 	(fold_builtin_call_array): Likewise.
> 	* cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
> 	(cgraph_edge::verify_corresponds_to_fndecl): Likewise.
> 	(cgraph_node::verify_node): Likewise.
> 	* cgraphclones.c (cgraph_node::create_clone): Likewise.
> 	* dse.c (scan_insn): Likewise.
> 	* fold-const.c (fold_binary_loc): Likewise.
> 	* gimple-pretty-print.c (dump_gimple_call): Likewise.
> 	* gimple.c (gimple_call_builtin_p): Likewise.
> 	* gimplify.c (gimplify_call_expr): Likewise.
> 	(gimple_boolify): Likewise.
> 	(gimplify_modify_expr): Likewise.
> 	* ipa-fnsummary.c (compute_fn_summary): Likewise.
> 	* omp-low.c (setjmp_or_longjmp_p): Likewise.
> 	* trans-mem.c (is_tm_irrevocable): Likewise.
> 	(is_tm_abort): Likewise.
> 	* tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
> 	* tree-inline.c (copy_bb): Likewise.
> 	* tree-sra.c (scan_function): Likewise.
> 	* tree-ssa-ccp.c (optimize_stack_restore): Likewise.
> 	(pass_fold_builtins::execute): Likewise.
> 	* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
> 	* tree-ssa-loop-im.c (stmt_cost): Likewise.
> 	* tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
>
> gcc/c/ChangeLog:
>
> 2018-08-10  Martin Liska  <mliska@suse.cz>
>
> 	* c-parser.c (c_parser_postfix_expression_after_primary):
>         Use DECL_BUILT_IN_P macro.
>
> gcc/cp/ChangeLog:
>
> 2018-08-10  Martin Liska  <mliska@suse.cz>
>
> 	* constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
> 	(cxx_eval_builtin_function_call): Likewise.
> 	* cp-gimplify.c (cp_gimplify_expr): Likewise.
> 	(cp_fold): Likewise.
> 	* semantics.c (finish_call_expr): Likewise.
> 	* tree.c (builtin_valid_in_constant_expr_p): Likewise.
> ---
>  gcc/builtins.c            | 10 ++--------
>  gcc/c/c-parser.c          |  9 +++------
>  gcc/cgraph.c              | 13 ++++++-------
>  gcc/cgraphclones.c        |  4 ++--
>  gcc/cp/constexpr.c        | 12 +++++-------
>  gcc/cp/cp-gimplify.c      | 12 ++++--------
>  gcc/cp/semantics.c        |  4 +---
>  gcc/cp/tree.c             |  5 ++---
>  gcc/dse.c                 |  5 ++---
>  gcc/fold-const.c          |  4 +---
>  gcc/gimple-pretty-print.c |  4 +---
>  gcc/gimple.c              |  3 +--
>  gcc/gimplify.c            | 14 ++++----------
>  gcc/ipa-fnsummary.c       |  8 ++++----
>  gcc/omp-low.c             |  5 ++---
>  gcc/trans-mem.c           |  8 ++------
>  gcc/tree-cfg.c            |  3 +--
>  gcc/tree-inline.c         |  4 ++--
>  gcc/tree-sra.c            |  4 ++--
>  gcc/tree-ssa-ccp.c        |  8 ++------
>  gcc/tree-ssa-dom.c        |  4 +---
>  gcc/tree-ssa-loop-im.c    |  4 +---
>  gcc/tree-stdarg.c         |  6 ++----
>  gcc/tree.h                |  4 +++-
>  24 files changed, 56 insertions(+), 101 deletions(-)
>
>
Martin Liška Aug. 15, 2018, 12:52 p.m. UTC | #2
On 08/14/2018 06:02 PM, Martin Sebor wrote:
> On 08/14/2018 03:06 AM, Martin Liška wrote:
>> Hi.
>>
>> The patch adds more usages of the new macro. I hope it improves
>> readability of code.
> 
> I think it does :)  I see that most invocations of it in your
> patch are with BUILT_IN_NORMAL as the second argument.  Is
> the argument implied by the last argument?  E.g., in
> 
>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
> 
> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
> be eliminated?  (Both to make the invocation less verbose and
> to avoid the mistake of using the macro with the wrong class.)

If I see correctly not, there are separate enums:

BUILT_IN_MD:

enum ix86_builtins {
  IX86_BUILTIN_MASKMOVQ,
  IX86_BUILTIN_LDMXCSR,
  IX86_BUILTIN_STMXCSR,
...
}

BUILT_IN_NORMAL:
enum built_in_function {
BUILT_IN_NONE,
BUILT_IN_ACOS,
BUILT_IN_ACOSF,
...
}

So the enum values overlap and thus one needs the class.


> 
> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
> to omit it.

But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
right now.

Martin

> 
> Martin
> 
>>
>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>
>> Ready to be installed?
>> Martin
>>
>> gcc/ChangeLog:
>>
>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>
>>     * tree.h (DECL_BUILT_IN_P): Add also check
>>         for TREE_CODE (NODE) == FUNCTION_DECL.
>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
>>     (fold_builtin_call_array): Likewise.
>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
>>     (cgraph_node::verify_node): Likewise.
>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
>>     * dse.c (scan_insn): Likewise.
>>     * fold-const.c (fold_binary_loc): Likewise.
>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
>>     * gimple.c (gimple_call_builtin_p): Likewise.
>>     * gimplify.c (gimplify_call_expr): Likewise.
>>     (gimple_boolify): Likewise.
>>     (gimplify_modify_expr): Likewise.
>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
>>     * trans-mem.c (is_tm_irrevocable): Likewise.
>>     (is_tm_abort): Likewise.
>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
>>     * tree-inline.c (copy_bb): Likewise.
>>     * tree-sra.c (scan_function): Likewise.
>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
>>     (pass_fold_builtins::execute): Likewise.
>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
>>
>> gcc/c/ChangeLog:
>>
>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>
>>     * c-parser.c (c_parser_postfix_expression_after_primary):
>>         Use DECL_BUILT_IN_P macro.
>>
>> gcc/cp/ChangeLog:
>>
>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>
>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
>>     (cxx_eval_builtin_function_call): Likewise.
>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
>>     (cp_fold): Likewise.
>>     * semantics.c (finish_call_expr): Likewise.
>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
>> ---
>>  gcc/builtins.c            | 10 ++--------
>>  gcc/c/c-parser.c          |  9 +++------
>>  gcc/cgraph.c              | 13 ++++++-------
>>  gcc/cgraphclones.c        |  4 ++--
>>  gcc/cp/constexpr.c        | 12 +++++-------
>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
>>  gcc/cp/semantics.c        |  4 +---
>>  gcc/cp/tree.c             |  5 ++---
>>  gcc/dse.c                 |  5 ++---
>>  gcc/fold-const.c          |  4 +---
>>  gcc/gimple-pretty-print.c |  4 +---
>>  gcc/gimple.c              |  3 +--
>>  gcc/gimplify.c            | 14 ++++----------
>>  gcc/ipa-fnsummary.c       |  8 ++++----
>>  gcc/omp-low.c             |  5 ++---
>>  gcc/trans-mem.c           |  8 ++------
>>  gcc/tree-cfg.c            |  3 +--
>>  gcc/tree-inline.c         |  4 ++--
>>  gcc/tree-sra.c            |  4 ++--
>>  gcc/tree-ssa-ccp.c        |  8 ++------
>>  gcc/tree-ssa-dom.c        |  4 +---
>>  gcc/tree-ssa-loop-im.c    |  4 +---
>>  gcc/tree-stdarg.c         |  6 ++----
>>  gcc/tree.h                |  4 +++-
>>  24 files changed, 56 insertions(+), 101 deletions(-)
>>
>>
>
From 257e63dcd53f218fc08e91f0f4961ea2b46e3e1d Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 10 Aug 2018 13:29:48 +0200
Subject: [PATCH] Use new macros: DECL_FE_BUILT_IN_P and
 DECL_NORMAL_BUILT_IN_P.

gcc/ChangeLog:

2018-08-10  Martin Liska  <mliska@suse.cz>

	* tree.h (DECL_BUILT_IN_P): Add also check
        for TREE_CODE (NODE) == FUNCTION_DECL.
	(DECL_NORMAL_BUILT_IN_P): New macro.
	(DECL_FE_BUILT_IN_P): Likewise.
	* builtins.c (fold_call_expr): Use DECL_{NORMAL,FE}_BUILT_IN_P macro.
	(fold_builtin_call_array): Likewise.
	* cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
	(cgraph_edge::verify_corresponds_to_fndecl): Likewise.
	(cgraph_node::verify_node): Likewise.
	* cgraphclones.c (cgraph_node::create_clone): Likewise.
	* dse.c (scan_insn): Likewise.
	* fold-const.c (fold_binary_loc): Likewise.
	* gimple-pretty-print.c (dump_gimple_call): Likewise.
	* gimple.c (gimple_call_builtin_p): Likewise.
	* gimplify.c (gimplify_call_expr): Likewise.
	(gimple_boolify): Likewise.
	(gimplify_modify_expr): Likewise.
	* ipa-fnsummary.c (compute_fn_summary): Likewise.
	* omp-low.c (setjmp_or_longjmp_p): Likewise.
	* trans-mem.c (is_tm_irrevocable): Likewise.
	(is_tm_abort): Likewise.
	* tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
	* tree-inline.c (copy_bb): Likewise.
	* tree-sra.c (scan_function): Likewise.
	* tree-ssa-ccp.c (optimize_stack_restore): Likewise.
	(pass_fold_builtins::execute): Likewise.
	* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
	* tree-ssa-loop-im.c (stmt_cost): Likewise.
	* tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.

gcc/c/ChangeLog:

2018-08-10  Martin Liska  <mliska@suse.cz>

	* c-parser.c (c_parser_postfix_expression_after_primary):
        Use DECL_{NORMAL,FE}_BUILT_IN_P macro.

gcc/cp/ChangeLog:

2018-08-10  Martin Liska  <mliska@suse.cz>

	* constexpr.c (constexpr_fn_retval):
        Use DECL_{NORMAL,FE}_BUILT_IN_P macro.
	(cxx_eval_builtin_function_call): Likewise.
	* cp-gimplify.c (cp_gimplify_expr): Likewise.
	(cp_fold): Likewise.
	* semantics.c (finish_call_expr): Likewise.
	* tree.c (builtin_valid_in_constant_expr_p): Likewise.
---
 gcc/builtins.c            | 16 +++++-----------
 gcc/c/c-parser.c          |  8 ++------
 gcc/cgraph.c              | 13 ++++++-------
 gcc/cgraphclones.c        |  3 +--
 gcc/cp/constexpr.c        | 10 +++-------
 gcc/cp/cp-gimplify.c      | 10 ++--------
 gcc/cp/semantics.c        |  4 +---
 gcc/cp/tree.c             |  4 +---
 gcc/dse.c                 |  4 +---
 gcc/fold-const.c          |  4 +---
 gcc/gimple-pretty-print.c |  4 +---
 gcc/gimple.c              |  3 +--
 gcc/gimplify.c            | 13 +++----------
 gcc/ipa-fnsummary.c       |  6 ++----
 gcc/omp-low.c             |  5 ++---
 gcc/predict.c             |  6 +++---
 gcc/trans-mem.c           |  8 ++------
 gcc/tree-cfg.c            |  3 +--
 gcc/tree-inline.c         |  4 ++--
 gcc/tree-sra.c            |  4 ++--
 gcc/tree-ssa-ccp.c        |  8 ++------
 gcc/tree-ssa-dom.c        |  4 +---
 gcc/tree-ssa-loop-im.c    |  4 +---
 gcc/tree-stdarg.c         |  6 ++----
 gcc/tree.h                | 14 +++++++++++++-
 25 files changed, 61 insertions(+), 107 deletions(-)

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 867d153d798..569651807a2 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -8298,9 +8298,9 @@ fold_builtin_expect (location_t loc, tree arg0, tree arg1, tree arg2,
 
   if (TREE_CODE (inner) == CALL_EXPR
       && (fndecl = get_callee_fndecl (inner))
-      && (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
-	  || DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL,
-			      BUILT_IN_EXPECT_WITH_PROBABILITY)))
+      && (DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_EXPECT)
+	  || DECL_NORMAL_BUILT_IN_P (fndecl,
+				     BUILT_IN_EXPECT_WITH_PROBABILITY)))
     return arg0;
 
   inner = inner_arg0;
@@ -9629,10 +9629,7 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (DECL_NORMAL_BUILT_IN_P (fndecl2, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
 
@@ -9675,10 +9672,7 @@ fold_builtin_call_array (location_t loc, tree,
       if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (DECL_NORMAL_BUILT_IN_P (fndecl2, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
       if (avoid_folding_inline_builtin (fndecl))
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 5ad4f57a4fe..885efda172e 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -9168,9 +9168,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 					      expr.value, exprlist,
 					      sizeof_arg,
 					      sizeof_ptr_memacc_comptypes);
-	  if (TREE_CODE (expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (expr.value) == BUILT_IN_MEMSET
+	  if (DECL_NORMAL_BUILT_IN_P (expr.value, BUILT_IN_MEMSET)
 	      && vec_safe_length (exprlist) == 3)
 	    {
 	      tree arg0 = (*exprlist)[0];
@@ -9187,9 +9185,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 
 	  expr.original_code = ERROR_MARK;
 	  if (TREE_CODE (expr.value) == INTEGER_CST
-	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
+	      && DECL_NORMAL_BUILT_IN_P (orig_expr.value, BUILT_IN_CONSTANT_P))
 	    expr.original_code = C_MAYBE_CONST_EXPR;
 	  expr.original_type = NULL;
 	  if (exprlist)
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d19f1aacab8..b3a1dd7d85d 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1559,8 +1559,8 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
 	{
 	  /* Keep calls marked as dead dead.  */
 	  if (new_stmt && is_gimple_call (new_stmt) && e->callee
-	      && DECL_BUILT_IN_CLASS (e->callee->decl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (e->callee->decl) == BUILT_IN_UNREACHABLE)
+	      && DECL_NORMAL_BUILT_IN_P (e->callee->decl,
+					 BUILT_IN_UNREACHABLE))
 	    {
               node->get_edge (old_stmt)->set_call_stmt
 		 (as_a <gcall *> (new_stmt));
@@ -3060,8 +3060,8 @@ cgraph_edge::verify_corresponds_to_fndecl (tree decl)
 
   /* Optimizers can redirect unreachable calls or calls triggering undefined
      behavior to builtin_unreachable.  */
-  if (DECL_BUILT_IN_CLASS (callee->decl) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (callee->decl) == BUILT_IN_UNREACHABLE)
+
+  if (DECL_NORMAL_BUILT_IN_P (callee->decl, BUILT_IN_UNREACHABLE))
     return false;
 
   if (callee->former_clone_of != node->decl
@@ -3186,9 +3186,8 @@ cgraph_node::verify_node (void)
 	  && !e->speculative
 	  /* Optimized out calls are redirected to __builtin_unreachable.  */
 	  && (e->count.nonzero_p ()
-	      || ! e->callee->decl
-	      || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	      || !DECL_NORMAL_BUILT_IN_P (e->callee->decl,
+					  BUILT_IN_UNREACHABLE))
 	  && count
 	      == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
 	  && (!e->count.ipa_p ()
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 6e84a31c1a5..ed353d2c060 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -482,8 +482,7 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count,
 	 version.  The only exception is when the edge was proved to
 	 be unreachable during the clonning procedure.  */
       if (!e->callee
-	  || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	  || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	  || !DECL_NORMAL_BUILT_IN_P (e->callee->decl, BUILT_IN_UNREACHABLE))
         e->redirect_callee_duplicating_thunks (new_node);
     }
   new_node->expand_all_artificial_thunks ();
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index ece2c8a92d9..c41ca019c14 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -712,9 +712,7 @@ constexpr_fn_retval (tree body)
     case CALL_EXPR:
 	{
 	  tree fun = get_function_named_in_call (body);
-	  if (fun != NULL_TREE
-	      && DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+	  if (DECL_NORMAL_BUILT_IN_P (fun, BUILT_IN_UNREACHABLE))
 	    return NULL_TREE;
 	}
       /* Fallthru.  */
@@ -1189,8 +1187,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 
   /* For __builtin_is_constant_evaluated, defer it if not
      ctx->pretend_const_required, otherwise fold it to true.  */
-  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_FRONTEND
-      && (int) DECL_FUNCTION_CODE (fun) == CP_BUILT_IN_IS_CONSTANT_EVALUATED)
+  if (DECL_FE_BUILT_IN_P (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED))
     {
       if (!ctx->pretend_const_required)
 	{
@@ -1233,8 +1230,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 	  /* Do not allow__builtin_unreachable in constexpr function.
 	     The __builtin_unreachable call with BUILTINS_LOCATION
 	     comes from cp_maybe_instrument_return.  */
-	  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+	  if (DECL_NORMAL_BUILT_IN_P (fun, BUILT_IN_UNREACHABLE)
 	      && EXPR_LOCATION (t) == BUILTINS_LOCATION)
 	    error ("%<constexpr%> call flows off the end of the function");
 	  else
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 7db4accb504..bd6acc9523f 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -796,10 +796,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (ret != GS_ERROR)
 	{
 	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
-	  if (decl
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	      && ((int) DECL_FUNCTION_CODE (decl)
-		  == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	  if (DECL_FE_BUILT_IN_P (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED))
 	    *expr_p = boolean_false_node;
 	}
       break;
@@ -2493,10 +2490,7 @@ cp_fold (tree x)
 	  nw = 1;
 
 	/* Defer folding __builtin_is_constant_evaluated.  */
-	if (callee
-	    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_FRONTEND
-	    && ((int) DECL_FUNCTION_CODE (callee)
-		== CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	if (DECL_FE_BUILT_IN_P (callee,  CP_BUILT_IN_IS_CONSTANT_EVALUATED))
 	  break;
 
 	x = copy_node (x);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bfdca5024d3..e3bafe58e4a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2545,9 +2545,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 	    }
 
 	  if ((complain & tf_warning)
-	      && TREE_CODE (fn) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fn) == BUILT_IN_MEMSET
+	      && DECL_NORMAL_BUILT_IN_P (fn, BUILT_IN_MEMSET)
 	      && vec_safe_length (*args) == 3
 	      && !any_type_dependent_arguments_p (*args))
 	    {
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 1cf3269d880..48508a17c1d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -420,9 +420,7 @@ builtin_valid_in_constant_expr_p (const_tree decl)
     return false;
   if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
     {
-      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	  && ((int) DECL_FUNCTION_CODE (decl)
-	      == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+      if (DECL_FE_BUILT_IN_P (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED))
 	return true;
       /* Not a built-in.  */
       return false;
diff --git a/gcc/dse.c b/gcc/dse.c
index 26c6007b9ed..228cb8606da 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2418,9 +2418,7 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn)
 	  && (sym = XEXP (XEXP (call, 0), 0))
 	  && GET_CODE (sym) == SYMBOL_REF
 	  && SYMBOL_REF_DECL (sym)
-	  && TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (sym)) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (sym)) == BUILT_IN_MEMSET)
+	  && DECL_NORMAL_BUILT_IN_P (SYMBOL_REF_DECL (sym), BUILT_IN_MEMSET))
 	memset_call = SYMBOL_REF_DECL (sym);
 
       if (const_call || memset_call)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b318fc7705f..a9c48fbad81 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10752,9 +10752,7 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
 	{
 	  tree fndecl = get_callee_fndecl (arg0);
 
-	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
+	  if (DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_STRLEN)
 	      && call_expr_nargs (arg0) == 1
 	      && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0))) == POINTER_TYPE)
 	    {
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d3c5ec6f79b..e2eb0cdab0b 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -910,9 +910,7 @@ dump_gimple_call (pretty_printer *buffer, gcall *gs, int spc,
     fn = TREE_OPERAND (fn, 0);
   if (TREE_CODE (fn) == FUNCTION_DECL && decl_is_tm_clone (fn))
     pp_string (buffer, " [tm-clone]");
-  if (TREE_CODE (fn) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_START
+  if (DECL_NORMAL_BUILT_IN_P (fn, BUILT_IN_TM_START)
       && gimple_call_num_args (gs) > 0)
     {
       tree t = gimple_call_arg (gs, 0);
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 8d56a966cc1..a90551b420a 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2681,8 +2681,7 @@ gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
   tree fndecl;
   if (is_gimple_call (stmt)
       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 
-      && DECL_FUNCTION_CODE (fndecl) == code)
+      && DECL_NORMAL_BUILT_IN_P (fndecl, code))
     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
   return false;
 }
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4a109aee27a..ed62241d823 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3295,10 +3295,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
       tree last_arg_fndecl = get_callee_fndecl (last_arg);
 
-      if (last_arg_fndecl
-	  && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
+      if (DECL_NORMAL_BUILT_IN_P (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
 	{
 	  tree call = *expr_p;
 
@@ -3771,9 +3768,7 @@ gimple_boolify (tree expr)
 
       /* For __builtin_expect ((long) (x), y) recurse into x as well
 	 if x is truth_value_p.  */
-      if (fn
-	  && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
+      if (DECL_NORMAL_BUILT_IN_P (fn, BUILT_IN_EXPECT)
 	  && call_expr_nargs (call) == 2)
 	{
 	  tree arg = CALL_EXPR_ARG (call, 0);
@@ -5717,9 +5712,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
 	  STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
 	  tree fndecl = get_callee_fndecl (*from_p);
-	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+	  if (DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_EXPECT)
 	      && call_expr_nargs (*from_p) == 3)
 	    call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
 						    CALL_EXPR_ARG (*from_p, 0),
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..8c4e3a48ae4 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2455,10 +2455,8 @@ compute_fn_summary (struct cgraph_node *node, bool early)
 	       for (e = node->callees; e; e = e->next_callee)
 		 {
 		   tree cdecl = e->callee->decl;
-		   if (DECL_BUILT_IN (cdecl)
-		       && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
-		       && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
-			   || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
+		   if (DECL_NORMAL_BUILT_IN_P (cdecl, BUILT_IN_APPLY_ARGS)
+		       || DECL_NORMAL_BUILT_IN_P (cdecl, BUILT_IN_VA_START))
 		     break;
 		 }
 	       node->local.can_change_signature = !e;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 843c66fd221..8aa72c1092f 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2975,9 +2975,8 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
 static bool
 setjmp_or_longjmp_p (const_tree fndecl)
 {
-  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
-	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+  if (DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_SETJMP)
+      || DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_LONGJMP))
     return true;
 
   tree declname = DECL_NAME (fndecl);
diff --git a/gcc/predict.c b/gcc/predict.c
index 3fbe3b704b3..7d511717fa8 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -3991,10 +3991,10 @@ strip_predict_hints (function *fun, bool early)
 	      tree fndecl = gimple_call_fndecl (stmt);
 
 	      if (!early
-		  && ((DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
+		  && ((DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_EXPECT)
 		       && gimple_call_num_args (stmt) == 2)
-		      || (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL,
-					   BUILT_IN_EXPECT_WITH_PROBABILITY)
+		      || (DECL_NORMAL_BUILT_IN_P (fndecl,
+						  BUILT_IN_EXPECT_WITH_PROBABILITY)
 			  && gimple_call_num_args (stmt) == 3)
 		      || (gimple_call_internal_p (stmt)
 			  && gimple_call_internal_fn (stmt) == IFN_BUILTIN_EXPECT)))
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ca14915ef0d..b171bf91366 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -234,9 +234,7 @@ is_tm_irrevocable (tree x)
      irrevocable.  */
   if (TREE_CODE (x) == ADDR_EXPR)
     x = TREE_OPERAND (x, 0);
-  if (TREE_CODE (x) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
+  if (DECL_NORMAL_BUILT_IN_P (x, BUILT_IN_TM_IRREVOCABLE))
     return true;
 
   return false;
@@ -440,9 +438,7 @@ is_tm_simple_store (gimple *stmt)
 static bool
 is_tm_abort (tree fndecl)
 {
-  return (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
+  return DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_TM_ABORT);
 }
 
 /* Build a GENERIC tree for a user abort.  This is called by front ends
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 14d66b7a728..74adc39f475 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -8312,8 +8312,7 @@ stmt_can_terminate_bb_p (gimple *t)
          wrapping it in __gcov_fork() which calls __gcov_flush()
 	 and clears the counters before forking has the same
 	 effect as returning twice.  Force a fake edge.  */
-      && !(DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	   && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FORK))
+      && !DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_FORK))
     return false;
 
   if (is_gimple_call (t))
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6a16ce546cb..cfad4d909c6 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1939,8 +1939,8 @@ copy_bb (copy_body_data *id, basic_block bb,
 	  else if (call_stmt
 		   && id->call_stmt
 		   && (decl = gimple_call_fndecl (stmt))
-		   && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-		   && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN
+		   && DECL_NORMAL_BUILT_IN_P (decl,
+					      BUILT_IN_VA_ARG_PACK_LEN)
 		   && ! gimple_call_va_arg_pack_p (id->call_stmt))
 	    {
 	      /* __builtin_va_arg_pack_len () should be replaced by
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 3e30f6bc3d4..03ec5e092cd 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1498,8 +1498,8 @@ scan_function (void)
 
 		  if (dest)
 		    {
-		      if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
-			  && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
+		      if (DECL_NORMAL_BUILT_IN_P (dest,
+						  BUILT_IN_APPLY_ARGS))
 			encountered_apply_args = true;
 		      if (recursive_call_p (current_function_decl, dest))
 			{
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 63c95318ace..e657c26cbfa 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2596,9 +2596,7 @@ optimize_stack_restore (gimple_stmt_iterator i)
       if (is_gimple_call (stack_save))
 	{
 	  callee = gimple_call_fndecl (stack_save);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
+	  if (DECL_NORMAL_BUILT_IN_P (callee, BUILT_IN_STACK_SAVE))
 	    {
 	      gimple_stmt_iterator stack_save_gsi;
 	      tree rhs;
@@ -3369,9 +3367,7 @@ pass_fold_builtins::execute (function *fun)
 	      continue;
 	    }
 	  callee = gimple_call_fndecl (stmt);
-	  if (!callee
-              || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (callee) == fcode)
+	  if (!DECL_NORMAL_BUILT_IN_P (callee, fcode))
 	    gsi_next (&i);
 	}
     }
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 267880f3b5c..e015e1db635 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1985,9 +1985,7 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
 	     folded to integer_one_node by now, it's fairly
 	     certain that the value simply isn't constant.  */
 	  tree callee = gimple_call_fndecl (stmt);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
+	  if (DECL_NORMAL_BUILT_IN_P (callee, BUILT_IN_CONSTANT_P))
 	    {
 	      propagate_tree_value_into_stmt (&si, integer_zero_node);
 	      stmt = gsi_stmt (si);
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 01a954eeb1e..d03fc5786e6 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -471,9 +471,7 @@ stmt_cost (gimple *stmt)
       /* Unless the call is a builtin_constant_p; this always folds to a
 	 constant, so moving it is useless.  */
       fndecl = gimple_call_fndecl (stmt);
-      if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
+      if (DECL_NORMAL_BUILT_IN_P (fndecl, BUILT_IN_CONSTANT_P))
 	return 0;
 
       return LIM_EXPENSIVE;
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index c8594851957..734f5c31c2f 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -866,10 +866,8 @@ optimize_va_list_gpr_fpr_size (function *fun)
 	    {
 	      tree callee = gimple_call_fndecl (stmt);
 
-	      if (callee
-		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-		  && (DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_START
-		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END))
+	      if (DECL_NORMAL_BUILT_IN_P (callee, BUILT_IN_VA_START)
+		  || DECL_NORMAL_BUILT_IN_P (callee, BUILT_IN_VA_END))
 		continue;
 	    }
 
diff --git a/gcc/tree.h b/gcc/tree.h
index 648e9e2a3c4..a7959eaaaeb 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3011,9 +3011,21 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
 /* For a function declaration, return true if NODE is non-null and it is
    a builtin of a CLASS with requested NAME.  */
 #define DECL_BUILT_IN_P(NODE, CLASS, NAME) \
-  (NODE != NULL_TREE && DECL_BUILT_IN_CLASS (NODE) == CLASS \
+  (NODE != NULL_TREE \
+   && TREE_CODE (NODE) == FUNCTION_DECL \
+   && DECL_BUILT_IN_CLASS (NODE) == CLASS \
    && DECL_FUNCTION_CODE (NODE) == NAME)
 
+/* For a function declaration, return true if NODE is non-null and it is
+   a builtin of a BUILT_IN_NORMAL class with requested NAME.  */
+#define DECL_NORMAL_BUILT_IN_P(NODE, NAME) \
+  DECL_BUILT_IN_P (NODE, BUILT_IN_NORMAL, NAME)
+
+/* For a function declaration, return true if NODE is non-null and it is
+   a builtin of a BUILT_IN_FRONTEND class with requested NAME.  */
+#define DECL_FE_BUILT_IN_P(NODE, NAME) \
+  DECL_BUILT_IN_P (NODE, BUILT_IN_FRONTEND, NAME)
+
 /* In FUNCTION_DECL, a chain of ..._DECL nodes.  */
 #define DECL_ARGUMENTS(NODE) \
    (FUNCTION_DECL_CHECK (NODE)->function_decl.arguments)
Richard Biener Aug. 20, 2018, 8:34 a.m. UTC | #3
On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 08/14/2018 06:02 PM, Martin Sebor wrote:
> > On 08/14/2018 03:06 AM, Martin Liška wrote:
> >> Hi.
> >>
> >> The patch adds more usages of the new macro. I hope it improves
> >> readability of code.
> >
> > I think it does :)  I see that most invocations of it in your
> > patch are with BUILT_IN_NORMAL as the second argument.  Is
> > the argument implied by the last argument?  E.g., in
> >
> >   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
> >
> > is there a way to determine that BUILT_IN_VA_ARG_PACK implies
> > DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
> > be eliminated?  (Both to make the invocation less verbose and
> > to avoid the mistake of using the macro with the wrong class.)
>
> If I see correctly not, there are separate enums:
>
> BUILT_IN_MD:
>
> enum ix86_builtins {
>   IX86_BUILTIN_MASKMOVQ,
>   IX86_BUILTIN_LDMXCSR,
>   IX86_BUILTIN_STMXCSR,
> ...
> }
>
> BUILT_IN_NORMAL:
> enum built_in_function {
> BUILT_IN_NONE,
> BUILT_IN_ACOS,
> BUILT_IN_ACOSF,
> ...
> }
>
> So the enum values overlap and thus one needs the class.
>
>
> >
> > If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
> > to omit it.
>
> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
> right now.

Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).

I think following what gimple.h does would be nicer which means using
inline functions and overloading.

decl_built_in_p (tree);
decl_built_in_p (tree, enum built_in_class);
decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL

Can you rework things this way please?  (ok, for gimple those are not inlines)

Thanks,
Richard.

> Martin
>
> >
> > Martin
> >
> >>
> >> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> >>
> >> Ready to be installed?
> >> Martin
> >>
> >> gcc/ChangeLog:
> >>
> >> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>
> >>     * tree.h (DECL_BUILT_IN_P): Add also check
> >>         for TREE_CODE (NODE) == FUNCTION_DECL.
> >>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
> >>     (fold_builtin_call_array): Likewise.
> >>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
> >>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
> >>     (cgraph_node::verify_node): Likewise.
> >>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
> >>     * dse.c (scan_insn): Likewise.
> >>     * fold-const.c (fold_binary_loc): Likewise.
> >>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
> >>     * gimple.c (gimple_call_builtin_p): Likewise.
> >>     * gimplify.c (gimplify_call_expr): Likewise.
> >>     (gimple_boolify): Likewise.
> >>     (gimplify_modify_expr): Likewise.
> >>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
> >>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
> >>     * trans-mem.c (is_tm_irrevocable): Likewise.
> >>     (is_tm_abort): Likewise.
> >>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
> >>     * tree-inline.c (copy_bb): Likewise.
> >>     * tree-sra.c (scan_function): Likewise.
> >>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
> >>     (pass_fold_builtins::execute): Likewise.
> >>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
> >>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
> >>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
> >>
> >> gcc/c/ChangeLog:
> >>
> >> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>
> >>     * c-parser.c (c_parser_postfix_expression_after_primary):
> >>         Use DECL_BUILT_IN_P macro.
> >>
> >> gcc/cp/ChangeLog:
> >>
> >> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>
> >>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
> >>     (cxx_eval_builtin_function_call): Likewise.
> >>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
> >>     (cp_fold): Likewise.
> >>     * semantics.c (finish_call_expr): Likewise.
> >>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
> >> ---
> >>  gcc/builtins.c            | 10 ++--------
> >>  gcc/c/c-parser.c          |  9 +++------
> >>  gcc/cgraph.c              | 13 ++++++-------
> >>  gcc/cgraphclones.c        |  4 ++--
> >>  gcc/cp/constexpr.c        | 12 +++++-------
> >>  gcc/cp/cp-gimplify.c      | 12 ++++--------
> >>  gcc/cp/semantics.c        |  4 +---
> >>  gcc/cp/tree.c             |  5 ++---
> >>  gcc/dse.c                 |  5 ++---
> >>  gcc/fold-const.c          |  4 +---
> >>  gcc/gimple-pretty-print.c |  4 +---
> >>  gcc/gimple.c              |  3 +--
> >>  gcc/gimplify.c            | 14 ++++----------
> >>  gcc/ipa-fnsummary.c       |  8 ++++----
> >>  gcc/omp-low.c             |  5 ++---
> >>  gcc/trans-mem.c           |  8 ++------
> >>  gcc/tree-cfg.c            |  3 +--
> >>  gcc/tree-inline.c         |  4 ++--
> >>  gcc/tree-sra.c            |  4 ++--
> >>  gcc/tree-ssa-ccp.c        |  8 ++------
> >>  gcc/tree-ssa-dom.c        |  4 +---
> >>  gcc/tree-ssa-loop-im.c    |  4 +---
> >>  gcc/tree-stdarg.c         |  6 ++----
> >>  gcc/tree.h                |  4 +++-
> >>  24 files changed, 56 insertions(+), 101 deletions(-)
> >>
> >>
> >
>
Martin Liška Aug. 23, 2018, 10:46 a.m. UTC | #4
On 08/20/2018 10:34 AM, Richard Biener wrote:
> On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 08/14/2018 06:02 PM, Martin Sebor wrote:
>>> On 08/14/2018 03:06 AM, Martin Liška wrote:
>>>> Hi.
>>>>
>>>> The patch adds more usages of the new macro. I hope it improves
>>>> readability of code.
>>>
>>> I think it does :)  I see that most invocations of it in your
>>> patch are with BUILT_IN_NORMAL as the second argument.  Is
>>> the argument implied by the last argument?  E.g., in
>>>
>>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
>>>
>>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
>>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
>>> be eliminated?  (Both to make the invocation less verbose and
>>> to avoid the mistake of using the macro with the wrong class.)
>>
>> If I see correctly not, there are separate enums:
>>
>> BUILT_IN_MD:
>>
>> enum ix86_builtins {
>>   IX86_BUILTIN_MASKMOVQ,
>>   IX86_BUILTIN_LDMXCSR,
>>   IX86_BUILTIN_STMXCSR,
>> ...
>> }
>>
>> BUILT_IN_NORMAL:
>> enum built_in_function {
>> BUILT_IN_NONE,
>> BUILT_IN_ACOS,
>> BUILT_IN_ACOSF,
>> ...
>> }
>>
>> So the enum values overlap and thus one needs the class.
>>
>>
>>>
>>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
>>> to omit it.
>>
>> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
>> right now.
> 
> Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
> and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).

Agree.

> 
> I think following what gimple.h does would be nicer which means using
> inline functions and overloading.
> 
> decl_built_in_p (tree);
> decl_built_in_p (tree, enum built_in_class);
> decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL

Yes, that's easier to use!

> 
> Can you rework things this way please?  (ok, for gimple those are not inlines)

Done in patch that can bootstrap and survives regression tests.
Ready for trunk?

Martin 

> 
> Thanks,
> Richard.
> 
>> Martin
>>
>>>
>>> Martin
>>>
>>>>
>>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>>>
>>>> Ready to be installed?
>>>> Martin
>>>>
>>>> gcc/ChangeLog:
>>>>
>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>
>>>>     * tree.h (DECL_BUILT_IN_P): Add also check
>>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
>>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
>>>>     (fold_builtin_call_array): Likewise.
>>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
>>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
>>>>     (cgraph_node::verify_node): Likewise.
>>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
>>>>     * dse.c (scan_insn): Likewise.
>>>>     * fold-const.c (fold_binary_loc): Likewise.
>>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
>>>>     * gimple.c (gimple_call_builtin_p): Likewise.
>>>>     * gimplify.c (gimplify_call_expr): Likewise.
>>>>     (gimple_boolify): Likewise.
>>>>     (gimplify_modify_expr): Likewise.
>>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
>>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
>>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
>>>>     (is_tm_abort): Likewise.
>>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
>>>>     * tree-inline.c (copy_bb): Likewise.
>>>>     * tree-sra.c (scan_function): Likewise.
>>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
>>>>     (pass_fold_builtins::execute): Likewise.
>>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
>>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
>>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
>>>>
>>>> gcc/c/ChangeLog:
>>>>
>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>
>>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
>>>>         Use DECL_BUILT_IN_P macro.
>>>>
>>>> gcc/cp/ChangeLog:
>>>>
>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>
>>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
>>>>     (cxx_eval_builtin_function_call): Likewise.
>>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
>>>>     (cp_fold): Likewise.
>>>>     * semantics.c (finish_call_expr): Likewise.
>>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
>>>> ---
>>>>  gcc/builtins.c            | 10 ++--------
>>>>  gcc/c/c-parser.c          |  9 +++------
>>>>  gcc/cgraph.c              | 13 ++++++-------
>>>>  gcc/cgraphclones.c        |  4 ++--
>>>>  gcc/cp/constexpr.c        | 12 +++++-------
>>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
>>>>  gcc/cp/semantics.c        |  4 +---
>>>>  gcc/cp/tree.c             |  5 ++---
>>>>  gcc/dse.c                 |  5 ++---
>>>>  gcc/fold-const.c          |  4 +---
>>>>  gcc/gimple-pretty-print.c |  4 +---
>>>>  gcc/gimple.c              |  3 +--
>>>>  gcc/gimplify.c            | 14 ++++----------
>>>>  gcc/ipa-fnsummary.c       |  8 ++++----
>>>>  gcc/omp-low.c             |  5 ++---
>>>>  gcc/trans-mem.c           |  8 ++------
>>>>  gcc/tree-cfg.c            |  3 +--
>>>>  gcc/tree-inline.c         |  4 ++--
>>>>  gcc/tree-sra.c            |  4 ++--
>>>>  gcc/tree-ssa-ccp.c        |  8 ++------
>>>>  gcc/tree-ssa-dom.c        |  4 +---
>>>>  gcc/tree-ssa-loop-im.c    |  4 +---
>>>>  gcc/tree-stdarg.c         |  6 ++----
>>>>  gcc/tree.h                |  4 +++-
>>>>  24 files changed, 56 insertions(+), 101 deletions(-)
>>>>
>>>>
>>>
>>
From 471151776904ed3f5182375d5258fa644024951b Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 10 Aug 2018 13:29:48 +0200
Subject: [PATCH] Add decl_built_in_p functions.

gcc/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* attribs.c (diag_attr_exclusions): Use decl_built_in_p
        functions.
	* builtins.c (is_builtin_fn): Likewise.
	(builtin_mathfn_code): Likewise.
	(fold_builtin_expect): Likewise.
	(fold_call_expr): Likewise.
	(fold_builtin_call_array): Likewise.
	(fold_call_stmt): Likewise.
	(set_builtin_user_assembler_name): Likewise.
	(is_simple_builtin): Likewise.
	* builtins.h (is_builtin_fn): Likewise.
	* calls.c (gimple_alloca_call_p): Likewise.
	(maybe_warn_nonstring_arg): Likewise.
	* cfgexpand.c (expand_call_stmt): Likewise.
	* cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
	(cgraph_edge::verify_corresponds_to_fndecl): Likewise.
	(cgraph_node::verify_node): Likewise.
	* cgraphclones.c (build_function_decl_skip_args): Likewise.
	(cgraph_node::create_clone): Likewise.
	* config/i386/i386.c (ix86_gimple_fold_builtin): Likewise.
	* dse.c (scan_insn): Likewise.
	* expr.c (expand_expr_real_1): Likewise.
	* fold-const.c (operand_equal_p): Likewise.
	(fold_binary_loc): Likewise.
	* gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
	* gimple-low.c (lower_stmt): Likewise.
	* gimple-pretty-print.c (dump_gimple_call): Likewise.
	* gimple-ssa-warn-restrict.c (wrestrict_dom_walker::check_call): Likewise.
	* gimple.c (gimple_build_call_from_tree): Likewise.
	(gimple_call_builtin_p): Likewise.
	(gimple_call_combined_fn): Likewise.
	* gimplify.c (gimplify_call_expr): Likewise.
	(gimple_boolify): Likewise.
	(gimplify_modify_expr): Likewise.
	(gimplify_addr_expr): Likewise.
	* hsa-gen.c (gen_hsa_insns_for_call): Likewise.
	* ipa-cp.c (determine_versionability): Likewise.
	* ipa-fnsummary.c (compute_fn_summary): Likewise.
	* ipa-param-manipulation.c (ipa_modify_formal_parameters): Likewise.
	* ipa-split.c (visit_bb): Likewise.
	(split_function): Likewise.
	* ipa-visibility.c (cgraph_externally_visible_p): Likewise.
	* lto-cgraph.c (input_node): Likewise.
	* lto-streamer-out.c (write_symbol): Likewise.
	* omp-low.c (setjmp_or_longjmp_p): Likewise.
	(lower_omp_1): Likewise.
	* predict.c (strip_predict_hints): Likewise.
	* print-tree.c (print_node): Likewise.
	* symtab.c (symtab_node::output_to_lto_symbol_table_p): Likewise.
	* trans-mem.c (is_tm_irrevocable): Likewise.
	(is_tm_load): Likewise.
	(is_tm_simple_load): Likewise.
	(is_tm_store): Likewise.
	(is_tm_simple_store): Likewise.
	(is_tm_abort): Likewise.
	(tm_region_init_1): Likewise.
	* tree-call-cdce.c (gen_shrink_wrap_conditions): Likewise.
	* tree-cfg.c (verify_gimple_call): Likewise.
	(move_stmt_r): Likewise.
	(stmt_can_terminate_bb_p): Likewise.
	* tree-eh.c (lower_eh_constructs_2): Likewise.
	* tree-if-conv.c (if_convertible_stmt_p): Likewise.
	* tree-inline.c (remap_gimple_stmt): Likewise.
	(copy_bb): Likewise.
	(estimate_num_insns): Likewise.
	(fold_marked_statements): Likewise.
	* tree-sra.c (scan_function): Likewise.
	* tree-ssa-ccp.c (surely_varying_stmt_p): Likewise.
	(optimize_stack_restore): Likewise.
	(pass_fold_builtins::execute): Likewise.
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
	(mark_all_reaching_defs_necessary_1): Likewise.
	* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
	* tree-ssa-forwprop.c (simplify_builtin_call): Likewise.
	(pass_forwprop::execute): Likewise.
	* tree-ssa-loop-im.c (stmt_cost): Likewise.
	* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
	* tree-ssa-sccvn.c (fully_constant_vn_reference_p): Likewise.
	* tree-ssa-strlen.c (get_string_length): Likewise.
	* tree-ssa-structalias.c (handle_lhs_call): Likewise.
	(find_func_aliases_for_call): Likewise.
	* tree-ssa-ter.c (find_replaceable_in_bb): Likewise.
	* tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
	* tree-tailcall.c (find_tail_calls): Likewise.
	* tree.c (need_assembler_name_p): Likewise.
	(free_lang_data_in_decl): Likewise.
	(get_call_combined_fn): Likewise.
	* ubsan.c (is_ubsan_builtin_p): Likewise.
	* varasm.c (incorporeal_function_p): Likewise.
	* tree.h (DECL_BUILT_IN): Remove it.
	(DECL_BUILT_IN_P): Likewise.
	(decl_built_in_p): Replace it with 3 new functions.

gcc/ada/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* gcc-interface/gigi.h (call_is_atomic_load):
        Use decl_built_in_p functions.

gcc/c-family/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* c-common.c (check_function_restrict):
        Use decl_built_in_p functions.
	(check_builtin_function_arguments): Likewise.
	(reject_gcc_builtin): Likewise.
	* c-warn.c (sizeof_pointer_memaccess_warning): Likewise.

gcc/c/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* c-decl.c (locate_old_decl):
        Use decl_built_in_p functions.
	(diagnose_mismatched_decls): Likewise.
	(merge_decls): Likewise.
	(warn_if_shadowing): Likewise.
	(pushdecl): Likewise.
	(implicitly_declare): Likewise.
	* c-parser.c (c_parser_postfix_expression_after_primary): Likewise.
	* c-tree.h (C_DECL_ISNT_PROTOTYPE): Likewise.
	* c-typeck.c (build_function_call_vec): Likewise.
	(convert_arguments): Likewise.

gcc/cp/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* call.c (build_call_a):
        Use decl_built_in_p functions.
	(build_cxx_call): Likewise.
	* constexpr.c (constexpr_fn_retval): Likewise.
	(cxx_eval_builtin_function_call): Likewise.
	(cxx_eval_call_expression): Likewise.
	(potential_constant_expression_1): Likewise.
	* cp-gimplify.c (cp_gimplify_expr): Likewise.
	(cp_fold): Likewise.
	* decl.c (decls_match): Likewise.
	(validate_constexpr_redeclaration): Likewise.
	(duplicate_decls): Likewise.
	(make_rtl_for_nonlocal_decl): Likewise.
	* name-lookup.c (consider_binding_level): Likewise.
	(cp_emit_debug_info_for_using): Likewise.
	* semantics.c (finish_call_expr): Likewise.
	* tree.c (builtin_valid_in_constant_expr_p): Likewise.

gcc/go/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* go-gcc.cc (Gcc_backend::call_expression):
        Use decl_built_in_p functions.

gcc/lto/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* lto-lang.c (handle_const_attribute):
        Use decl_built_in_p functions.
	* lto-symtab.c (lto_symtab_merge_p): Likewise.
	(lto_symtab_merge_decls_1): Likewise.
	(lto_symtab_merge_symbols): Likewise.
	* lto.c (lto_maybe_register_decl): Likewise.
	(read_cgraph_and_symbols): Likewise.
---
 gcc/ada/gcc-interface/gigi.h   |  2 +-
 gcc/attribs.c                  |  2 +-
 gcc/builtins.c                 | 47 ++++++++------------------------
 gcc/builtins.h                 |  1 -
 gcc/c-family/c-common.c        |  9 ++----
 gcc/c-family/c-warn.c          |  3 +-
 gcc/c/c-decl.c                 | 29 ++++++++------------
 gcc/c/c-parser.c               |  8 ++----
 gcc/c/c-tree.h                 |  2 +-
 gcc/c/c-typeck.c               |  7 ++---
 gcc/calls.c                    |  4 +--
 gcc/cfgexpand.c                |  5 ++--
 gcc/cgraph.c                   | 11 +++-----
 gcc/cgraphclones.c             |  5 ++--
 gcc/config/i386/i386.c         |  5 ++--
 gcc/cp/call.c                  |  8 ++----
 gcc/cp/constexpr.c             | 15 ++++------
 gcc/cp/cp-gimplify.c           | 14 ++++------
 gcc/cp/decl.c                  | 21 +++++++-------
 gcc/cp/name-lookup.c           |  8 ++----
 gcc/cp/semantics.c             |  4 +--
 gcc/cp/tree.c                  |  5 ++--
 gcc/dse.c                      |  5 +---
 gcc/expr.c                     |  2 +-
 gcc/fold-const.c               |  7 ++---
 gcc/gimple-fold.c              |  3 +-
 gcc/gimple-low.c               |  3 +-
 gcc/gimple-pretty-print.c      |  4 +--
 gcc/gimple-ssa-warn-restrict.c |  2 +-
 gcc/gimple.c                   |  9 ++----
 gcc/gimplify.c                 | 21 ++++----------
 gcc/go/go-gcc.cc               |  5 ++--
 gcc/hsa-gen.c                  |  3 +-
 gcc/ipa-cp.c                   |  3 +-
 gcc/ipa-fnsummary.c            |  6 ++--
 gcc/ipa-param-manipulation.c   |  2 +-
 gcc/ipa-split.c                |  5 ++--
 gcc/ipa-visibility.c           |  2 +-
 gcc/lto-cgraph.c               |  2 +-
 gcc/lto-streamer-out.c         |  2 +-
 gcc/lto/lto-lang.c             |  3 +-
 gcc/lto/lto-symtab.c           |  8 +++---
 gcc/lto/lto.c                  |  4 +--
 gcc/omp-low.c                  |  8 ++----
 gcc/predict.c                  |  4 +--
 gcc/print-tree.c               |  6 ++--
 gcc/symtab.c                   |  2 +-
 gcc/trans-mem.c                | 18 +++++-------
 gcc/tree-call-cdce.c           |  2 +-
 gcc/tree-cfg.c                 | 10 +++----
 gcc/tree-eh.c                  |  2 +-
 gcc/tree-if-conv.c             |  2 +-
 gcc/tree-inline.c              |  9 +++---
 gcc/tree-sra.c                 |  3 +-
 gcc/tree-ssa-ccp.c             | 15 ++++------
 gcc/tree-ssa-dce.c             |  6 ++--
 gcc/tree-ssa-dom.c             |  4 +--
 gcc/tree-ssa-forwprop.c        |  6 ++--
 gcc/tree-ssa-loop-im.c         |  4 +--
 gcc/tree-ssa-math-opts.c       |  3 +-
 gcc/tree-ssa-sccvn.c           |  2 +-
 gcc/tree-ssa-strlen.c          |  2 +-
 gcc/tree-ssa-structalias.c     |  6 ++--
 gcc/tree-ssa-ter.c             |  5 ++--
 gcc/tree-stdarg.c              |  9 ++----
 gcc/tree-tailcall.c            |  2 +-
 gcc/tree.c                     | 11 ++++----
 gcc/tree.h                     | 50 ++++++++++++++++++++++++----------
 gcc/ubsan.c                    |  3 +-
 gcc/varasm.c                   |  2 +-
 70 files changed, 205 insertions(+), 307 deletions(-)

diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index b890195cefc..13007f684c4 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -1081,7 +1081,7 @@ call_is_atomic_load (tree exp)
 {
   tree fndecl = get_callee_fndecl (exp);
 
-  if (!(fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL))
+  if (!decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return false;
 
   enum built_in_function code = DECL_FUNCTION_CODE (fndecl);
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 64700b6c8ce..2e1a49454fa 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -432,7 +432,7 @@ diag_attr_exclusions (tree last_decl, tree node, tree attrname,
 	  bool note = last_decl != NULL_TREE;
 	  auto_diagnostic_group d;
 	  if (TREE_CODE (node) == FUNCTION_DECL
-	      && DECL_BUILT_IN (node))
+	      && decl_built_in_p (node))
 	    note &= warning (OPT_Wattributes,
 			     "ignoring attribute %qE in declaration of "
 			     "a built-in function %qD because it conflicts "
diff --git a/gcc/builtins.c b/gcc/builtins.c
index b1a79f3f33f..4d4e17d350f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -208,15 +208,6 @@ is_builtin_name (const char *name)
   return false;
 }
 
-
-/* Return true if DECL is a function symbol representing a built-in.  */
-
-bool
-is_builtin_fn (tree decl)
-{
-  return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
-}
-
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -8151,11 +8142,8 @@ builtin_mathfn_code (const_tree t)
     return END_BUILTINS;
 
   fndecl = get_callee_fndecl (t);
-  if (fndecl == NULL_TREE
-      || TREE_CODE (fndecl) != FUNCTION_DECL
-      || ! DECL_BUILT_IN (fndecl)
-      || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
-    return END_BUILTINS;
+  if (!decl_built_in_p (fndecl, BUILT_IN_NORMAL))
+      return END_BUILTINS;
 
   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   init_const_call_expr_arg_iterator (t, &iter);
@@ -8310,9 +8298,8 @@ fold_builtin_expect (location_t loc, tree arg0, tree arg1, tree arg2,
 
   if (TREE_CODE (inner) == CALL_EXPR
       && (fndecl = get_callee_fndecl (inner))
-      && (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
-	  || DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL,
-			      BUILT_IN_EXPECT_WITH_PROBABILITY)))
+      && (decl_built_in_p (fndecl, BUILT_IN_EXPECT)
+	  || decl_built_in_p (fndecl, BUILT_IN_EXPECT_WITH_PROBABILITY)))
     return arg0;
 
   inner = inner_arg0;
@@ -9625,9 +9612,7 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
 {
   tree ret = NULL_TREE;
   tree fndecl = get_callee_fndecl (exp);
-  if (fndecl
-      && TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl)
+  if (decl_built_in_p (fndecl)
       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
 	 yet.  Defer folding until we see all the arguments
 	 (after inlining).  */
@@ -9641,10 +9626,7 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
 
@@ -9679,18 +9661,14 @@ fold_builtin_call_array (location_t loc, tree,
     return NULL_TREE;
 
   tree fndecl = TREE_OPERAND (fn, 0);
-  if (TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl))
+  if (decl_built_in_p (fndecl))
     {
       /* If last argument is __builtin_va_arg_pack (), arguments to this
 	 function are not finalized yet.  Defer folding until they are.  */
       if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
       if (avoid_folding_inline_builtin (fndecl))
@@ -10809,9 +10787,7 @@ fold_call_stmt (gcall *stmt, bool ignore)
   tree ret = NULL_TREE;
   tree fndecl = gimple_call_fndecl (stmt);
   location_t loc = gimple_location (stmt);
-  if (fndecl
-      && TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl)
+  if (decl_built_in_p (fndecl)
       && !gimple_call_va_arg_pack_p (stmt))
     {
       int nargs = gimple_call_num_args (stmt);
@@ -10858,8 +10834,7 @@ fold_call_stmt (gcall *stmt, bool ignore)
 void
 set_builtin_user_assembler_name (tree decl, const char *asmspec)
 {
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+  gcc_assert (decl_built_in_p (decl, BUILT_IN_NORMAL)
 	      && asmspec != 0);
 
   tree builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
@@ -10879,7 +10854,7 @@ set_builtin_user_assembler_name (tree decl, const char *asmspec)
 bool
 is_simple_builtin (tree decl)
 {
-  if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (decl, BUILT_IN_NORMAL))
     switch (DECL_FUNCTION_CODE (decl))
       {
 	/* Builtins that expand to constants.  */
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 805f1801604..c3d5ccbb6b6 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -49,7 +49,6 @@ extern struct target_builtins *this_target_builtins;
 /* Non-zero if __builtin_constant_p should be folded right away.  */
 extern bool force_folding_builtin_constant_p;
 
-extern bool is_builtin_fn (tree);
 extern bool called_as_built_in (tree);
 extern bool get_object_alignment_1 (tree, unsigned int *,
 				    unsigned HOST_WIDE_INT *);
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 95cff215d60..287912065b7 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5326,8 +5326,7 @@ check_function_restrict (const_tree fndecl, const_tree fntype,
     {
       /* Avoid diagnosing calls built-ins with a zero size/bound
 	 here.  They are checked in more detail elsewhere.  */
-      if (DECL_BUILT_IN (fndecl)
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+      if (decl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && nargs == 3
 	  && TREE_CODE (argarray[2]) == INTEGER_CST
 	  && integer_zerop (argarray[2]))
@@ -5755,8 +5754,7 @@ bool
 check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
 				  tree fndecl, int nargs, tree *args)
 {
-  if (!DECL_BUILT_IN (fndecl)
-      || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+  if (!decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return true;
 
   switch (DECL_FUNCTION_CODE (fndecl))
@@ -8005,13 +8003,12 @@ reject_gcc_builtin (const_tree expr, location_t loc /* = UNKNOWN_LOCATION */)
 
   if (TREE_TYPE (expr)
       && TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
-      && TREE_CODE (expr) == FUNCTION_DECL
       /* The intersection of DECL_BUILT_IN and DECL_IS_BUILTIN avoids
 	 false positives for user-declared built-ins such as abs or
 	 strlen, and for C++ operators new and delete.
 	 The c_decl_implicit() test avoids false positives for implicitly
 	 declared built-ins with library fallbacks (such as abs).  */
-      && DECL_BUILT_IN (expr)
+      && decl_built_in_p (expr)
       && DECL_IS_BUILTIN (expr)
       && !c_decl_implicit (expr)
       && !DECL_ASSEMBLER_NAME_SET_P (expr))
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index ca259aa7bd0..ef4a8bed4a7 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -701,8 +701,7 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
   unsigned int idx = ~0;
   location_t loc;
 
-  if (TREE_CODE (callee) != FUNCTION_DECL
-      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
+  if (!decl_built_in_p (callee, BUILT_IN_NORMAL)
       || vec_safe_length (params) <= 1)
     return;
 
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 95249779e3c..37f2435695a 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -1800,7 +1800,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
 static void
 locate_old_decl (tree decl)
 {
-  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)
+  if (decl_built_in_p (decl)
       && !C_DECL_DECLARED_BUILTIN (decl))
     ;
   else if (DECL_INITIAL (decl))
@@ -1842,8 +1842,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
      unless OLDDECL is a builtin.  OLDDECL will be discarded in any case.  */
   if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
-      if (!(TREE_CODE (olddecl) == FUNCTION_DECL
-	    && DECL_BUILT_IN (olddecl)
+      if (!(decl_built_in_p (olddecl)
 	    && !C_DECL_DECLARED_BUILTIN (olddecl)))
 	{
 	  auto_diagnostic_group d;
@@ -1876,8 +1875,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 
   if (!comptypes (oldtype, newtype))
     {
-      if (TREE_CODE (olddecl) == FUNCTION_DECL
-	  && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
+      if (decl_built_in_p (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
 	{
 	  /* Accept harmless mismatch in function types.
 	     This is for the ffs and fprintf builtins.  */
@@ -2025,7 +2023,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	 define the built-in with an old-style definition (so we
 	 can't validate the argument list) the built-in definition is
 	 overridden, but optionally warn this was a bad choice of name.  */
-      if (DECL_BUILT_IN (olddecl)
+      if (decl_built_in_p (olddecl)
 	  && !C_DECL_DECLARED_BUILTIN (olddecl)
 	  && (!TREE_PUBLIC (newdecl)
 	      || (DECL_INITIAL (newdecl)
@@ -2296,9 +2294,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       && !(TREE_CODE (newdecl) == FUNCTION_DECL
 	   && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))
       /* Don't warn about redundant redeclarations of builtins.  */
-      && !(TREE_CODE (newdecl) == FUNCTION_DECL
-	   && !DECL_BUILT_IN (newdecl)
-	   && DECL_BUILT_IN (olddecl)
+      && !(!decl_built_in_p (newdecl)
+	   && decl_built_in_p (olddecl)
 	   && !C_DECL_DECLARED_BUILTIN (olddecl))
       /* Don't warn about an extern followed by a definition.  */
       && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl))
@@ -2576,7 +2573,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 	       || DECL_DISREGARD_INLINE_LIMITS (olddecl));
 	}
 
-      if (DECL_BUILT_IN (olddecl))
+      if (decl_built_in_p (olddecl))
 	{
 	  /* If redeclaring a builtin function, it stays built in.
 	     But it gets tagged as having been declared.  */
@@ -2839,8 +2836,7 @@ warn_if_shadowing (tree new_decl)
 				 "declaration",
 				 new_decl);
 	  }
-	else if (TREE_CODE (old_decl) == FUNCTION_DECL
-		 && DECL_BUILT_IN (old_decl))
+	else if (decl_built_in_p (old_decl))
 	  {
 	    warning (OPT_Wshadow, "declaration of %q+D shadows "
 		     "a built-in function", new_decl);
@@ -2952,8 +2948,7 @@ pushdecl (tree x)
 	      else
 		thistype = TREE_TYPE (b_use->decl);
 	      b_use->u.type = TREE_TYPE (b_use->decl);
-	      if (TREE_CODE (b_use->decl) == FUNCTION_DECL
-		  && DECL_BUILT_IN (b_use->decl))
+	      if (decl_built_in_p (b_use->decl))
 		thistype
 		  = build_type_attribute_variant (thistype,
 						  TYPE_ATTRIBUTES
@@ -3057,7 +3052,7 @@ pushdecl (tree x)
 	  else
 	    thistype = type;
 	  b->u.type = TREE_TYPE (b->decl);
-	  if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
+	  if (decl_built_in_p (b->decl))
 	    thistype
 	      = build_type_attribute_variant (thistype,
 					      TYPE_ATTRIBUTES (b->u.type));
@@ -3408,7 +3403,7 @@ implicitly_declare (location_t loc, tree functionid)
 	 in the external scope because they're pushed before the file
 	 scope gets created.  Catch this here and rebind them into the
 	 file scope.  */
-      if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl))
+      if (!decl_built_in_p (decl) && DECL_IS_BUILTIN (decl))
 	{
 	  bind (functionid, decl, file_scope,
 		/*invisible=*/false, /*nested=*/true,
@@ -3429,7 +3424,7 @@ implicitly_declare (location_t loc, tree functionid)
 	      implicit_decl_warning (loc, functionid, decl);
 	      C_DECL_IMPLICIT (decl) = 1;
 	    }
-	  if (DECL_BUILT_IN (decl))
+	  if (decl_built_in_p (decl))
 	    {
 	      newtype = build_type_attribute_variant (newtype,
 						      TYPE_ATTRIBUTES
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 0d5dbea8f67..0dab38cca4a 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -9174,9 +9174,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 					      expr.value, exprlist,
 					      sizeof_arg,
 					      sizeof_ptr_memacc_comptypes);
-	  if (TREE_CODE (expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (expr.value) == BUILT_IN_MEMSET
+	  if (decl_built_in_p (expr.value, BUILT_IN_MEMSET)
 	      && vec_safe_length (exprlist) == 3)
 	    {
 	      tree arg0 = (*exprlist)[0];
@@ -9193,9 +9191,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 
 	  expr.original_code = ERROR_MARK;
 	  if (TREE_CODE (expr.value) == INTEGER_CST
-	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
+	      && decl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
 	    expr.original_code = C_MAYBE_CONST_EXPR;
 	  expr.original_type = NULL;
 	  if (exprlist)
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index ae1a1e60d4b..ac0bade40cb 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -102,7 +102,7 @@ along with GCC; see the file COPYING3.  If not see
 #define C_DECL_ISNT_PROTOTYPE(EXP)			\
        (EXP == 0					\
 	|| (!prototype_p (TREE_TYPE (EXP))	\
-	    && !DECL_BUILT_IN (EXP)))
+	    && !decl_built_in_p (EXP)))
 
 /* For FUNCTION_TYPE, a hidden list of types of arguments.  The same as
    TYPE_ARG_TYPES for functions with prototypes, but created for functions
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 54c7967a06b..ba06a347153 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3108,9 +3108,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
   argarray = vec_safe_address (params);
 
   /* Check that arguments to builtin functions match the expectations.  */
-  if (fundecl
-      && DECL_BUILT_IN (fundecl)
-      && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL
+  if (decl_built_in_p (fundecl, BUILT_IN_NORMAL)
       && !check_builtin_function_arguments (loc, arg_loc, fundecl, nargs,
 					    argarray))
     return error_mark_node;
@@ -3233,8 +3231,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
      precision should be removed (classification) or not
      (comparison).  */
   if (type_generic
-      && DECL_BUILT_IN (fundecl)
-      && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL)
+      && decl_built_in_p (fundecl, BUILT_IN_NORMAL))
     {
       switch (DECL_FUNCTION_CODE (fundecl))
 	{
diff --git a/gcc/calls.c b/gcc/calls.c
index 0fb10b182b1..70d74a2ac49 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -715,7 +715,7 @@ gimple_alloca_call_p (const gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     switch (DECL_FUNCTION_CODE (fndecl))
       {
       CASE_BUILT_IN_ALLOCA:
@@ -1542,7 +1542,7 @@ get_attr_nonstring_decl (tree expr, tree *ref)
 void
 maybe_warn_nonstring_arg (tree fndecl, tree exp)
 {
-  if (!fndecl || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+  if (!decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return;
 
   if (TREE_NO_WARNING (exp))
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..d03c8aa8c7e 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2616,7 +2616,7 @@ expand_call_stmt (gcall *stmt)
   exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
 
   CALL_EXPR_FN (exp) = gimple_call_fn (stmt);
-  builtin_p = decl && DECL_BUILT_IN (decl);
+  builtin_p = decl && decl_built_in_p (decl);
 
   /* If this is not a builtin function, the function type through which the
      call is made may be different from the type of the function.  */
@@ -2654,8 +2654,7 @@ expand_call_stmt (gcall *stmt)
   CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt);
   CALL_EXPR_MUST_TAIL_CALL (exp) = gimple_call_must_tail_p (stmt);
   CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt);
-  if (decl
-      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+  if (decl_built_in_p (decl, BUILT_IN_NORMAL)
       && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (decl)))
     CALL_ALLOCA_FOR_VAR_P (exp) = gimple_call_alloca_for_var_p (stmt);
   else
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d19f1aacab8..8be4ae58e3f 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1559,8 +1559,7 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
 	{
 	  /* Keep calls marked as dead dead.  */
 	  if (new_stmt && is_gimple_call (new_stmt) && e->callee
-	      && DECL_BUILT_IN_CLASS (e->callee->decl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (e->callee->decl) == BUILT_IN_UNREACHABLE)
+	      && decl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
 	    {
               node->get_edge (old_stmt)->set_call_stmt
 		 (as_a <gcall *> (new_stmt));
@@ -3060,8 +3059,8 @@ cgraph_edge::verify_corresponds_to_fndecl (tree decl)
 
   /* Optimizers can redirect unreachable calls or calls triggering undefined
      behavior to builtin_unreachable.  */
-  if (DECL_BUILT_IN_CLASS (callee->decl) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (callee->decl) == BUILT_IN_UNREACHABLE)
+
+  if (decl_built_in_p (callee->decl, BUILT_IN_UNREACHABLE))
     return false;
 
   if (callee->former_clone_of != node->decl
@@ -3186,9 +3185,7 @@ cgraph_node::verify_node (void)
 	  && !e->speculative
 	  /* Optimized out calls are redirected to __builtin_unreachable.  */
 	  && (e->count.nonzero_p ()
-	      || ! e->callee->decl
-	      || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	      || !decl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
 	  && count
 	      == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
 	  && (!e->count.ipa_p ()
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 6e84a31c1a5..07958214327 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -222,7 +222,7 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
     DECL_VINDEX (new_decl) = NULL_TREE;
 
   /* When signature changes, we need to clear builtin info.  */
-  if (DECL_BUILT_IN (new_decl)
+  if (decl_built_in_p (new_decl)
       && args_to_skip
       && !bitmap_empty_p (args_to_skip))
     {
@@ -482,8 +482,7 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count,
 	 version.  The only exception is when the edge was proved to
 	 be unreachable during the clonning procedure.  */
       if (!e->callee
-	  || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	  || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	  || !decl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
         e->redirect_callee_duplicating_thunks (new_node);
     }
   new_node->expand_all_artificial_thunks ();
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0b2b1b796d6..de4e50d16bb 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -33493,7 +33493,7 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
 {
   gimple *stmt = gsi_stmt (*gsi);
   tree fndecl = gimple_call_fndecl (stmt);
-  gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
+  gcc_checking_assert (decl_built_in_p (fndecl, BUILT_IN_MD));
   int n_args = gimple_call_num_args (stmt);
   enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
   tree decl = NULL_TREE;
@@ -38082,8 +38082,7 @@ rdseed_step:
 	      if (is_gimple_call (def_stmt))
 		{
 		  tree fndecl = gimple_call_fndecl (def_stmt);
-		  if (fndecl
-		      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+		  if (decl_built_in_p (fndecl, BUILT_IN_MD))
 		    switch ((unsigned int) DECL_FUNCTION_CODE (fndecl))
 		      {
 		      case IX86_BUILTIN_CMPPD:
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 1f72ac863bd..a40bc68a77f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -389,7 +389,7 @@ build_call_a (tree function, int n, tree *argarray)
   /* Don't pass empty class objects by value.  This is useful
      for tags in STL, which are used to control overload resolution.
      We don't need to handle other cases of copying empty classes.  */
-  if (! decl || ! DECL_BUILT_IN (decl))
+  if (! decl_built_in_p (decl))
     for (i = 0; i < n; i++)
       {
 	tree arg = CALL_EXPR_ARG (function, i);
@@ -8865,10 +8865,8 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
   fndecl = get_callee_fndecl (fn);
 
   /* Check that arguments to builtin functions match the expectations.  */
-  if (fndecl
-      && !processing_template_decl
-      && DECL_BUILT_IN (fndecl)
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (!processing_template_decl
+      && decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       int i;
 
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 54c8b5edf8d..bef9003d90d 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -720,9 +720,7 @@ constexpr_fn_retval (tree body)
     case CALL_EXPR:
 	{
 	  tree fun = get_function_named_in_call (body);
-	  if (fun != NULL_TREE
-	      && DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+	  if (decl_built_in_p (fun, BUILT_IN_UNREACHABLE))
 	    return NULL_TREE;
 	}
       /* Fallthru.  */
@@ -1198,8 +1196,8 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 
   /* For __builtin_is_constant_evaluated, defer it if not
      ctx->pretend_const_required, otherwise fold it to true.  */
-  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_FRONTEND
-      && (int) DECL_FUNCTION_CODE (fun) == CP_BUILT_IN_IS_CONSTANT_EVALUATED)
+  if (decl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+		       BUILT_IN_FRONTEND))
     {
       if (!ctx->pretend_const_required)
 	{
@@ -1242,8 +1240,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 	  /* Do not allow__builtin_unreachable in constexpr function.
 	     The __builtin_unreachable call with BUILTINS_LOCATION
 	     comes from cp_maybe_instrument_return.  */
-	  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+	  if (decl_built_in_p (fun, BUILT_IN_UNREACHABLE)
 	      && EXPR_LOCATION (t) == BUILTINS_LOCATION)
 	    error ("%<constexpr%> call flows off the end of the function");
 	  else
@@ -1528,7 +1525,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
   if (is_ubsan_builtin_p (fun))
     return void_node;
 
-  if (is_builtin_fn (fun))
+  if (decl_built_in_p (fun))
     return cxx_eval_builtin_function_call (ctx, t, fun,
 					   lval, non_constant_p, overflow_p);
   if (!DECL_DECLARED_CONSTEXPR_P (fun))
@@ -5522,7 +5519,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 		if (!DECL_DECLARED_CONSTEXPR_P (fun)
 		    /* Allow any built-in function; if the expansion
 		       isn't constant, we'll deal with that then.  */
-		    && !is_builtin_fn (fun))
+		    && !decl_built_in_p (fun))
 		  {
 		    if (flags & tf_error)
 		      {
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index f6109914102..c18f9efba12 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -796,10 +796,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (ret != GS_ERROR)
 	{
 	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
-	  if (decl
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	      && ((int) DECL_FUNCTION_CODE (decl)
-		  == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	  if (decl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+			       BUILT_IN_FRONTEND))
 	    *expr_p = boolean_false_node;
 	}
       break;
@@ -2489,17 +2487,15 @@ cp_fold (tree x)
 	/* Some built-in function calls will be evaluated at compile-time in
 	   fold ().  Set optimize to 1 when folding __builtin_constant_p inside
 	   a constexpr function so that fold_builtin_1 doesn't fold it to 0.  */
-	if (callee && DECL_BUILT_IN (callee) && !optimize
+	if (decl_built_in_p (callee) && !optimize
 	    && DECL_IS_BUILTIN_CONSTANT_P (callee)
 	    && current_function_decl
 	    && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
 	  nw = 1;
 
 	/* Defer folding __builtin_is_constant_evaluated.  */
-	if (callee
-	    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_FRONTEND
-	    && ((int) DECL_FUNCTION_CODE (callee)
-		== CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	if (decl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+			     BUILT_IN_FRONTEND))
 	  break;
 
 	x = copy_node (x);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f6dbd6b11c3..3bd299188ae 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -968,7 +968,7 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
       if (same_type_p (TREE_TYPE (f1), r2))
 	{
 	  if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
-	      && (DECL_BUILT_IN (olddecl)
+	      && (decl_built_in_p (olddecl)
 #ifdef SYSTEM_IMPLICIT_EXTERN_C
 		  || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl))
 		  || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl))
@@ -1208,7 +1208,7 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl)
     return true;
   if (TREE_CODE (old_decl) == FUNCTION_DECL)
     {
-      if (DECL_BUILT_IN (old_decl))
+      if (decl_built_in_p (old_decl))
 	{
 	  /* Hide a built-in declaration.  */
 	  DECL_DECLARED_CONSTEXPR_P (old_decl)
@@ -1442,7 +1442,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	    {
 	      warning_at (newdecl_loc,
 			  OPT_Wshadow, 
-			  DECL_BUILT_IN (olddecl)
+			  decl_built_in_p (olddecl)
 			  ? G_("shadowing built-in function %q#D")
 			  : G_("shadowing library function %q#D"), olddecl);
 	      /* Discard the old built-in function.  */
@@ -1450,7 +1450,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	    }
 	  /* If the built-in is not ansi, then programs can override
 	     it even globally without an error.  */
-	  else if (! DECL_BUILT_IN (olddecl))
+	  else if (! decl_built_in_p (olddecl))
 	    warning_at (newdecl_loc, 0,
 			"library function %q#D redeclared as non-function %q#D",
 			olddecl, newdecl);
@@ -1537,7 +1537,7 @@ next_arg:;
 	      /* Don't really override olddecl for __* prefixed builtins
 		 except for __[^b]*_chk, the compiler might be using those
 		 explicitly.  */
-	      if (DECL_BUILT_IN (olddecl))
+	      if (decl_built_in_p (olddecl))
 		{
 		  tree id = DECL_NAME (olddecl);
 		  const char *name = IDENTIFIER_POINTER (id);
@@ -1578,9 +1578,9 @@ next_arg:;
 			    "declaration %q#D", newdecl, olddecl);
 	      else
 		warning (OPT_Wshadow, 
-                         DECL_BUILT_IN (olddecl)
-                         ? G_("shadowing built-in function %q#D")
-                         : G_("shadowing library function %q#D"), olddecl);
+			 decl_built_in_p (olddecl)
+			 ? G_("shadowing built-in function %q#D")
+			 : G_("shadowing library function %q#D"), olddecl);
 	    }
 	  else
 	    /* Discard the old built-in function.  */
@@ -2522,7 +2522,7 @@ next_arg:;
       /* If redeclaring a builtin function, it stays built in
 	 if newdecl is a gnu_inline definition, or if newdecl is just
 	 a declaration.  */
-      if (DECL_BUILT_IN (olddecl)
+      if (decl_built_in_p (olddecl)
 	  && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
 	{
 	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
@@ -6610,8 +6610,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
 	}
       else
 	{
-	  if (TREE_CODE (decl) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+	  if (decl_built_in_p (decl, BUILT_IN_NORMAL))
 	    set_builtin_user_assembler_name (decl, asmspec);
 	  set_user_assembler_name (decl, asmspec);
 	}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 8c7f68522da..3a7e13caed2 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5790,8 +5790,7 @@ consider_binding_level (tree name, best_match <tree, const char *> &bm,
 	continue;
 
       /* Skip anticipated decls of builtin functions.  */
-      if (TREE_CODE (d) == FUNCTION_DECL
-	  && DECL_BUILT_IN (d)
+      if (decl_built_in_p (d)
 	  && DECL_ANTICIPATED (d))
 	continue;
 
@@ -7272,9 +7271,8 @@ cp_emit_debug_info_for_using (tree t, tree context)
 
   /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
      of a builtin function.  */
-  if (TREE_CODE (t) == FUNCTION_DECL
-      && DECL_EXTERNAL (t)
-      && DECL_BUILT_IN (t))
+  if (decl_built_in_p (t)
+      && DECL_EXTERNAL (t))
     return;
 
   /* Do not supply context to imported_module_or_decl, if
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bfdca5024d3..9179aa8f245 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2545,9 +2545,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 	    }
 
 	  if ((complain & tf_warning)
-	      && TREE_CODE (fn) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fn) == BUILT_IN_MEMSET
+	      && decl_built_in_p (fn, BUILT_IN_MEMSET)
 	      && vec_safe_length (*args) == 3
 	      && !any_type_dependent_arguments_p (*args))
 	    {
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8a1d2993f94..d1e569c7fc5 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -420,9 +420,8 @@ builtin_valid_in_constant_expr_p (const_tree decl)
     return false;
   if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
     {
-      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	  && ((int) DECL_FUNCTION_CODE (decl)
-	      == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+      if (decl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+			   BUILT_IN_FRONTEND))
 	return true;
       /* Not a built-in.  */
       return false;
diff --git a/gcc/dse.c b/gcc/dse.c
index 26c6007b9ed..3e688a27cd6 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2417,10 +2417,7 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn)
 	  && (call = get_call_rtx_from (insn))
 	  && (sym = XEXP (XEXP (call, 0), 0))
 	  && GET_CODE (sym) == SYMBOL_REF
-	  && SYMBOL_REF_DECL (sym)
-	  && TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (sym)) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (sym)) == BUILT_IN_MEMSET)
+	  && decl_built_in_p (SYMBOL_REF_DECL (sym), BUILT_IN_MEMSET))
 	memset_call = SYMBOL_REF_DECL (sym);
 
       if (const_call || memset_call)
diff --git a/gcc/expr.c b/gcc/expr.c
index 58574bafbf3..ce080fcb6eb 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10937,7 +10937,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	  }
 
 	/* Check for a built-in function.  */
-	if (fndecl && DECL_BUILT_IN (fndecl))
+	if (decl_built_in_p (fndecl))
 	  {
 	    gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
 	    return expand_builtin (exp, target, subtarget, tmode, ignore);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b318fc7705f..5a3d79f7c26 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3450,8 +3450,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 
     case tcc_declaration:
       /* Consider __builtin_sqrt equal to sqrt.  */
-      return (TREE_CODE (arg0) == FUNCTION_DECL
-	      && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
+      return (decl_built_in_p (arg0) && decl_built_in_p (arg1)
 	      && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
 	      && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
 
@@ -10752,9 +10751,7 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
 	{
 	  tree fndecl = get_callee_fndecl (arg0);
 
-	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
+	  if (decl_built_in_p (fndecl, BUILT_IN_STRLEN)
 	      && call_expr_nargs (arg0) == 1
 	      && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0))) == POINTER_TYPE)
 	    {
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 07341ebe66f..bd6e7e22937 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6347,8 +6347,7 @@ gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
 
 	fn = (*valueize) (gimple_call_fn (stmt));
 	if (TREE_CODE (fn) == ADDR_EXPR
-	    && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
-	    && DECL_BUILT_IN (TREE_OPERAND (fn, 0))
+	    && decl_built_in_p (TREE_OPERAND (fn, 0))
 	    && gimple_builtin_call_types_compatible_p (stmt,
 						       TREE_OPERAND (fn, 0)))
 	  {
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 9623fb86a04..7d47a1bbdc0 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -354,8 +354,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
 	      TREE_SET_BLOCK (arg, data->block);
 	  }
 
-	if (decl
-	    && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+	if (decl_built_in_p (decl, BUILT_IN_NORMAL))
 	  {
 	    if (DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
 	      {
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d3c5ec6f79b..b54f643e4d8 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -910,9 +910,7 @@ dump_gimple_call (pretty_printer *buffer, gcall *gs, int spc,
     fn = TREE_OPERAND (fn, 0);
   if (TREE_CODE (fn) == FUNCTION_DECL && decl_is_tm_clone (fn))
     pp_string (buffer, " [tm-clone]");
-  if (TREE_CODE (fn) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_START
+  if (decl_built_in_p (fn, BUILT_IN_TM_START)
       && gimple_call_num_args (gs) > 0)
     {
       tree t = gimple_call_arg (gs, 0);
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 977dd860ef7..a43a57eb743 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -1731,7 +1731,7 @@ wrestrict_dom_walker::check_call (gimple *call)
     return;
 
   tree func = gimple_call_fndecl (call);
-  if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
+  if (!decl_built_in_p (func, BUILT_IN_NORMAL))
     return;
 
   /* Argument number to extract from the call (depends on the built-in
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 8d56a966cc1..22b88407eaf 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -375,8 +375,7 @@ gimple_build_call_from_tree (tree t, tree fnptrtype)
   gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t));
   gimple_call_set_must_tail (call, CALL_EXPR_MUST_TAIL_CALL (t));
   gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t));
-  if (fndecl
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL)
       && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (fndecl)))
     gimple_call_set_alloca_for_var (call, CALL_ALLOCA_FOR_VAR_P (t));
   else
@@ -2681,8 +2680,7 @@ gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
   tree fndecl;
   if (is_gimple_call (stmt)
       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 
-      && DECL_FUNCTION_CODE (fndecl) == code)
+      && decl_built_in_p (fndecl, code))
     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
   return false;
 }
@@ -2700,8 +2698,7 @@ gimple_call_combined_fn (const gimple *stmt)
 	return as_combined_fn (gimple_call_internal_fn (call));
 
       tree fndecl = gimple_call_fndecl (stmt);
-      if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+      if (decl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && gimple_builtin_call_types_compatible_p (stmt, fndecl))
 	return as_combined_fn (DECL_FUNCTION_CODE (fndecl));
     }
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e35137aec2c..47656905a44 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3209,8 +3209,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
      transform all calls in the same manner as the expanders do, but
      we do transform most of them.  */
   fndecl = get_callee_fndecl (*expr_p);
-  if (fndecl
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     switch (DECL_FUNCTION_CODE (fndecl))
       {
       CASE_BUILT_IN_ALLOCA:
@@ -3245,7 +3244,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       default:
         ;
       }
-  if (fndecl && DECL_BUILT_IN (fndecl))
+  if (decl_built_in_p (fndecl))
     {
       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
       if (new_tree && new_tree != *expr_p)
@@ -3296,10 +3295,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
       tree last_arg_fndecl = get_callee_fndecl (last_arg);
 
-      if (last_arg_fndecl
-	  && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
+      if (decl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
 	{
 	  tree call = *expr_p;
 
@@ -3772,9 +3768,7 @@ gimple_boolify (tree expr)
 
       /* For __builtin_expect ((long) (x), y) recurse into x as well
 	 if x is truth_value_p.  */
-      if (fn
-	  && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
+      if (decl_built_in_p (fn, BUILT_IN_EXPECT)
 	  && call_expr_nargs (call) == 2)
 	{
 	  tree arg = CALL_EXPR_ARG (call, 0);
@@ -5718,9 +5712,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
 	  STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
 	  tree fndecl = get_callee_fndecl (*from_p);
-	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+	  if (decl_built_in_p (fndecl, BUILT_IN_EXPECT)
 	      && call_expr_nargs (*from_p) == 3)
 	    call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
 						    CALL_EXPR_ARG (*from_p, 0),
@@ -5977,8 +5969,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       /* If we see a call to a declared builtin or see its address
 	 being taken (we can unify those cases here) then we can mark
 	 the builtin for implicit generation by GCC.  */
-      if (TREE_CODE (op0) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
+      if (decl_built_in_p (op0, BUILT_IN_NORMAL)
 	  && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
 	set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
 
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 76a2026f1e0..1f6e22e2b40 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -1947,9 +1947,8 @@ Gcc_backend::call_expression(Bfunction*, // containing fcn for call
   // This is to support builtin math functions when using 80387 math.
   tree excess_type = NULL_TREE;
   if (optimize
-      && TREE_CODE(fndecl) == FUNCTION_DECL
-      && DECL_IS_BUILTIN(fndecl)
-      && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL
+      && decl_built_in_p (fndecl, BUILT_IN_NORMAL)
+      && DECL_IS_BUILTIN (fndecl)
       && nargs > 0
       && ((SCALAR_FLOAT_TYPE_P(rettype)
 	   && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..4428aebb95a 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -5303,8 +5303,7 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb)
       tree function_decl = gimple_call_fndecl (stmt);
       /* Prefetch pass can create type-mismatching prefetch builtin calls which
 	 fail the gimple_call_builtin_p test above.  Handle them here.  */
-      if (DECL_BUILT_IN_CLASS (function_decl)
-	  && DECL_FUNCTION_CODE (function_decl) == BUILT_IN_PREFETCH)
+      if (decl_built_in_p (function_decl, BUILT_IN_PREFETCH))
 	return;
 
       if (function_decl == NULL_TREE)
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 42dd4cc2904..1b9542fff9b 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -638,8 +638,7 @@ determine_versionability (struct cgraph_node *node,
   if (DECL_EXTERNAL (node->decl))
     for (cgraph_edge *edge = node->callees; !reason && edge;
 	 edge = edge->next_callee)
-      if (DECL_BUILT_IN (edge->callee->decl)
-	  && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL)
+      if (decl_built_in_p (edge->callee->decl))
         {
 	  if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
 	    reason = "external function which calls va_arg_pack";
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..f1ca355d509 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2455,10 +2455,8 @@ compute_fn_summary (struct cgraph_node *node, bool early)
 	       for (e = node->callees; e; e = e->next_callee)
 		 {
 		   tree cdecl = e->callee->decl;
-		   if (DECL_BUILT_IN (cdecl)
-		       && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
-		       && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
-			   || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
+		   if (decl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS)
+		       || decl_built_in_p (cdecl, BUILT_IN_VA_START))
 		     break;
 		 }
 	       node->local.can_change_signature = !e;
diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
index 1ab1fcccdae..3a9f483f12c 100644
--- a/gcc/ipa-param-manipulation.c
+++ b/gcc/ipa-param-manipulation.c
@@ -218,7 +218,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
     }
 
   /* When signature changes, we need to clear builtin info.  */
-  if (DECL_BUILT_IN (fndecl))
+  if (decl_built_in_p (fndecl))
     {
       DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
       DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 0e6440f8997..12fb01844f8 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -899,8 +899,7 @@ visit_bb (basic_block bb, basic_block return_bb,
       /* Check builtins that prevent splitting.  */
       if (gimple_code (stmt) == GIMPLE_CALL
 	  && (decl = gimple_call_fndecl (stmt)) != NULL_TREE
-	  && DECL_BUILT_IN (decl)
-	  && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+	  && decl_built_in_p (decl, BUILT_IN_NORMAL))
 	switch (DECL_FUNCTION_CODE (decl))
 	  {
 	  /* FIXME: once we will allow passing non-parm values to split part,
@@ -1347,7 +1346,7 @@ split_function (basic_block return_bb, struct split_point *split_point,
   /* For usual cloning it is enough to clear builtin only when signature
      changes.  For partial inlining we however can not expect the part
      of builtin implementation to have same semantic as the whole.  */
-  if (DECL_BUILT_IN (node->decl))
+  if (decl_built_in_p (node->decl))
     {
       DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN;
       DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
index 907dc9d0e2b..a7185068d16 100644
--- a/gcc/ipa-visibility.c
+++ b/gcc/ipa-visibility.c
@@ -203,7 +203,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
      using the implicit built-in declarations anymore.  Similarly this enables
      us to remove them as unreachable before actual calls may appear during
      expansion or folding.  */
-  if (DECL_BUILT_IN (node->decl))
+  if (decl_built_in_p (node->decl))
     return true;
 
   /* If linker counts on us, we must preserve the function.  */
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index d5e390cb5f4..56b535f9e8c 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1266,7 +1266,7 @@ input_node (struct lto_file_decl_data *file_data,
      have already been read will have their tag stored in the 'aux'
      field.  Since built-in functions can be referenced in multiple
      functions, they are expected to be read more than once.  */
-  if (node->aux && !DECL_BUILT_IN (node->decl))
+  if (node->aux && !decl_built_in_p (node->decl))
     internal_error ("bytecode stream: found multiple instances of cgraph "
 		    "node with uid %d", node->get_uid ());
 
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 9e28d678342..50d9c9a5884 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -2618,7 +2618,7 @@ write_symbol (struct streamer_tree_cache_d *cache,
   unsigned char c;
 
   gcc_checking_assert (TREE_PUBLIC (t)
-		       && !is_builtin_fn (t)
+		       && !decl_built_in_p (t)
 		       && !DECL_ABSTRACT_P (t)
 		       && (!VAR_P (t) || !DECL_HARD_REGISTER (t)));
 
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index de6ec1c077a..a15fa88a3ac 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -303,8 +303,7 @@ handle_const_attribute (tree *node, tree ARG_UNUSED (name),
 			tree ARG_UNUSED (args), int ARG_UNUSED (flags),
 			bool * ARG_UNUSED (no_add_attrs))
 {
-  if (TREE_CODE (*node) != FUNCTION_DECL
-      || !DECL_BUILT_IN (*node))
+  if (!decl_built_in_p (*node))
     inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name);
 
   tree type = TREE_TYPE (*node);
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 0d603c0281f..584907f8351 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -546,14 +546,14 @@ lto_symtab_merge_p (tree prevailing, tree decl)
   
   if (TREE_CODE (prevailing) == FUNCTION_DECL)
     {
-      if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl))
+      if (decl_built_in_p (prevailing) != decl_built_in_p (decl))
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "Not merging decls; "
 		     "DECL_BUILT_IN mismatch\n");
 	  return false;
 	}
-      if (DECL_BUILT_IN (prevailing)
+      if (decl_built_in_p (prevailing)
 	  && (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl)
 	      || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl)))
 	{
@@ -797,7 +797,7 @@ lto_symtab_merge_decls_1 (symtab_node *first)
 	{
 	  for (e = first; e; e = e->next_sharing_asm_name)
 	    if (TREE_CODE (e->decl) == FUNCTION_DECL
-		&& !DECL_BUILT_IN (e->decl)
+		&& !decl_built_in_p (e->decl)
 		&& lto_symtab_symbol_p (e))
 	      {
 		prevailing = e;
@@ -1030,7 +1030,7 @@ lto_symtab_merge_symbols (void)
 	      /* Builtins are not merged via decl merging.  It is however
 		 possible that tree merging unified the declaration.  We
 		 do not want duplicate entries in symbol table.  */
-	      if (cnode && DECL_BUILT_IN (node->decl)
+	      if (decl_built_in_p (node->decl)
 		  && (cnode2 = cgraph_node::get (node->decl))
 		  && cnode2 != cnode)
 		lto_cgraph_replace_node (cnode2, cnode);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 10618896022..8d45228df47 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -894,7 +894,7 @@ lto_maybe_register_decl (struct data_in *data_in, tree t, unsigned ix)
   if (TREE_CODE (t) == VAR_DECL)
     lto_register_var_decl_in_symtab (data_in, t, ix);
   else if (TREE_CODE (t) == FUNCTION_DECL
-	   && !DECL_BUILT_IN (t))
+	   && !decl_built_in_p (t))
     lto_register_function_decl_in_symtab (data_in, t, ix);
 }
 
@@ -2923,7 +2923,7 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   FOR_EACH_SYMBOL (snode)
     if (snode->externally_visible && snode->real_symbol_p ()
 	&& snode->lto_file_data && snode->lto_file_data->resolution_map
-	&& !is_builtin_fn (snode->decl)
+	&& !decl_built_in_p (snode->decl)
 	&& !(VAR_P (snode->decl) && DECL_HARD_REGISTER (snode->decl)))
       {
 	ld_plugin_symbol_resolution_t *res;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 843c66fd221..1f576b975c3 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2975,9 +2975,8 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
 static bool
 setjmp_or_longjmp_p (const_tree fndecl)
 {
-  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
-	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+  if (decl_built_in_p (fndecl, BUILT_IN_SETJMP)
+      || decl_built_in_p (fndecl, BUILT_IN_LONGJMP))
     return true;
 
   tree declname = DECL_NAME (fndecl);
@@ -8831,8 +8830,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       tree fndecl;
       call_stmt = as_a <gcall *> (stmt);
       fndecl = gimple_call_fndecl (call_stmt);
-      if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+      if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	switch (DECL_FUNCTION_CODE (fndecl))
 	  {
 	  case BUILT_IN_GOMP_BARRIER:
diff --git a/gcc/predict.c b/gcc/predict.c
index 8c8e79153fc..58822da883e 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -3996,9 +3996,9 @@ strip_predict_hints (function *fun, bool early)
 	      tree fndecl = gimple_call_fndecl (stmt);
 
 	      if (!early
-		  && ((DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
+		  && ((decl_built_in_p (fndecl, BUILT_IN_EXPECT)
 		       && gimple_call_num_args (stmt) == 2)
-		      || (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL,
+		      || (decl_built_in_p (fndecl,
 					   BUILT_IN_EXPECT_WITH_PROBABILITY)
 			  && gimple_call_num_args (stmt) == 3)
 		      || (gimple_call_internal_p (stmt)
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 5347e064704..754e3ca2f6c 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -427,7 +427,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 	fputs (" autoinline", file);
       if (code == FUNCTION_DECL && DECL_UNINLINABLE (node))
 	fputs (" uninlinable", file);
-      if (code == FUNCTION_DECL && DECL_BUILT_IN (node))
+      if (decl_built_in_p (node))
 	fputs (" built-in", file);
       if (code == FUNCTION_DECL && DECL_STATIC_CHAIN (node))
 	fputs (" static-chain", file);
@@ -502,7 +502,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 	  print_node (file, "size", DECL_SIZE (node), indent + 4);
 	  print_node (file, "unit-size", DECL_SIZE_UNIT (node), indent + 4);
 
-	  if (code != FUNCTION_DECL || DECL_BUILT_IN (node))
+	  if (code != FUNCTION_DECL || decl_built_in_p (node))
 	    indent_to (file, indent + 3);
 
 	  if (DECL_USER_ALIGN (node))
@@ -514,7 +514,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 	    fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
 		     DECL_OFFSET_ALIGN (node));
 
-	  if (code == FUNCTION_DECL && DECL_BUILT_IN (node))
+	  if (decl_built_in_p (node))
 	    {
 	      if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
 		fprintf (file, " built-in: BUILT_IN_MD:%d", DECL_FUNCTION_CODE (node));
diff --git a/gcc/symtab.c b/gcc/symtab.c
index c5464cbe6d7..bda29e813ec 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -2323,7 +2323,7 @@ symtab_node::output_to_lto_symbol_table_p (void)
     return false;
   /* FIXME: Builtins corresponding to real functions probably should have
      symbol table entries.  */
-  if (is_builtin_fn (decl))
+  if (decl_built_in_p (decl))
     return false;
 
   /* We have real symbol that should be in symbol table.  However try to trim
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ca14915ef0d..e6110f8bc83 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -234,9 +234,7 @@ is_tm_irrevocable (tree x)
      irrevocable.  */
   if (TREE_CODE (x) == ADDR_EXPR)
     x = TREE_OPERAND (x, 0);
-  if (TREE_CODE (x) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
+  if (decl_built_in_p (x, BUILT_IN_TM_IRREVOCABLE))
     return true;
 
   return false;
@@ -358,7 +356,7 @@ is_tm_load (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+  return (decl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl)));
 }
 
@@ -374,7 +372,7 @@ is_tm_simple_load (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
       return (fcode == BUILT_IN_TM_LOAD_1
@@ -402,7 +400,7 @@ is_tm_store (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+  return (decl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl)));
 }
 
@@ -418,7 +416,7 @@ is_tm_simple_store (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
       return (fcode == BUILT_IN_TM_STORE_1
@@ -440,9 +438,7 @@ is_tm_simple_store (gimple *stmt)
 static bool
 is_tm_abort (tree fndecl)
 {
-  return (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
+  return decl_built_in_p (fndecl, BUILT_IN_TM_ABORT);
 }
 
 /* Build a GENERIC tree for a user abort.  This is called by front ends
@@ -2007,7 +2003,7 @@ tm_region_init_1 (struct tm_region *region, basic_block bb)
       if (gimple_code (g) == GIMPLE_CALL)
 	{
 	  tree fn = gimple_call_fndecl (g);
-	  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
+	  if (decl_built_in_p (fn, BUILT_IN_NORMAL))
 	    {
 	      if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
 		   || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index a47be1d0362..22285b7e5f0 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -737,7 +737,7 @@ gen_shrink_wrap_conditions (gcall *bi_call, vec<gimple *> conds,
 
   call = bi_call;
   fn = gimple_call_fndecl (call);
-  gcc_assert (fn && DECL_BUILT_IN (fn));
+  gcc_assert (decl_built_in_p (fn));
   fnc = DECL_FUNCTION_CODE (fn);
   *nconds = 0;
 
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 14d66b7a728..9749ab3efba 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3427,7 +3427,7 @@ verify_gimple_call (gcall *stmt)
       return true;
     }
 
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       switch (DECL_FUNCTION_CODE (fndecl))
 	{
@@ -6884,7 +6884,7 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
       /* Remap the region numbers for __builtin_eh_{pointer,filter}.  */
       {
 	tree r, fndecl = gimple_call_fndecl (stmt);
-	if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	  switch (DECL_FUNCTION_CODE (fndecl))
 	    {
 	    case BUILT_IN_EH_COPY_VALUES:
@@ -8304,16 +8304,14 @@ stmt_can_terminate_bb_p (gimple *t)
     }
 
   if (is_gimple_call (t)
-      && fndecl
-      && DECL_BUILT_IN (fndecl)
+      && decl_built_in_p (fndecl)
       && (call_flags & ECF_NOTHROW)
       && !(call_flags & ECF_RETURNS_TWICE)
       /* fork() doesn't really return twice, but the effect of
          wrapping it in __gcov_fork() which calls __gcov_flush()
 	 and clears the counters before forking has the same
 	 effect as returning twice.  Force a fake edge.  */
-      && !(DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	   && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FORK))
+      && !decl_built_in_p (fndecl, BUILT_IN_FORK))
     return false;
 
   if (is_gimple_call (t))
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f367040af45..ecf7d93829e 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -1984,7 +1984,7 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
 	tree fndecl = gimple_call_fndecl (stmt);
 	tree rhs, lhs;
 
-	if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	  switch (DECL_FUNCTION_CODE (fndecl))
 	    {
 	    case BUILT_IN_EH_POINTER:
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index e181468fba9..570a3250fa3 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -1079,7 +1079,7 @@ if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
 		&& !(flags & ECF_LOOPING_CONST_OR_PURE)
 		/* We can only vectorize some builtins at the moment,
 		   so restrict if-conversion to those.  */
-		&& DECL_BUILT_IN (fndecl))
+		&& decl_built_in_p (fndecl))
 	      return true;
 	  }
 	return false;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 2b6bb5c0e31..e42d6cbee8a 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1702,7 +1702,7 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
 	  case GIMPLE_CALL:
 	    {
 	      tree r, fndecl = gimple_call_fndecl (copy);
-	      if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	      if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
 		switch (DECL_FUNCTION_CODE (fndecl))
 		  {
 		  case BUILT_IN_EH_COPY_VALUES:
@@ -1939,8 +1939,7 @@ copy_bb (copy_body_data *id, basic_block bb,
 	  else if (call_stmt
 		   && id->call_stmt
 		   && (decl = gimple_call_fndecl (stmt))
-		   && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-		   && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
+		   && decl_built_in_p (decl, BUILT_IN_VA_ARG_PACK_LEN))
 	    {
 	      /* __builtin_va_arg_pack_len () should be replaced by
 		 the number of anonymous arguments.  */
@@ -4033,7 +4032,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
 	if (gimple_call_internal_p (stmt))
 	  return 0;
 	else if ((decl = gimple_call_fndecl (stmt))
-		 && DECL_BUILT_IN (decl))
+		 && decl_built_in_p (decl))
 	  {
 	    /* Do not special case builtins where we see the body.
 	       This just confuse inliner.  */
@@ -4897,7 +4896,7 @@ fold_marked_statements (int first, hash_set<gimple *> *statements)
 	      gimple *old_stmt = gsi_stmt (gsi);
 	      tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0;
 
-	      if (old_decl && DECL_BUILT_IN (old_decl))
+	      if (decl_built_in_p (old_decl))
 		{
 		  /* Folding builtins can create multiple instructions,
 		     we need to look at all of them.  */
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 3e30f6bc3d4..cc3444b270b 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1498,8 +1498,7 @@ scan_function (void)
 
 		  if (dest)
 		    {
-		      if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
-			  && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
+		      if (decl_built_in_p (dest, BUILT_IN_APPLY_ARGS))
 			encountered_apply_args = true;
 		      if (recursive_call_p (current_function_decl, dest))
 			{
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index d0f799eb39d..5c11b8a853e 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -807,7 +807,7 @@ surely_varying_stmt_p (gimple *stmt)
       tree fndecl, fntype = gimple_call_fntype (stmt);
       if (!gimple_call_lhs (stmt)
 	  || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
-	      && !DECL_BUILT_IN (fndecl)
+	      && !decl_built_in_p (fndecl)
 	      && !lookup_attribute ("assume_aligned",
 				    TYPE_ATTRIBUTES (fntype))
 	      && !lookup_attribute ("alloc_align",
@@ -2559,8 +2559,7 @@ optimize_stack_restore (gimple_stmt_iterator i)
 	continue;
 
       callee = gimple_call_fndecl (stmt);
-      if (!callee
-	  || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
+      if (!decl_built_in_p (callee, BUILT_IN_NORMAL)
 	  /* All regular builtins are ok, just obviously not alloca.  */
 	  || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)))
 	return NULL_TREE;
@@ -2596,9 +2595,7 @@ optimize_stack_restore (gimple_stmt_iterator i)
       if (is_gimple_call (stack_save))
 	{
 	  callee = gimple_call_fndecl (stack_save);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
+	  if (decl_built_in_p (callee, BUILT_IN_STACK_SAVE))
 	    {
 	      gimple_stmt_iterator stack_save_gsi;
 	      tree rhs;
@@ -3195,7 +3192,7 @@ pass_fold_builtins::execute (function *fun)
 	    }
 
 	  callee = gimple_call_fndecl (stmt);
-	  if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+	  if (!decl_built_in_p (callee, BUILT_IN_NORMAL))
 	    {
 	      gsi_next (&i);
 	      continue;
@@ -3369,9 +3366,7 @@ pass_fold_builtins::execute (function *fun)
 	      continue;
 	    }
 	  callee = gimple_call_fndecl (stmt);
-	  if (!callee
-              || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (callee) == fcode)
+	  if (!decl_built_in_p (callee, fcode))
 	    gsi_next (&i);
 	}
     }
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index d23148675c9..498e8c97638 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -223,8 +223,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
     case GIMPLE_CALL:
       {
 	tree callee = gimple_call_fndecl (stmt);
-	if (callee != NULL_TREE
-	    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+	if (decl_built_in_p (callee, BUILT_IN_NORMAL))
 	  switch (DECL_FUNCTION_CODE (callee))
 	    {
 	    case BUILT_IN_MALLOC:
@@ -564,8 +563,7 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
   if (is_gimple_call (def_stmt))
     {
       tree callee = gimple_call_fndecl (def_stmt);
-      if (callee != NULL_TREE
-	  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+      if (decl_built_in_p (callee, BUILT_IN_NORMAL))
 	switch (DECL_FUNCTION_CODE (callee))
 	  {
 	  case BUILT_IN_MALLOC:
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 267880f3b5c..a98c9cd470c 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1985,9 +1985,7 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
 	     folded to integer_one_node by now, it's fairly
 	     certain that the value simply isn't constant.  */
 	  tree callee = gimple_call_fndecl (stmt);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
+	  if (decl_built_in_p (callee, BUILT_IN_CONSTANT_P))
 	    {
 	      propagate_tree_value_into_stmt (&si, integer_zero_node);
 	      stmt = gsi_stmt (si);
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 56078110b39..33ac1dfe478 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1277,8 +1277,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
 		 or mempcpy, with string literal as second argument and
 		 constant length.  */
 	      callee1 = gimple_call_fndecl (stmt1);
-	      if (callee1 == NULL_TREE
-		  || DECL_BUILT_IN_CLASS (callee1) != BUILT_IN_NORMAL
+	      if (!decl_built_in_p (callee1, BUILT_IN_NORMAL)
 		  || gimple_call_num_args (stmt1) != 3)
 		break;
 	      if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY
@@ -2537,8 +2536,7 @@ pass_forwprop::execute (function *fun)
 	    case GIMPLE_CALL:
 	      {
 		tree callee = gimple_call_fndecl (stmt);
-		if (callee != NULL_TREE
-		    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+		if (decl_built_in_p (callee, BUILT_IN_NORMAL))
 		  changed = simplify_builtin_call (&gsi, callee);
 		break;
 	      }
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 01a954eeb1e..cf4a5f789a8 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -471,9 +471,7 @@ stmt_cost (gimple *stmt)
       /* Unless the call is a builtin_constant_p; this always folds to a
 	 constant, so moving it is useless.  */
       fndecl = gimple_call_fndecl (stmt);
-      if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
+      if (decl_built_in_p (fndecl, BUILT_IN_CONSTANT_P))
 	return 0;
 
       return LIM_EXPENSIVE;
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index a90d9d28e4e..ece27143fe4 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -792,8 +792,7 @@ pass_cse_reciprocals::execute (function *fun)
 		  if (ifn == IFN_LAST)
 		    {
 		      fndecl = gimple_call_fndecl (call);
-		      if (!fndecl
-			  || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_MD)
+		      if (!decl_built_in_p (fndecl, BUILT_IN_MD))
 			continue;
 		      fndecl = targetm.builtin_reciprocal (fndecl);
 		      if (!fndecl)
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 43f3313911f..cb59cece717 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1279,7 +1279,7 @@ fully_constant_vn_reference_p (vn_reference_t ref)
   if (op->opcode == CALL_EXPR
       && TREE_CODE (op->op0) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
-      && DECL_BUILT_IN (TREE_OPERAND (op->op0, 0))
+      && decl_built_in_p (TREE_OPERAND (op->op0, 0))
       && operands.length () >= 2
       && operands.length () <= 3)
     {
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index d0792aa38c8..39e51dc9966 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -581,7 +581,7 @@ get_string_length (strinfo *si)
 
       gcc_assert (is_gimple_call (stmt));
       callee = gimple_call_fndecl (stmt);
-      gcc_assert (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL);
+      gcc_assert (decl_built_in_p (callee, BUILT_IN_NORMAL));
       lhs = gimple_call_lhs (stmt);
       /* unshare_strinfo is intentionally not called here.  The (delayed)
 	 transformation of strcpy or strcat into stpcpy is done at the place
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index fd24f84fb14..baad8ec9838 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4074,8 +4074,7 @@ handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> rhsc,
       /* If this is not a real malloc call assume the memory was
 	 initialized and thus may point to global memory.  All
 	 builtin functions with the malloc attribute behave in a sane way.  */
-      if (!fndecl
-	  || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+      if (!decl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	make_constraint_from (vi, nonlocal_id);
       tmpc.var = vi->id;
       tmpc.offset = 0;
@@ -4728,8 +4727,7 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
   tree fndecl = gimple_call_fndecl (t);
   varinfo_t fi;
 
-  if (fndecl != NULL_TREE
-      && DECL_BUILT_IN (fndecl)
+  if (decl_built_in_p (fndecl)
       && find_func_aliases_for_builtin_call (fn, t))
     return;
 
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 4339520039b..d575c689d38 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -573,7 +573,7 @@ find_replaceable_in_bb (temp_expr_table *tab, basic_block bb)
 {
   gimple_stmt_iterator bsi;
   gimple *stmt;
-  tree def, use, fndecl;
+  tree def, use;
   int partition;
   var_map map = tab->map;
   ssa_op_iter iter;
@@ -682,8 +682,7 @@ find_replaceable_in_bb (temp_expr_table *tab, basic_block bb)
 	 replacement over BUILT_IN calls since many will expand to inline
 	 insns instead of a true call.  */
       if (is_gimple_call (stmt)
-	  && !((fndecl = gimple_call_fndecl (stmt))
-	       && DECL_BUILT_IN (fndecl)))
+	  && !decl_built_in_p (gimple_call_fndecl (stmt)))
 	cur_call_cnt++;
 
       /* Increment counter if this statement sets a local
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index c8594851957..a84e83559a2 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -693,8 +693,7 @@ optimize_va_list_gpr_fpr_size (function *fun)
 	    continue;
 
 	  callee = gimple_call_fndecl (stmt);
-	  if (!callee
-	      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+	  if (!decl_built_in_p (callee, BUILT_IN_NORMAL))
 	    continue;
 
 	  switch (DECL_FUNCTION_CODE (callee))
@@ -866,10 +865,8 @@ optimize_va_list_gpr_fpr_size (function *fun)
 	    {
 	      tree callee = gimple_call_fndecl (stmt);
 
-	      if (callee
-		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-		  && (DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_START
-		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END))
+	      if (decl_built_in_p (callee, BUILT_IN_VA_START)
+		  || decl_built_in_p (callee, BUILT_IN_VA_END))
 		continue;
 	    }
 
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 9ebed9de524..4c79b15f122 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -476,7 +476,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
   tail_recursion = false;
   func = gimple_call_fndecl (call);
   if (func
-      && !DECL_BUILT_IN (func)
+      && !decl_built_in_p (func)
       && recursive_call_p (current_function_decl, func))
     {
       tree arg;
diff --git a/gcc/tree.c b/gcc/tree.c
index f00a519b302..69a8af24a4f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5240,7 +5240,7 @@ need_assembler_name_p (tree decl)
     {
       /* Do not set assembler name on builtins.  Allow RTL expansion to
 	 decide whether to expand inline or via a regular call.  */
-      if (DECL_BUILT_IN (decl)
+      if (decl_built_in_p (decl)
 	  && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND)
 	return false;
 
@@ -5371,10 +5371,9 @@ free_lang_data_in_decl (tree decl)
 	 nodes and thus we can't use TREE_CHAIN in multiple lists.  */
       tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
       while (*nextp)
-        {
-          tree var = *nextp;
-          if (TREE_CODE (var) == FUNCTION_DECL
-              && DECL_BUILT_IN (var))
+	{
+	  tree var = *nextp;
+	  if (decl_built_in_p (var))
 	    *nextp = TREE_CHAIN (var);
 	  else
 	    nextp = &TREE_CHAIN (var);
@@ -9100,7 +9099,7 @@ get_call_combined_fn (const_tree call)
     return as_combined_fn (CALL_EXPR_IFN (call));
 
   tree fndecl = get_callee_fndecl (call);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (decl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return as_combined_fn (DECL_FUNCTION_CODE (fndecl));
 
   return CFN_LAST;
diff --git a/gcc/tree.h b/gcc/tree.h
index 5d4f034e008..be0c6ceca62 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2995,25 +2995,11 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
 #define DECL_STRUCT_FUNCTION(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->function_decl.f)
 
-/* In a FUNCTION_DECL, nonzero means a built in function of a
-   standard library or more generally a built in function that is
-   recognized by optimizers and expanders.
-
-   Note that it is different from the DECL_IS_BUILTIN accessor.  For
-   instance, user declared prototypes of C library functions are not
-   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
-#define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
 
 /* For a builtin function, identify which part of the compiler defined it.  */
 #define DECL_BUILT_IN_CLASS(NODE) \
    (FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
 
-/* For a function declaration, return true if NODE is non-null and it is
-   a builtin of a CLASS with requested NAME.  */
-#define DECL_BUILT_IN_P(NODE, CLASS, NAME) \
-  (NODE != NULL_TREE && DECL_BUILT_IN_CLASS (NODE) == CLASS \
-   && DECL_FUNCTION_CODE (NODE) == NAME)
-
 /* In FUNCTION_DECL, a chain of ..._DECL nodes.  */
 #define DECL_ARGUMENTS(NODE) \
    (FUNCTION_DECL_CHECK (NODE)->function_decl.arguments)
@@ -5848,4 +5834,40 @@ type_has_mode_precision_p (const_tree t)
   return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t)));
 }
 
+/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
+   standard library or more generally a built in function that is
+   recognized by optimizers and expanders.
+
+   Note that it is different from the DECL_IS_BUILTIN accessor.  For
+   instance, user declared prototypes of C library functions are not
+   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
+
+inline bool
+decl_built_in_p (const_tree node)
+{
+  return (node != NULL_TREE
+	  && TREE_CODE (node) == FUNCTION_DECL
+	  && DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
+}
+
+/* For a FUNCTION_DECL NODE, return true when a function is
+   a built-in of class KLASS.  */
+
+inline bool
+decl_built_in_p (const_tree node, built_in_class klass)
+{
+  return (decl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass);
+}
+
+
+/* For a FUNCTION_DECL NODE, return true when a function is
+   a built-in of class KLASS with name equal to NAME.  */
+
+inline bool
+decl_built_in_p (const_tree node, int name,
+		 built_in_class klass = BUILT_IN_NORMAL)
+{
+  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
+}
+
 #endif  /* GCC_TREE_H  */
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 722f5702612..27d91b5cf22 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -662,8 +662,7 @@ ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
 bool
 is_ubsan_builtin_p (tree t)
 {
-  return TREE_CODE (t) == FUNCTION_DECL
-	 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
+  return decl_built_in_p (t, BUILT_IN_NORMAL)
 	 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
 		     "__builtin___ubsan_", 18) == 0;
 }
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 0d3609e2807..193855247f4 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2401,7 +2401,7 @@ static hash_set<tree> *pending_assemble_externals_set;
 static bool
 incorporeal_function_p (tree decl)
 {
-  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
+  if (decl_built_in_p (decl))
     {
       const char *name;
Richard Biener Aug. 23, 2018, 11:58 a.m. UTC | #5
On Thu, Aug 23, 2018 at 12:46 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 08/20/2018 10:34 AM, Richard Biener wrote:
> > On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 08/14/2018 06:02 PM, Martin Sebor wrote:
> >>> On 08/14/2018 03:06 AM, Martin Liška wrote:
> >>>> Hi.
> >>>>
> >>>> The patch adds more usages of the new macro. I hope it improves
> >>>> readability of code.
> >>>
> >>> I think it does :)  I see that most invocations of it in your
> >>> patch are with BUILT_IN_NORMAL as the second argument.  Is
> >>> the argument implied by the last argument?  E.g., in
> >>>
> >>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
> >>>
> >>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
> >>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
> >>> be eliminated?  (Both to make the invocation less verbose and
> >>> to avoid the mistake of using the macro with the wrong class.)
> >>
> >> If I see correctly not, there are separate enums:
> >>
> >> BUILT_IN_MD:
> >>
> >> enum ix86_builtins {
> >>   IX86_BUILTIN_MASKMOVQ,
> >>   IX86_BUILTIN_LDMXCSR,
> >>   IX86_BUILTIN_STMXCSR,
> >> ...
> >> }
> >>
> >> BUILT_IN_NORMAL:
> >> enum built_in_function {
> >> BUILT_IN_NONE,
> >> BUILT_IN_ACOS,
> >> BUILT_IN_ACOSF,
> >> ...
> >> }
> >>
> >> So the enum values overlap and thus one needs the class.
> >>
> >>
> >>>
> >>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
> >>> to omit it.
> >>
> >> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
> >> right now.
> >
> > Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
> > and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).
>
> Agree.
>
> >
> > I think following what gimple.h does would be nicer which means using
> > inline functions and overloading.
> >
> > decl_built_in_p (tree);
> > decl_built_in_p (tree, enum built_in_class);
> > decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL
>
> Yes, that's easier to use!
>
> >
> > Can you rework things this way please?  (ok, for gimple those are not inlines)
>
> Done in patch that can bootstrap and survives regression tests.
> Ready for trunk?

+/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
+   standard library or more generally a built in function that is
+   recognized by optimizers and expanders.
+
+   Note that it is different from the DECL_IS_BUILTIN accessor.  For
+   instance, user declared prototypes of C library functions are not
+   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
+
+inline bool
+decl_built_in_p (const_tree node)
+{
+  return (node != NULL_TREE
+         && TREE_CODE (node) == FUNCTION_DECL

You document for a FUNCTION_DECL NODE but the check
for FUNCTION_DECL anyway.  I realize doing all (possibly redundant)
checks in decl_built_in_p is convenient at callers, but at least update
docs accordingly?  In reality I somewhat prefer

inline bool
decl_built_in_p (const_tree node)
{
  return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
}

and

inline bool
decl_built_in_p (const_tree node, built_in_class klass)
{
  return DECL_BUILT_IN_CLASS (node) == klass;
}

esp. since the built_in_class overload doesn't work for
NOT_BUILT_IN for your variant.

And if we're at changing, maybe call the functions
fndecl_built_in_p to make it clear we're expecting FUNCTION_DECLs...

+/* For a FUNCTION_DECL NODE, return true when a function is
+   a built-in of class KLASS with name equal to NAME.  */
+
+inline bool
+decl_built_in_p (const_tree node, int name,

why's that 'int' and not built_in_function?

+                built_in_class klass = BUILT_IN_NORMAL)

This deviates from the gimple.h routines as well (also builtin vs. built_in, but
built_in is better).

+{
+  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
+}


> Martin
>
> >
> > Thanks,
> > Richard.
> >
> >> Martin
> >>
> >>>
> >>> Martin
> >>>
> >>>>
> >>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> >>>>
> >>>> Ready to be installed?
> >>>> Martin
> >>>>
> >>>> gcc/ChangeLog:
> >>>>
> >>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>
> >>>>     * tree.h (DECL_BUILT_IN_P): Add also check
> >>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
> >>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
> >>>>     (fold_builtin_call_array): Likewise.
> >>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
> >>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
> >>>>     (cgraph_node::verify_node): Likewise.
> >>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
> >>>>     * dse.c (scan_insn): Likewise.
> >>>>     * fold-const.c (fold_binary_loc): Likewise.
> >>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
> >>>>     * gimple.c (gimple_call_builtin_p): Likewise.
> >>>>     * gimplify.c (gimplify_call_expr): Likewise.
> >>>>     (gimple_boolify): Likewise.
> >>>>     (gimplify_modify_expr): Likewise.
> >>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
> >>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
> >>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
> >>>>     (is_tm_abort): Likewise.
> >>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
> >>>>     * tree-inline.c (copy_bb): Likewise.
> >>>>     * tree-sra.c (scan_function): Likewise.
> >>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
> >>>>     (pass_fold_builtins::execute): Likewise.
> >>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
> >>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
> >>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
> >>>>
> >>>> gcc/c/ChangeLog:
> >>>>
> >>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>
> >>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
> >>>>         Use DECL_BUILT_IN_P macro.
> >>>>
> >>>> gcc/cp/ChangeLog:
> >>>>
> >>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>
> >>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
> >>>>     (cxx_eval_builtin_function_call): Likewise.
> >>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
> >>>>     (cp_fold): Likewise.
> >>>>     * semantics.c (finish_call_expr): Likewise.
> >>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
> >>>> ---
> >>>>  gcc/builtins.c            | 10 ++--------
> >>>>  gcc/c/c-parser.c          |  9 +++------
> >>>>  gcc/cgraph.c              | 13 ++++++-------
> >>>>  gcc/cgraphclones.c        |  4 ++--
> >>>>  gcc/cp/constexpr.c        | 12 +++++-------
> >>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
> >>>>  gcc/cp/semantics.c        |  4 +---
> >>>>  gcc/cp/tree.c             |  5 ++---
> >>>>  gcc/dse.c                 |  5 ++---
> >>>>  gcc/fold-const.c          |  4 +---
> >>>>  gcc/gimple-pretty-print.c |  4 +---
> >>>>  gcc/gimple.c              |  3 +--
> >>>>  gcc/gimplify.c            | 14 ++++----------
> >>>>  gcc/ipa-fnsummary.c       |  8 ++++----
> >>>>  gcc/omp-low.c             |  5 ++---
> >>>>  gcc/trans-mem.c           |  8 ++------
> >>>>  gcc/tree-cfg.c            |  3 +--
> >>>>  gcc/tree-inline.c         |  4 ++--
> >>>>  gcc/tree-sra.c            |  4 ++--
> >>>>  gcc/tree-ssa-ccp.c        |  8 ++------
> >>>>  gcc/tree-ssa-dom.c        |  4 +---
> >>>>  gcc/tree-ssa-loop-im.c    |  4 +---
> >>>>  gcc/tree-stdarg.c         |  6 ++----
> >>>>  gcc/tree.h                |  4 +++-
> >>>>  24 files changed, 56 insertions(+), 101 deletions(-)
> >>>>
> >>>>
> >>>
> >>
>
Martin Liška Aug. 23, 2018, 1:30 p.m. UTC | #6
On 08/23/2018 01:58 PM, Richard Biener wrote:
> On Thu, Aug 23, 2018 at 12:46 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 08/20/2018 10:34 AM, Richard Biener wrote:
>>> On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> On 08/14/2018 06:02 PM, Martin Sebor wrote:
>>>>> On 08/14/2018 03:06 AM, Martin Liška wrote:
>>>>>> Hi.
>>>>>>
>>>>>> The patch adds more usages of the new macro. I hope it improves
>>>>>> readability of code.
>>>>>
>>>>> I think it does :)  I see that most invocations of it in your
>>>>> patch are with BUILT_IN_NORMAL as the second argument.  Is
>>>>> the argument implied by the last argument?  E.g., in
>>>>>
>>>>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
>>>>>
>>>>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
>>>>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
>>>>> be eliminated?  (Both to make the invocation less verbose and
>>>>> to avoid the mistake of using the macro with the wrong class.)
>>>>
>>>> If I see correctly not, there are separate enums:
>>>>
>>>> BUILT_IN_MD:
>>>>
>>>> enum ix86_builtins {
>>>>   IX86_BUILTIN_MASKMOVQ,
>>>>   IX86_BUILTIN_LDMXCSR,
>>>>   IX86_BUILTIN_STMXCSR,
>>>> ...
>>>> }
>>>>
>>>> BUILT_IN_NORMAL:
>>>> enum built_in_function {
>>>> BUILT_IN_NONE,
>>>> BUILT_IN_ACOS,
>>>> BUILT_IN_ACOSF,
>>>> ...
>>>> }
>>>>
>>>> So the enum values overlap and thus one needs the class.
>>>>
>>>>
>>>>>
>>>>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
>>>>> to omit it.
>>>>
>>>> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
>>>> right now.
>>>
>>> Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
>>> and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).
>>
>> Agree.
>>
>>>
>>> I think following what gimple.h does would be nicer which means using
>>> inline functions and overloading.
>>>
>>> decl_built_in_p (tree);
>>> decl_built_in_p (tree, enum built_in_class);
>>> decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL
>>
>> Yes, that's easier to use!
>>
>>>
>>> Can you rework things this way please?  (ok, for gimple those are not inlines)
>>
>> Done in patch that can bootstrap and survives regression tests.
>> Ready for trunk?
> 
> +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
> +   standard library or more generally a built in function that is
> +   recognized by optimizers and expanders.
> +
> +   Note that it is different from the DECL_IS_BUILTIN accessor.  For
> +   instance, user declared prototypes of C library functions are not
> +   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
> +
> +inline bool
> +decl_built_in_p (const_tree node)
> +{
> +  return (node != NULL_TREE
> +         && TREE_CODE (node) == FUNCTION_DECL
> 
> You document for a FUNCTION_DECL NODE but the check
> for FUNCTION_DECL anyway.  I realize doing all (possibly redundant)
> checks in decl_built_in_p is convenient at callers, but at least update
> docs accordingly?  In reality I somewhat prefer

Yes, please let stay with version that does the checks. It can provide
more readable code like:

       /* If last argument is __builtin_va_arg_pack (), arguments to this
         function are not finalized yet.  Defer folding until they are.  */
       if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
        {
          tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
-         if (fndecl2
-             && TREE_CODE (fndecl2) == FUNCTION_DECL
-             && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-             && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+         if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
            return NULL_TREE;
        }
       if (avoid_folding_inline_builtin (fndecl))

> 
> inline bool
> decl_built_in_p (const_tree node)
> {
>   return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
> }
> 
> and
> 
> inline bool
> decl_built_in_p (const_tree node, built_in_class klass)
> {
>   return DECL_BUILT_IN_CLASS (node) == klass;
> }
> 
> esp. since the built_in_class overload doesn't work for
> NOT_BUILT_IN for your variant.

That's true. One should probably use DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN
in this case.

> 
> And if we're at changing, maybe call the functions
> fndecl_built_in_p to make it clear we're expecting FUNCTION_DECLs...
> 
> +/* For a FUNCTION_DECL NODE, return true when a function is
> +   a built-in of class KLASS with name equal to NAME.  */
> +
> +inline bool
> +decl_built_in_p (const_tree node, int name,
> 
> why's that 'int' and not built_in_function?

Because we want to also call it for e.g. cp_built_in_function
enum types:

gcc/cp/cp-gimplify.c:2498:26: error: no matching function for call to ‘decl_built_in_p(tree_node*&, cp_built_in_function, built_in_class)’

Note that:
gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)

is only used for BUILT_IN_NORMAL, which decl_built_in_p should handle also FE and TARGET codes.

> 
> +                built_in_class klass = BUILT_IN_NORMAL)
> 
> This deviates from the gimple.h routines as well (also builtin vs. built_in, but
> built_in is better).

As you with here, I'm fine with both. Are you fine with the consensus that the functions will
do check for null argument and TREE_CODE check?

Martin

> 
> +{
> +  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
> +}
> 
> 
>> Martin
>>
>>>
>>> Thanks,
>>> Richard.
>>>
>>>> Martin
>>>>
>>>>>
>>>>> Martin
>>>>>
>>>>>>
>>>>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>>>>>
>>>>>> Ready to be installed?
>>>>>> Martin
>>>>>>
>>>>>> gcc/ChangeLog:
>>>>>>
>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>
>>>>>>     * tree.h (DECL_BUILT_IN_P): Add also check
>>>>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
>>>>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
>>>>>>     (fold_builtin_call_array): Likewise.
>>>>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
>>>>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
>>>>>>     (cgraph_node::verify_node): Likewise.
>>>>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
>>>>>>     * dse.c (scan_insn): Likewise.
>>>>>>     * fold-const.c (fold_binary_loc): Likewise.
>>>>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
>>>>>>     * gimple.c (gimple_call_builtin_p): Likewise.
>>>>>>     * gimplify.c (gimplify_call_expr): Likewise.
>>>>>>     (gimple_boolify): Likewise.
>>>>>>     (gimplify_modify_expr): Likewise.
>>>>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
>>>>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
>>>>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
>>>>>>     (is_tm_abort): Likewise.
>>>>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
>>>>>>     * tree-inline.c (copy_bb): Likewise.
>>>>>>     * tree-sra.c (scan_function): Likewise.
>>>>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
>>>>>>     (pass_fold_builtins::execute): Likewise.
>>>>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
>>>>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
>>>>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
>>>>>>
>>>>>> gcc/c/ChangeLog:
>>>>>>
>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>
>>>>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
>>>>>>         Use DECL_BUILT_IN_P macro.
>>>>>>
>>>>>> gcc/cp/ChangeLog:
>>>>>>
>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>
>>>>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
>>>>>>     (cxx_eval_builtin_function_call): Likewise.
>>>>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
>>>>>>     (cp_fold): Likewise.
>>>>>>     * semantics.c (finish_call_expr): Likewise.
>>>>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
>>>>>> ---
>>>>>>  gcc/builtins.c            | 10 ++--------
>>>>>>  gcc/c/c-parser.c          |  9 +++------
>>>>>>  gcc/cgraph.c              | 13 ++++++-------
>>>>>>  gcc/cgraphclones.c        |  4 ++--
>>>>>>  gcc/cp/constexpr.c        | 12 +++++-------
>>>>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
>>>>>>  gcc/cp/semantics.c        |  4 +---
>>>>>>  gcc/cp/tree.c             |  5 ++---
>>>>>>  gcc/dse.c                 |  5 ++---
>>>>>>  gcc/fold-const.c          |  4 +---
>>>>>>  gcc/gimple-pretty-print.c |  4 +---
>>>>>>  gcc/gimple.c              |  3 +--
>>>>>>  gcc/gimplify.c            | 14 ++++----------
>>>>>>  gcc/ipa-fnsummary.c       |  8 ++++----
>>>>>>  gcc/omp-low.c             |  5 ++---
>>>>>>  gcc/trans-mem.c           |  8 ++------
>>>>>>  gcc/tree-cfg.c            |  3 +--
>>>>>>  gcc/tree-inline.c         |  4 ++--
>>>>>>  gcc/tree-sra.c            |  4 ++--
>>>>>>  gcc/tree-ssa-ccp.c        |  8 ++------
>>>>>>  gcc/tree-ssa-dom.c        |  4 +---
>>>>>>  gcc/tree-ssa-loop-im.c    |  4 +---
>>>>>>  gcc/tree-stdarg.c         |  6 ++----
>>>>>>  gcc/tree.h                |  4 +++-
>>>>>>  24 files changed, 56 insertions(+), 101 deletions(-)
>>>>>>
>>>>>>
>>>>>
>>>>
>>
Richard Biener Aug. 23, 2018, 1:58 p.m. UTC | #7
On Thu, Aug 23, 2018 at 3:30 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 08/23/2018 01:58 PM, Richard Biener wrote:
> > On Thu, Aug 23, 2018 at 12:46 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 08/20/2018 10:34 AM, Richard Biener wrote:
> >>> On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> On 08/14/2018 06:02 PM, Martin Sebor wrote:
> >>>>> On 08/14/2018 03:06 AM, Martin Liška wrote:
> >>>>>> Hi.
> >>>>>>
> >>>>>> The patch adds more usages of the new macro. I hope it improves
> >>>>>> readability of code.
> >>>>>
> >>>>> I think it does :)  I see that most invocations of it in your
> >>>>> patch are with BUILT_IN_NORMAL as the second argument.  Is
> >>>>> the argument implied by the last argument?  E.g., in
> >>>>>
> >>>>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
> >>>>>
> >>>>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
> >>>>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
> >>>>> be eliminated?  (Both to make the invocation less verbose and
> >>>>> to avoid the mistake of using the macro with the wrong class.)
> >>>>
> >>>> If I see correctly not, there are separate enums:
> >>>>
> >>>> BUILT_IN_MD:
> >>>>
> >>>> enum ix86_builtins {
> >>>>   IX86_BUILTIN_MASKMOVQ,
> >>>>   IX86_BUILTIN_LDMXCSR,
> >>>>   IX86_BUILTIN_STMXCSR,
> >>>> ...
> >>>> }
> >>>>
> >>>> BUILT_IN_NORMAL:
> >>>> enum built_in_function {
> >>>> BUILT_IN_NONE,
> >>>> BUILT_IN_ACOS,
> >>>> BUILT_IN_ACOSF,
> >>>> ...
> >>>> }
> >>>>
> >>>> So the enum values overlap and thus one needs the class.
> >>>>
> >>>>
> >>>>>
> >>>>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
> >>>>> to omit it.
> >>>>
> >>>> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
> >>>> right now.
> >>>
> >>> Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
> >>> and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).
> >>
> >> Agree.
> >>
> >>>
> >>> I think following what gimple.h does would be nicer which means using
> >>> inline functions and overloading.
> >>>
> >>> decl_built_in_p (tree);
> >>> decl_built_in_p (tree, enum built_in_class);
> >>> decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL
> >>
> >> Yes, that's easier to use!
> >>
> >>>
> >>> Can you rework things this way please?  (ok, for gimple those are not inlines)
> >>
> >> Done in patch that can bootstrap and survives regression tests.
> >> Ready for trunk?
> >
> > +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
> > +   standard library or more generally a built in function that is
> > +   recognized by optimizers and expanders.
> > +
> > +   Note that it is different from the DECL_IS_BUILTIN accessor.  For
> > +   instance, user declared prototypes of C library functions are not
> > +   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
> > +
> > +inline bool
> > +decl_built_in_p (const_tree node)
> > +{
> > +  return (node != NULL_TREE
> > +         && TREE_CODE (node) == FUNCTION_DECL
> >
> > You document for a FUNCTION_DECL NODE but the check
> > for FUNCTION_DECL anyway.  I realize doing all (possibly redundant)
> > checks in decl_built_in_p is convenient at callers, but at least update
> > docs accordingly?  In reality I somewhat prefer
>
> Yes, please let stay with version that does the checks. It can provide
> more readable code like:
>
>        /* If last argument is __builtin_va_arg_pack (), arguments to this
>          function are not finalized yet.  Defer folding until they are.  */
>        if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
>         {
>           tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
> -         if (fndecl2
> -             && TREE_CODE (fndecl2) == FUNCTION_DECL
> -             && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
> -             && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
> +         if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
>             return NULL_TREE;
>         }
>        if (avoid_folding_inline_builtin (fndecl))

But here the TREE_CODE (fndecl2) == FUNCTION_DECL check is redundant
(get_callee_fndecl always returns a FUNCTION_DECL).  So it would become

  if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))

which is IMHO good enough.

> >
> > inline bool
> > decl_built_in_p (const_tree node)
> > {
> >   return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
> > }
> >
> > and
> >
> > inline bool
> > decl_built_in_p (const_tree node, built_in_class klass)
> > {
> >   return DECL_BUILT_IN_CLASS (node) == klass;
> > }
> >
> > esp. since the built_in_class overload doesn't work for
> > NOT_BUILT_IN for your variant.
>
> That's true. One should probably use DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN
> in this case.
>
> >
> > And if we're at changing, maybe call the functions
> > fndecl_built_in_p to make it clear we're expecting FUNCTION_DECLs...
> >
> > +/* For a FUNCTION_DECL NODE, return true when a function is
> > +   a built-in of class KLASS with name equal to NAME.  */
> > +
> > +inline bool
> > +decl_built_in_p (const_tree node, int name,
> >
> > why's that 'int' and not built_in_function?
>
> Because we want to also call it for e.g. cp_built_in_function
> enum types:
>
> gcc/cp/cp-gimplify.c:2498:26: error: no matching function for call to ‘decl_built_in_p(tree_node*&, cp_built_in_function, built_in_class)’
>
> Note that:
> gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
>
> is only used for BUILT_IN_NORMAL, which decl_built_in_p should handle also FE and TARGET codes.

I know ...

> >
> > +                built_in_class klass = BUILT_IN_NORMAL)

So without the default arg we could make two overloads:

fndecl_built_in_p (const_tree, enum built_in_function)
fndecl_built_in_p (const_tree, int, enum built_in_class)

and keep the type checking?

> > This deviates from the gimple.h routines as well (also builtin vs. built_in, but
> > built_in is better).
>
> As you with here, I'm fine with both. Are you fine with the consensus that the functions will
> do check for null argument and TREE_CODE check?

Not yet ;)  The extra checks are not going to be optimized away in
those places that do
not need them I think.  Any more convincing examples?

Richard.

> Martin
>
> >
> > +{
> > +  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
> > +}
> >
> >
> >> Martin
> >>
> >>>
> >>> Thanks,
> >>> Richard.
> >>>
> >>>> Martin
> >>>>
> >>>>>
> >>>>> Martin
> >>>>>
> >>>>>>
> >>>>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> >>>>>>
> >>>>>> Ready to be installed?
> >>>>>> Martin
> >>>>>>
> >>>>>> gcc/ChangeLog:
> >>>>>>
> >>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>>>
> >>>>>>     * tree.h (DECL_BUILT_IN_P): Add also check
> >>>>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
> >>>>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
> >>>>>>     (fold_builtin_call_array): Likewise.
> >>>>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
> >>>>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
> >>>>>>     (cgraph_node::verify_node): Likewise.
> >>>>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
> >>>>>>     * dse.c (scan_insn): Likewise.
> >>>>>>     * fold-const.c (fold_binary_loc): Likewise.
> >>>>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
> >>>>>>     * gimple.c (gimple_call_builtin_p): Likewise.
> >>>>>>     * gimplify.c (gimplify_call_expr): Likewise.
> >>>>>>     (gimple_boolify): Likewise.
> >>>>>>     (gimplify_modify_expr): Likewise.
> >>>>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
> >>>>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
> >>>>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
> >>>>>>     (is_tm_abort): Likewise.
> >>>>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
> >>>>>>     * tree-inline.c (copy_bb): Likewise.
> >>>>>>     * tree-sra.c (scan_function): Likewise.
> >>>>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
> >>>>>>     (pass_fold_builtins::execute): Likewise.
> >>>>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
> >>>>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
> >>>>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
> >>>>>>
> >>>>>> gcc/c/ChangeLog:
> >>>>>>
> >>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>>>
> >>>>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
> >>>>>>         Use DECL_BUILT_IN_P macro.
> >>>>>>
> >>>>>> gcc/cp/ChangeLog:
> >>>>>>
> >>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>>>
> >>>>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
> >>>>>>     (cxx_eval_builtin_function_call): Likewise.
> >>>>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
> >>>>>>     (cp_fold): Likewise.
> >>>>>>     * semantics.c (finish_call_expr): Likewise.
> >>>>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
> >>>>>> ---
> >>>>>>  gcc/builtins.c            | 10 ++--------
> >>>>>>  gcc/c/c-parser.c          |  9 +++------
> >>>>>>  gcc/cgraph.c              | 13 ++++++-------
> >>>>>>  gcc/cgraphclones.c        |  4 ++--
> >>>>>>  gcc/cp/constexpr.c        | 12 +++++-------
> >>>>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
> >>>>>>  gcc/cp/semantics.c        |  4 +---
> >>>>>>  gcc/cp/tree.c             |  5 ++---
> >>>>>>  gcc/dse.c                 |  5 ++---
> >>>>>>  gcc/fold-const.c          |  4 +---
> >>>>>>  gcc/gimple-pretty-print.c |  4 +---
> >>>>>>  gcc/gimple.c              |  3 +--
> >>>>>>  gcc/gimplify.c            | 14 ++++----------
> >>>>>>  gcc/ipa-fnsummary.c       |  8 ++++----
> >>>>>>  gcc/omp-low.c             |  5 ++---
> >>>>>>  gcc/trans-mem.c           |  8 ++------
> >>>>>>  gcc/tree-cfg.c            |  3 +--
> >>>>>>  gcc/tree-inline.c         |  4 ++--
> >>>>>>  gcc/tree-sra.c            |  4 ++--
> >>>>>>  gcc/tree-ssa-ccp.c        |  8 ++------
> >>>>>>  gcc/tree-ssa-dom.c        |  4 +---
> >>>>>>  gcc/tree-ssa-loop-im.c    |  4 +---
> >>>>>>  gcc/tree-stdarg.c         |  6 ++----
> >>>>>>  gcc/tree.h                |  4 +++-
> >>>>>>  24 files changed, 56 insertions(+), 101 deletions(-)
> >>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>
>
Martin Liška Aug. 23, 2018, 2:43 p.m. UTC | #8
On 08/23/2018 03:58 PM, Richard Biener wrote:
> On Thu, Aug 23, 2018 at 3:30 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 08/23/2018 01:58 PM, Richard Biener wrote:
>>> On Thu, Aug 23, 2018 at 12:46 PM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> On 08/20/2018 10:34 AM, Richard Biener wrote:
>>>>> On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
>>>>>>
>>>>>> On 08/14/2018 06:02 PM, Martin Sebor wrote:
>>>>>>> On 08/14/2018 03:06 AM, Martin Liška wrote:
>>>>>>>> Hi.
>>>>>>>>
>>>>>>>> The patch adds more usages of the new macro. I hope it improves
>>>>>>>> readability of code.
>>>>>>>
>>>>>>> I think it does :)  I see that most invocations of it in your
>>>>>>> patch are with BUILT_IN_NORMAL as the second argument.  Is
>>>>>>> the argument implied by the last argument?  E.g., in
>>>>>>>
>>>>>>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
>>>>>>>
>>>>>>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
>>>>>>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
>>>>>>> be eliminated?  (Both to make the invocation less verbose and
>>>>>>> to avoid the mistake of using the macro with the wrong class.)
>>>>>>
>>>>>> If I see correctly not, there are separate enums:
>>>>>>
>>>>>> BUILT_IN_MD:
>>>>>>
>>>>>> enum ix86_builtins {
>>>>>>   IX86_BUILTIN_MASKMOVQ,
>>>>>>   IX86_BUILTIN_LDMXCSR,
>>>>>>   IX86_BUILTIN_STMXCSR,
>>>>>> ...
>>>>>> }
>>>>>>
>>>>>> BUILT_IN_NORMAL:
>>>>>> enum built_in_function {
>>>>>> BUILT_IN_NONE,
>>>>>> BUILT_IN_ACOS,
>>>>>> BUILT_IN_ACOSF,
>>>>>> ...
>>>>>> }
>>>>>>
>>>>>> So the enum values overlap and thus one needs the class.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
>>>>>>> to omit it.
>>>>>>
>>>>>> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
>>>>>> right now.
>>>>>
>>>>> Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
>>>>> and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).
>>>>
>>>> Agree.
>>>>
>>>>>
>>>>> I think following what gimple.h does would be nicer which means using
>>>>> inline functions and overloading.
>>>>>
>>>>> decl_built_in_p (tree);
>>>>> decl_built_in_p (tree, enum built_in_class);
>>>>> decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL
>>>>
>>>> Yes, that's easier to use!
>>>>
>>>>>
>>>>> Can you rework things this way please?  (ok, for gimple those are not inlines)
>>>>
>>>> Done in patch that can bootstrap and survives regression tests.
>>>> Ready for trunk?
>>>
>>> +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
>>> +   standard library or more generally a built in function that is
>>> +   recognized by optimizers and expanders.
>>> +
>>> +   Note that it is different from the DECL_IS_BUILTIN accessor.  For
>>> +   instance, user declared prototypes of C library functions are not
>>> +   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
>>> +
>>> +inline bool
>>> +decl_built_in_p (const_tree node)
>>> +{
>>> +  return (node != NULL_TREE
>>> +         && TREE_CODE (node) == FUNCTION_DECL
>>>
>>> You document for a FUNCTION_DECL NODE but the check
>>> for FUNCTION_DECL anyway.  I realize doing all (possibly redundant)
>>> checks in decl_built_in_p is convenient at callers, but at least update
>>> docs accordingly?  In reality I somewhat prefer
>>
>> Yes, please let stay with version that does the checks. It can provide
>> more readable code like:
>>
>>        /* If last argument is __builtin_va_arg_pack (), arguments to this
>>          function are not finalized yet.  Defer folding until they are.  */
>>        if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
>>         {
>>           tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
>> -         if (fndecl2
>> -             && TREE_CODE (fndecl2) == FUNCTION_DECL
>> -             && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
>> -             && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
>> +         if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
>>             return NULL_TREE;
>>         }
>>        if (avoid_folding_inline_builtin (fndecl))
> 
> But here the TREE_CODE (fndecl2) == FUNCTION_DECL check is redundant
> (get_callee_fndecl always returns a FUNCTION_DECL).  So it would become
> 
>   if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
> 
> which is IMHO good enough.

Ok, let's do it this way.

> 
>>>
>>> inline bool
>>> decl_built_in_p (const_tree node)
>>> {
>>>   return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
>>> }
>>>
>>> and
>>>
>>> inline bool
>>> decl_built_in_p (const_tree node, built_in_class klass)
>>> {
>>>   return DECL_BUILT_IN_CLASS (node) == klass;
>>> }
>>>
>>> esp. since the built_in_class overload doesn't work for
>>> NOT_BUILT_IN for your variant.
>>
>> That's true. One should probably use DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN
>> in this case.
>>
>>>
>>> And if we're at changing, maybe call the functions
>>> fndecl_built_in_p to make it clear we're expecting FUNCTION_DECLs...
>>>
>>> +/* For a FUNCTION_DECL NODE, return true when a function is
>>> +   a built-in of class KLASS with name equal to NAME.  */
>>> +
>>> +inline bool
>>> +decl_built_in_p (const_tree node, int name,
>>>
>>> why's that 'int' and not built_in_function?
>>
>> Because we want to also call it for e.g. cp_built_in_function
>> enum types:
>>
>> gcc/cp/cp-gimplify.c:2498:26: error: no matching function for call to ‘decl_built_in_p(tree_node*&, cp_built_in_function, built_in_class)’
>>
>> Note that:
>> gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
>>
>> is only used for BUILT_IN_NORMAL, which decl_built_in_p should handle also FE and TARGET codes.
> 
> I know ...
> 
>>>
>>> +                built_in_class klass = BUILT_IN_NORMAL)
> 
> So without the default arg we could make two overloads:
> 
> fndecl_built_in_p (const_tree, enum built_in_function)
> fndecl_built_in_p (const_tree, int, enum built_in_class)
> 
> and keep the type checking?

Works for me.

> 
>>> This deviates from the gimple.h routines as well (also builtin vs. built_in, but
>>> built_in is better).
>>
>> As you with here, I'm fine with both. Are you fine with the consensus that the functions will
>> do check for null argument and TREE_CODE check?
> 
> Not yet ;)  The extra checks are not going to be optimized away in
> those places that do
> not need them I think.  Any more convincing examples?

Not really, null-checking is quite short. I'll rework the patch to put back the null-checking.

Martin

> 
> Richard.
> 
>> Martin
>>
>>>
>>> +{
>>> +  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
>>> +}
>>>
>>>
>>>> Martin
>>>>
>>>>>
>>>>> Thanks,
>>>>> Richard.
>>>>>
>>>>>> Martin
>>>>>>
>>>>>>>
>>>>>>> Martin
>>>>>>>
>>>>>>>>
>>>>>>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>>>>>>>
>>>>>>>> Ready to be installed?
>>>>>>>> Martin
>>>>>>>>
>>>>>>>> gcc/ChangeLog:
>>>>>>>>
>>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>>>
>>>>>>>>     * tree.h (DECL_BUILT_IN_P): Add also check
>>>>>>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
>>>>>>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
>>>>>>>>     (fold_builtin_call_array): Likewise.
>>>>>>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
>>>>>>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
>>>>>>>>     (cgraph_node::verify_node): Likewise.
>>>>>>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
>>>>>>>>     * dse.c (scan_insn): Likewise.
>>>>>>>>     * fold-const.c (fold_binary_loc): Likewise.
>>>>>>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
>>>>>>>>     * gimple.c (gimple_call_builtin_p): Likewise.
>>>>>>>>     * gimplify.c (gimplify_call_expr): Likewise.
>>>>>>>>     (gimple_boolify): Likewise.
>>>>>>>>     (gimplify_modify_expr): Likewise.
>>>>>>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
>>>>>>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
>>>>>>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
>>>>>>>>     (is_tm_abort): Likewise.
>>>>>>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
>>>>>>>>     * tree-inline.c (copy_bb): Likewise.
>>>>>>>>     * tree-sra.c (scan_function): Likewise.
>>>>>>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
>>>>>>>>     (pass_fold_builtins::execute): Likewise.
>>>>>>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
>>>>>>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
>>>>>>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
>>>>>>>>
>>>>>>>> gcc/c/ChangeLog:
>>>>>>>>
>>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>>>
>>>>>>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
>>>>>>>>         Use DECL_BUILT_IN_P macro.
>>>>>>>>
>>>>>>>> gcc/cp/ChangeLog:
>>>>>>>>
>>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>>>
>>>>>>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
>>>>>>>>     (cxx_eval_builtin_function_call): Likewise.
>>>>>>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
>>>>>>>>     (cp_fold): Likewise.
>>>>>>>>     * semantics.c (finish_call_expr): Likewise.
>>>>>>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
>>>>>>>> ---
>>>>>>>>  gcc/builtins.c            | 10 ++--------
>>>>>>>>  gcc/c/c-parser.c          |  9 +++------
>>>>>>>>  gcc/cgraph.c              | 13 ++++++-------
>>>>>>>>  gcc/cgraphclones.c        |  4 ++--
>>>>>>>>  gcc/cp/constexpr.c        | 12 +++++-------
>>>>>>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
>>>>>>>>  gcc/cp/semantics.c        |  4 +---
>>>>>>>>  gcc/cp/tree.c             |  5 ++---
>>>>>>>>  gcc/dse.c                 |  5 ++---
>>>>>>>>  gcc/fold-const.c          |  4 +---
>>>>>>>>  gcc/gimple-pretty-print.c |  4 +---
>>>>>>>>  gcc/gimple.c              |  3 +--
>>>>>>>>  gcc/gimplify.c            | 14 ++++----------
>>>>>>>>  gcc/ipa-fnsummary.c       |  8 ++++----
>>>>>>>>  gcc/omp-low.c             |  5 ++---
>>>>>>>>  gcc/trans-mem.c           |  8 ++------
>>>>>>>>  gcc/tree-cfg.c            |  3 +--
>>>>>>>>  gcc/tree-inline.c         |  4 ++--
>>>>>>>>  gcc/tree-sra.c            |  4 ++--
>>>>>>>>  gcc/tree-ssa-ccp.c        |  8 ++------
>>>>>>>>  gcc/tree-ssa-dom.c        |  4 +---
>>>>>>>>  gcc/tree-ssa-loop-im.c    |  4 +---
>>>>>>>>  gcc/tree-stdarg.c         |  6 ++----
>>>>>>>>  gcc/tree.h                |  4 +++-
>>>>>>>>  24 files changed, 56 insertions(+), 101 deletions(-)
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>
>>
Martin Liška Aug. 27, 2018, 7:20 a.m. UTC | #9
On 08/23/2018 03:58 PM, Richard Biener wrote:
> On Thu, Aug 23, 2018 at 3:30 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 08/23/2018 01:58 PM, Richard Biener wrote:
>>> On Thu, Aug 23, 2018 at 12:46 PM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> On 08/20/2018 10:34 AM, Richard Biener wrote:
>>>>> On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
>>>>>>
>>>>>> On 08/14/2018 06:02 PM, Martin Sebor wrote:
>>>>>>> On 08/14/2018 03:06 AM, Martin Liška wrote:
>>>>>>>> Hi.
>>>>>>>>
>>>>>>>> The patch adds more usages of the new macro. I hope it improves
>>>>>>>> readability of code.
>>>>>>>
>>>>>>> I think it does :)  I see that most invocations of it in your
>>>>>>> patch are with BUILT_IN_NORMAL as the second argument.  Is
>>>>>>> the argument implied by the last argument?  E.g., in
>>>>>>>
>>>>>>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
>>>>>>>
>>>>>>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
>>>>>>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
>>>>>>> be eliminated?  (Both to make the invocation less verbose and
>>>>>>> to avoid the mistake of using the macro with the wrong class.)
>>>>>>
>>>>>> If I see correctly not, there are separate enums:
>>>>>>
>>>>>> BUILT_IN_MD:
>>>>>>
>>>>>> enum ix86_builtins {
>>>>>>   IX86_BUILTIN_MASKMOVQ,
>>>>>>   IX86_BUILTIN_LDMXCSR,
>>>>>>   IX86_BUILTIN_STMXCSR,
>>>>>> ...
>>>>>> }
>>>>>>
>>>>>> BUILT_IN_NORMAL:
>>>>>> enum built_in_function {
>>>>>> BUILT_IN_NONE,
>>>>>> BUILT_IN_ACOS,
>>>>>> BUILT_IN_ACOSF,
>>>>>> ...
>>>>>> }
>>>>>>
>>>>>> So the enum values overlap and thus one needs the class.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
>>>>>>> to omit it.
>>>>>>
>>>>>> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
>>>>>> right now.
>>>>>
>>>>> Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
>>>>> and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).
>>>>
>>>> Agree.
>>>>
>>>>>
>>>>> I think following what gimple.h does would be nicer which means using
>>>>> inline functions and overloading.
>>>>>
>>>>> decl_built_in_p (tree);
>>>>> decl_built_in_p (tree, enum built_in_class);
>>>>> decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL
>>>>
>>>> Yes, that's easier to use!
>>>>
>>>>>
>>>>> Can you rework things this way please?  (ok, for gimple those are not inlines)
>>>>
>>>> Done in patch that can bootstrap and survives regression tests.
>>>> Ready for trunk?
>>>
>>> +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
>>> +   standard library or more generally a built in function that is
>>> +   recognized by optimizers and expanders.
>>> +
>>> +   Note that it is different from the DECL_IS_BUILTIN accessor.  For
>>> +   instance, user declared prototypes of C library functions are not
>>> +   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
>>> +
>>> +inline bool
>>> +decl_built_in_p (const_tree node)
>>> +{
>>> +  return (node != NULL_TREE
>>> +         && TREE_CODE (node) == FUNCTION_DECL
>>>
>>> You document for a FUNCTION_DECL NODE but the check
>>> for FUNCTION_DECL anyway.  I realize doing all (possibly redundant)
>>> checks in decl_built_in_p is convenient at callers, but at least update
>>> docs accordingly?  In reality I somewhat prefer
>>
>> Yes, please let stay with version that does the checks. It can provide
>> more readable code like:
>>
>>        /* If last argument is __builtin_va_arg_pack (), arguments to this
>>          function are not finalized yet.  Defer folding until they are.  */
>>        if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
>>         {
>>           tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
>> -         if (fndecl2
>> -             && TREE_CODE (fndecl2) == FUNCTION_DECL
>> -             && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
>> -             && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
>> +         if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
>>             return NULL_TREE;
>>         }
>>        if (avoid_folding_inline_builtin (fndecl))
> 
> But here the TREE_CODE (fndecl2) == FUNCTION_DECL check is redundant
> (get_callee_fndecl always returns a FUNCTION_DECL).  So it would become
> 
>   if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
> 
> which is IMHO good enough.

Hello.

I reworked the patch that way.

> 
>>>
>>> inline bool
>>> decl_built_in_p (const_tree node)
>>> {
>>>   return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
>>> }
>>>
>>> and
>>>
>>> inline bool
>>> decl_built_in_p (const_tree node, built_in_class klass)
>>> {
>>>   return DECL_BUILT_IN_CLASS (node) == klass;
>>> }
>>>
>>> esp. since the built_in_class overload doesn't work for
>>> NOT_BUILT_IN for your variant.
>>
>> That's true. One should probably use DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN
>> in this case.
>>
>>>
>>> And if we're at changing, maybe call the functions
>>> fndecl_built_in_p to make it clear we're expecting FUNCTION_DECLs...
>>>
>>> +/* For a FUNCTION_DECL NODE, return true when a function is
>>> +   a built-in of class KLASS with name equal to NAME.  */
>>> +
>>> +inline bool
>>> +decl_built_in_p (const_tree node, int name,
>>>
>>> why's that 'int' and not built_in_function?
>>
>> Because we want to also call it for e.g. cp_built_in_function
>> enum types:
>>
>> gcc/cp/cp-gimplify.c:2498:26: error: no matching function for call to ‘decl_built_in_p(tree_node*&, cp_built_in_function, built_in_class)’
>>
>> Note that:
>> gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
>>
>> is only used for BUILT_IN_NORMAL, which decl_built_in_p should handle also FE and TARGET codes.
> 
> I know ...
> 
>>>
>>> +                built_in_class klass = BUILT_IN_NORMAL)
> 
> So without the default arg we could make two overloads:
> 
> fndecl_built_in_p (const_tree, enum built_in_function)
> fndecl_built_in_p (const_tree, int, enum built_in_class)
> 
> and keep the type checking?

Yes, good idea.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin

> 
>>> This deviates from the gimple.h routines as well (also builtin vs. built_in, but
>>> built_in is better).
>>
>> As you with here, I'm fine with both. Are you fine with the consensus that the functions will
>> do check for null argument and TREE_CODE check?
> 
> Not yet ;)  The extra checks are not going to be optimized away in
> those places that do
> not need them I think.  Any more convincing examples?
> 
> Richard.
> 
>> Martin
>>
>>>
>>> +{
>>> +  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
>>> +}
>>>
>>>
>>>> Martin
>>>>
>>>>>
>>>>> Thanks,
>>>>> Richard.
>>>>>
>>>>>> Martin
>>>>>>
>>>>>>>
>>>>>>> Martin
>>>>>>>
>>>>>>>>
>>>>>>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>>>>>>>
>>>>>>>> Ready to be installed?
>>>>>>>> Martin
>>>>>>>>
>>>>>>>> gcc/ChangeLog:
>>>>>>>>
>>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>>>
>>>>>>>>     * tree.h (DECL_BUILT_IN_P): Add also check
>>>>>>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
>>>>>>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
>>>>>>>>     (fold_builtin_call_array): Likewise.
>>>>>>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
>>>>>>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
>>>>>>>>     (cgraph_node::verify_node): Likewise.
>>>>>>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
>>>>>>>>     * dse.c (scan_insn): Likewise.
>>>>>>>>     * fold-const.c (fold_binary_loc): Likewise.
>>>>>>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
>>>>>>>>     * gimple.c (gimple_call_builtin_p): Likewise.
>>>>>>>>     * gimplify.c (gimplify_call_expr): Likewise.
>>>>>>>>     (gimple_boolify): Likewise.
>>>>>>>>     (gimplify_modify_expr): Likewise.
>>>>>>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
>>>>>>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
>>>>>>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
>>>>>>>>     (is_tm_abort): Likewise.
>>>>>>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
>>>>>>>>     * tree-inline.c (copy_bb): Likewise.
>>>>>>>>     * tree-sra.c (scan_function): Likewise.
>>>>>>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
>>>>>>>>     (pass_fold_builtins::execute): Likewise.
>>>>>>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
>>>>>>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
>>>>>>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
>>>>>>>>
>>>>>>>> gcc/c/ChangeLog:
>>>>>>>>
>>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>>>
>>>>>>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
>>>>>>>>         Use DECL_BUILT_IN_P macro.
>>>>>>>>
>>>>>>>> gcc/cp/ChangeLog:
>>>>>>>>
>>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
>>>>>>>>
>>>>>>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
>>>>>>>>     (cxx_eval_builtin_function_call): Likewise.
>>>>>>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
>>>>>>>>     (cp_fold): Likewise.
>>>>>>>>     * semantics.c (finish_call_expr): Likewise.
>>>>>>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
>>>>>>>> ---
>>>>>>>>  gcc/builtins.c            | 10 ++--------
>>>>>>>>  gcc/c/c-parser.c          |  9 +++------
>>>>>>>>  gcc/cgraph.c              | 13 ++++++-------
>>>>>>>>  gcc/cgraphclones.c        |  4 ++--
>>>>>>>>  gcc/cp/constexpr.c        | 12 +++++-------
>>>>>>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
>>>>>>>>  gcc/cp/semantics.c        |  4 +---
>>>>>>>>  gcc/cp/tree.c             |  5 ++---
>>>>>>>>  gcc/dse.c                 |  5 ++---
>>>>>>>>  gcc/fold-const.c          |  4 +---
>>>>>>>>  gcc/gimple-pretty-print.c |  4 +---
>>>>>>>>  gcc/gimple.c              |  3 +--
>>>>>>>>  gcc/gimplify.c            | 14 ++++----------
>>>>>>>>  gcc/ipa-fnsummary.c       |  8 ++++----
>>>>>>>>  gcc/omp-low.c             |  5 ++---
>>>>>>>>  gcc/trans-mem.c           |  8 ++------
>>>>>>>>  gcc/tree-cfg.c            |  3 +--
>>>>>>>>  gcc/tree-inline.c         |  4 ++--
>>>>>>>>  gcc/tree-sra.c            |  4 ++--
>>>>>>>>  gcc/tree-ssa-ccp.c        |  8 ++------
>>>>>>>>  gcc/tree-ssa-dom.c        |  4 +---
>>>>>>>>  gcc/tree-ssa-loop-im.c    |  4 +---
>>>>>>>>  gcc/tree-stdarg.c         |  6 ++----
>>>>>>>>  gcc/tree.h                |  4 +++-
>>>>>>>>  24 files changed, 56 insertions(+), 101 deletions(-)
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>
>>
From 574810813ca86bd76ad6ac16e0bcdeb7de3405e3 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 24 Aug 2018 13:01:42 +0200
Subject: [PATCH] Come up with fndecl_built_in_p.

gcc/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* builtins.h (is_builtin_fn): Remove and fndecl_built_in_p.
	* builtins.c (is_builtin_fn): Likewise.
	* attribs.c (diag_attr_exclusions): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.
	(builtin_mathfn_code): Likewise.
	(fold_builtin_expect): Likewise.
	(fold_call_expr): Likewise.
	(fold_builtin_call_array): Likewise.
	(fold_call_stmt): Likewise.
	(set_builtin_user_assembler_name): Likewise.
	(is_simple_builtin): Likewise.
	* calls.c (gimple_alloca_call_p): Likewise.
	(maybe_warn_nonstring_arg): Likewise.
	* cfgexpand.c (expand_call_stmt): Likewise.
	* cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
	(cgraph_edge::verify_corresponds_to_fndecl): Likewise.
	(cgraph_node::verify_node): Likewise.
	* cgraphclones.c (build_function_decl_skip_args): Likewise.
	(cgraph_node::create_clone): Likewise.
	* config/arm/arm.c (arm_insert_attributes): Likewise.
	* config/i386/i386.c (ix86_gimple_fold_builtin): Likewise.
	* dse.c (scan_insn): Likewise.
	* expr.c (expand_expr_real_1): Likewise.
	* fold-const.c (operand_equal_p): Likewise.
	(fold_binary_loc): Likewise.
	* gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
	* gimple-low.c (lower_stmt): Likewise.
	* gimple-pretty-print.c (dump_gimple_call): Likewise.
	* gimple-ssa-warn-restrict.c (wrestrict_dom_walker::check_call): Likewise.
	* gimple.c (gimple_build_call_from_tree): Likewise.
	(gimple_call_builtin_p): Likewise.
	(gimple_call_combined_fn): Likewise.
	* gimplify.c (gimplify_call_expr): Likewise.
	(gimple_boolify): Likewise.
	(gimplify_modify_expr): Likewise.
	(gimplify_addr_expr): Likewise.
	* hsa-gen.c (gen_hsa_insns_for_call): Likewise.
	* ipa-cp.c (determine_versionability): Likewise.
	* ipa-fnsummary.c (compute_fn_summary): Likewise.
	* ipa-param-manipulation.c (ipa_modify_formal_parameters): Likewise.
	* ipa-split.c (visit_bb): Likewise.
	(split_function): Likewise.
	* ipa-visibility.c (cgraph_externally_visible_p): Likewise.
	* lto-cgraph.c (input_node): Likewise.
	* lto-streamer-out.c (write_symbol): Likewise.
	* omp-low.c (setjmp_or_longjmp_p): Likewise.
	(lower_omp_1): Likewise.
	* predict.c (strip_predict_hints): Likewise.
	* print-tree.c (print_node): Likewise.
	* symtab.c (symtab_node::output_to_lto_symbol_table_p): Likewise.
	* trans-mem.c (is_tm_irrevocable): Likewise.
	(is_tm_load): Likewise.
	(is_tm_simple_load): Likewise.
	(is_tm_store): Likewise.
	(is_tm_simple_store): Likewise.
	(is_tm_abort): Likewise.
	(tm_region_init_1): Likewise.
	* tree-call-cdce.c (gen_shrink_wrap_conditions): Likewise.
	* tree-cfg.c (verify_gimple_call): Likewise.
	(move_stmt_r): Likewise.
	(stmt_can_terminate_bb_p): Likewise.
	* tree-eh.c (lower_eh_constructs_2): Likewise.
	* tree-if-conv.c (if_convertible_stmt_p): Likewise.
	* tree-inline.c (remap_gimple_stmt): Likewise.
	(copy_bb): Likewise.
	(estimate_num_insns): Likewise.
	(fold_marked_statements): Likewise.
	* tree-sra.c (scan_function): Likewise.
	* tree-ssa-ccp.c (surely_varying_stmt_p): Likewise.
	(optimize_stack_restore): Likewise.
	(pass_fold_builtins::execute): Likewise.
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
	(mark_all_reaching_defs_necessary_1): Likewise.
	* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
	* tree-ssa-forwprop.c (simplify_builtin_call): Likewise.
	(pass_forwprop::execute): Likewise.
	* tree-ssa-loop-im.c (stmt_cost): Likewise.
	* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
	* tree-ssa-sccvn.c (fully_constant_vn_reference_p): Likewise.
	* tree-ssa-strlen.c (get_string_length): Likewise.
	* tree-ssa-structalias.c (handle_lhs_call): Likewise.
	(find_func_aliases_for_call): Likewise.
	* tree-ssa-ter.c (find_replaceable_in_bb): Likewise.
	* tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
	* tree-tailcall.c (find_tail_calls): Likewise.
	* tree.c (need_assembler_name_p): Likewise.
	(free_lang_data_in_decl): Likewise.
	(get_call_combined_fn): Likewise.
	* ubsan.c (is_ubsan_builtin_p): Likewise.
	* varasm.c (incorporeal_function_p): Likewise.
	* tree.h (DECL_BUILT_IN): Remove and replace with
        fndecl_built_in_p.
	(DECL_BUILT_IN_P): Transfort to fndecl_built_in_p.
	(fndecl_built_in_p): New.

gcc/ada/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* gcc-interface/decl.c (update_profile): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.
	* gcc-interface/gigi.h (call_is_atomic_load): Likewise.
	* gcc-interface/utils.c (gnat_pushdecl): Likewise.

gcc/c-family/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* c-common.c (check_function_restrict): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.
	(check_builtin_function_arguments): Likewise.
	(reject_gcc_builtin): Likewise.
	* c-warn.c (sizeof_pointer_memaccess_warning): Likewise.

gcc/c/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* c-decl.c (locate_old_decl): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.
	(diagnose_mismatched_decls): Likewise.
	(merge_decls): Likewise.
	(warn_if_shadowing): Likewise.
	(pushdecl): Likewise.
	(implicitly_declare): Likewise.
	* c-parser.c (c_parser_postfix_expression_after_primary): Likewise.
	* c-tree.h (C_DECL_ISNT_PROTOTYPE): Likewise.
	* c-typeck.c (build_function_call_vec): Likewise.
	(convert_arguments): Likewise.

gcc/cp/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* call.c (build_call_a): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.
	(build_cxx_call): Likewise.
	* constexpr.c (constexpr_fn_retval): Likewise.
	(cxx_eval_builtin_function_call): Likewise.
	(cxx_eval_call_expression): Likewise.
	(potential_constant_expression_1): Likewise.
	* cp-gimplify.c (cp_gimplify_expr): Likewise.
	(cp_fold): Likewise.
	* decl.c (decls_match): Likewise.
	(validate_constexpr_redeclaration): Likewise.
	(duplicate_decls): Likewise.
	(make_rtl_for_nonlocal_decl): Likewise.
	* name-lookup.c (consider_binding_level): Likewise.
	(cp_emit_debug_info_for_using): Likewise.
	* semantics.c (finish_call_expr): Likewise.
	* tree.c (builtin_valid_in_constant_expr_p): Likewise.

gcc/go/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* go-gcc.cc (Gcc_backend::call_expression): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.

gcc/lto/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* lto-lang.c (handle_const_attribute): Use new function
        fndecl_built_in_p and remove check for FUNCTION_DECL if
        possible.
	* lto-symtab.c (lto_symtab_merge_p): Likewise.
	(lto_symtab_merge_decls_1): Likewise.
	(lto_symtab_merge_symbols): Likewise.
	* lto.c (lto_maybe_register_decl): Likewise.
	(read_cgraph_and_symbols): Likewise.
---
 gcc/ada/gcc-interface/decl.c   |  2 +-
 gcc/ada/gcc-interface/gigi.h   |  2 +-
 gcc/ada/gcc-interface/utils.c  |  2 +-
 gcc/attribs.c                  |  2 +-
 gcc/builtins.c                 | 46 +++++++-------------------
 gcc/builtins.h                 |  1 -
 gcc/c-family/c-common.c        |  8 ++---
 gcc/c-family/c-warn.c          |  2 +-
 gcc/c/c-decl.c                 | 25 +++++++-------
 gcc/c/c-parser.c               |  6 ++--
 gcc/c/c-tree.h                 |  2 +-
 gcc/c/c-typeck.c               |  7 ++--
 gcc/calls.c                    |  4 +--
 gcc/cfgexpand.c                |  5 ++-
 gcc/cgraph.c                   | 10 +++---
 gcc/cgraphclones.c             |  5 ++-
 gcc/config/arm/arm.c           |  2 +-
 gcc/config/i386/i386.c         |  4 +--
 gcc/cp/call.c                  |  5 ++-
 gcc/cp/constexpr.c             | 14 ++++----
 gcc/cp/cp-gimplify.c           | 12 +++----
 gcc/cp/decl.c                  | 20 ++++++------
 gcc/cp/name-lookup.c           |  4 +--
 gcc/cp/semantics.c             |  3 +-
 gcc/cp/tree.c                  |  5 ++-
 gcc/dse.c                      |  3 +-
 gcc/expr.c                     |  2 +-
 gcc/fold-const.c               |  5 ++-
 gcc/gimple-fold.c              |  3 +-
 gcc/gimple-low.c               |  2 +-
 gcc/gimple-pretty-print.c      |  3 +-
 gcc/gimple-ssa-warn-restrict.c |  2 +-
 gcc/gimple.c                   |  7 ++--
 gcc/gimplify.c                 | 17 ++++------
 gcc/go/go-gcc.cc               |  4 +--
 gcc/hsa-gen.c                  |  3 +-
 gcc/ipa-cp.c                   |  3 +-
 gcc/ipa-fnsummary.c            |  6 ++--
 gcc/ipa-param-manipulation.c   |  2 +-
 gcc/ipa-split.c                |  5 ++-
 gcc/ipa-visibility.c           |  2 +-
 gcc/lto-cgraph.c               |  2 +-
 gcc/lto-streamer-out.c         |  3 +-
 gcc/lto/lto-lang.c             |  3 +-
 gcc/lto/lto-symtab.c           |  8 ++---
 gcc/lto/lto.c                  |  5 +--
 gcc/omp-low.c                  |  7 ++--
 gcc/predict.c                  |  4 +--
 gcc/print-tree.c               |  6 ++--
 gcc/symtab.c                   |  2 +-
 gcc/trans-mem.c                | 20 ++++++------
 gcc/tree-call-cdce.c           |  2 +-
 gcc/tree-cfg.c                 |  9 +++--
 gcc/tree-eh.c                  |  2 +-
 gcc/tree-if-conv.c             |  2 +-
 gcc/tree-inline.c              |  9 +++--
 gcc/tree-sra.c                 |  3 +-
 gcc/tree-ssa-ccp.c             | 13 +++-----
 gcc/tree-ssa-dce.c             |  4 +--
 gcc/tree-ssa-dom.c             |  3 +-
 gcc/tree-ssa-forwprop.c        |  4 +--
 gcc/tree-ssa-loop-im.c         |  4 +--
 gcc/tree-ssa-math-opts.c       |  2 +-
 gcc/tree-ssa-sccvn.c           |  2 +-
 gcc/tree-ssa-strlen.c          |  2 +-
 gcc/tree-ssa-structalias.c     |  4 +--
 gcc/tree-ssa-ter.c             |  2 +-
 gcc/tree-stdarg.c              |  7 ++--
 gcc/tree-tailcall.c            |  2 +-
 gcc/tree.c                     | 11 +++----
 gcc/tree.h                     | 60 ++++++++++++++++++++++++++--------
 gcc/ubsan.c                    |  2 +-
 gcc/varasm.c                   |  2 +-
 73 files changed, 221 insertions(+), 257 deletions(-)

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index b1dc379c247..6f605bd64ec 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -5421,7 +5421,7 @@ update_profile (Entity_Id gnat_subprog)
   if (DECL_P (gnu_type))
     {
       /* Builtins cannot have their address taken so we can reset them.  */
-      gcc_assert (DECL_BUILT_IN (gnu_type));
+      gcc_assert (fndecl_built_in_p (gnu_type));
       save_gnu_tree (gnat_subprog, NULL_TREE, false);
       save_gnu_tree (gnat_subprog, gnu_type, false);
       return;
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index b890195cefc..eb64a8bbdbd 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -1081,7 +1081,7 @@ call_is_atomic_load (tree exp)
 {
   tree fndecl = get_callee_fndecl (exp);
 
-  if (!(fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL))
+  if (!(fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)))
     return false;
 
   enum built_in_function code = DECL_FUNCTION_CODE (fndecl);
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index cc1fe770f2c..313d984b83d 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -773,7 +773,7 @@ gnat_pushdecl (tree decl, Node_Id gnat_node)
 	 debugger at the proper time.  */
       if (DECL_EXTERNAL (decl)
 	  && TREE_CODE (decl) == FUNCTION_DECL
-	  && DECL_BUILT_IN (decl))
+	  && fndecl_built_in_p (decl))
 	vec_safe_push (builtin_decls, decl);
       else if (global_bindings_p ())
 	vec_safe_push (global_decls, decl);
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 64700b6c8ce..8b721274d3b 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -432,7 +432,7 @@ diag_attr_exclusions (tree last_decl, tree node, tree attrname,
 	  bool note = last_decl != NULL_TREE;
 	  auto_diagnostic_group d;
 	  if (TREE_CODE (node) == FUNCTION_DECL
-	      && DECL_BUILT_IN (node))
+	      && fndecl_built_in_p (node))
 	    note &= warning (OPT_Wattributes,
 			     "ignoring attribute %qE in declaration of "
 			     "a built-in function %qD because it conflicts "
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6a992bd939b..c4b52b9c627 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -208,15 +208,6 @@ is_builtin_name (const char *name)
   return false;
 }
 
-
-/* Return true if DECL is a function symbol representing a built-in.  */
-
-bool
-is_builtin_fn (tree decl)
-{
-  return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
-}
-
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -8154,11 +8145,8 @@ builtin_mathfn_code (const_tree t)
     return END_BUILTINS;
 
   fndecl = get_callee_fndecl (t);
-  if (fndecl == NULL_TREE
-      || TREE_CODE (fndecl) != FUNCTION_DECL
-      || ! DECL_BUILT_IN (fndecl)
-      || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
-    return END_BUILTINS;
+  if (fndecl == NULL_TREE || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
+      return END_BUILTINS;
 
   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   init_const_call_expr_arg_iterator (t, &iter);
@@ -8313,9 +8301,8 @@ fold_builtin_expect (location_t loc, tree arg0, tree arg1, tree arg2,
 
   if (TREE_CODE (inner) == CALL_EXPR
       && (fndecl = get_callee_fndecl (inner))
-      && (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
-	  || DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL,
-			      BUILT_IN_EXPECT_WITH_PROBABILITY)))
+      && (fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
+	  || fndecl_built_in_p (fndecl, BUILT_IN_EXPECT_WITH_PROBABILITY)))
     return arg0;
 
   inner = inner_arg0;
@@ -9628,9 +9615,7 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
 {
   tree ret = NULL_TREE;
   tree fndecl = get_callee_fndecl (exp);
-  if (fndecl
-      && TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl)
+  if (fndecl && fndecl_built_in_p (fndecl)
       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
 	 yet.  Defer folding until we see all the arguments
 	 (after inlining).  */
@@ -9644,10 +9629,7 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
 
@@ -9683,17 +9665,14 @@ fold_builtin_call_array (location_t loc, tree,
 
   tree fndecl = TREE_OPERAND (fn, 0);
   if (TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl))
+      && fndecl_built_in_p (fndecl))
     {
       /* If last argument is __builtin_va_arg_pack (), arguments to this
 	 function are not finalized yet.  Defer folding until they are.  */
       if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
       if (avoid_folding_inline_builtin (fndecl))
@@ -10812,9 +10791,7 @@ fold_call_stmt (gcall *stmt, bool ignore)
   tree ret = NULL_TREE;
   tree fndecl = gimple_call_fndecl (stmt);
   location_t loc = gimple_location (stmt);
-  if (fndecl
-      && TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl)
+  if (fndecl && fndecl_built_in_p (fndecl)
       && !gimple_call_va_arg_pack_p (stmt))
     {
       int nargs = gimple_call_num_args (stmt);
@@ -10861,8 +10838,7 @@ fold_call_stmt (gcall *stmt, bool ignore)
 void
 set_builtin_user_assembler_name (tree decl, const char *asmspec)
 {
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+  gcc_assert (fndecl_built_in_p (decl, BUILT_IN_NORMAL)
 	      && asmspec != 0);
 
   tree builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
@@ -10882,7 +10858,7 @@ set_builtin_user_assembler_name (tree decl, const char *asmspec)
 bool
 is_simple_builtin (tree decl)
 {
-  if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+  if (decl && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
     switch (DECL_FUNCTION_CODE (decl))
       {
 	/* Builtins that expand to constants.  */
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 805f1801604..c3d5ccbb6b6 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -49,7 +49,6 @@ extern struct target_builtins *this_target_builtins;
 /* Non-zero if __builtin_constant_p should be folded right away.  */
 extern bool force_folding_builtin_constant_p;
 
-extern bool is_builtin_fn (tree);
 extern bool called_as_built_in (tree);
 extern bool get_object_alignment_1 (tree, unsigned int *,
 				    unsigned HOST_WIDE_INT *);
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 95cff215d60..0b0969b5216 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5326,8 +5326,7 @@ check_function_restrict (const_tree fndecl, const_tree fntype,
     {
       /* Avoid diagnosing calls built-ins with a zero size/bound
 	 here.  They are checked in more detail elsewhere.  */
-      if (DECL_BUILT_IN (fndecl)
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+      if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && nargs == 3
 	  && TREE_CODE (argarray[2]) == INTEGER_CST
 	  && integer_zerop (argarray[2]))
@@ -5755,8 +5754,7 @@ bool
 check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
 				  tree fndecl, int nargs, tree *args)
 {
-  if (!DECL_BUILT_IN (fndecl)
-      || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+  if (!fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return true;
 
   switch (DECL_FUNCTION_CODE (fndecl))
@@ -8011,7 +8009,7 @@ reject_gcc_builtin (const_tree expr, location_t loc /* = UNKNOWN_LOCATION */)
 	 strlen, and for C++ operators new and delete.
 	 The c_decl_implicit() test avoids false positives for implicitly
 	 declared built-ins with library fallbacks (such as abs).  */
-      && DECL_BUILT_IN (expr)
+      && fndecl_built_in_p (expr)
       && DECL_IS_BUILTIN (expr)
       && !c_decl_implicit (expr)
       && !DECL_ASSEMBLER_NAME_SET_P (expr))
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index ca259aa7bd0..95b66c1eabb 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -702,7 +702,7 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
   location_t loc;
 
   if (TREE_CODE (callee) != FUNCTION_DECL
-      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
+      || !fndecl_built_in_p (callee, BUILT_IN_NORMAL)
       || vec_safe_length (params) <= 1)
     return;
 
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 95249779e3c..80647ee0207 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -1800,7 +1800,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
 static void
 locate_old_decl (tree decl)
 {
-  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)
+  if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl)
       && !C_DECL_DECLARED_BUILTIN (decl))
     ;
   else if (DECL_INITIAL (decl))
@@ -1843,7 +1843,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
       if (!(TREE_CODE (olddecl) == FUNCTION_DECL
-	    && DECL_BUILT_IN (olddecl)
+	    && fndecl_built_in_p (olddecl)
 	    && !C_DECL_DECLARED_BUILTIN (olddecl)))
 	{
 	  auto_diagnostic_group d;
@@ -1877,7 +1877,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   if (!comptypes (oldtype, newtype))
     {
       if (TREE_CODE (olddecl) == FUNCTION_DECL
-	  && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
+	  && fndecl_built_in_p (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
 	{
 	  /* Accept harmless mismatch in function types.
 	     This is for the ffs and fprintf builtins.  */
@@ -2025,7 +2025,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	 define the built-in with an old-style definition (so we
 	 can't validate the argument list) the built-in definition is
 	 overridden, but optionally warn this was a bad choice of name.  */
-      if (DECL_BUILT_IN (olddecl)
+      if (fndecl_built_in_p (olddecl)
 	  && !C_DECL_DECLARED_BUILTIN (olddecl)
 	  && (!TREE_PUBLIC (newdecl)
 	      || (DECL_INITIAL (newdecl)
@@ -2297,8 +2297,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	   && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))
       /* Don't warn about redundant redeclarations of builtins.  */
       && !(TREE_CODE (newdecl) == FUNCTION_DECL
-	   && !DECL_BUILT_IN (newdecl)
-	   && DECL_BUILT_IN (olddecl)
+	   && !fndecl_built_in_p (newdecl)
+	   && fndecl_built_in_p (olddecl)
 	   && !C_DECL_DECLARED_BUILTIN (olddecl))
       /* Don't warn about an extern followed by a definition.  */
       && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl))
@@ -2576,7 +2576,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 	       || DECL_DISREGARD_INLINE_LIMITS (olddecl));
 	}
 
-      if (DECL_BUILT_IN (olddecl))
+      if (fndecl_built_in_p (olddecl))
 	{
 	  /* If redeclaring a builtin function, it stays built in.
 	     But it gets tagged as having been declared.  */
@@ -2840,7 +2840,7 @@ warn_if_shadowing (tree new_decl)
 				 new_decl);
 	  }
 	else if (TREE_CODE (old_decl) == FUNCTION_DECL
-		 && DECL_BUILT_IN (old_decl))
+		 && fndecl_built_in_p (old_decl))
 	  {
 	    warning (OPT_Wshadow, "declaration of %q+D shadows "
 		     "a built-in function", new_decl);
@@ -2953,7 +2953,7 @@ pushdecl (tree x)
 		thistype = TREE_TYPE (b_use->decl);
 	      b_use->u.type = TREE_TYPE (b_use->decl);
 	      if (TREE_CODE (b_use->decl) == FUNCTION_DECL
-		  && DECL_BUILT_IN (b_use->decl))
+		  && fndecl_built_in_p (b_use->decl))
 		thistype
 		  = build_type_attribute_variant (thistype,
 						  TYPE_ATTRIBUTES
@@ -3057,7 +3057,8 @@ pushdecl (tree x)
 	  else
 	    thistype = type;
 	  b->u.type = TREE_TYPE (b->decl);
-	  if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
+	  if (TREE_CODE (b->decl) == FUNCTION_DECL
+	      && fndecl_built_in_p (b->decl))
 	    thistype
 	      = build_type_attribute_variant (thistype,
 					      TYPE_ATTRIBUTES (b->u.type));
@@ -3408,7 +3409,7 @@ implicitly_declare (location_t loc, tree functionid)
 	 in the external scope because they're pushed before the file
 	 scope gets created.  Catch this here and rebind them into the
 	 file scope.  */
-      if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl))
+      if (!fndecl_built_in_p (decl) && DECL_IS_BUILTIN (decl))
 	{
 	  bind (functionid, decl, file_scope,
 		/*invisible=*/false, /*nested=*/true,
@@ -3429,7 +3430,7 @@ implicitly_declare (location_t loc, tree functionid)
 	      implicit_decl_warning (loc, functionid, decl);
 	      C_DECL_IMPLICIT (decl) = 1;
 	    }
-	  if (DECL_BUILT_IN (decl))
+	  if (fndecl_built_in_p (decl))
 	    {
 	      newtype = build_type_attribute_variant (newtype,
 						      TYPE_ATTRIBUTES
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 0d5dbea8f67..28384dfe913 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -9175,8 +9175,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 					      sizeof_arg,
 					      sizeof_ptr_memacc_comptypes);
 	  if (TREE_CODE (expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (expr.value) == BUILT_IN_MEMSET
+	      && fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
 	      && vec_safe_length (exprlist) == 3)
 	    {
 	      tree arg0 = (*exprlist)[0];
@@ -9194,8 +9193,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 	  expr.original_code = ERROR_MARK;
 	  if (TREE_CODE (expr.value) == INTEGER_CST
 	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
+	      && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
 	    expr.original_code = C_MAYBE_CONST_EXPR;
 	  expr.original_type = NULL;
 	  if (exprlist)
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index ae1a1e60d4b..017c01c592c 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -102,7 +102,7 @@ along with GCC; see the file COPYING3.  If not see
 #define C_DECL_ISNT_PROTOTYPE(EXP)			\
        (EXP == 0					\
 	|| (!prototype_p (TREE_TYPE (EXP))	\
-	    && !DECL_BUILT_IN (EXP)))
+	    && !fndecl_built_in_p (EXP)))
 
 /* For FUNCTION_TYPE, a hidden list of types of arguments.  The same as
    TYPE_ARG_TYPES for functions with prototypes, but created for functions
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 54c7967a06b..5f8df12564d 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3108,9 +3108,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
   argarray = vec_safe_address (params);
 
   /* Check that arguments to builtin functions match the expectations.  */
-  if (fundecl
-      && DECL_BUILT_IN (fundecl)
-      && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL
+  if (fundecl && fndecl_built_in_p (fundecl, BUILT_IN_NORMAL)
       && !check_builtin_function_arguments (loc, arg_loc, fundecl, nargs,
 					    argarray))
     return error_mark_node;
@@ -3233,8 +3231,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
      precision should be removed (classification) or not
      (comparison).  */
   if (type_generic
-      && DECL_BUILT_IN (fundecl)
-      && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL)
+      && fndecl_built_in_p (fundecl, BUILT_IN_NORMAL))
     {
       switch (DECL_FUNCTION_CODE (fundecl))
 	{
diff --git a/gcc/calls.c b/gcc/calls.c
index 0fb10b182b1..f57ecf91636 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -715,7 +715,7 @@ gimple_alloca_call_p (const gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     switch (DECL_FUNCTION_CODE (fndecl))
       {
       CASE_BUILT_IN_ALLOCA:
@@ -1542,7 +1542,7 @@ get_attr_nonstring_decl (tree expr, tree *ref)
 void
 maybe_warn_nonstring_arg (tree fndecl, tree exp)
 {
-  if (!fndecl || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+  if (!fndecl || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return;
 
   if (TREE_NO_WARNING (exp))
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..a1d30ca3ee3 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2616,7 +2616,7 @@ expand_call_stmt (gcall *stmt)
   exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
 
   CALL_EXPR_FN (exp) = gimple_call_fn (stmt);
-  builtin_p = decl && DECL_BUILT_IN (decl);
+  builtin_p = decl && fndecl_built_in_p (decl);
 
   /* If this is not a builtin function, the function type through which the
      call is made may be different from the type of the function.  */
@@ -2654,8 +2654,7 @@ expand_call_stmt (gcall *stmt)
   CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt);
   CALL_EXPR_MUST_TAIL_CALL (exp) = gimple_call_must_tail_p (stmt);
   CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt);
-  if (decl
-      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+  if (decl && fndecl_built_in_p (decl, BUILT_IN_NORMAL)
       && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (decl)))
     CALL_ALLOCA_FOR_VAR_P (exp) = gimple_call_alloca_for_var_p (stmt);
   else
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d19f1aacab8..148f29ea749 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1559,8 +1559,7 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
 	{
 	  /* Keep calls marked as dead dead.  */
 	  if (new_stmt && is_gimple_call (new_stmt) && e->callee
-	      && DECL_BUILT_IN_CLASS (e->callee->decl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (e->callee->decl) == BUILT_IN_UNREACHABLE)
+	      && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
 	    {
               node->get_edge (old_stmt)->set_call_stmt
 		 (as_a <gcall *> (new_stmt));
@@ -3060,8 +3059,8 @@ cgraph_edge::verify_corresponds_to_fndecl (tree decl)
 
   /* Optimizers can redirect unreachable calls or calls triggering undefined
      behavior to builtin_unreachable.  */
-  if (DECL_BUILT_IN_CLASS (callee->decl) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (callee->decl) == BUILT_IN_UNREACHABLE)
+
+  if (fndecl_built_in_p (callee->decl, BUILT_IN_UNREACHABLE))
     return false;
 
   if (callee->former_clone_of != node->decl
@@ -3187,8 +3186,7 @@ cgraph_node::verify_node (void)
 	  /* Optimized out calls are redirected to __builtin_unreachable.  */
 	  && (e->count.nonzero_p ()
 	      || ! e->callee->decl
-	      || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	      || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
 	  && count
 	      == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
 	  && (!e->count.ipa_p ()
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 6e84a31c1a5..0c0a94b04a3 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -222,7 +222,7 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
     DECL_VINDEX (new_decl) = NULL_TREE;
 
   /* When signature changes, we need to clear builtin info.  */
-  if (DECL_BUILT_IN (new_decl)
+  if (fndecl_built_in_p (new_decl)
       && args_to_skip
       && !bitmap_empty_p (args_to_skip))
     {
@@ -482,8 +482,7 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count,
 	 version.  The only exception is when the edge was proved to
 	 be unreachable during the clonning procedure.  */
       if (!e->callee
-	  || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	  || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	  || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
         e->redirect_callee_duplicating_thunks (new_node);
     }
   new_node->expand_all_artificial_thunks ();
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c081216decd..6332e68df05 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -30841,7 +30841,7 @@ arm_insert_attributes (tree fndecl, tree * attributes)
     return;
 
   if (TREE_CODE (fndecl) != FUNCTION_DECL || DECL_EXTERNAL(fndecl)
-      || DECL_BUILT_IN (fndecl) || DECL_ARTIFICIAL (fndecl))
+      || fndecl_built_in_p (fndecl) || DECL_ARTIFICIAL (fndecl))
    return;
 
   /* Nested definitions must inherit mode.  */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 98677386a2b..eab482c4c84 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -33329,7 +33329,7 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
 {
   gimple *stmt = gsi_stmt (*gsi);
   tree fndecl = gimple_call_fndecl (stmt);
-  gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
+  gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
   int n_args = gimple_call_num_args (stmt);
   enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
   tree decl = NULL_TREE;
@@ -37919,7 +37919,7 @@ rdseed_step:
 		{
 		  tree fndecl = gimple_call_fndecl (def_stmt);
 		  if (fndecl
-		      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+		      && fndecl_built_in_p (fndecl, BUILT_IN_MD))
 		    switch ((unsigned int) DECL_FUNCTION_CODE (fndecl))
 		      {
 		      case IX86_BUILTIN_CMPPD:
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 626830c0d9a..d74f2be7d7c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -389,7 +389,7 @@ build_call_a (tree function, int n, tree *argarray)
   /* Don't pass empty class objects by value.  This is useful
      for tags in STL, which are used to control overload resolution.
      We don't need to handle other cases of copying empty classes.  */
-  if (! decl || ! DECL_BUILT_IN (decl))
+  if (!decl || !fndecl_built_in_p (decl))
     for (i = 0; i < n; i++)
       {
 	tree arg = CALL_EXPR_ARG (function, i);
@@ -8869,8 +8869,7 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
   /* Check that arguments to builtin functions match the expectations.  */
   if (fndecl
       && !processing_template_decl
-      && DECL_BUILT_IN (fndecl)
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+      && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       int i;
 
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 54c8b5edf8d..f646519135f 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -721,8 +721,7 @@ constexpr_fn_retval (tree body)
 	{
 	  tree fun = get_function_named_in_call (body);
 	  if (fun != NULL_TREE
-	      && DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+	      && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE))
 	    return NULL_TREE;
 	}
       /* Fallthru.  */
@@ -1198,8 +1197,8 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 
   /* For __builtin_is_constant_evaluated, defer it if not
      ctx->pretend_const_required, otherwise fold it to true.  */
-  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_FRONTEND
-      && (int) DECL_FUNCTION_CODE (fun) == CP_BUILT_IN_IS_CONSTANT_EVALUATED)
+  if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+		       BUILT_IN_FRONTEND))
     {
       if (!ctx->pretend_const_required)
 	{
@@ -1242,8 +1241,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 	  /* Do not allow__builtin_unreachable in constexpr function.
 	     The __builtin_unreachable call with BUILTINS_LOCATION
 	     comes from cp_maybe_instrument_return.  */
-	  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+	  if (fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE)
 	      && EXPR_LOCATION (t) == BUILTINS_LOCATION)
 	    error ("%<constexpr%> call flows off the end of the function");
 	  else
@@ -1528,7 +1526,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
   if (is_ubsan_builtin_p (fun))
     return void_node;
 
-  if (is_builtin_fn (fun))
+  if (fndecl_built_in_p (fun))
     return cxx_eval_builtin_function_call (ctx, t, fun,
 					   lval, non_constant_p, overflow_p);
   if (!DECL_DECLARED_CONSTEXPR_P (fun))
@@ -5522,7 +5520,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 		if (!DECL_DECLARED_CONSTEXPR_P (fun)
 		    /* Allow any built-in function; if the expansion
 		       isn't constant, we'll deal with that then.  */
-		    && !is_builtin_fn (fun))
+		    && !fndecl_built_in_p (fun))
 		  {
 		    if (flags & tf_error)
 		      {
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index f6109914102..90a8f9fef8f 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -797,9 +797,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 	{
 	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
 	  if (decl
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	      && ((int) DECL_FUNCTION_CODE (decl)
-		  == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	      && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+				  BUILT_IN_FRONTEND))
 	    *expr_p = boolean_false_node;
 	}
       break;
@@ -2489,7 +2488,7 @@ cp_fold (tree x)
 	/* Some built-in function calls will be evaluated at compile-time in
 	   fold ().  Set optimize to 1 when folding __builtin_constant_p inside
 	   a constexpr function so that fold_builtin_1 doesn't fold it to 0.  */
-	if (callee && DECL_BUILT_IN (callee) && !optimize
+	if (callee && fndecl_built_in_p (callee) && !optimize
 	    && DECL_IS_BUILTIN_CONSTANT_P (callee)
 	    && current_function_decl
 	    && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
@@ -2497,9 +2496,8 @@ cp_fold (tree x)
 
 	/* Defer folding __builtin_is_constant_evaluated.  */
 	if (callee
-	    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_FRONTEND
-	    && ((int) DECL_FUNCTION_CODE (callee)
-		== CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	    && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+				BUILT_IN_FRONTEND))
 	  break;
 
 	x = copy_node (x);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9056ad0dbce..c9c5fa6b4d5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -968,7 +968,7 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
       if (same_type_p (TREE_TYPE (f1), r2))
 	{
 	  if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
-	      && (DECL_BUILT_IN (olddecl)
+	      && (fndecl_built_in_p (olddecl)
 #ifdef SYSTEM_IMPLICIT_EXTERN_C
 		  || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl))
 		  || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl))
@@ -1208,7 +1208,7 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl)
     return true;
   if (TREE_CODE (old_decl) == FUNCTION_DECL)
     {
-      if (DECL_BUILT_IN (old_decl))
+      if (fndecl_built_in_p (old_decl))
 	{
 	  /* Hide a built-in declaration.  */
 	  DECL_DECLARED_CONSTEXPR_P (old_decl)
@@ -1442,7 +1442,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	    {
 	      warning_at (newdecl_loc,
 			  OPT_Wshadow, 
-			  DECL_BUILT_IN (olddecl)
+			  fndecl_built_in_p (olddecl)
 			  ? G_("shadowing built-in function %q#D")
 			  : G_("shadowing library function %q#D"), olddecl);
 	      /* Discard the old built-in function.  */
@@ -1450,7 +1450,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	    }
 	  /* If the built-in is not ansi, then programs can override
 	     it even globally without an error.  */
-	  else if (! DECL_BUILT_IN (olddecl))
+	  else if (! fndecl_built_in_p (olddecl))
 	    warning_at (newdecl_loc, 0,
 			"library function %q#D redeclared as non-function %q#D",
 			olddecl, newdecl);
@@ -1537,7 +1537,7 @@ next_arg:;
 	      /* Don't really override olddecl for __* prefixed builtins
 		 except for __[^b]*_chk, the compiler might be using those
 		 explicitly.  */
-	      if (DECL_BUILT_IN (olddecl))
+	      if (fndecl_built_in_p (olddecl))
 		{
 		  tree id = DECL_NAME (olddecl);
 		  const char *name = IDENTIFIER_POINTER (id);
@@ -1578,9 +1578,9 @@ next_arg:;
 			    "declaration %q#D", newdecl, olddecl);
 	      else
 		warning (OPT_Wshadow, 
-                         DECL_BUILT_IN (olddecl)
-                         ? G_("shadowing built-in function %q#D")
-                         : G_("shadowing library function %q#D"), olddecl);
+			 fndecl_built_in_p (olddecl)
+			 ? G_("shadowing built-in function %q#D")
+			 : G_("shadowing library function %q#D"), olddecl);
 	    }
 	  else
 	    /* Discard the old built-in function.  */
@@ -2522,7 +2522,7 @@ next_arg:;
       /* If redeclaring a builtin function, it stays built in
 	 if newdecl is a gnu_inline definition, or if newdecl is just
 	 a declaration.  */
-      if (DECL_BUILT_IN (olddecl)
+      if (fndecl_built_in_p (olddecl)
 	  && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
 	{
 	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
@@ -6611,7 +6611,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
       else
 	{
 	  if (TREE_CODE (decl) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+	      && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
 	    set_builtin_user_assembler_name (decl, asmspec);
 	  set_user_assembler_name (decl, asmspec);
 	}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 8c7f68522da..8e009b29d61 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5791,7 +5791,7 @@ consider_binding_level (tree name, best_match <tree, const char *> &bm,
 
       /* Skip anticipated decls of builtin functions.  */
       if (TREE_CODE (d) == FUNCTION_DECL
-	  && DECL_BUILT_IN (d)
+	  && fndecl_built_in_p (d)
 	  && DECL_ANTICIPATED (d))
 	continue;
 
@@ -7274,7 +7274,7 @@ cp_emit_debug_info_for_using (tree t, tree context)
      of a builtin function.  */
   if (TREE_CODE (t) == FUNCTION_DECL
       && DECL_EXTERNAL (t)
-      && DECL_BUILT_IN (t))
+      && fndecl_built_in_p (t))
     return;
 
   /* Do not supply context to imported_module_or_decl, if
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bfdca5024d3..b24d09224a9 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2546,8 +2546,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 
 	  if ((complain & tf_warning)
 	      && TREE_CODE (fn) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fn) == BUILT_IN_MEMSET
+	      && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
 	      && vec_safe_length (*args) == 3
 	      && !any_type_dependent_arguments_p (*args))
 	    {
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8a1d2993f94..c6f216dab4b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -420,9 +420,8 @@ builtin_valid_in_constant_expr_p (const_tree decl)
     return false;
   if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
     {
-      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	  && ((int) DECL_FUNCTION_CODE (decl)
-	      == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+      if (fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+			   BUILT_IN_FRONTEND))
 	return true;
       /* Not a built-in.  */
       return false;
diff --git a/gcc/dse.c b/gcc/dse.c
index 26c6007b9ed..cfebfa0e110 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2419,8 +2419,7 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn)
 	  && GET_CODE (sym) == SYMBOL_REF
 	  && SYMBOL_REF_DECL (sym)
 	  && TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (sym)) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (sym)) == BUILT_IN_MEMSET)
+	  && fndecl_built_in_p (SYMBOL_REF_DECL (sym), BUILT_IN_MEMSET))
 	memset_call = SYMBOL_REF_DECL (sym);
 
       if (const_call || memset_call)
diff --git a/gcc/expr.c b/gcc/expr.c
index 58574bafbf3..2645c259af8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10937,7 +10937,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	  }
 
 	/* Check for a built-in function.  */
-	if (fndecl && DECL_BUILT_IN (fndecl))
+	if (fndecl && fndecl_built_in_p (fndecl))
 	  {
 	    gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
 	    return expand_builtin (exp, target, subtarget, tmode, ignore);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1e44a2454ad..63e15f027fb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3451,7 +3451,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
     case tcc_declaration:
       /* Consider __builtin_sqrt equal to sqrt.  */
       return (TREE_CODE (arg0) == FUNCTION_DECL
-	      && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
+	      && fndecl_built_in_p (arg0) && fndecl_built_in_p (arg1)
 	      && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
 	      && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
 
@@ -10761,8 +10761,7 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
 	  tree fndecl = get_callee_fndecl (arg0);
 
 	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
+	      && fndecl_built_in_p (fndecl, BUILT_IN_STRLEN)
 	      && call_expr_nargs (arg0) == 1
 	      && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0))) == POINTER_TYPE)
 	    {
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 07341ebe66f..cbca6a95b76 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6347,8 +6347,7 @@ gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
 
 	fn = (*valueize) (gimple_call_fn (stmt));
 	if (TREE_CODE (fn) == ADDR_EXPR
-	    && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
-	    && DECL_BUILT_IN (TREE_OPERAND (fn, 0))
+	    && fndecl_built_in_p (TREE_OPERAND (fn, 0))
 	    && gimple_builtin_call_types_compatible_p (stmt,
 						       TREE_OPERAND (fn, 0)))
 	  {
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 9623fb86a04..c3777a1e761 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -355,7 +355,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
 	  }
 
 	if (decl
-	    && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+	    && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
 	  {
 	    if (DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
 	      {
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d3c5ec6f79b..af2019db6b9 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -911,8 +911,7 @@ dump_gimple_call (pretty_printer *buffer, gcall *gs, int spc,
   if (TREE_CODE (fn) == FUNCTION_DECL && decl_is_tm_clone (fn))
     pp_string (buffer, " [tm-clone]");
   if (TREE_CODE (fn) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_START
+      && fndecl_built_in_p (fn, BUILT_IN_TM_START)
       && gimple_call_num_args (gs) > 0)
     {
       tree t = gimple_call_arg (gs, 0);
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 977dd860ef7..ea30b7108f8 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -1731,7 +1731,7 @@ wrestrict_dom_walker::check_call (gimple *call)
     return;
 
   tree func = gimple_call_fndecl (call);
-  if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
+  if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
     return;
 
   /* Argument number to extract from the call (depends on the built-in
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 8d56a966cc1..e3e651b1e61 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -376,7 +376,7 @@ gimple_build_call_from_tree (tree t, tree fnptrtype)
   gimple_call_set_must_tail (call, CALL_EXPR_MUST_TAIL_CALL (t));
   gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t));
   if (fndecl
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+      && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
       && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (fndecl)))
     gimple_call_set_alloca_for_var (call, CALL_ALLOCA_FOR_VAR_P (t));
   else
@@ -2681,8 +2681,7 @@ gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
   tree fndecl;
   if (is_gimple_call (stmt)
       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 
-      && DECL_FUNCTION_CODE (fndecl) == code)
+      && fndecl_built_in_p (fndecl, code))
     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
   return false;
 }
@@ -2701,7 +2700,7 @@ gimple_call_combined_fn (const gimple *stmt)
 
       tree fndecl = gimple_call_fndecl (stmt);
       if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+	  && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && gimple_builtin_call_types_compatible_p (stmt, fndecl))
 	return as_combined_fn (DECL_FUNCTION_CODE (fndecl));
     }
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e35137aec2c..dbd0f0ebd0c 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3209,8 +3209,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
      transform all calls in the same manner as the expanders do, but
      we do transform most of them.  */
   fndecl = get_callee_fndecl (*expr_p);
-  if (fndecl
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     switch (DECL_FUNCTION_CODE (fndecl))
       {
       CASE_BUILT_IN_ALLOCA:
@@ -3245,7 +3244,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       default:
         ;
       }
-  if (fndecl && DECL_BUILT_IN (fndecl))
+  if (fndecl && fndecl_built_in_p (fndecl))
     {
       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
       if (new_tree && new_tree != *expr_p)
@@ -3297,9 +3296,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       tree last_arg_fndecl = get_callee_fndecl (last_arg);
 
       if (last_arg_fndecl
-	  && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
+	  && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
 	{
 	  tree call = *expr_p;
 
@@ -3773,8 +3770,7 @@ gimple_boolify (tree expr)
       /* For __builtin_expect ((long) (x), y) recurse into x as well
 	 if x is truth_value_p.  */
       if (fn
-	  && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
+	  && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
 	  && call_expr_nargs (call) == 2)
 	{
 	  tree arg = CALL_EXPR_ARG (call, 0);
@@ -5719,8 +5715,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
 	  tree fndecl = get_callee_fndecl (*from_p);
 	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+	      && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
 	      && call_expr_nargs (*from_p) == 3)
 	    call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
 						    CALL_EXPR_ARG (*from_p, 0),
@@ -5978,7 +5973,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 	 being taken (we can unify those cases here) then we can mark
 	 the builtin for implicit generation by GCC.  */
       if (TREE_CODE (op0) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
+	  && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
 	  && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
 	set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
 
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 76a2026f1e0..1a449b7cc47 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -1948,8 +1948,8 @@ Gcc_backend::call_expression(Bfunction*, // containing fcn for call
   tree excess_type = NULL_TREE;
   if (optimize
       && TREE_CODE(fndecl) == FUNCTION_DECL
-      && DECL_IS_BUILTIN(fndecl)
-      && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL
+      && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
+      && DECL_IS_BUILTIN (fndecl)
       && nargs > 0
       && ((SCALAR_FLOAT_TYPE_P(rettype)
 	   && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..e0621ea831b 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -5303,8 +5303,7 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb)
       tree function_decl = gimple_call_fndecl (stmt);
       /* Prefetch pass can create type-mismatching prefetch builtin calls which
 	 fail the gimple_call_builtin_p test above.  Handle them here.  */
-      if (DECL_BUILT_IN_CLASS (function_decl)
-	  && DECL_FUNCTION_CODE (function_decl) == BUILT_IN_PREFETCH)
+      if (fndecl_built_in_p (function_decl, BUILT_IN_PREFETCH))
 	return;
 
       if (function_decl == NULL_TREE)
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 42dd4cc2904..4838194cd73 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -638,8 +638,7 @@ determine_versionability (struct cgraph_node *node,
   if (DECL_EXTERNAL (node->decl))
     for (cgraph_edge *edge = node->callees; !reason && edge;
 	 edge = edge->next_callee)
-      if (DECL_BUILT_IN (edge->callee->decl)
-	  && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL)
+      if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
         {
 	  if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
 	    reason = "external function which calls va_arg_pack";
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..8b2656e397c 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2455,10 +2455,8 @@ compute_fn_summary (struct cgraph_node *node, bool early)
 	       for (e = node->callees; e; e = e->next_callee)
 		 {
 		   tree cdecl = e->callee->decl;
-		   if (DECL_BUILT_IN (cdecl)
-		       && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
-		       && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
-			   || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
+		   if (fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS)
+		       || fndecl_built_in_p (cdecl, BUILT_IN_VA_START))
 		     break;
 		 }
 	       node->local.can_change_signature = !e;
diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
index 1ab1fcccdae..1e3a92a125f 100644
--- a/gcc/ipa-param-manipulation.c
+++ b/gcc/ipa-param-manipulation.c
@@ -218,7 +218,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
     }
 
   /* When signature changes, we need to clear builtin info.  */
-  if (DECL_BUILT_IN (fndecl))
+  if (fndecl_built_in_p (fndecl))
     {
       DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
       DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 0e6440f8997..38f5bcf00a6 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -899,8 +899,7 @@ visit_bb (basic_block bb, basic_block return_bb,
       /* Check builtins that prevent splitting.  */
       if (gimple_code (stmt) == GIMPLE_CALL
 	  && (decl = gimple_call_fndecl (stmt)) != NULL_TREE
-	  && DECL_BUILT_IN (decl)
-	  && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+	  && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
 	switch (DECL_FUNCTION_CODE (decl))
 	  {
 	  /* FIXME: once we will allow passing non-parm values to split part,
@@ -1347,7 +1346,7 @@ split_function (basic_block return_bb, struct split_point *split_point,
   /* For usual cloning it is enough to clear builtin only when signature
      changes.  For partial inlining we however can not expect the part
      of builtin implementation to have same semantic as the whole.  */
-  if (DECL_BUILT_IN (node->decl))
+  if (fndecl_built_in_p (node->decl))
     {
       DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN;
       DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
index 907dc9d0e2b..000207fa31b 100644
--- a/gcc/ipa-visibility.c
+++ b/gcc/ipa-visibility.c
@@ -203,7 +203,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
      using the implicit built-in declarations anymore.  Similarly this enables
      us to remove them as unreachable before actual calls may appear during
      expansion or folding.  */
-  if (DECL_BUILT_IN (node->decl))
+  if (fndecl_built_in_p (node->decl))
     return true;
 
   /* If linker counts on us, we must preserve the function.  */
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index d5e390cb5f4..1e6a7adeaa2 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1266,7 +1266,7 @@ input_node (struct lto_file_decl_data *file_data,
      have already been read will have their tag stored in the 'aux'
      field.  Since built-in functions can be referenced in multiple
      functions, they are expected to be read more than once.  */
-  if (node->aux && !DECL_BUILT_IN (node->decl))
+  if (node->aux && !fndecl_built_in_p (node->decl))
     internal_error ("bytecode stream: found multiple instances of cgraph "
 		    "node with uid %d", node->get_uid ());
 
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 9e28d678342..f9d0f3e08ec 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -2618,7 +2618,8 @@ write_symbol (struct streamer_tree_cache_d *cache,
   unsigned char c;
 
   gcc_checking_assert (TREE_PUBLIC (t)
-		       && !is_builtin_fn (t)
+		       && (TREE_CODE (t) != FUNCTION_DECL
+			   || !fndecl_built_in_p (t))
 		       && !DECL_ABSTRACT_P (t)
 		       && (!VAR_P (t) || !DECL_HARD_REGISTER (t)));
 
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index de6ec1c077a..8eb4a25a634 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -303,8 +303,7 @@ handle_const_attribute (tree *node, tree ARG_UNUSED (name),
 			tree ARG_UNUSED (args), int ARG_UNUSED (flags),
 			bool * ARG_UNUSED (no_add_attrs))
 {
-  if (TREE_CODE (*node) != FUNCTION_DECL
-      || !DECL_BUILT_IN (*node))
+  if (!fndecl_built_in_p (*node))
     inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name);
 
   tree type = TREE_TYPE (*node);
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 0d603c0281f..cf08d455d87 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -546,14 +546,14 @@ lto_symtab_merge_p (tree prevailing, tree decl)
   
   if (TREE_CODE (prevailing) == FUNCTION_DECL)
     {
-      if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl))
+      if (fndecl_built_in_p (prevailing) != fndecl_built_in_p (decl))
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "Not merging decls; "
 		     "DECL_BUILT_IN mismatch\n");
 	  return false;
 	}
-      if (DECL_BUILT_IN (prevailing)
+      if (fndecl_built_in_p (prevailing)
 	  && (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl)
 	      || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl)))
 	{
@@ -797,7 +797,7 @@ lto_symtab_merge_decls_1 (symtab_node *first)
 	{
 	  for (e = first; e; e = e->next_sharing_asm_name)
 	    if (TREE_CODE (e->decl) == FUNCTION_DECL
-		&& !DECL_BUILT_IN (e->decl)
+		&& !fndecl_built_in_p (e->decl)
 		&& lto_symtab_symbol_p (e))
 	      {
 		prevailing = e;
@@ -1030,7 +1030,7 @@ lto_symtab_merge_symbols (void)
 	      /* Builtins are not merged via decl merging.  It is however
 		 possible that tree merging unified the declaration.  We
 		 do not want duplicate entries in symbol table.  */
-	      if (cnode && DECL_BUILT_IN (node->decl)
+	      if (cnode && fndecl_built_in_p (node->decl)
 		  && (cnode2 = cgraph_node::get (node->decl))
 		  && cnode2 != cnode)
 		lto_cgraph_replace_node (cnode2, cnode);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 10618896022..5b92bee026e 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -894,7 +894,7 @@ lto_maybe_register_decl (struct data_in *data_in, tree t, unsigned ix)
   if (TREE_CODE (t) == VAR_DECL)
     lto_register_var_decl_in_symtab (data_in, t, ix);
   else if (TREE_CODE (t) == FUNCTION_DECL
-	   && !DECL_BUILT_IN (t))
+	   && !fndecl_built_in_p (t))
     lto_register_function_decl_in_symtab (data_in, t, ix);
 }
 
@@ -2923,7 +2923,8 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   FOR_EACH_SYMBOL (snode)
     if (snode->externally_visible && snode->real_symbol_p ()
 	&& snode->lto_file_data && snode->lto_file_data->resolution_map
-	&& !is_builtin_fn (snode->decl)
+	&& !(TREE_CODE (snode->decl) != FUNCTION_DECL
+	     || fndecl_built_in_p (snode->decl))
 	&& !(VAR_P (snode->decl) && DECL_HARD_REGISTER (snode->decl)))
       {
 	ld_plugin_symbol_resolution_t *res;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 843c66fd221..fdabf67249b 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2975,9 +2975,8 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
 static bool
 setjmp_or_longjmp_p (const_tree fndecl)
 {
-  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
-	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+  if (fndecl_built_in_p (fndecl, BUILT_IN_SETJMP)
+      || fndecl_built_in_p (fndecl, BUILT_IN_LONGJMP))
     return true;
 
   tree declname = DECL_NAME (fndecl);
@@ -8832,7 +8831,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       call_stmt = as_a <gcall *> (stmt);
       fndecl = gimple_call_fndecl (call_stmt);
       if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	  && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	switch (DECL_FUNCTION_CODE (fndecl))
 	  {
 	  case BUILT_IN_GOMP_BARRIER:
diff --git a/gcc/predict.c b/gcc/predict.c
index 8c8e79153fc..a14a336467e 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -3996,9 +3996,9 @@ strip_predict_hints (function *fun, bool early)
 	      tree fndecl = gimple_call_fndecl (stmt);
 
 	      if (!early
-		  && ((DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
+		  && ((fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
 		       && gimple_call_num_args (stmt) == 2)
-		      || (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL,
+		      || (fndecl_built_in_p (fndecl,
 					   BUILT_IN_EXPECT_WITH_PROBABILITY)
 			  && gimple_call_num_args (stmt) == 3)
 		      || (gimple_call_internal_p (stmt)
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 5347e064704..8caf9dd0dd0 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -427,7 +427,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 	fputs (" autoinline", file);
       if (code == FUNCTION_DECL && DECL_UNINLINABLE (node))
 	fputs (" uninlinable", file);
-      if (code == FUNCTION_DECL && DECL_BUILT_IN (node))
+      if (code == FUNCTION_DECL && fndecl_built_in_p (node))
 	fputs (" built-in", file);
       if (code == FUNCTION_DECL && DECL_STATIC_CHAIN (node))
 	fputs (" static-chain", file);
@@ -502,7 +502,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 	  print_node (file, "size", DECL_SIZE (node), indent + 4);
 	  print_node (file, "unit-size", DECL_SIZE_UNIT (node), indent + 4);
 
-	  if (code != FUNCTION_DECL || DECL_BUILT_IN (node))
+	  if (code != FUNCTION_DECL || fndecl_built_in_p (node))
 	    indent_to (file, indent + 3);
 
 	  if (DECL_USER_ALIGN (node))
@@ -514,7 +514,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 	    fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
 		     DECL_OFFSET_ALIGN (node));
 
-	  if (code == FUNCTION_DECL && DECL_BUILT_IN (node))
+	  if (code == FUNCTION_DECL && fndecl_built_in_p (node))
 	    {
 	      if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
 		fprintf (file, " built-in: BUILT_IN_MD:%d", DECL_FUNCTION_CODE (node));
diff --git a/gcc/symtab.c b/gcc/symtab.c
index c5464cbe6d7..3cf1f629413 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -2323,7 +2323,7 @@ symtab_node::output_to_lto_symbol_table_p (void)
     return false;
   /* FIXME: Builtins corresponding to real functions probably should have
      symbol table entries.  */
-  if (is_builtin_fn (decl))
+  if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl))
     return false;
 
   /* We have real symbol that should be in symbol table.  However try to trim
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ca14915ef0d..1d4eb806202 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -235,8 +235,7 @@ is_tm_irrevocable (tree x)
   if (TREE_CODE (x) == ADDR_EXPR)
     x = TREE_OPERAND (x, 0);
   if (TREE_CODE (x) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
+      && fndecl_built_in_p (x, BUILT_IN_TM_IRREVOCABLE))
     return true;
 
   return false;
@@ -358,7 +357,8 @@ is_tm_load (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+  return (fndecl
+	  && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl)));
 }
 
@@ -374,7 +374,7 @@ is_tm_simple_load (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
       return (fcode == BUILT_IN_TM_LOAD_1
@@ -402,7 +402,8 @@ is_tm_store (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+  return (fndecl
+	  && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
 	  && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl)));
 }
 
@@ -418,7 +419,8 @@ is_tm_simple_store (gimple *stmt)
     return false;
 
   fndecl = gimple_call_fndecl (stmt);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (fndecl
+      && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
       return (fcode == BUILT_IN_TM_STORE_1
@@ -440,9 +442,7 @@ is_tm_simple_store (gimple *stmt)
 static bool
 is_tm_abort (tree fndecl)
 {
-  return (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
+  return (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_TM_ABORT));
 }
 
 /* Build a GENERIC tree for a user abort.  This is called by front ends
@@ -2007,7 +2007,7 @@ tm_region_init_1 (struct tm_region *region, basic_block bb)
       if (gimple_code (g) == GIMPLE_CALL)
 	{
 	  tree fn = gimple_call_fndecl (g);
-	  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
+	  if (fn && fndecl_built_in_p (fn, BUILT_IN_NORMAL))
 	    {
 	      if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
 		   || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index a47be1d0362..01401cad6e6 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -737,7 +737,7 @@ gen_shrink_wrap_conditions (gcall *bi_call, vec<gimple *> conds,
 
   call = bi_call;
   fn = gimple_call_fndecl (call);
-  gcc_assert (fn && DECL_BUILT_IN (fn));
+  gcc_assert (fn && fndecl_built_in_p (fn));
   fnc = DECL_FUNCTION_CODE (fn);
   *nconds = 0;
 
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 463dd8a3bf9..de9f1ddb71f 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3427,7 +3427,7 @@ verify_gimple_call (gcall *stmt)
       return true;
     }
 
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       switch (DECL_FUNCTION_CODE (fndecl))
 	{
@@ -6884,7 +6884,7 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
       /* Remap the region numbers for __builtin_eh_{pointer,filter}.  */
       {
 	tree r, fndecl = gimple_call_fndecl (stmt);
-	if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	  switch (DECL_FUNCTION_CODE (fndecl))
 	    {
 	    case BUILT_IN_EH_COPY_VALUES:
@@ -8305,15 +8305,14 @@ stmt_can_terminate_bb_p (gimple *t)
 
   if (is_gimple_call (t)
       && fndecl
-      && DECL_BUILT_IN (fndecl)
+      && fndecl_built_in_p (fndecl)
       && (call_flags & ECF_NOTHROW)
       && !(call_flags & ECF_RETURNS_TWICE)
       /* fork() doesn't really return twice, but the effect of
          wrapping it in __gcov_fork() which calls __gcov_flush()
 	 and clears the counters before forking has the same
 	 effect as returning twice.  Force a fake edge.  */
-      && !(DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	   && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FORK))
+      && !fndecl_built_in_p (fndecl, BUILT_IN_FORK))
     return false;
 
   if (is_gimple_call (t))
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f367040af45..aea16c998ad 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -1984,7 +1984,7 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
 	tree fndecl = gimple_call_fndecl (stmt);
 	tree rhs, lhs;
 
-	if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	  switch (DECL_FUNCTION_CODE (fndecl))
 	    {
 	    case BUILT_IN_EH_POINTER:
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index e181468fba9..77eefac4e34 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -1079,7 +1079,7 @@ if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
 		&& !(flags & ECF_LOOPING_CONST_OR_PURE)
 		/* We can only vectorize some builtins at the moment,
 		   so restrict if-conversion to those.  */
-		&& DECL_BUILT_IN (fndecl))
+		&& fndecl_built_in_p (fndecl))
 	      return true;
 	  }
 	return false;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index ef615cc347e..9352acc8af6 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1702,7 +1702,7 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
 	  case GIMPLE_CALL:
 	    {
 	      tree r, fndecl = gimple_call_fndecl (copy);
-	      if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+	      if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
 		switch (DECL_FUNCTION_CODE (fndecl))
 		  {
 		  case BUILT_IN_EH_COPY_VALUES:
@@ -1939,8 +1939,7 @@ copy_bb (copy_body_data *id, basic_block bb,
 	  else if (call_stmt
 		   && id->call_stmt
 		   && (decl = gimple_call_fndecl (stmt))
-		   && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-		   && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
+		   && fndecl_built_in_p (decl, BUILT_IN_VA_ARG_PACK_LEN))
 	    {
 	      /* __builtin_va_arg_pack_len () should be replaced by
 		 the number of anonymous arguments.  */
@@ -4039,7 +4038,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
 	if (gimple_call_internal_p (stmt))
 	  return 0;
 	else if ((decl = gimple_call_fndecl (stmt))
-		 && DECL_BUILT_IN (decl))
+		 && fndecl_built_in_p (decl))
 	  {
 	    /* Do not special case builtins where we see the body.
 	       This just confuse inliner.  */
@@ -4903,7 +4902,7 @@ fold_marked_statements (int first, hash_set<gimple *> *statements)
 	      gimple *old_stmt = gsi_stmt (gsi);
 	      tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0;
 
-	      if (old_decl && DECL_BUILT_IN (old_decl))
+	      if (old_decl && fndecl_built_in_p (old_decl))
 		{
 		  /* Folding builtins can create multiple instructions,
 		     we need to look at all of them.  */
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 3e30f6bc3d4..a9681ece0ae 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1498,8 +1498,7 @@ scan_function (void)
 
 		  if (dest)
 		    {
-		      if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
-			  && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
+		      if (fndecl_built_in_p (dest, BUILT_IN_APPLY_ARGS))
 			encountered_apply_args = true;
 		      if (recursive_call_p (current_function_decl, dest))
 			{
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index d0f799eb39d..95368a5c79d 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -807,7 +807,7 @@ surely_varying_stmt_p (gimple *stmt)
       tree fndecl, fntype = gimple_call_fntype (stmt);
       if (!gimple_call_lhs (stmt)
 	  || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
-	      && !DECL_BUILT_IN (fndecl)
+	      && !fndecl_built_in_p (fndecl)
 	      && !lookup_attribute ("assume_aligned",
 				    TYPE_ATTRIBUTES (fntype))
 	      && !lookup_attribute ("alloc_align",
@@ -2560,7 +2560,7 @@ optimize_stack_restore (gimple_stmt_iterator i)
 
       callee = gimple_call_fndecl (stmt);
       if (!callee
-	  || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
+	  || !fndecl_built_in_p (callee, BUILT_IN_NORMAL)
 	  /* All regular builtins are ok, just obviously not alloca.  */
 	  || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)))
 	return NULL_TREE;
@@ -2596,9 +2596,7 @@ optimize_stack_restore (gimple_stmt_iterator i)
       if (is_gimple_call (stack_save))
 	{
 	  callee = gimple_call_fndecl (stack_save);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
+	  if (callee && fndecl_built_in_p (callee, BUILT_IN_STACK_SAVE))
 	    {
 	      gimple_stmt_iterator stack_save_gsi;
 	      tree rhs;
@@ -3195,7 +3193,7 @@ pass_fold_builtins::execute (function *fun)
 	    }
 
 	  callee = gimple_call_fndecl (stmt);
-	  if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+	  if (!callee || !fndecl_built_in_p (callee, BUILT_IN_NORMAL))
 	    {
 	      gsi_next (&i);
 	      continue;
@@ -3370,8 +3368,7 @@ pass_fold_builtins::execute (function *fun)
 	    }
 	  callee = gimple_call_fndecl (stmt);
 	  if (!callee
-              || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (callee) == fcode)
+	      || !fndecl_built_in_p (callee, fcode))
 	    gsi_next (&i);
 	}
     }
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index d23148675c9..91ce2aa4fc5 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -224,7 +224,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
       {
 	tree callee = gimple_call_fndecl (stmt);
 	if (callee != NULL_TREE
-	    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+	    && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
 	  switch (DECL_FUNCTION_CODE (callee))
 	    {
 	    case BUILT_IN_MALLOC:
@@ -565,7 +565,7 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
     {
       tree callee = gimple_call_fndecl (def_stmt);
       if (callee != NULL_TREE
-	  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+	  && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
 	switch (DECL_FUNCTION_CODE (callee))
 	  {
 	  case BUILT_IN_MALLOC:
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 267880f3b5c..215d5e89d2b 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1986,8 +1986,7 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
 	     certain that the value simply isn't constant.  */
 	  tree callee = gimple_call_fndecl (stmt);
 	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
+	      && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
 	    {
 	      propagate_tree_value_into_stmt (&si, integer_zero_node);
 	      stmt = gsi_stmt (si);
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 56078110b39..470c00ba6ed 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1278,7 +1278,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
 		 constant length.  */
 	      callee1 = gimple_call_fndecl (stmt1);
 	      if (callee1 == NULL_TREE
-		  || DECL_BUILT_IN_CLASS (callee1) != BUILT_IN_NORMAL
+		  || !fndecl_built_in_p (callee1, BUILT_IN_NORMAL)
 		  || gimple_call_num_args (stmt1) != 3)
 		break;
 	      if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY
@@ -2538,7 +2538,7 @@ pass_forwprop::execute (function *fun)
 	      {
 		tree callee = gimple_call_fndecl (stmt);
 		if (callee != NULL_TREE
-		    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+		    && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
 		  changed = simplify_builtin_call (&gsi, callee);
 		break;
 	      }
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 01a954eeb1e..9c62f20866c 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -471,9 +471,7 @@ stmt_cost (gimple *stmt)
       /* Unless the call is a builtin_constant_p; this always folds to a
 	 constant, so moving it is useless.  */
       fndecl = gimple_call_fndecl (stmt);
-      if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
+      if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_CONSTANT_P))
 	return 0;
 
       return LIM_EXPENSIVE;
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index a90d9d28e4e..25378da6f4a 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -793,7 +793,7 @@ pass_cse_reciprocals::execute (function *fun)
 		    {
 		      fndecl = gimple_call_fndecl (call);
 		      if (!fndecl
-			  || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_MD)
+			  || !fndecl_built_in_p (fndecl, BUILT_IN_MD))
 			continue;
 		      fndecl = targetm.builtin_reciprocal (fndecl);
 		      if (!fndecl)
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 43f3313911f..8d00a272f56 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1279,7 +1279,7 @@ fully_constant_vn_reference_p (vn_reference_t ref)
   if (op->opcode == CALL_EXPR
       && TREE_CODE (op->op0) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
-      && DECL_BUILT_IN (TREE_OPERAND (op->op0, 0))
+      && fndecl_built_in_p (TREE_OPERAND (op->op0, 0))
       && operands.length () >= 2
       && operands.length () <= 3)
     {
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index d0792aa38c8..b90d4a17985 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -581,7 +581,7 @@ get_string_length (strinfo *si)
 
       gcc_assert (is_gimple_call (stmt));
       callee = gimple_call_fndecl (stmt);
-      gcc_assert (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL);
+      gcc_assert (callee && fndecl_built_in_p (callee, BUILT_IN_NORMAL));
       lhs = gimple_call_lhs (stmt);
       /* unshare_strinfo is intentionally not called here.  The (delayed)
 	 transformation of strcpy or strcat into stpcpy is done at the place
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index fd24f84fb14..22558351138 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4075,7 +4075,7 @@ handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> rhsc,
 	 initialized and thus may point to global memory.  All
 	 builtin functions with the malloc attribute behave in a sane way.  */
       if (!fndecl
-	  || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+	  || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
 	make_constraint_from (vi, nonlocal_id);
       tmpc.var = vi->id;
       tmpc.offset = 0;
@@ -4729,7 +4729,7 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
   varinfo_t fi;
 
   if (fndecl != NULL_TREE
-      && DECL_BUILT_IN (fndecl)
+      && fndecl_built_in_p (fndecl)
       && find_func_aliases_for_builtin_call (fn, t))
     return;
 
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 4339520039b..5380c500298 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -683,7 +683,7 @@ find_replaceable_in_bb (temp_expr_table *tab, basic_block bb)
 	 insns instead of a true call.  */
       if (is_gimple_call (stmt)
 	  && !((fndecl = gimple_call_fndecl (stmt))
-	       && DECL_BUILT_IN (fndecl)))
+	  && !fndecl_built_in_p (fndecl)))
 	cur_call_cnt++;
 
       /* Increment counter if this statement sets a local
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index c8594851957..f40dc5641cd 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -694,7 +694,7 @@ optimize_va_list_gpr_fpr_size (function *fun)
 
 	  callee = gimple_call_fndecl (stmt);
 	  if (!callee
-	      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+	      || !fndecl_built_in_p (callee, BUILT_IN_NORMAL))
 	    continue;
 
 	  switch (DECL_FUNCTION_CODE (callee))
@@ -867,9 +867,8 @@ optimize_va_list_gpr_fpr_size (function *fun)
 	      tree callee = gimple_call_fndecl (stmt);
 
 	      if (callee
-		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-		  && (DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_START
-		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END))
+		  && (fndecl_built_in_p (callee, BUILT_IN_VA_START)
+		      || fndecl_built_in_p (callee, BUILT_IN_VA_END)))
 		continue;
 	    }
 
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 9ebed9de524..8e9c2cbd289 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -476,7 +476,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
   tail_recursion = false;
   func = gimple_call_fndecl (call);
   if (func
-      && !DECL_BUILT_IN (func)
+      && !fndecl_built_in_p (func)
       && recursive_call_p (current_function_decl, func))
     {
       tree arg;
diff --git a/gcc/tree.c b/gcc/tree.c
index f00a519b302..5ae467437b5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5240,7 +5240,7 @@ need_assembler_name_p (tree decl)
     {
       /* Do not set assembler name on builtins.  Allow RTL expansion to
 	 decide whether to expand inline or via a regular call.  */
-      if (DECL_BUILT_IN (decl)
+      if (fndecl_built_in_p (decl)
 	  && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND)
 	return false;
 
@@ -5371,10 +5371,9 @@ free_lang_data_in_decl (tree decl)
 	 nodes and thus we can't use TREE_CHAIN in multiple lists.  */
       tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
       while (*nextp)
-        {
-          tree var = *nextp;
-          if (TREE_CODE (var) == FUNCTION_DECL
-              && DECL_BUILT_IN (var))
+	{
+	  tree var = *nextp;
+	  if (fndecl_built_in_p (var))
 	    *nextp = TREE_CHAIN (var);
 	  else
 	    nextp = &TREE_CHAIN (var);
@@ -9100,7 +9099,7 @@ get_call_combined_fn (const_tree call)
     return as_combined_fn (CALL_EXPR_IFN (call));
 
   tree fndecl = get_callee_fndecl (call);
-  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     return as_combined_fn (DECL_FUNCTION_CODE (fndecl));
 
   return CFN_LAST;
diff --git a/gcc/tree.h b/gcc/tree.h
index 5d4f034e008..bf210c1a51f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2995,25 +2995,11 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
 #define DECL_STRUCT_FUNCTION(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->function_decl.f)
 
-/* In a FUNCTION_DECL, nonzero means a built in function of a
-   standard library or more generally a built in function that is
-   recognized by optimizers and expanders.
-
-   Note that it is different from the DECL_IS_BUILTIN accessor.  For
-   instance, user declared prototypes of C library functions are not
-   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
-#define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
 
 /* For a builtin function, identify which part of the compiler defined it.  */
 #define DECL_BUILT_IN_CLASS(NODE) \
    (FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
 
-/* For a function declaration, return true if NODE is non-null and it is
-   a builtin of a CLASS with requested NAME.  */
-#define DECL_BUILT_IN_P(NODE, CLASS, NAME) \
-  (NODE != NULL_TREE && DECL_BUILT_IN_CLASS (NODE) == CLASS \
-   && DECL_FUNCTION_CODE (NODE) == NAME)
-
 /* In FUNCTION_DECL, a chain of ..._DECL nodes.  */
 #define DECL_ARGUMENTS(NODE) \
    (FUNCTION_DECL_CHECK (NODE)->function_decl.arguments)
@@ -5848,4 +5834,50 @@ type_has_mode_precision_p (const_tree t)
   return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t)));
 }
 
+/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
+   standard library or more generally a built in function that is
+   recognized by optimizers and expanders.
+
+   Note that it is different from the DECL_IS_BUILTIN accessor.  For
+   instance, user declared prototypes of C library functions are not
+   DECL_IS_BUILTIN but may be DECL_BUILT_IN.
+
+   When a NULL argument is pass or tree code of the NODE is not FUNCTION_DECL
+   false is returned.  */
+
+inline bool
+fndecl_built_in_p (const_tree node)
+{
+  return (node != NULL_TREE
+	  && DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
+}
+
+/* For a FUNCTION_DECL NODE, return true when a function is
+   a built-in of class KLASS.  */
+
+inline bool
+fndecl_built_in_p (const_tree node, built_in_class klass)
+{
+  return (fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass);
+}
+
+/* For a FUNCTION_DECL NODE, return true when a function is
+   a built-in of class KLASS with name equal to NAME.  */
+
+inline bool
+fndecl_built_in_p (const_tree node, int name, built_in_class klass)
+{
+  return (fndecl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
+}
+
+/* For a FUNCTION_DECL NODE, return true when a function is
+   a built-in of class BUILT_IN_NORMAL class with name equal to NAME.  */
+
+inline bool
+fndecl_built_in_p (const_tree node, built_in_function name)
+{
+  return (fndecl_built_in_p (node, BUILT_IN_NORMAL)
+	  && DECL_FUNCTION_CODE (node) == name);
+}
+
 #endif  /* GCC_TREE_H  */
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 722f5702612..9bbcecc58af 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -663,7 +663,7 @@ bool
 is_ubsan_builtin_p (tree t)
 {
   return TREE_CODE (t) == FUNCTION_DECL
-	 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
+	 && fndecl_built_in_p (t, BUILT_IN_NORMAL)
 	 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
 		     "__builtin___ubsan_", 18) == 0;
 }
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 99de27d9d3c..2180da48895 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2401,7 +2401,7 @@ static hash_set<tree> *pending_assemble_externals_set;
 static bool
 incorporeal_function_p (tree decl)
 {
-  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
+  if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl))
     {
       const char *name;
Richard Biener Aug. 27, 2018, 8:18 a.m. UTC | #10
On Mon, Aug 27, 2018 at 9:20 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 08/23/2018 03:58 PM, Richard Biener wrote:
> > On Thu, Aug 23, 2018 at 3:30 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 08/23/2018 01:58 PM, Richard Biener wrote:
> >>> On Thu, Aug 23, 2018 at 12:46 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> On 08/20/2018 10:34 AM, Richard Biener wrote:
> >>>>> On Wed, Aug 15, 2018 at 2:52 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>>>
> >>>>>> On 08/14/2018 06:02 PM, Martin Sebor wrote:
> >>>>>>> On 08/14/2018 03:06 AM, Martin Liška wrote:
> >>>>>>>> Hi.
> >>>>>>>>
> >>>>>>>> The patch adds more usages of the new macro. I hope it improves
> >>>>>>>> readability of code.
> >>>>>>>
> >>>>>>> I think it does :)  I see that most invocations of it in your
> >>>>>>> patch are with BUILT_IN_NORMAL as the second argument.  Is
> >>>>>>> the argument implied by the last argument?  E.g., in
> >>>>>>>
> >>>>>>>   DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK)
> >>>>>>>
> >>>>>>> is there a way to determine that BUILT_IN_VA_ARG_PACK implies
> >>>>>>> DECL_BUILT_IN_CLASS(fndecl), so that the second argument could
> >>>>>>> be eliminated?  (Both to make the invocation less verbose and
> >>>>>>> to avoid the mistake of using the macro with the wrong class.)
> >>>>>>
> >>>>>> If I see correctly not, there are separate enums:
> >>>>>>
> >>>>>> BUILT_IN_MD:
> >>>>>>
> >>>>>> enum ix86_builtins {
> >>>>>>   IX86_BUILTIN_MASKMOVQ,
> >>>>>>   IX86_BUILTIN_LDMXCSR,
> >>>>>>   IX86_BUILTIN_STMXCSR,
> >>>>>> ...
> >>>>>> }
> >>>>>>
> >>>>>> BUILT_IN_NORMAL:
> >>>>>> enum built_in_function {
> >>>>>> BUILT_IN_NONE,
> >>>>>> BUILT_IN_ACOS,
> >>>>>> BUILT_IN_ACOSF,
> >>>>>> ...
> >>>>>> }
> >>>>>>
> >>>>>> So the enum values overlap and thus one needs the class.
> >>>>>>
> >>>>>>
> >>>>>>>
> >>>>>>> If not, adding DECL_NORMAL_BUILT_IN_P() would make it possible
> >>>>>>> to omit it.
> >>>>>>
> >>>>>> But yes, this is nice idea, I'm sending V2 of the patch that I'm testing
> >>>>>> right now.
> >>>>>
> >>>>> Ick, and now we have DECL_IS_BUILTIN, DECL_BUILT_IN, DECL_BUILT_IN_P
> >>>>> and DECL_NORMAL_BUILT_IN_P ... (esp the first one is confusing).
> >>>>
> >>>> Agree.
> >>>>
> >>>>>
> >>>>> I think following what gimple.h does would be nicer which means using
> >>>>> inline functions and overloading.
> >>>>>
> >>>>> decl_built_in_p (tree);
> >>>>> decl_built_in_p (tree, enum built_in_class);
> >>>>> decl_built_in_p (tree, enum built_in_function); /// implies BUILT_IN_NORMAL
> >>>>
> >>>> Yes, that's easier to use!
> >>>>
> >>>>>
> >>>>> Can you rework things this way please?  (ok, for gimple those are not inlines)
> >>>>
> >>>> Done in patch that can bootstrap and survives regression tests.
> >>>> Ready for trunk?
> >>>
> >>> +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
> >>> +   standard library or more generally a built in function that is
> >>> +   recognized by optimizers and expanders.
> >>> +
> >>> +   Note that it is different from the DECL_IS_BUILTIN accessor.  For
> >>> +   instance, user declared prototypes of C library functions are not
> >>> +   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
> >>> +
> >>> +inline bool
> >>> +decl_built_in_p (const_tree node)
> >>> +{
> >>> +  return (node != NULL_TREE
> >>> +         && TREE_CODE (node) == FUNCTION_DECL
> >>>
> >>> You document for a FUNCTION_DECL NODE but the check
> >>> for FUNCTION_DECL anyway.  I realize doing all (possibly redundant)
> >>> checks in decl_built_in_p is convenient at callers, but at least update
> >>> docs accordingly?  In reality I somewhat prefer
> >>
> >> Yes, please let stay with version that does the checks. It can provide
> >> more readable code like:
> >>
> >>        /* If last argument is __builtin_va_arg_pack (), arguments to this
> >>          function are not finalized yet.  Defer folding until they are.  */
> >>        if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
> >>         {
> >>           tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
> >> -         if (fndecl2
> >> -             && TREE_CODE (fndecl2) == FUNCTION_DECL
> >> -             && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
> >> -             && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
> >> +         if (decl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
> >>             return NULL_TREE;
> >>         }
> >>        if (avoid_folding_inline_builtin (fndecl))
> >
> > But here the TREE_CODE (fndecl2) == FUNCTION_DECL check is redundant
> > (get_callee_fndecl always returns a FUNCTION_DECL).  So it would become
> >
> >   if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK))
> >
> > which is IMHO good enough.
>
> Hello.
>
> I reworked the patch that way.
>
> >
> >>>
> >>> inline bool
> >>> decl_built_in_p (const_tree node)
> >>> {
> >>>   return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
> >>> }
> >>>
> >>> and
> >>>
> >>> inline bool
> >>> decl_built_in_p (const_tree node, built_in_class klass)
> >>> {
> >>>   return DECL_BUILT_IN_CLASS (node) == klass;
> >>> }
> >>>
> >>> esp. since the built_in_class overload doesn't work for
> >>> NOT_BUILT_IN for your variant.
> >>
> >> That's true. One should probably use DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN
> >> in this case.
> >>
> >>>
> >>> And if we're at changing, maybe call the functions
> >>> fndecl_built_in_p to make it clear we're expecting FUNCTION_DECLs...
> >>>
> >>> +/* For a FUNCTION_DECL NODE, return true when a function is
> >>> +   a built-in of class KLASS with name equal to NAME.  */
> >>> +
> >>> +inline bool
> >>> +decl_built_in_p (const_tree node, int name,
> >>>
> >>> why's that 'int' and not built_in_function?
> >>
> >> Because we want to also call it for e.g. cp_built_in_function
> >> enum types:
> >>
> >> gcc/cp/cp-gimplify.c:2498:26: error: no matching function for call to ‘decl_built_in_p(tree_node*&, cp_built_in_function, built_in_class)’
> >>
> >> Note that:
> >> gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
> >>
> >> is only used for BUILT_IN_NORMAL, which decl_built_in_p should handle also FE and TARGET codes.
> >
> > I know ...
> >
> >>>
> >>> +                built_in_class klass = BUILT_IN_NORMAL)
> >
> > So without the default arg we could make two overloads:
> >
> > fndecl_built_in_p (const_tree, enum built_in_function)
> > fndecl_built_in_p (const_tree, int, enum built_in_class)
> >
> > and keep the type checking?
>
> Yes, good idea.
>
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>
> Ready to be installed?

You left the NULL checks in the code but still have

+inline bool
+fndecl_built_in_p (const_tree node)
+{
+  return (node != NULL_TREE
+         && DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
+}

Please remove the now redundant NULL check here.

OK with that change,
Richard.

> Martin
>
> >
> >>> This deviates from the gimple.h routines as well (also builtin vs. built_in, but
> >>> built_in is better).
> >>
> >> As you with here, I'm fine with both. Are you fine with the consensus that the functions will
> >> do check for null argument and TREE_CODE check?
> >
> > Not yet ;)  The extra checks are not going to be optimized away in
> > those places that do
> > not need them I think.  Any more convincing examples?
> >
> > Richard.
> >
> >> Martin
> >>
> >>>
> >>> +{
> >>> +  return (decl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
> >>> +}
> >>>
> >>>
> >>>> Martin
> >>>>
> >>>>>
> >>>>> Thanks,
> >>>>> Richard.
> >>>>>
> >>>>>> Martin
> >>>>>>
> >>>>>>>
> >>>>>>> Martin
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> >>>>>>>>
> >>>>>>>> Ready to be installed?
> >>>>>>>> Martin
> >>>>>>>>
> >>>>>>>> gcc/ChangeLog:
> >>>>>>>>
> >>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>>>>>
> >>>>>>>>     * tree.h (DECL_BUILT_IN_P): Add also check
> >>>>>>>>         for TREE_CODE (NODE) == FUNCTION_DECL.
> >>>>>>>>     * builtins.c (fold_call_expr): Use DECL_BUILT_IN_P macro.
> >>>>>>>>     (fold_builtin_call_array): Likewise.
> >>>>>>>>     * cgraph.c (cgraph_update_edges_for_call_stmt_node): Likewise.
> >>>>>>>>     (cgraph_edge::verify_corresponds_to_fndecl): Likewise.
> >>>>>>>>     (cgraph_node::verify_node): Likewise.
> >>>>>>>>     * cgraphclones.c (cgraph_node::create_clone): Likewise.
> >>>>>>>>     * dse.c (scan_insn): Likewise.
> >>>>>>>>     * fold-const.c (fold_binary_loc): Likewise.
> >>>>>>>>     * gimple-pretty-print.c (dump_gimple_call): Likewise.
> >>>>>>>>     * gimple.c (gimple_call_builtin_p): Likewise.
> >>>>>>>>     * gimplify.c (gimplify_call_expr): Likewise.
> >>>>>>>>     (gimple_boolify): Likewise.
> >>>>>>>>     (gimplify_modify_expr): Likewise.
> >>>>>>>>     * ipa-fnsummary.c (compute_fn_summary): Likewise.
> >>>>>>>>     * omp-low.c (setjmp_or_longjmp_p): Likewise.
> >>>>>>>>     * trans-mem.c (is_tm_irrevocable): Likewise.
> >>>>>>>>     (is_tm_abort): Likewise.
> >>>>>>>>     * tree-cfg.c (stmt_can_terminate_bb_p): Likewise.
> >>>>>>>>     * tree-inline.c (copy_bb): Likewise.
> >>>>>>>>     * tree-sra.c (scan_function): Likewise.
> >>>>>>>>     * tree-ssa-ccp.c (optimize_stack_restore): Likewise.
> >>>>>>>>     (pass_fold_builtins::execute): Likewise.
> >>>>>>>>     * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Likewise.
> >>>>>>>>     * tree-ssa-loop-im.c (stmt_cost): Likewise.
> >>>>>>>>     * tree-stdarg.c (optimize_va_list_gpr_fpr_size): Likewise.
> >>>>>>>>
> >>>>>>>> gcc/c/ChangeLog:
> >>>>>>>>
> >>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>>>>>
> >>>>>>>>     * c-parser.c (c_parser_postfix_expression_after_primary):
> >>>>>>>>         Use DECL_BUILT_IN_P macro.
> >>>>>>>>
> >>>>>>>> gcc/cp/ChangeLog:
> >>>>>>>>
> >>>>>>>> 2018-08-10  Martin Liska  <mliska@suse.cz>
> >>>>>>>>
> >>>>>>>>     * constexpr.c (constexpr_fn_retval): Use DECL_BUILT_IN_P macro.
> >>>>>>>>     (cxx_eval_builtin_function_call): Likewise.
> >>>>>>>>     * cp-gimplify.c (cp_gimplify_expr): Likewise.
> >>>>>>>>     (cp_fold): Likewise.
> >>>>>>>>     * semantics.c (finish_call_expr): Likewise.
> >>>>>>>>     * tree.c (builtin_valid_in_constant_expr_p): Likewise.
> >>>>>>>> ---
> >>>>>>>>  gcc/builtins.c            | 10 ++--------
> >>>>>>>>  gcc/c/c-parser.c          |  9 +++------
> >>>>>>>>  gcc/cgraph.c              | 13 ++++++-------
> >>>>>>>>  gcc/cgraphclones.c        |  4 ++--
> >>>>>>>>  gcc/cp/constexpr.c        | 12 +++++-------
> >>>>>>>>  gcc/cp/cp-gimplify.c      | 12 ++++--------
> >>>>>>>>  gcc/cp/semantics.c        |  4 +---
> >>>>>>>>  gcc/cp/tree.c             |  5 ++---
> >>>>>>>>  gcc/dse.c                 |  5 ++---
> >>>>>>>>  gcc/fold-const.c          |  4 +---
> >>>>>>>>  gcc/gimple-pretty-print.c |  4 +---
> >>>>>>>>  gcc/gimple.c              |  3 +--
> >>>>>>>>  gcc/gimplify.c            | 14 ++++----------
> >>>>>>>>  gcc/ipa-fnsummary.c       |  8 ++++----
> >>>>>>>>  gcc/omp-low.c             |  5 ++---
> >>>>>>>>  gcc/trans-mem.c           |  8 ++------
> >>>>>>>>  gcc/tree-cfg.c            |  3 +--
> >>>>>>>>  gcc/tree-inline.c         |  4 ++--
> >>>>>>>>  gcc/tree-sra.c            |  4 ++--
> >>>>>>>>  gcc/tree-ssa-ccp.c        |  8 ++------
> >>>>>>>>  gcc/tree-ssa-dom.c        |  4 +---
> >>>>>>>>  gcc/tree-ssa-loop-im.c    |  4 +---
> >>>>>>>>  gcc/tree-stdarg.c         |  6 ++----
> >>>>>>>>  gcc/tree.h                |  4 +++-
> >>>>>>>>  24 files changed, 56 insertions(+), 101 deletions(-)
> >>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>
> >>
>
Martin Sebor Aug. 27, 2018, 4:02 p.m. UTC | #11
On 08/27/2018 01:20 AM, Martin Liška wrote:
> +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
> + standard library or more generally a built in function that is
> + recognized by optimizers and expanders.

I'm a little confused by this description: the last part makes
me wonder about what a true value implies about a function.  It
sounds like the function returns true for any built-in, library
or otherwise, correct (i.e., including a front-end built-in)?
If yes, then maybe drop the part about standard library functions?
Say:

   Return true if a FUNCTION_DECL NODE is a GCC built-in function.


> +
> + Note that it is different from the DECL_IS_BUILTIN accessor. For
> + instance, user declared prototypes of C library functions are not
> + DECL_IS_BUILTIN but may be DECL_BUILT_IN.
> +
> + When a NULL argument is pass or tree code of the NODE is not
> FUNCTION_DECL
> + false is returned. */

"Passed" -- so perhaps "When NODE is null..."

Martin

> +
> +inline bool
> +fndecl_built_in_p (const_tree node)
> +{
> + return (node != NULL_TREE
> + && DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
> +}
Martin Liška Aug. 28, 2018, 7:17 a.m. UTC | #12
On 08/27/2018 06:02 PM, Martin Sebor wrote:
> On 08/27/2018 01:20 AM, Martin Liška wrote:
>> +/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
>> + standard library or more generally a built in function that is
>> + recognized by optimizers and expanders.

Hi.

Thanks for help with that.

> 
> I'm a little confused by this description: the last part makes
> me wonder about what a true value implies about a function.  It
> sounds like the function returns true for any built-in, library
> or otherwise, correct (i.e., including a front-end built-in)?
> If yes, then maybe drop the part about standard library functions?
> Say:
> 
>   Return true if a FUNCTION_DECL NODE is a GCC built-in function.

Yes, it's better!

> 
> 
>> +
>> + Note that it is different from the DECL_IS_BUILTIN accessor. For
>> + instance, user declared prototypes of C library functions are not
>> + DECL_IS_BUILTIN but may be DECL_BUILT_IN.
>> +
>> + When a NULL argument is pass or tree code of the NODE is not
>> FUNCTION_DECL
>> + false is returned. */
> 
> "Passed" -- so perhaps "When NODE is null..."

Ho be honest this part became out of date, I'm going to remove that.

There's a part that I'm going to install.

Martin

> 
> Martin
> 
>> +
>> +inline bool
>> +fndecl_built_in_p (const_tree node)
>> +{
>> + return (node != NULL_TREE
>> + && DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
>> +}
>
From b6a2c3c2bfccb1528f11db3e829657199d8b0eba Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 28 Aug 2018 09:15:43 +0200
Subject: [PATCH] Update documentation of fndecl_built_in_p.

gcc/ChangeLog:

2018-08-28  Martin Liska  <mliska@suse.cz>

	* tree.h: Update documentation of fndecl_built_in_p
	functions.
---
 gcc/tree.h | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/gcc/tree.h b/gcc/tree.h
index db04eb7e58b..562a88b8aff 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5834,16 +5834,11 @@ type_has_mode_precision_p (const_tree t)
   return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t)));
 }
 
-/* For a FUNCTION_DECL NODE, nonzero means a built in function of a
-   standard library or more generally a built in function that is
-   recognized by optimizers and expanders.
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function.
 
    Note that it is different from the DECL_IS_BUILTIN accessor.  For
    instance, user declared prototypes of C library functions are not
-   DECL_IS_BUILTIN but may be DECL_BUILT_IN.
-
-   When a NULL argument is pass or tree code of the NODE is not FUNCTION_DECL
-   false is returned.  */
+   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
 
 inline bool
 fndecl_built_in_p (const_tree node)
@@ -5851,8 +5846,8 @@ fndecl_built_in_p (const_tree node)
   return (DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
 }
 
-/* For a FUNCTION_DECL NODE, return true when a function is
-   a built-in of class KLASS.  */
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
+   of class KLASS.  */
 
 inline bool
 fndecl_built_in_p (const_tree node, built_in_class klass)
@@ -5860,8 +5855,8 @@ fndecl_built_in_p (const_tree node, built_in_class klass)
   return (fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass);
 }
 
-/* For a FUNCTION_DECL NODE, return true when a function is
-   a built-in of class KLASS with name equal to NAME.  */
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
+   of class KLASS with name equal to NAME.  */
 
 inline bool
 fndecl_built_in_p (const_tree node, int name, built_in_class klass)
@@ -5869,8 +5864,8 @@ fndecl_built_in_p (const_tree node, int name, built_in_class klass)
   return (fndecl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
 }
 
-/* For a FUNCTION_DECL NODE, return true when a function is
-   a built-in of class BUILT_IN_NORMAL class with name equal to NAME.  */
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
+   of BUILT_IN_NORMAL class with name equal to NAME.  */
 
 inline bool
 fndecl_built_in_p (const_tree node, built_in_function name)
H.J. Lu Aug. 28, 2018, 7:18 p.m. UTC | #13
>
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>
> Ready to be installed?

This caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87130


H.J.
diff mbox series

Patch

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 867d153d798..e6279979544 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -9629,10 +9629,7 @@  fold_call_expr (location_t loc, tree exp, bool ignore)
       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (DECL_BUILT_IN_P (fndecl2, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
 
@@ -9675,10 +9672,7 @@  fold_builtin_call_array (location_t loc, tree,
       if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
 	{
 	  tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
-	  if (fndecl2
-	      && TREE_CODE (fndecl2) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	  if (DECL_BUILT_IN_P (fndecl2, BUILT_IN_NORMAL, BUILT_IN_VA_ARG_PACK))
 	    return NULL_TREE;
 	}
       if (avoid_folding_inline_builtin (fndecl))
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7a926285f3a..6e44ee7e366 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -9159,9 +9159,7 @@  c_parser_postfix_expression_after_primary (c_parser *parser,
 					      expr.value, exprlist,
 					      sizeof_arg,
 					      sizeof_ptr_memacc_comptypes);
-	  if (TREE_CODE (expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (expr.value) == BUILT_IN_MEMSET
+	  if (DECL_BUILT_IN_P (expr.value, BUILT_IN_NORMAL, BUILT_IN_MEMSET)
 	      && vec_safe_length (exprlist) == 3)
 	    {
 	      tree arg0 = (*exprlist)[0];
@@ -9178,9 +9176,8 @@  c_parser_postfix_expression_after_primary (c_parser *parser,
 
 	  expr.original_code = ERROR_MARK;
 	  if (TREE_CODE (expr.value) == INTEGER_CST
-	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
+	      && DECL_BUILT_IN_P (orig_expr.value, BUILT_IN_NORMAL,
+				  BUILT_IN_CONSTANT_P))
 	    expr.original_code = C_MAYBE_CONST_EXPR;
 	  expr.original_type = NULL;
 	  if (exprlist)
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d19f1aacab8..bc90ac3c7c6 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1559,8 +1559,8 @@  cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
 	{
 	  /* Keep calls marked as dead dead.  */
 	  if (new_stmt && is_gimple_call (new_stmt) && e->callee
-	      && DECL_BUILT_IN_CLASS (e->callee->decl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (e->callee->decl) == BUILT_IN_UNREACHABLE)
+	      && DECL_BUILT_IN_P (e->callee->decl, BUILT_IN_NORMAL,
+				  BUILT_IN_UNREACHABLE))
 	    {
               node->get_edge (old_stmt)->set_call_stmt
 		 (as_a <gcall *> (new_stmt));
@@ -3060,8 +3060,8 @@  cgraph_edge::verify_corresponds_to_fndecl (tree decl)
 
   /* Optimizers can redirect unreachable calls or calls triggering undefined
      behavior to builtin_unreachable.  */
-  if (DECL_BUILT_IN_CLASS (callee->decl) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (callee->decl) == BUILT_IN_UNREACHABLE)
+
+  if (DECL_BUILT_IN_P (callee->decl, BUILT_IN_NORMAL, BUILT_IN_UNREACHABLE))
     return false;
 
   if (callee->former_clone_of != node->decl
@@ -3186,9 +3186,8 @@  cgraph_node::verify_node (void)
 	  && !e->speculative
 	  /* Optimized out calls are redirected to __builtin_unreachable.  */
 	  && (e->count.nonzero_p ()
-	      || ! e->callee->decl
-	      || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	      || !DECL_BUILT_IN_P (e->callee->decl, BUILT_IN_NORMAL,
+				   BUILT_IN_UNREACHABLE))
 	  && count
 	      == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
 	  && (!e->count.ipa_p ()
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 6e84a31c1a5..b7c328f25b8 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -482,8 +482,8 @@  cgraph_node::create_clone (tree new_decl, profile_count prof_count,
 	 version.  The only exception is when the edge was proved to
 	 be unreachable during the clonning procedure.  */
       if (!e->callee
-	  || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
-	  || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
+	  || !DECL_BUILT_IN_P (e->callee->decl, BUILT_IN_NORMAL,
+			       BUILT_IN_UNREACHABLE))
         e->redirect_callee_duplicating_thunks (new_node);
     }
   new_node->expand_all_artificial_thunks ();
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index ece2c8a92d9..2fa7a34974e 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -712,9 +712,8 @@  constexpr_fn_retval (tree body)
     case CALL_EXPR:
 	{
 	  tree fun = get_function_named_in_call (body);
-	  if (fun != NULL_TREE
-	      && DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+	  if (DECL_BUILT_IN_P (fun, BUILT_IN_NORMAL,
+			       BUILT_IN_UNREACHABLE))
 	    return NULL_TREE;
 	}
       /* Fallthru.  */
@@ -1189,8 +1188,8 @@  cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 
   /* For __builtin_is_constant_evaluated, defer it if not
      ctx->pretend_const_required, otherwise fold it to true.  */
-  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_FRONTEND
-      && (int) DECL_FUNCTION_CODE (fun) == CP_BUILT_IN_IS_CONSTANT_EVALUATED)
+  if (DECL_BUILT_IN_P (fun, BUILT_IN_FRONTEND,
+		       CP_BUILT_IN_IS_CONSTANT_EVALUATED))
     {
       if (!ctx->pretend_const_required)
 	{
@@ -1233,8 +1232,7 @@  cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 	  /* Do not allow__builtin_unreachable in constexpr function.
 	     The __builtin_unreachable call with BUILTINS_LOCATION
 	     comes from cp_maybe_instrument_return.  */
-	  if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+	  if (DECL_BUILT_IN_P (fun, BUILT_IN_NORMAL, BUILT_IN_UNREACHABLE)
 	      && EXPR_LOCATION (t) == BUILTINS_LOCATION)
 	    error ("%<constexpr%> call flows off the end of the function");
 	  else
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 7db4accb504..e7c5c8deef2 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -796,10 +796,8 @@  cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (ret != GS_ERROR)
 	{
 	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
-	  if (decl
-	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	      && ((int) DECL_FUNCTION_CODE (decl)
-		  == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	  if (DECL_BUILT_IN_P (decl, BUILT_IN_FRONTEND,
+			       CP_BUILT_IN_IS_CONSTANT_EVALUATED))
 	    *expr_p = boolean_false_node;
 	}
       break;
@@ -2493,10 +2491,8 @@  cp_fold (tree x)
 	  nw = 1;
 
 	/* Defer folding __builtin_is_constant_evaluated.  */
-	if (callee
-	    && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_FRONTEND
-	    && ((int) DECL_FUNCTION_CODE (callee)
-		== CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+	if (DECL_BUILT_IN_P (callee, BUILT_IN_FRONTEND,
+			     CP_BUILT_IN_IS_CONSTANT_EVALUATED))
 	  break;
 
 	x = copy_node (x);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bfdca5024d3..153c020546a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2545,9 +2545,7 @@  finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 	    }
 
 	  if ((complain & tf_warning)
-	      && TREE_CODE (fn) == FUNCTION_DECL
-	      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fn) == BUILT_IN_MEMSET
+	      && DECL_BUILT_IN_P (fn, BUILT_IN_NORMAL, BUILT_IN_MEMSET)
 	      && vec_safe_length (*args) == 3
 	      && !any_type_dependent_arguments_p (*args))
 	    {
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 1cf3269d880..a91060d3c21 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -420,9 +420,8 @@  builtin_valid_in_constant_expr_p (const_tree decl)
     return false;
   if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
     {
-      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
-	  && ((int) DECL_FUNCTION_CODE (decl)
-	      == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+      if (DECL_BUILT_IN_P (decl, BUILT_IN_FRONTEND,
+			   CP_BUILT_IN_IS_CONSTANT_EVALUATED))
 	return true;
       /* Not a built-in.  */
       return false;
diff --git a/gcc/dse.c b/gcc/dse.c
index 26c6007b9ed..c09766241a1 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2418,9 +2418,8 @@  scan_insn (bb_info_t bb_info, rtx_insn *insn)
 	  && (sym = XEXP (XEXP (call, 0), 0))
 	  && GET_CODE (sym) == SYMBOL_REF
 	  && SYMBOL_REF_DECL (sym)
-	  && TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (sym)) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (sym)) == BUILT_IN_MEMSET)
+	  && DECL_BUILT_IN_P (SYMBOL_REF_DECL (sym), BUILT_IN_NORMAL,
+			      BUILT_IN_MEMSET))
 	memset_call = SYMBOL_REF_DECL (sym);
 
       if (const_call || memset_call)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b318fc7705f..55f063549ee 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10752,9 +10752,7 @@  fold_binary_loc (location_t loc, enum tree_code code, tree type,
 	{
 	  tree fndecl = get_callee_fndecl (arg0);
 
-	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
+	  if (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_STRLEN)
 	      && call_expr_nargs (arg0) == 1
 	      && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0))) == POINTER_TYPE)
 	    {
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d3c5ec6f79b..6eed1e8d3ea 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -910,9 +910,7 @@  dump_gimple_call (pretty_printer *buffer, gcall *gs, int spc,
     fn = TREE_OPERAND (fn, 0);
   if (TREE_CODE (fn) == FUNCTION_DECL && decl_is_tm_clone (fn))
     pp_string (buffer, " [tm-clone]");
-  if (TREE_CODE (fn) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_START
+  if (DECL_BUILT_IN_P (fn, BUILT_IN_NORMAL, BUILT_IN_TM_START)
       && gimple_call_num_args (gs) > 0)
     {
       tree t = gimple_call_arg (gs, 0);
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 8d56a966cc1..4fa519f0fe5 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2681,8 +2681,7 @@  gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
   tree fndecl;
   if (is_gimple_call (stmt)
       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 
-      && DECL_FUNCTION_CODE (fndecl) == code)
+      && DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, code))
     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
   return false;
 }
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4a109aee27a..153f20c5ac9 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3295,10 +3295,8 @@  gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
       tree last_arg_fndecl = get_callee_fndecl (last_arg);
 
-      if (last_arg_fndecl
-	  && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
-	  && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
+      if (DECL_BUILT_IN_P (last_arg_fndecl, BUILT_IN_NORMAL,
+			   BUILT_IN_VA_ARG_PACK))
 	{
 	  tree call = *expr_p;
 
@@ -3771,9 +3769,7 @@  gimple_boolify (tree expr)
 
       /* For __builtin_expect ((long) (x), y) recurse into x as well
 	 if x is truth_value_p.  */
-      if (fn
-	  && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
+      if (DECL_BUILT_IN_P (fn, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
 	  && call_expr_nargs (call) == 2)
 	{
 	  tree arg = CALL_EXPR_ARG (call, 0);
@@ -5717,9 +5713,7 @@  gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
 	  STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
 	  tree fndecl = get_callee_fndecl (*from_p);
-	  if (fndecl
-	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+	  if (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_EXPECT)
 	      && call_expr_nargs (*from_p) == 3)
 	    call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
 						    CALL_EXPR_ARG (*from_p, 0),
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..dabd858bf32 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2455,10 +2455,10 @@  compute_fn_summary (struct cgraph_node *node, bool early)
 	       for (e = node->callees; e; e = e->next_callee)
 		 {
 		   tree cdecl = e->callee->decl;
-		   if (DECL_BUILT_IN (cdecl)
-		       && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
-		       && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
-			   || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
+		   if (DECL_BUILT_IN_P (cdecl, BUILT_IN_NORMAL,
+					BUILT_IN_APPLY_ARGS)
+		       || DECL_BUILT_IN_P (cdecl, BUILT_IN_NORMAL,
+					   BUILT_IN_VA_START))
 		     break;
 		 }
 	       node->local.can_change_signature = !e;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 843c66fd221..e9f1bee8055 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2975,9 +2975,8 @@  scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
 static bool
 setjmp_or_longjmp_p (const_tree fndecl)
 {
-  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
-	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+  if (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_SETJMP)
+      || DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_LONGJMP))
     return true;
 
   tree declname = DECL_NAME (fndecl);
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ca14915ef0d..e1fed1134c8 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -234,9 +234,7 @@  is_tm_irrevocable (tree x)
      irrevocable.  */
   if (TREE_CODE (x) == ADDR_EXPR)
     x = TREE_OPERAND (x, 0);
-  if (TREE_CODE (x) == FUNCTION_DECL
-      && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
+  if (DECL_BUILT_IN_P (x, BUILT_IN_NORMAL, BUILT_IN_TM_IRREVOCABLE))
     return true;
 
   return false;
@@ -440,9 +438,7 @@  is_tm_simple_store (gimple *stmt)
 static bool
 is_tm_abort (tree fndecl)
 {
-  return (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
+  return DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_TM_ABORT);
 }
 
 /* Build a GENERIC tree for a user abort.  This is called by front ends
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 14d66b7a728..459f2ce8cc5 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -8312,8 +8312,7 @@  stmt_can_terminate_bb_p (gimple *t)
          wrapping it in __gcov_fork() which calls __gcov_flush()
 	 and clears the counters before forking has the same
 	 effect as returning twice.  Force a fake edge.  */
-      && !(DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	   && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FORK))
+      && !DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_FORK))
     return false;
 
   if (is_gimple_call (t))
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6a16ce546cb..03db7453a75 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1939,8 +1939,8 @@  copy_bb (copy_body_data *id, basic_block bb,
 	  else if (call_stmt
 		   && id->call_stmt
 		   && (decl = gimple_call_fndecl (stmt))
-		   && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-		   && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN
+		   && DECL_BUILT_IN_P (decl, BUILT_IN_NORMAL,
+				       BUILT_IN_VA_ARG_PACK_LEN)
 		   && ! gimple_call_va_arg_pack_p (id->call_stmt))
 	    {
 	      /* __builtin_va_arg_pack_len () should be replaced by
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 3e30f6bc3d4..23c9b865a15 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1498,8 +1498,8 @@  scan_function (void)
 
 		  if (dest)
 		    {
-		      if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
-			  && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
+		      if (DECL_BUILT_IN_P (dest, BUILT_IN_NORMAL,
+					   BUILT_IN_APPLY_ARGS))
 			encountered_apply_args = true;
 		      if (recursive_call_p (current_function_decl, dest))
 			{
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 63c95318ace..3e30e78f9eb 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2596,9 +2596,7 @@  optimize_stack_restore (gimple_stmt_iterator i)
       if (is_gimple_call (stack_save))
 	{
 	  callee = gimple_call_fndecl (stack_save);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
+	  if (DECL_BUILT_IN_P (callee, BUILT_IN_NORMAL, BUILT_IN_STACK_SAVE))
 	    {
 	      gimple_stmt_iterator stack_save_gsi;
 	      tree rhs;
@@ -3369,9 +3367,7 @@  pass_fold_builtins::execute (function *fun)
 	      continue;
 	    }
 	  callee = gimple_call_fndecl (stmt);
-	  if (!callee
-              || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
-	      || DECL_FUNCTION_CODE (callee) == fcode)
+	  if (!DECL_BUILT_IN_P (callee, BUILT_IN_NORMAL, fcode))
 	    gsi_next (&i);
 	}
     }
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 267880f3b5c..578eaa4233a 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1985,9 +1985,7 @@  dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
 	     folded to integer_one_node by now, it's fairly
 	     certain that the value simply isn't constant.  */
 	  tree callee = gimple_call_fndecl (stmt);
-	  if (callee
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
+	  if (DECL_BUILT_IN_P (callee, BUILT_IN_NORMAL, BUILT_IN_CONSTANT_P))
 	    {
 	      propagate_tree_value_into_stmt (&si, integer_zero_node);
 	      stmt = gsi_stmt (si);
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 01a954eeb1e..4d0a24c8a0f 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -471,9 +471,7 @@  stmt_cost (gimple *stmt)
       /* Unless the call is a builtin_constant_p; this always folds to a
 	 constant, so moving it is useless.  */
       fndecl = gimple_call_fndecl (stmt);
-      if (fndecl
-	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
+      if (DECL_BUILT_IN_P (fndecl, BUILT_IN_NORMAL, BUILT_IN_CONSTANT_P))
 	return 0;
 
       return LIM_EXPENSIVE;
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index c8594851957..58250eab5fa 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -866,10 +866,8 @@  optimize_va_list_gpr_fpr_size (function *fun)
 	    {
 	      tree callee = gimple_call_fndecl (stmt);
 
-	      if (callee
-		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-		  && (DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_START
-		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END))
+	      if (DECL_BUILT_IN_P (callee, BUILT_IN_NORMAL, BUILT_IN_VA_START)
+		  || DECL_BUILT_IN_P (callee, BUILT_IN_NORMAL, BUILT_IN_VA_END))
 		continue;
 	    }
 
diff --git a/gcc/tree.h b/gcc/tree.h
index 648e9e2a3c4..b464dbe683b 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3011,7 +3011,9 @@  extern vec<tree, va_gc> **decl_debug_args_insert (tree);
 /* For a function declaration, return true if NODE is non-null and it is
    a builtin of a CLASS with requested NAME.  */
 #define DECL_BUILT_IN_P(NODE, CLASS, NAME) \
-  (NODE != NULL_TREE && DECL_BUILT_IN_CLASS (NODE) == CLASS \
+  (NODE != NULL_TREE \
+   && TREE_CODE (NODE) == FUNCTION_DECL \
+   && DECL_BUILT_IN_CLASS (NODE) == CLASS \
    && DECL_FUNCTION_CODE (NODE) == NAME)
 
 /* In FUNCTION_DECL, a chain of ..._DECL nodes.  */