Use checking forms of DECL_FUNCTION_CODE (PR 91421)
diff mbox series

Message ID mpta7cdtnj2.fsf@arm.com
State New
Headers show
Series
  • Use checking forms of DECL_FUNCTION_CODE (PR 91421)
Related show

Commit Message

Richard Sandiford Aug. 13, 2019, 9:36 a.m. UTC
We were shoe-horning all built-in enumerations (including frontend
and target-specific ones) into a field of type built_in_function.  This
was accessed as either an lvalue or an rvalue using DECL_FUNCTION_CODE.

The obvious danger with this (as was noted by several ??? comments)
is that the ranges have nothing to do with each other, and targets can
easily have more built-in functions than generic code.  But my patch to
make the field bigger was the straw that finally made the problem visible.

This patch therefore:

- replaces the field with a plain unsigned int

- turns DECL_FUNCTION_CODE into an rvalue-only accessor that checks
  that the function really is BUILT_IN_NORMAL

- adds corresponding DECL_MD_FUNCTION_CODE and DECL_FE_FUNCTION_CODE
  accessors for BUILT_IN_MD and BUILT_IN_FRONTEND respectively

- adds DECL_UNCHECKED_FUNCTION_CODE for places that need to access the
  underlying field (should be low-level code only)

- adds new helpers for setting the built-in class and function code

- makes DECL_BUILT_IN_CLASS an rvalue-only accessor too, since all
  assignments should go through the new helpers

Tested on aarch64-linux-gnu and x86_64-linux-gnu (--enable-languages=all
--enable-host-shared).  OK to install?

Richard


2019-08-13  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	PR middle-end/91421
	* tree-core.h (function_decl::function_code): Change type to
	unsigned int.
	* tree.h (DECL_FUNCTION_CODE): Rename old definition to...
	(DECL_UNCHECKED_FUNCTION_CODE): ...this.
	(DECL_BUILT_IN_CLASS): Make an rvalue macro only.
	(DECL_FUNCTION_CODE): New function.  Assert that the built-in class
	is BUILT_IN_NORMAL.
	(DECL_MD_FUNCTION_CODE, DECL_FE_FUNCTION_CODE): New functions.
	(set_decl_built_in_function, copy_decl_built_in_function): Likewise.
	(fndecl_built_in_p): Change the type of the "name" argument to
	unsigned int.
	* builtins.c (expand_builtin): Move DECL_FUNCTION_CODE use
	after check for DECL_BUILT_IN_CLASS.
	* cgraphclones.c (build_function_decl_skip_args): Use
	set_decl_built_in_function.
	* ipa-param-manipulation.c (ipa_modify_formal_parameters): Likewise.
	* ipa-split.c (split_function): Likewise.
	* langhooks.c (add_builtin_function_common): Likewise.
	* omp-simd-clone.c (simd_clone_create): Likewise.
	* tree-streamer-in.c (unpack_ts_function_decl_value_fields): Likewise.
	* config/darwin.c (darwin_init_cfstring_builtins): Likewise.
	(darwin_fold_builtin): Use DECL_MD_FUNCTION_CODE instead of
	DECL_FUNCTION_CODE.
	* fold-const.c (operand_equal_p): Compare DECL_UNCHECKED_FUNCTION_CODE
	instead of DECL_FUNCTION_CODE.
	* lto-streamer-out.c (hash_tree): Use DECL_UNCHECKED_FUNCTION_CODE
	instead of DECL_FUNCTION_CODE.
	* tree-streamer-out.c (pack_ts_function_decl_value_fields): Likewise.
	* print-tree.c (print_node): Use DECL_MD_FUNCTION_CODE when
	printing DECL_BUILT_IN_MD.  Handle DECL_BUILT_IN_FRONTEND.
	* config/aarch64/aarch64-builtins.c (aarch64_expand_builtin)
	(aarch64_fold_builtin, aarch64_gimple_fold_builtin): Use
	DECL_MD_FUNCTION_CODE instead of DECL_FUNCTION_CODE.
	* config/aarch64/aarch64.c (aarch64_builtin_reciprocal): Likewise.
	* config/alpha/alpha.c (alpha_expand_builtin, alpha_fold_builtin):
	(alpha_gimple_fold_builtin): Likewise.
	* config/arc/arc.c (arc_expand_builtin): Likewise.
	* config/arm/arm-builtins.c (arm_expand_builtin): Likewise.
	* config/avr/avr-c.c (avr_resolve_overloaded_builtin): Likewise.
	* config/avr/avr.c (avr_expand_builtin, avr_fold_builtin): Likewise.
	* config/bfin/bfin.c (bfin_expand_builtin): Likewise.
	* config/c6x/c6x.c (c6x_expand_builtin): Likewise.
	* config/frv/frv.c (frv_expand_builtin): Likewise.
	* config/gcn/gcn.c (gcn_expand_builtin_1): Likewise.
	(gcn_expand_builtin): Likewise.
	* config/i386/i386-builtins.c (ix86_builtin_reciprocal): Likewise.
	(fold_builtin_cpu): Likewise.
	* config/i386/i386-expand.c (ix86_expand_builtin): Likewise.
	* config/i386/i386.c (ix86_fold_builtin): Likewise.
	(ix86_gimple_fold_builtin): Likewise.
	* config/ia64/ia64.c (ia64_fold_builtin): Likewise.
	(ia64_expand_builtin): Likewise.
	* config/iq2000/iq2000.c (iq2000_expand_builtin): Likewise.
	* config/mips/mips.c (mips_expand_builtin): Likewise.
	* config/msp430/msp430.c (msp430_expand_builtin): Likewise.
	* config/nds32/nds32-intrinsic.c (nds32_expand_builtin_impl): Likewise.
	* config/nios2/nios2.c (nios2_expand_builtin): Likewise.
	* config/nvptx/nvptx.c (nvptx_expand_builtin): Likewise.
	* config/pa/pa.c (pa_expand_builtin): Likewise.
	* config/pru/pru.c (pru_expand_builtin): Likewise.
	* config/riscv/riscv-builtins.c (riscv_expand_builtin): Likewise.
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
	Likewise.
	* config/rs6000/rs6000-call.c (htm_expand_builtin): Likewise.
	(altivec_expand_dst_builtin, altivec_expand_builtin): Likewise.
	(rs6000_gimple_fold_builtin, rs6000_expand_builtin): Likewise.
	* config/rs6000/rs6000.c (rs6000_builtin_md_vectorized_function)
	(rs6000_builtin_reciprocal): Likewise.
	* config/rx/rx.c (rx_expand_builtin): Likewise.
	* config/s390/s390-c.c (s390_resolve_overloaded_builtin): Likewise.
	* config/s390/s390.c (s390_expand_builtin): Likewise.
	* config/sh/sh.c (sh_expand_builtin): Likewise.
	* config/sparc/sparc.c (sparc_expand_builtin): Likewise.
	(sparc_fold_builtin): Likewise.
	* config/spu/spu-c.c (spu_resolve_overloaded_builtin): Likewise.
	* config/spu/spu.c (spu_expand_builtin): Likewise.
	* config/stormy16/stormy16.c (xstormy16_expand_builtin): Likewise.
	* config/tilegx/tilegx.c (tilegx_expand_builtin): Likewise.
	* config/tilepro/tilepro.c (tilepro_expand_builtin): Likewise.
	* config/xtensa/xtensa.c (xtensa_fold_builtin): Likewise.
	(xtensa_expand_builtin): Likewise.

gcc/ada/
	PR middle-end/91421
	* gcc-interface/trans.c (gigi): Call set_decl_buillt_in_function.
	(Call_to_gnu): Use DECL_FE_FUNCTION_CODE instead of DECL_FUNCTION_CODE.

gcc/c/
	PR middle-end/91421
	* c-decl.c (merge_decls): Use copy_decl_built_in_function.

gcc/c-family/
	PR middle-end/91421
	* c-common.c (resolve_overloaded_builtin): Use
	copy_decl_built_in_function.

gcc/cp/
	PR middle-end/91421
	* decl.c (duplicate_decls):  Use copy_decl_built_in_function.
	* pt.c (declare_integer_pack): Use set_decl_built_in_function.

gcc/d/
	PR middle-end/91421
	* intrinsics.cc (maybe_set_intrinsic): Use set_decl_built_in_function.

gcc/jit/
	PR middle-end/91421
	* jit-playback.c (new_function): Use set_decl_built_in_function.

gcc/lto/
	PR middle-end/91421
	* lto-common.c (compare_tree_sccs_1): Use DECL_UNCHECKED_FUNCTION_CODE
	instead of DECL_FUNCTION_CODE.
	* lto-symtab.c (lto_symtab_merge_p): Likewise.

Comments

Jeff Law Aug. 13, 2019, 6:32 p.m. UTC | #1
On 8/13/19 3:36 AM, Richard Sandiford wrote:
> We were shoe-horning all built-in enumerations (including frontend
> and target-specific ones) into a field of type built_in_function.  This
> was accessed as either an lvalue or an rvalue using DECL_FUNCTION_CODE.
> 
> The obvious danger with this (as was noted by several ??? comments)
> is that the ranges have nothing to do with each other, and targets can
> easily have more built-in functions than generic code.  But my patch to
> make the field bigger was the straw that finally made the problem visible.
> 
> This patch therefore:
> 
> - replaces the field with a plain unsigned int
> 
> - turns DECL_FUNCTION_CODE into an rvalue-only accessor that checks
>   that the function really is BUILT_IN_NORMAL
> 
> - adds corresponding DECL_MD_FUNCTION_CODE and DECL_FE_FUNCTION_CODE
>   accessors for BUILT_IN_MD and BUILT_IN_FRONTEND respectively
> 
> - adds DECL_UNCHECKED_FUNCTION_CODE for places that need to access the
>   underlying field (should be low-level code only)
> 
> - adds new helpers for setting the built-in class and function code
> 
> - makes DECL_BUILT_IN_CLASS an rvalue-only accessor too, since all
>   assignments should go through the new helpers
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu (--enable-languages=all
> --enable-host-shared).  OK to install?
> 
> Richard
> 
> 
> 2019-08-13  Richard Sandiford  <richard.sandiford@arm.com>
> 
> gcc/
> 	PR middle-end/91421
> 	* tree-core.h (function_decl::function_code): Change type to
> 	unsigned int.
> 	* tree.h (DECL_FUNCTION_CODE): Rename old definition to...
> 	(DECL_UNCHECKED_FUNCTION_CODE): ...this.
> 	(DECL_BUILT_IN_CLASS): Make an rvalue macro only.
> 	(DECL_FUNCTION_CODE): New function.  Assert that the built-in class
> 	is BUILT_IN_NORMAL.
> 	(DECL_MD_FUNCTION_CODE, DECL_FE_FUNCTION_CODE): New functions.
> 	(set_decl_built_in_function, copy_decl_built_in_function): Likewise.
> 	(fndecl_built_in_p): Change the type of the "name" argument to
> 	unsigned int.
> 	* builtins.c (expand_builtin): Move DECL_FUNCTION_CODE use
> 	after check for DECL_BUILT_IN_CLASS.
> 	* cgraphclones.c (build_function_decl_skip_args): Use
> 	set_decl_built_in_function.
> 	* ipa-param-manipulation.c (ipa_modify_formal_parameters): Likewise.
> 	* ipa-split.c (split_function): Likewise.
> 	* langhooks.c (add_builtin_function_common): Likewise.
> 	* omp-simd-clone.c (simd_clone_create): Likewise.
> 	* tree-streamer-in.c (unpack_ts_function_decl_value_fields): Likewise.
> 	* config/darwin.c (darwin_init_cfstring_builtins): Likewise.
> 	(darwin_fold_builtin): Use DECL_MD_FUNCTION_CODE instead of
> 	DECL_FUNCTION_CODE.
> 	* fold-const.c (operand_equal_p): Compare DECL_UNCHECKED_FUNCTION_CODE
> 	instead of DECL_FUNCTION_CODE.
> 	* lto-streamer-out.c (hash_tree): Use DECL_UNCHECKED_FUNCTION_CODE
> 	instead of DECL_FUNCTION_CODE.
> 	* tree-streamer-out.c (pack_ts_function_decl_value_fields): Likewise.
> 	* print-tree.c (print_node): Use DECL_MD_FUNCTION_CODE when
> 	printing DECL_BUILT_IN_MD.  Handle DECL_BUILT_IN_FRONTEND.
> 	* config/aarch64/aarch64-builtins.c (aarch64_expand_builtin)
> 	(aarch64_fold_builtin, aarch64_gimple_fold_builtin): Use
> 	DECL_MD_FUNCTION_CODE instead of DECL_FUNCTION_CODE.
> 	* config/aarch64/aarch64.c (aarch64_builtin_reciprocal): Likewise.
> 	* config/alpha/alpha.c (alpha_expand_builtin, alpha_fold_builtin):
> 	(alpha_gimple_fold_builtin): Likewise.
> 	* config/arc/arc.c (arc_expand_builtin): Likewise.
> 	* config/arm/arm-builtins.c (arm_expand_builtin): Likewise.
> 	* config/avr/avr-c.c (avr_resolve_overloaded_builtin): Likewise.
> 	* config/avr/avr.c (avr_expand_builtin, avr_fold_builtin): Likewise.
> 	* config/bfin/bfin.c (bfin_expand_builtin): Likewise.
> 	* config/c6x/c6x.c (c6x_expand_builtin): Likewise.
> 	* config/frv/frv.c (frv_expand_builtin): Likewise.
> 	* config/gcn/gcn.c (gcn_expand_builtin_1): Likewise.
> 	(gcn_expand_builtin): Likewise.
> 	* config/i386/i386-builtins.c (ix86_builtin_reciprocal): Likewise.
> 	(fold_builtin_cpu): Likewise.
> 	* config/i386/i386-expand.c (ix86_expand_builtin): Likewise.
> 	* config/i386/i386.c (ix86_fold_builtin): Likewise.
> 	(ix86_gimple_fold_builtin): Likewise.
> 	* config/ia64/ia64.c (ia64_fold_builtin): Likewise.
> 	(ia64_expand_builtin): Likewise.
> 	* config/iq2000/iq2000.c (iq2000_expand_builtin): Likewise.
> 	* config/mips/mips.c (mips_expand_builtin): Likewise.
> 	* config/msp430/msp430.c (msp430_expand_builtin): Likewise.
> 	* config/nds32/nds32-intrinsic.c (nds32_expand_builtin_impl): Likewise.
> 	* config/nios2/nios2.c (nios2_expand_builtin): Likewise.
> 	* config/nvptx/nvptx.c (nvptx_expand_builtin): Likewise.
> 	* config/pa/pa.c (pa_expand_builtin): Likewise.
> 	* config/pru/pru.c (pru_expand_builtin): Likewise.
> 	* config/riscv/riscv-builtins.c (riscv_expand_builtin): Likewise.
> 	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
> 	Likewise.
> 	* config/rs6000/rs6000-call.c (htm_expand_builtin): Likewise.
> 	(altivec_expand_dst_builtin, altivec_expand_builtin): Likewise.
> 	(rs6000_gimple_fold_builtin, rs6000_expand_builtin): Likewise.
> 	* config/rs6000/rs6000.c (rs6000_builtin_md_vectorized_function)
> 	(rs6000_builtin_reciprocal): Likewise.
> 	* config/rx/rx.c (rx_expand_builtin): Likewise.
> 	* config/s390/s390-c.c (s390_resolve_overloaded_builtin): Likewise.
> 	* config/s390/s390.c (s390_expand_builtin): Likewise.
> 	* config/sh/sh.c (sh_expand_builtin): Likewise.
> 	* config/sparc/sparc.c (sparc_expand_builtin): Likewise.
> 	(sparc_fold_builtin): Likewise.
> 	* config/spu/spu-c.c (spu_resolve_overloaded_builtin): Likewise.
> 	* config/spu/spu.c (spu_expand_builtin): Likewise.
> 	* config/stormy16/stormy16.c (xstormy16_expand_builtin): Likewise.
> 	* config/tilegx/tilegx.c (tilegx_expand_builtin): Likewise.
> 	* config/tilepro/tilepro.c (tilepro_expand_builtin): Likewise.
> 	* config/xtensa/xtensa.c (xtensa_fold_builtin): Likewise.
> 	(xtensa_expand_builtin): Likewise.
> 
> gcc/ada/
> 	PR middle-end/91421
> 	* gcc-interface/trans.c (gigi): Call set_decl_buillt_in_function.
> 	(Call_to_gnu): Use DECL_FE_FUNCTION_CODE instead of DECL_FUNCTION_CODE.
> 
> gcc/c/
> 	PR middle-end/91421
> 	* c-decl.c (merge_decls): Use copy_decl_built_in_function.
> 
> gcc/c-family/
> 	PR middle-end/91421
> 	* c-common.c (resolve_overloaded_builtin): Use
> 	copy_decl_built_in_function.
> 
> gcc/cp/
> 	PR middle-end/91421
> 	* decl.c (duplicate_decls):  Use copy_decl_built_in_function.
> 	* pt.c (declare_integer_pack): Use set_decl_built_in_function.
> 
> gcc/d/
> 	PR middle-end/91421
> 	* intrinsics.cc (maybe_set_intrinsic): Use set_decl_built_in_function.
> 
> gcc/jit/
> 	PR middle-end/91421
> 	* jit-playback.c (new_function): Use set_decl_built_in_function.
> 
> gcc/lto/
> 	PR middle-end/91421
> 	* lto-common.c (compare_tree_sccs_1): Use DECL_UNCHECKED_FUNCTION_CODE
> 	instead of DECL_FUNCTION_CODE.
> 	* lto-symtab.c (lto_symtab_merge_p): Likewise.
> 
OK.  I just lightly spot-checked the relatively mechanical bits.  I
don't expect any problems.

Jeff

Patch
diff mbox series

Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h	2019-08-07 14:18:16.003997792 +0100
+++ gcc/tree-core.h	2019-08-13 10:31:24.846972645 +0100
@@ -1859,9 +1859,8 @@  struct GTY(()) tree_function_decl {
   /* Index within a virtual table.  */
   tree vindex;
 
-  /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
-     DECL_FUNCTION_CODE.  Otherwise unused.  */
-  enum built_in_function function_code;
+  /* In a FUNCTION_DECL this is DECL_UNCHECKED_FUNCTION_CODE.  */
+  unsigned int function_code;
 
   ENUM_BITFIELD(built_in_class) built_in_class : 2;
   unsigned static_ctor_flag : 1;
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	2019-08-06 15:45:20.876386296 +0100
+++ gcc/tree.h	2019-08-13 10:31:24.846972645 +0100
@@ -2515,10 +2515,10 @@  #define SET_DECL_MODE(NODE, MODE) \
   (DECL_COMMON_CHECK (NODE)->decl_common.mode = (MODE))
 
 /* For FUNCTION_DECL, if it is built-in, this identifies which built-in
-   operation it is.  Note, however, that this field is overloaded, with
-   DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be
-   checked before any access to the former.  */
-#define DECL_FUNCTION_CODE(NODE) \
+   operation it is.  This is only intended for low-level accesses;
+   normally DECL_FUNCTION_CODE, DECL_FE_FUNCTION_CODE or DECL_MD_FUNCTION
+   should be used instead.  */
+#define DECL_UNCHECKED_FUNCTION_CODE(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->function_decl.function_code)
 
 /* Test if FCODE is a function code for an alloca operation.  */
@@ -3140,10 +3140,9 @@  #define DECL_HAS_DEBUG_ARGS_P(NODE) \
 #define DECL_STRUCT_FUNCTION(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->function_decl.f)
 
-
 /* 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)
+   ((built_in_class) FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
 
 /* In FUNCTION_DECL, a chain of ..._DECL nodes.  */
 #define DECL_ARGUMENTS(NODE) \
@@ -3882,6 +3881,61 @@  valid_vector_subparts_p (poly_uint64 sub
   return true;
 }
 
+/* Return the built-in function that DECL represents, given that it is known
+   to be a FUNCTION_DECL with built-in class BUILT_IN_NORMAL.  */
+inline built_in_function
+DECL_FUNCTION_CODE (const_tree decl)
+{
+  const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+  gcc_checking_assert (fndecl.built_in_class == BUILT_IN_NORMAL);
+  return (built_in_function) fndecl.function_code;
+}
+
+/* Return the target-specific built-in function that DECL represents,
+   given that it is known to be a FUNCTION_DECL with built-in class
+   BUILT_IN_MD.  */
+inline int
+DECL_MD_FUNCTION_CODE (const_tree decl)
+{
+  const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+  gcc_checking_assert (fndecl.built_in_class == BUILT_IN_MD);
+  return fndecl.function_code;
+}
+
+/* Return the frontend-specific built-in function that DECL represents,
+   given that it is known to be a FUNCTION_DECL with built-in class
+   BUILT_IN_FRONTEND.  */
+inline int
+DECL_FE_FUNCTION_CODE (const_tree decl)
+{
+  const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+  gcc_checking_assert (fndecl.built_in_class == BUILT_IN_FRONTEND);
+  return fndecl.function_code;
+}
+
+/* Record that FUNCTION_DECL DECL represents built-in function FCODE of
+   class FCLASS.  */
+inline void
+set_decl_built_in_function (tree decl, built_in_class fclass,
+			    unsigned int fcode)
+{
+  tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+  fndecl.built_in_class = fclass;
+  fndecl.function_code = fcode;
+}
+
+/* Record that FUNCTION_DECL NEWDECL represents the same built-in function
+   as OLDDECL (or none, if OLDDECL doesn't represent a built-in function).  */
+inline void
+copy_decl_built_in_function (tree newdecl, const_tree olddecl)
+{
+  tree_function_decl &newfndecl = FUNCTION_DECL_CHECK (newdecl)->function_decl;
+  const tree_function_decl &oldfndecl
+    = FUNCTION_DECL_CHECK (olddecl)->function_decl;
+  newfndecl.built_in_class = oldfndecl.built_in_class;
+  newfndecl.function_code = oldfndecl.function_code;
+}
+
 /* In NON_LVALUE_EXPR and VIEW_CONVERT_EXPR, set when this node is merely a
    wrapper added to express a location_t on behalf of the node's child
    (e.g. by maybe_wrap_with_location).  */
@@ -6073,9 +6127,10 @@  fndecl_built_in_p (const_tree node, buil
    of class KLASS with name equal to NAME.  */
 
 inline bool
-fndecl_built_in_p (const_tree node, int name, built_in_class klass)
+fndecl_built_in_p (const_tree node, unsigned int name, built_in_class klass)
 {
-  return (fndecl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
+  return (fndecl_built_in_p (node, klass)
+	  && DECL_UNCHECKED_FUNCTION_CODE (node) == name);
 }
 
 /* Return true if a FUNCTION_DECL NODE is a GCC built-in function
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	2019-07-29 09:39:47.786181095 +0100
+++ gcc/builtins.c	2019-08-13 10:31:24.774973159 +0100
@@ -7236,7 +7236,6 @@  expand_builtin (tree exp, rtx target, rt
 		int ignore)
 {
   tree fndecl = get_callee_fndecl (exp);
-  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
   machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
   int flags;
 
@@ -7248,6 +7247,7 @@  expand_builtin (tree exp, rtx target, rt
      redundant checks and be sure, that possible overflow will be detected
      by ASan.  */
 
+  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
   if ((flag_sanitize & SANITIZE_ADDRESS) && asan_intercepted_p (fcode))
     return expand_call (exp, target, ignore);
 
Index: gcc/cgraphclones.c
===================================================================
--- gcc/cgraphclones.c	2019-08-08 18:11:51.395313410 +0100
+++ gcc/cgraphclones.c	2019-08-13 10:31:24.782973102 +0100
@@ -225,10 +225,7 @@  build_function_decl_skip_args (tree orig
   if (fndecl_built_in_p (new_decl)
       && args_to_skip
       && !bitmap_empty_p (args_to_skip))
-    {
-      DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
-      DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
-    }
+    set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0);
   /* The FE might have information and assumptions about the other
      arguments.  */
   DECL_LANG_SPECIFIC (new_decl) = NULL;
Index: gcc/ipa-param-manipulation.c
===================================================================
--- gcc/ipa-param-manipulation.c	2019-08-05 17:46:43.025559703 +0100
+++ gcc/ipa-param-manipulation.c	2019-08-13 10:31:24.846972645 +0100
@@ -219,10 +219,7 @@  ipa_modify_formal_parameters (tree fndec
 
   /* When signature changes, we need to clear builtin info.  */
   if (fndecl_built_in_p (fndecl))
-    {
-      DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
-      DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
-    }
+    set_decl_built_in_function (fndecl, NOT_BUILT_IN, 0);
 
   TREE_TYPE (fndecl) = new_type;
   DECL_VIRTUAL_P (fndecl) = 0;
Index: gcc/ipa-split.c
===================================================================
--- gcc/ipa-split.c	2019-07-10 19:41:26.375898187 +0100
+++ gcc/ipa-split.c	2019-08-13 10:31:24.846972645 +0100
@@ -1351,10 +1351,7 @@  split_function (basic_block return_bb, c
      changes.  For partial inlining we however cannot expect the part
      of builtin implementation to have same semantic as the whole.  */
   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;
-    }
+    set_decl_built_in_function (node->decl, NOT_BUILT_IN, 0);
 
   /* If return_bb contains any clobbers that refer to SSA_NAMEs
      set in the split part, remove them.  Also reset debug stmts that
Index: gcc/langhooks.c
===================================================================
--- gcc/langhooks.c	2019-03-08 18:15:33.660751905 +0000
+++ gcc/langhooks.c	2019-08-13 10:31:24.846972645 +0100
@@ -615,12 +615,8 @@  add_builtin_function_common (const char
 
   TREE_PUBLIC (decl)         = 1;
   DECL_EXTERNAL (decl)       = 1;
-  DECL_BUILT_IN_CLASS (decl) = cl;
 
-  DECL_FUNCTION_CODE (decl)  = (enum built_in_function) function_code;
-
-  /* DECL_FUNCTION_CODE is a bitfield; verify that the value fits.  */
-  gcc_assert (DECL_FUNCTION_CODE (decl) == function_code);
+  set_decl_built_in_function (decl, cl, function_code);
 
   if (library_name)
     {
Index: gcc/omp-simd-clone.c
===================================================================
--- gcc/omp-simd-clone.c	2019-08-05 17:46:20.537724904 +0100
+++ gcc/omp-simd-clone.c	2019-08-13 10:31:24.846972645 +0100
@@ -461,8 +461,7 @@  simd_clone_create (struct cgraph_node *o
   if (new_node == NULL)
     return new_node;
 
-  DECL_BUILT_IN_CLASS (new_node->decl) = NOT_BUILT_IN;
-  DECL_FUNCTION_CODE (new_node->decl) = (enum built_in_function) 0;
+  set_decl_built_in_function (new_node->decl, NOT_BUILT_IN, 0);
   TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
   DECL_COMDAT (new_node->decl) = DECL_COMDAT (old_node->decl);
   DECL_WEAK (new_node->decl) = DECL_WEAK (old_node->decl);
Index: gcc/tree-streamer-in.c
===================================================================
--- gcc/tree-streamer-in.c	2019-07-29 09:39:50.034163022 +0100
+++ gcc/tree-streamer-in.c	2019-08-13 10:31:24.846972645 +0100
@@ -324,8 +324,7 @@  unpack_ts_decl_with_vis_value_fields (st
 static void
 unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
 {
-  DECL_BUILT_IN_CLASS (expr) = bp_unpack_enum (bp, built_in_class,
-					       BUILT_IN_LAST);
+  built_in_class cl = bp_unpack_enum (bp, built_in_class, BUILT_IN_LAST);
   DECL_STATIC_CONSTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
   DECL_STATIC_DESTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
   DECL_UNINLINABLE (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -344,22 +343,22 @@  unpack_ts_function_decl_value_fields (st
   DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1);
   DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
   DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
-  if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
+  unsigned int fcode = 0;
+  if (cl != NOT_BUILT_IN)
     {
-      DECL_FUNCTION_CODE (expr) = (enum built_in_function) bp_unpack_value (bp,
-	                                                                    12);
-      if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL
-	  && DECL_FUNCTION_CODE (expr) >= END_BUILTINS)
+      fcode = bp_unpack_value (bp, 32);
+      if (cl == BUILT_IN_NORMAL && fcode >= END_BUILTINS)
 	fatal_error (input_location,
 		     "machine independent builtin code out of range");
-      else if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD)
+      else if (cl == BUILT_IN_MD)
 	{
-          tree result = targetm.builtin_decl (DECL_FUNCTION_CODE (expr), true);
+          tree result = targetm.builtin_decl (fcode, true);
 	  if (!result || result == error_mark_node)
 	    fatal_error (input_location,
 			 "target specific builtin not available");
 	}
     }
+  set_decl_built_in_function (expr, cl, fcode);
 }
 
 
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	2019-07-08 07:20:49.575443789 +0100
+++ gcc/config/darwin.c	2019-08-13 10:31:24.794973018 +0100
@@ -3439,8 +3439,7 @@  darwin_init_cfstring_builtins (unsigned
      in place of the existing, which may be NULL.  */
   DECL_LANG_SPECIFIC (cfsfun) = NULL;
   (*lang_hooks.dup_lang_specific_decl) (cfsfun);
-  DECL_BUILT_IN_CLASS (cfsfun) = BUILT_IN_MD;
-  DECL_FUNCTION_CODE (cfsfun) = darwin_builtin_cfstring;
+  set_decl_built_in_function (cfsfun, BUILT_IN_MD, darwin_builtin_cfstring);
   lang_hooks.builtin_function (cfsfun);
 
   /* extern int __CFConstantStringClassReference[];  */
@@ -3464,7 +3463,7 @@  darwin_init_cfstring_builtins (unsigned
 darwin_fold_builtin (tree fndecl, int n_args, tree *argp,
 		     bool ARG_UNUSED (ignore))
 {
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   if (fcode == darwin_builtin_cfstring)
     {
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	2019-08-07 14:18:14.932005777 +0100
+++ gcc/fold-const.c	2019-08-13 10:31:24.846972645 +0100
@@ -3466,7 +3466,8 @@  #define OP_SAME_WITH_NULL(N)				\
       return (TREE_CODE (arg0) == FUNCTION_DECL
 	      && 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));
+	      && (DECL_UNCHECKED_FUNCTION_CODE (arg0)
+		  == DECL_UNCHECKED_FUNCTION_CODE (arg1)));
 
     case tcc_exceptional:
       if (TREE_CODE (arg0) == CONSTRUCTOR)
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c	2019-07-29 09:39:48.686173860 +0100
+++ gcc/lto-streamer-out.c	2019-08-13 10:31:24.846972645 +0100
@@ -1137,7 +1137,7 @@  #define visit(SIBLING) \
       hstate.add_flag (DECL_LOOPING_CONST_OR_PURE_P (t));
       hstate.commit_flag ();
       if (DECL_BUILT_IN_CLASS (t) != NOT_BUILT_IN)
-	hstate.add_int (DECL_FUNCTION_CODE (t));
+	hstate.add_int (DECL_UNCHECKED_FUNCTION_CODE (t));
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
Index: gcc/tree-streamer-out.c
===================================================================
--- gcc/tree-streamer-out.c	2019-07-29 09:39:50.030163053 +0100
+++ gcc/tree-streamer-out.c	2019-08-13 10:31:24.846972645 +0100
@@ -306,7 +306,7 @@  pack_ts_function_decl_value_fields (stru
   bp_pack_value (bp, DECL_PURE_P (expr), 1);
   bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
   if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
-    bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 12);
+    bp_pack_value (bp, DECL_UNCHECKED_FUNCTION_CODE (expr), 32);
 }
 
 
Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c	2019-07-01 09:37:05.944535171 +0100
+++ gcc/print-tree.c	2019-08-13 10:31:24.846972645 +0100
@@ -519,7 +519,11 @@  print_node (FILE *file, const char *pref
 	  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));
+		fprintf (file, " built-in: BUILT_IN_MD:%d",
+			 DECL_MD_FUNCTION_CODE (node));
+	      else if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_FRONTEND)
+		fprintf (file, " built-in: BUILT_IN_FRONTEND:%d",
+			 DECL_FE_FUNCTION_CODE (node));
 	      else
 		fprintf (file, " built-in: %s:%s",
 			 built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)],
Index: gcc/config/aarch64/aarch64-builtins.c
===================================================================
--- gcc/config/aarch64/aarch64-builtins.c	2019-08-08 18:11:22.000000000 +0100
+++ gcc/config/aarch64/aarch64-builtins.c	2019-08-13 10:31:24.782973102 +0100
@@ -1595,7 +1595,7 @@  aarch64_expand_builtin (tree exp,
 		     int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  int fcode = DECL_FUNCTION_CODE (fndecl);
+  int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   int icode;
   rtx pat, op0;
   tree arg0;
@@ -1881,7 +1881,7 @@  #define VAR1(T, N, MAP, A) \
 aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
 		      bool ignore ATTRIBUTE_UNUSED)
 {
-  int fcode = DECL_FUNCTION_CODE (fndecl);
+  int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
 
   switch (fcode)
@@ -1913,7 +1913,7 @@  aarch64_gimple_fold_builtin (gimple_stmt
       fndecl = gimple_call_fndecl (stmt);
       if (fndecl)
 	{
-	  int fcode = DECL_FUNCTION_CODE (fndecl);
+	  int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 	  unsigned nargs = gimple_call_num_args (stmt);
 	  tree *args = (nargs > 0
 			? gimple_call_arg_ptr (stmt, 0)
Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	2019-08-08 18:11:22.000000000 +0100
+++ gcc/config/aarch64/aarch64.c	2019-08-13 10:31:24.786973074 +0100
@@ -10832,7 +10832,7 @@  aarch64_builtin_reciprocal (tree fndecl)
 
   if (!use_rsqrt_p (mode))
     return NULL_TREE;
-  return aarch64_builtin_rsqrt (DECL_FUNCTION_CODE (fndecl));
+  return aarch64_builtin_rsqrt (DECL_MD_FUNCTION_CODE (fndecl));
 }
 
 /* Emit instruction sequence to compute either the approximate square root
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	2019-07-31 08:32:45.540537966 +0100
+++ gcc/config/alpha/alpha.c	2019-08-13 10:31:24.786973074 +0100
@@ -6657,7 +6657,7 @@  alpha_expand_builtin (tree exp, rtx targ
 #define MAX_ARGS 2
 
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree arg;
   call_expr_arg_iterator iter;
   enum insn_code icode;
@@ -7056,7 +7056,7 @@  alpha_fold_builtin (tree fndecl, int n_a
 	}
     }
 
-  switch (DECL_FUNCTION_CODE (fndecl))
+  switch (DECL_MD_FUNCTION_CODE (fndecl))
     {
     case ALPHA_BUILTIN_CMPBGE:
       return alpha_fold_builtin_cmpbge (opint, op_const);
@@ -7172,7 +7172,7 @@  alpha_gimple_fold_builtin (gimple_stmt_i
 	{
 	  tree arg0, arg1;
 
-	  switch (DECL_FUNCTION_CODE (fndecl))
+	  switch (DECL_MD_FUNCTION_CODE (fndecl))
 	    {
 	    case ALPHA_BUILTIN_UMULH:
 	      arg0 = gimple_call_arg (stmt, 0);
Index: gcc/config/arc/arc.c
===================================================================
--- gcc/config/arc/arc.c	2019-07-29 09:39:47.250185405 +0100
+++ gcc/config/arc/arc.c	2019-08-13 10:31:24.786973074 +0100
@@ -6996,7 +6996,7 @@  arc_expand_builtin (tree exp,
 		    int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int id = DECL_FUNCTION_CODE (fndecl);
+  unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
   const struct arc_builtin_description *d = &arc_bdesc[id];
   int i, j, n_args = call_expr_nargs (exp);
   rtx pat = NULL_RTX;
Index: gcc/config/arm/arm-builtins.c
===================================================================
--- gcc/config/arm/arm-builtins.c	2019-07-29 19:49:37.389302642 +0100
+++ gcc/config/arm/arm-builtins.c	2019-08-13 10:31:24.790973046 +0100
@@ -2555,7 +2555,7 @@  arm_expand_builtin (tree exp,
   rtx               op1;
   rtx               op2;
   rtx               pat;
-  unsigned int      fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int      fcode = DECL_MD_FUNCTION_CODE (fndecl);
   size_t            i;
   machine_mode tmode;
   machine_mode mode0;
Index: gcc/config/avr/avr-c.c
===================================================================
--- gcc/config/avr/avr-c.c	2019-03-08 18:15:37.644736763 +0000
+++ gcc/config/avr/avr-c.c	2019-08-13 10:31:24.790973046 +0100
@@ -54,7 +54,7 @@  avr_resolve_overloaded_builtin (unsigned
   location_t loc = (location_t) iloc;
   vec<tree, va_gc> &args = * (vec<tree, va_gc>*) vargs;
 
-  switch (DECL_FUNCTION_CODE (fndecl))
+  switch (DECL_MD_FUNCTION_CODE (fndecl))
     {
     default:
       break;
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c	2019-07-29 09:39:46.838188716 +0100
+++ gcc/config/avr/avr.c	2019-08-13 10:31:24.790973046 +0100
@@ -14243,7 +14243,7 @@  avr_expand_builtin (tree exp, rtx target
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
-  unsigned int id = DECL_FUNCTION_CODE (fndecl);
+  unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
   const struct avr_builtin_description *d = &avr_bdesc[id];
   tree arg0;
   rtx op0;
@@ -14395,7 +14395,7 @@  avr_fold_absfx (tree tval)
 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
                   bool ignore ATTRIBUTE_UNUSED)
 {
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
 
   if (!optimize)
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c	2019-07-01 09:37:07.380523145 +0100
+++ gcc/config/bfin/bfin.c	2019-08-13 10:31:24.790973046 +0100
@@ -5498,7 +5498,7 @@  bfin_expand_builtin (tree exp, rtx targe
   enum insn_code icode;
   const struct builtin_description *d;
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree arg0, arg1, arg2;
   rtx op0, op1, op2, accvec, pat, tmp1, tmp2, a0reg, a1reg;
   machine_mode tmode, mode0;
Index: gcc/config/c6x/c6x.c
===================================================================
--- gcc/config/c6x/c6x.c	2019-07-16 09:11:06.429416627 +0100
+++ gcc/config/c6x/c6x.c	2019-08-13 10:31:24.790973046 +0100
@@ -6661,7 +6661,7 @@  c6x_expand_builtin (tree exp, rtx target
   size_t i;
   const struct builtin_description *d;
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
     if (d->code == fcode)
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	2019-05-29 10:49:36.272711405 +0100
+++ gcc/config/frv/frv.c	2019-08-13 10:31:24.794973018 +0100
@@ -9113,7 +9113,7 @@  frv_expand_builtin (tree exp,
                     int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned fcode = (unsigned)DECL_FUNCTION_CODE (fndecl);
+  unsigned fcode = DECL_MD_FUNCTION_CODE (fndecl);
   unsigned i;
   struct builtin_description *d;
 
Index: gcc/config/gcn/gcn.c
===================================================================
--- gcc/config/gcn/gcn.c	2019-08-05 17:46:20.589724524 +0100
+++ gcc/config/gcn/gcn.c	2019-08-13 10:31:24.794973018 +0100
@@ -3546,7 +3546,7 @@  gcn_expand_builtin_1 (tree exp, rtx targ
 		      struct gcn_builtin_description *)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  switch (DECL_FUNCTION_CODE (fndecl))
+  switch (DECL_MD_FUNCTION_CODE (fndecl))
     {
     case GCN_BUILTIN_FLAT_LOAD_INT32:
       {
@@ -3773,7 +3773,7 @@  gcn_expand_builtin (tree exp, rtx target
 		    int ignore)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   struct gcn_builtin_description *d;
 
   gcc_assert (fcode < GCN_BUILTIN_MAX);
Index: gcc/config/i386/i386-builtins.c
===================================================================
--- gcc/config/i386/i386-builtins.c	2019-07-01 09:37:06.296532222 +0100
+++ gcc/config/i386/i386-builtins.c	2019-08-13 10:31:24.794973018 +0100
@@ -1833,7 +1833,7 @@  ix86_vectorize_builtin_gather (const_tre
 ix86_builtin_reciprocal (tree fndecl)
 {
   enum ix86_builtins fn_code
-    = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
+    = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   switch (fn_code)
     {
       /* Vectorized version of sqrt to rsqrt conversion.  */
@@ -2407,8 +2407,8 @@  make_var_decl (tree type, const char *na
 fold_builtin_cpu (tree fndecl, tree *args)
 {
   unsigned int i;
-  enum ix86_builtins fn_code = (enum ix86_builtins)
-				DECL_FUNCTION_CODE (fndecl);
+  enum ix86_builtins fn_code
+    = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   tree param_string_cst = NULL;
 
   tree __processor_model_type = build_processor_model_struct ();
Index: gcc/config/i386/i386-expand.c
===================================================================
--- gcc/config/i386/i386-expand.c	2019-08-05 17:46:20.549724816 +0100
+++ gcc/config/i386/i386-expand.c	2019-08-13 10:31:24.802972959 +0100
@@ -10978,7 +10978,7 @@  ix86_expand_builtin (tree exp, rtx targe
   tree arg0, arg1, arg2, arg3, arg4;
   rtx op0, op1, op2, op3, op4, pat, pat2, insn;
   machine_mode mode0, mode1, mode2, mode3, mode4;
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   /* For CPU builtins that can be folded, fold first and expand the fold.  */
   switch (fcode)
@@ -12535,7 +12535,7 @@  ix86_expand_builtin (tree exp, rtx targe
 		  tree fndecl = gimple_call_fndecl (def_stmt);
 		  if (fndecl
 		      && fndecl_built_in_p (fndecl, BUILT_IN_MD))
-		    switch ((unsigned int) DECL_FUNCTION_CODE (fndecl))
+		    switch (DECL_MD_FUNCTION_CODE (fndecl))
 		      {
 		      case IX86_BUILTIN_CMPPD:
 		      case IX86_BUILTIN_CMPPS:
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2019-07-10 19:41:19.499953255 +0100
+++ gcc/config/i386/i386.c	2019-08-13 10:31:24.806972931 +0100
@@ -16817,8 +16817,8 @@  ix86_fold_builtin (tree fndecl, int n_ar
 {
   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
     {
-      enum ix86_builtins fn_code = (enum ix86_builtins)
-				   DECL_FUNCTION_CODE (fndecl);
+      enum ix86_builtins fn_code
+	= (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
       enum rtx_code rcode;
       bool is_vshift;
       unsigned HOST_WIDE_INT mask;
@@ -17283,7 +17283,8 @@  ix86_gimple_fold_builtin (gimple_stmt_it
   tree fndecl = gimple_call_fndecl (stmt);
   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);
+  enum ix86_builtins fn_code
+    = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   tree decl = NULL_TREE;
   tree arg0, arg1, arg2;
   enum rtx_code rcode;
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	2019-05-29 10:49:36.716710116 +0100
+++ gcc/config/ia64/ia64.c	2019-08-13 10:31:24.810972903 +0100
@@ -10556,8 +10556,8 @@  ia64_fold_builtin (tree fndecl, int n_ar
 {
   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
     {
-      enum ia64_builtins fn_code = (enum ia64_builtins)
-				   DECL_FUNCTION_CODE (fndecl);
+      enum ia64_builtins fn_code
+	= (enum ia64_builtins) DECL_MD_FUNCTION_CODE (fndecl);
       switch (fn_code)
 	{
 	case IA64_BUILTIN_NANQ:
@@ -10591,7 +10591,7 @@  ia64_expand_builtin (tree exp, rtx targe
 		     int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   switch (fcode)
     {
Index: gcc/config/iq2000/iq2000.c
===================================================================
--- gcc/config/iq2000/iq2000.c	2019-04-08 21:55:28.238369625 +0100
+++ gcc/config/iq2000/iq2000.c	2019-08-13 10:31:24.810972903 +0100
@@ -2707,7 +2707,7 @@  iq2000_expand_builtin (tree exp, rtx tar
 		       int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  int fcode = DECL_FUNCTION_CODE (fndecl);
+  int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   enum rtx_code code [5];
 
   code[0] = REG;
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2019-07-07 10:49:05.525781087 +0100
+++ gcc/config/mips/mips.c	2019-08-13 10:31:24.814972874 +0100
@@ -17215,7 +17215,7 @@  mips_expand_builtin (tree exp, rtx targe
   const struct mips_builtin_description *d;
 
   fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  fcode = DECL_FUNCTION_CODE (fndecl);
+  fcode = DECL_MD_FUNCTION_CODE (fndecl);
   gcc_assert (fcode < ARRAY_SIZE (mips_builtins));
   d = &mips_builtins[fcode];
   avail = d->avail ();
Index: gcc/config/msp430/msp430.c
===================================================================
--- gcc/config/msp430/msp430.c	2019-07-30 11:59:19.132842697 +0100
+++ gcc/config/msp430/msp430.c	2019-08-13 10:31:24.814972874 +0100
@@ -2711,7 +2711,7 @@  msp430_expand_builtin (tree exp,
 		       int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
 
   if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
Index: gcc/config/nds32/nds32-intrinsic.c
===================================================================
--- gcc/config/nds32/nds32-intrinsic.c	2019-03-18 12:24:58.563435528 +0000
+++ gcc/config/nds32/nds32-intrinsic.c	2019-08-13 10:31:24.814972874 +0100
@@ -993,7 +993,7 @@  nds32_expand_builtin_impl (tree exp,
 			   int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   unsigned i;
   struct builtin_description *d;
 
Index: gcc/config/nios2/nios2.c
===================================================================
--- gcc/config/nios2/nios2.c	2019-05-29 10:49:36.660710280 +0100
+++ gcc/config/nios2/nios2.c	2019-08-13 10:31:24.814972874 +0100
@@ -4009,7 +4009,7 @@  nios2_expand_builtin (tree exp, rtx targ
 		      int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   if (fcode < nios2_fpu_builtin_base)
     {
Index: gcc/config/nvptx/nvptx.c
===================================================================
--- gcc/config/nvptx/nvptx.c	2019-06-18 15:45:13.826363000 +0100
+++ gcc/config/nvptx/nvptx.c	2019-08-13 10:31:24.818972847 +0100
@@ -5452,7 +5452,7 @@  nvptx_expand_builtin (tree exp, rtx targ
 		      machine_mode mode, int ignore)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  switch (DECL_FUNCTION_CODE (fndecl))
+  switch (DECL_MD_FUNCTION_CODE (fndecl))
     {
     case NVPTX_BUILTIN_SHUFFLE:
     case NVPTX_BUILTIN_SHUFFLELL:
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	2019-07-18 09:22:13.245773095 +0100
+++ gcc/config/pa/pa.c	2019-08-13 10:31:24.818972847 +0100
@@ -653,7 +653,7 @@  pa_expand_builtin (tree exp, rtx target,
 		   int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   switch (fcode)
     {
Index: gcc/config/pru/pru.c
===================================================================
--- gcc/config/pru/pru.c	2019-06-18 09:35:55.133867715 +0100
+++ gcc/config/pru/pru.c	2019-08-13 10:31:24.826972788 +0100
@@ -2873,7 +2873,7 @@  pru_expand_builtin (tree exp, rtx target
 		    int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
 
   if (fcode == PRU_BUILTIN_DELAY_CYCLES)
Index: gcc/config/riscv/riscv-builtins.c
===================================================================
--- gcc/config/riscv/riscv-builtins.c	2019-03-08 18:15:38.084735089 +0000
+++ gcc/config/riscv/riscv-builtins.c	2019-08-13 10:31:24.826972788 +0100
@@ -256,7 +256,7 @@  riscv_expand_builtin (tree exp, rtx targ
 		      int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   const struct riscv_builtin_description *d = &riscv_builtins[fcode];
 
   switch (d->builtin_type)
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	2019-07-16 09:11:06.497416088 +0100
+++ gcc/config/rs6000/rs6000-c.c	2019-08-13 10:31:24.826972788 +0100
@@ -6124,7 +6124,7 @@  altivec_resolve_overloaded_builtin (loca
   vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
   unsigned int nargs = vec_safe_length (arglist);
   enum rs6000_builtins fcode
-    = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   tree types[3], args[3];
   const struct altivec_builtin_types *desc;
Index: gcc/config/rs6000/rs6000-call.c
===================================================================
--- gcc/config/rs6000/rs6000-call.c	2019-07-29 09:39:47.186185920 +0100
+++ gcc/config/rs6000/rs6000-call.c	2019-08-13 10:31:24.826972788 +0100
@@ -4003,7 +4003,8 @@  htm_expand_builtin (tree exp, rtx target
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
-  enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+  enum rs6000_builtins fcode
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   const struct builtin_description *d;
   size_t i;
 
@@ -4472,7 +4473,8 @@  altivec_expand_dst_builtin (tree exp, rt
 			    bool *expandedp)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+  enum rs6000_builtins fcode
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   tree arg0, arg1, arg2;
   machine_mode mode0, mode1;
   rtx pat, op0, op1, op2;
@@ -4666,7 +4668,7 @@  altivec_expand_builtin (tree exp, rtx ta
   rtx op0, pat;
   machine_mode tmode, mode0;
   enum rs6000_builtins fcode
-    = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
 
   if (rs6000_overloaded_builtin_p (fcode))
     {
@@ -5325,7 +5327,7 @@  rs6000_gimple_fold_builtin (gimple_stmt_
   tree fndecl = gimple_call_fndecl (stmt);
   gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
   enum rs6000_builtins fn_code
-    = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   tree arg0, arg1, lhs, temp;
   enum tree_code bcode;
   gimple *g;
@@ -6216,7 +6218,7 @@  rs6000_expand_builtin (tree exp, rtx tar
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   enum rs6000_builtins fcode
-    = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   size_t uns_fcode = (size_t)fcode;
   const struct builtin_description *d;
   size_t i;
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	2019-08-05 17:46:20.813722877 +0100
+++ gcc/config/rs6000/rs6000.c	2019-08-13 10:31:24.830972760 +0100
@@ -5335,7 +5335,7 @@  rs6000_builtin_md_vectorized_function (t
   in_n = TYPE_VECTOR_SUBPARTS (type_in);
 
   enum rs6000_builtins fn
-    = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+    = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   switch (fn)
     {
     case RS6000_BUILTIN_RSQRTF:
@@ -21300,7 +21300,7 @@  rs6000_ira_change_pseudo_allocno_class (
 static tree
 rs6000_builtin_reciprocal (tree fndecl)
 {
-  switch (DECL_FUNCTION_CODE (fndecl))
+  switch (DECL_MD_FUNCTION_CODE (fndecl))
     {
     case VSX_BUILTIN_XVSQRTDP:
       if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
Index: gcc/config/rx/rx.c
===================================================================
--- gcc/config/rx/rx.c	2019-05-30 18:34:35.838485781 +0100
+++ gcc/config/rx/rx.c	2019-08-13 10:31:24.830972760 +0100
@@ -2616,7 +2616,7 @@  rx_expand_builtin (tree exp,
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   tree arg    = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
   rtx  op     = arg ? expand_normal (arg) : NULL_RTX;
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   switch (fcode)
     {
Index: gcc/config/s390/s390-c.c
===================================================================
--- gcc/config/s390/s390-c.c	2019-04-04 08:34:54.193929900 +0100
+++ gcc/config/s390/s390-c.c	2019-08-13 10:31:24.830972760 +0100
@@ -860,7 +860,7 @@  s390_resolve_overloaded_builtin (locatio
   vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
   unsigned int in_args_num = vec_safe_length (arglist);
   unsigned int ob_args_num = 0;
-  unsigned int ob_fcode = DECL_FUNCTION_CODE (ob_fndecl);
+  unsigned int ob_fcode = DECL_MD_FUNCTION_CODE (ob_fndecl);
   enum s390_overloaded_builtin_vars bindex;
   unsigned int i;
   int last_match_type = INT_MAX;
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	2019-07-29 09:39:46.702189811 +0100
+++ gcc/config/s390/s390.c	2019-08-13 10:31:24.834972731 +0100
@@ -770,7 +770,7 @@  s390_expand_builtin (tree exp, rtx targe
 #define MAX_ARGS 6
 
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   enum insn_code icode;
   rtx op[MAX_ARGS], pat;
   int arity;
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	2019-06-21 15:37:49.843877214 +0100
+++ gcc/config/sh/sh.c	2019-08-13 10:31:24.834972731 +0100
@@ -10461,7 +10461,7 @@  sh_expand_builtin (tree exp, rtx target,
 		   machine_mode mode ATTRIBUTE_UNUSED, int ignore)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   const struct builtin_description *d = &bdesc[fcode];
   enum insn_code icode = d->icode;
   int signature = d->signature;
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	2019-06-21 15:37:49.667878681 +0100
+++ gcc/config/sparc/sparc.c	2019-08-13 10:31:24.834972731 +0100
@@ -11661,7 +11661,8 @@  sparc_expand_builtin (tree exp, rtx targ
 		      int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  enum sparc_builtins code = (enum sparc_builtins) DECL_FUNCTION_CODE (fndecl);
+  enum sparc_builtins code
+    = (enum sparc_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   enum insn_code icode = sparc_builtins_icode[code];
   bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
   call_expr_arg_iterator iter;
@@ -11829,7 +11830,8 @@  sparc_handle_vis_mul8x16 (vec<tree> *n_e
 sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
 		    tree *args, bool ignore)
 {
-  enum sparc_builtins code = (enum sparc_builtins) DECL_FUNCTION_CODE (fndecl);
+  enum sparc_builtins code
+    = (enum sparc_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   tree rtype = TREE_TYPE (TREE_TYPE (fndecl));
   tree arg0, arg1, arg2;
 
Index: gcc/config/spu/spu-c.c
===================================================================
--- gcc/config/spu/spu-c.c	2019-03-08 18:15:36.952739391 +0000
+++ gcc/config/spu/spu-c.c	2019-08-13 10:31:24.834972731 +0100
@@ -93,7 +93,7 @@  #define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_
 			  || POINTER_TYPE_P (t))
   vec<tree, va_gc> *fnargs = static_cast <vec<tree, va_gc> *> (passed_args);
   unsigned int nargs = vec_safe_length (fnargs);
-  int new_fcode, fcode = DECL_FUNCTION_CODE (fndecl);
+  int new_fcode, fcode = DECL_MD_FUNCTION_CODE (fndecl);
   struct spu_builtin_description *desc;
   tree match = NULL_TREE;
 
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c	2019-05-29 10:49:36.312711290 +0100
+++ gcc/config/spu/spu.c	2019-08-13 10:31:24.838972703 +0100
@@ -6591,7 +6591,7 @@  spu_expand_builtin (tree exp,
 		    int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   struct spu_builtin_description *d;
 
   if (fcode < NUM_SPU_BUILTINS)
Index: gcc/config/stormy16/stormy16.c
===================================================================
--- gcc/config/stormy16/stormy16.c	2019-05-29 10:49:36.612710418 +0100
+++ gcc/config/stormy16/stormy16.c	2019-08-13 10:31:24.838972703 +0100
@@ -2326,7 +2326,7 @@  xstormy16_expand_builtin (tree exp, rtx
 
   fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
   argtree = TREE_OPERAND (exp, 1);
-  i = DECL_FUNCTION_CODE (fndecl);
+  i = DECL_MD_FUNCTION_CODE (fndecl);
   code = s16builtins[i].md_code;
 
   for (a = 0; a < 10 && argtree; a++)
Index: gcc/config/tilegx/tilegx.c
===================================================================
--- gcc/config/tilegx/tilegx.c	2019-05-29 10:49:36.572710536 +0100
+++ gcc/config/tilegx/tilegx.c	2019-08-13 10:31:24.838972703 +0100
@@ -3531,7 +3531,7 @@  tilegx_expand_builtin (tree exp,
 #define MAX_BUILTIN_ARGS 4
 
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree arg;
   call_expr_arg_iterator iter;
   enum insn_code icode;
Index: gcc/config/tilepro/tilepro.c
===================================================================
--- gcc/config/tilepro/tilepro.c	2019-05-29 10:49:36.880709641 +0100
+++ gcc/config/tilepro/tilepro.c	2019-08-13 10:31:24.838972703 +0100
@@ -3095,7 +3095,7 @@  tilepro_expand_builtin (tree exp,
 #define MAX_BUILTIN_ARGS 4
 
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree arg;
   call_expr_arg_iterator iter;
   enum insn_code icode;
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	2019-06-21 15:37:49.891876813 +0100
+++ gcc/config/xtensa/xtensa.c	2019-08-13 10:31:24.838972703 +0100
@@ -3450,7 +3450,7 @@  xtensa_init_builtins (void)
 xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
 		     bool ignore ATTRIBUTE_UNUSED)
 {
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   tree arg0, arg1;
 
   switch (fcode)
@@ -3481,7 +3481,7 @@  xtensa_expand_builtin (tree exp, rtx tar
 		       int ignore)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   switch (fcode)
     {
Index: gcc/ada/gcc-interface/trans.c
===================================================================
--- gcc/ada/gcc-interface/trans.c	2019-08-05 17:46:19.993728900 +0100
+++ gcc/ada/gcc-interface/trans.c	2019-08-13 10:31:24.774973159 +0100
@@ -493,8 +493,7 @@  gigi (Node_Id gnat_root,
        build_function_type_list (integer_type_node, jmpbuf_ptr_type,
 				 NULL_TREE),
        NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
-  DECL_BUILT_IN_CLASS (setjmp_decl) = BUILT_IN_NORMAL;
-  DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP;
+  set_decl_built_in_function (setjmp_decl, BUILT_IN_NORMAL, BUILT_IN_SETJMP);
 
   /* update_setjmp_buf updates a setjmp buffer from the current stack pointer
      address.  */
@@ -503,8 +502,8 @@  gigi (Node_Id gnat_root,
       (get_identifier ("__builtin_update_setjmp_buf"), NULL_TREE,
        build_function_type_list (void_type_node, jmpbuf_ptr_type, NULL_TREE),
        NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
-  DECL_BUILT_IN_CLASS (update_setjmp_buf_decl) = BUILT_IN_NORMAL;
-  DECL_FUNCTION_CODE (update_setjmp_buf_decl) = BUILT_IN_UPDATE_SETJMP_BUF;
+  set_decl_built_in_function (update_setjmp_buf_decl, BUILT_IN_NORMAL,
+			      BUILT_IN_UPDATE_SETJMP_BUF);
 
   /* Indicate that it never returns.  */
   ftype = build_function_type_list (void_type_node,
@@ -5535,7 +5534,7 @@  Call_to_gnu (Node_Id gnat_node, tree *gn
       tree pred_cst = build_int_cst (integer_type_node, PRED_BUILTIN_EXPECT);
       enum internal_fn icode = IFN_BUILTIN_EXPECT;
 
-      switch (DECL_FUNCTION_CODE (gnu_subprog))
+      switch (DECL_FE_FUNCTION_CODE (gnu_subprog))
 	{
 	case BUILT_IN_EXPECT:
 	  break;
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	2019-08-13 10:31:18.215019968 +0100
+++ gcc/c/c-decl.c	2019-08-13 10:31:24.778973130 +0100
@@ -2736,8 +2736,7 @@  merge_decls (tree newdecl, tree olddecl,
 	{
 	  /* If redeclaring a builtin function, it stays built in.
 	     But it gets tagged as having been declared.  */
-	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
-	  DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+	  copy_decl_built_in_function (newdecl, olddecl);
 	  C_DECL_DECLARED_BUILTIN (newdecl) = 1;
 	  if (new_is_prototype)
 	    {
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	2019-07-03 20:50:42.514348985 +0100
+++ gcc/c-family/c-common.c	2019-08-13 10:31:24.778973130 +0100
@@ -7332,8 +7332,6 @@  resolve_overloaded_atomic_store (locatio
 resolve_overloaded_builtin (location_t loc, tree function,
 			    vec<tree, va_gc> *params)
 {
-  enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
-
   /* Is function one of the _FETCH_OP_ or _OP_FETCH_ built-ins?
      Those are not valid to call with a pointer to _Bool (or C++ bool)
      and so must be rejected.  */
@@ -7355,6 +7353,7 @@  resolve_overloaded_builtin (location_t l
     }
 
   /* Handle BUILT_IN_NORMAL here.  */
+  enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
   switch (orig_code)
     {
     case BUILT_IN_SPECULATION_SAFE_VALUE_N:
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	2019-08-09 09:31:25.569331666 +0100
+++ gcc/cp/decl.c	2019-08-13 10:31:24.842972676 +0100
@@ -2544,8 +2544,7 @@  duplicate_decls (tree newdecl, tree oldd
       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);
-	  DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+	  copy_decl_built_in_function (newdecl, olddecl);
 	  /* If we're keeping the built-in definition, keep the rtl,
 	     regardless of declaration matches.  */
 	  COPY_DECL_RTL (olddecl, newdecl);
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	2019-08-07 19:31:48.352992747 +0100
+++ gcc/cp/pt.c	2019-08-13 10:31:24.842972676 +0100
@@ -28331,9 +28331,8 @@  declare_integer_pack (void)
 							 NULL_TREE),
 			       NULL_TREE, ECF_CONST);
   DECL_DECLARED_CONSTEXPR_P (ipfn) = true;
-  DECL_BUILT_IN_CLASS (ipfn) = BUILT_IN_FRONTEND;
-  DECL_FUNCTION_CODE (ipfn)
-    = (enum built_in_function) (int) CP_BUILT_IN_INTEGER_PACK;
+  set_decl_built_in_function (ipfn, BUILT_IN_FRONTEND,
+			      CP_BUILT_IN_INTEGER_PACK);
 }
 
 /* Set up the hash tables for template instantiations.  */
Index: gcc/d/intrinsics.cc
===================================================================
--- gcc/d/intrinsics.cc	2019-03-08 18:14:26.281008042 +0000
+++ gcc/d/intrinsics.cc	2019-08-13 10:31:24.842972676 +0100
@@ -134,10 +134,7 @@  maybe_set_intrinsic (FuncDeclaration *de
 	  /* If there is no function body, then the implementation is always
 	     provided by the compiler.  */
 	  if (!decl->fbody)
-	    {
-	      DECL_BUILT_IN_CLASS (decl->csym) = BUILT_IN_FRONTEND;
-	      DECL_FUNCTION_CODE (decl->csym) = (built_in_function) code;
-	    }
+	    set_decl_built_in_function (decl->csym, BUILT_IN_FRONTEND, code);
 
 	  /* Infer whether the intrinsic can be used for CTFE, let the
 	     front-end know that it can be evaluated at compile-time.  */
Index: gcc/jit/jit-playback.c
===================================================================
--- gcc/jit/jit-playback.c	2019-07-06 09:25:06.913500498 +0100
+++ gcc/jit/jit-playback.c	2019-08-13 10:31:24.846972645 +0100
@@ -453,12 +453,11 @@  new_function (location *loc,
 
   if (builtin_id)
     {
-      DECL_FUNCTION_CODE (fndecl) = builtin_id;
       gcc_assert (loc == NULL);
       DECL_SOURCE_LOCATION (fndecl) = BUILTINS_LOCATION;
 
-      DECL_BUILT_IN_CLASS (fndecl) =
-	builtins_manager::get_class (builtin_id);
+      built_in_class fclass = builtins_manager::get_class (builtin_id);
+      set_decl_built_in_function (fndecl, fclass, builtin_id);
       set_builtin_decl (builtin_id, fndecl,
 			builtins_manager::implicit_p (builtin_id));
 
Index: gcc/lto/lto-common.c
===================================================================
--- gcc/lto/lto-common.c	2019-07-29 09:39:49.754165272 +0100
+++ gcc/lto/lto-common.c	2019-08-13 10:31:24.846972645 +0100
@@ -1241,7 +1241,7 @@  #define compare_values(X) \
       compare_values (DECL_CXX_CONSTRUCTOR_P);
       compare_values (DECL_CXX_DESTRUCTOR_P);
       if (DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN)
-	compare_values (DECL_FUNCTION_CODE);
+	compare_values (DECL_UNCHECKED_FUNCTION_CODE);
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
Index: gcc/lto/lto-symtab.c
===================================================================
--- gcc/lto/lto-symtab.c	2019-04-04 08:34:52.529936110 +0100
+++ gcc/lto/lto-symtab.c	2019-08-13 10:31:24.846972645 +0100
@@ -556,7 +556,8 @@  lto_symtab_merge_p (tree prevailing, tre
 	}
       if (fndecl_built_in_p (prevailing)
 	  && (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl)
-	      || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl)))
+	      || (DECL_UNCHECKED_FUNCTION_CODE (prevailing)
+		  != DECL_UNCHECKED_FUNCTION_CODE (decl))))
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "Not merging decls; "