diff mbox

[RFC] Builtin infrastructure change

Message ID 20110913232752.GA17828@hungry-tiger.westford.ibm.com
State New
Headers show

Commit Message

Michael Meissner Sept. 13, 2011, 11:27 p.m. UTC
This patch touches a bunch of files, but most of the changes are fairly
mechanical.  What this does is change the infrastructure of how machine
independent builtin functions are handled.  At this point, there is no change
to the compiler from a user perspective.  Instead of having two parallel arrays
that have tree pointers for built-in functions:

	built_in_decls
	implicit_built_in_decls

I have replaced these by two macros that call inline functions:

	BUILT_IN_DECLS
	IMPLICIT_BUILT_IN_DECLS

and changed the other parts that want to modify the builtins.  By changing it
to a functional approach instead of an array, we can more easily change the
code underneath.

Assuming there no objections that I can't deal with, the next patch would then
add the support to only dynamically allocate the tree structures for the
builtin functions and the types/attributes as we need them.  So if you never
touch any builtin function, you would not allocate some 600-1,000 tree nodes to
hold all of the declarations that aren't needed.  Now, we still would have the
identifier nodes that have the names.

After this, I hope to modify the powerpc back end to do similar savings, and
then have builtins be enabled and disabled, via the target attribute or pragma.

I have built the full compiler (C, C++, Java, Ada, Fortran, Objective C, and
Objection C++) on the powerpc and did a comparison against an unpatched
compiler and there were no regressions.  I have also built a full x86 compiler
with the changes, but I have not yet done the make check comparison.

Right now, I have not built the other targets (sparc, vms, pa, darwinm and
ia64) where there were changes made.  I would appreciate it if other
maintainers could do a smoke test of the patches.

Any comments?

[gcc]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* tree.h (built_in_decls): Change builtin interface from being an
	array to an inline function for both normal and implicit builtin
	functions.  Change all references to built_in_decls and
	implicit_built_in_decls to the new macros/functions, and poison
	the old names. Make sure 0 is not a legitimate builtin index.
	(implicit_built_in_decls): Ditto.
	(struct built_in_decl_info): Ditto.
	(built_in_info): Ditto.
	(built_in_get_decl): Ditto.
	(built_in_set_decl): Ditto.
	(built_in_copy_decl): Ditto.
	(built_in_no_implicit): Ditto.
	(BUILT_IN_DECLS): Ditto.
	(IMPLICIT_BUILT_IN_DECLS): Ditto.
	* tree-complex.c (expand_complex_libcall): Ditto.
	* tree-loop-distribution.c (generate_memset_zero): Ditto.
	* tree.c (iterative_hash_expr): Ditto.
	(build_common_builtin_nodes): Ditto.
	* builtins.c (built_in_decls): Ditto.
	(implicit_built_in_decls): Ditto.
	(mathfn_built_in_1): Ditto.
	(expand_builtin_cexpi): Ditto.
	(expand_builtin_mempcpy_args): Ditto.
	(expand_builtin_stpcpy): Ditto.
	(gimplify_va_arg_expr): Ditto.
	(expand_builtin_sync_operation): Ditto.
	(build_builtin_expect_predicate): Ditto.
	(fold_builtin_memory_op): Ditto.
	(fold_builtin_strcpy): Ditto.
	(fold_builtin_strncpy): Ditto.
	(fold_builtin_interclass_mathfn): Ditto.
	(fold_builtin_classify): Ditto.
	(fold_builtin_2): Ditto.
	(fold_builtin_strstr): Ditto.
	(fold_builtin_strpbrk): Ditto.
	(fold_builtin_strcat): Ditto.
	(fold_builtin_strncat): Ditto.
	(fold_builtin_strcspn): Ditto.
	(fold_builtin_fputs): Ditto.
	(fold_builtin_sprintf): Ditto.
	(fold_builtin_snprintf): Ditto.
	(expand_builtin_memory_chk): Ditto.
	(fold_builtin_stxcpy_chk): Ditto.
	(fold_builtin_strncpy_chk): Ditto.
	(fold_builtin_strcat_chk): Ditto.
	(fold_builtin_strncat_chk): Ditto.
	(fold_builtin_sprintf_chk_1): Ditto.
	(fold_builtin_printf): Ditto.
	(fold_builtin_fprintf): Ditto.
	(fold_call_stmt): Ditto.
	(set_builtin_user_assembler_name): Ditto.
	* tree-emults.c (emutls_common_1): Ditto.
	(lower_emutls_function_body): Ditto.
	* omp-low.c (scan_omp): Ditto.
	(lower_rec_input_clauses): Ditto.
	(lower_reduction_clauses): Ditto.
	(expand_parallel_call): Ditto.
	(expand_task_call): Ditto.
	(maybe_catch_exception): Ditto.
	(optimize_omp_library_calls): Ditto.
	(expand_omp_for_generic): Ditto.
	(expand_omp_for_static_chunk): Ditto.
	(expand_omp_sections): Ditto.
	(expand_omp_atomic_pipeline): Ditto.
	(expand_omp_atomic_mutex): Ditto.
	(lower_omp_single_simple): Ditto.
	(lower_omp_single_copy): Ditto.
	(lower_omp_single): Ditto.
	(lower_omp_master): Ditto.
	(lower_omp_ordered): Ditto.
	(lower_omp_critical): Ditto.
	* tree-ssa-ccp.c (optimize_stdarg_builtin): Ditto.
	* builtins.def (BUILT_IN_NONE): Ditto.
	* tree-ssa-math-opts.c (execute_optimize_bswap): Ditto.
	* gimple-low.c (lower_function_body): Ditto.
	(lower_builtin_setjmp): Ditto.
	* c-decl.c (finish_decl): Ditto.
	* tree-eh.c (lower_resx): ditto.
	(lower_eh_dispatch): Ditto.
	* function.c (gimplify_parameters): Ditto.
	* c-typeck.c (build_function_call_vec): Ditto.
	* gimplify.c (build_stack_save_restore): Ditto.
	(gimplify_vla_decl): Ditto.
	(gimplify_modify_expr_to_memcpy): Ditto.
	(gimplify_modify_expr_to_memset): Ditto.
	(gimplify_variable_sized_compare): Ditto.
	(gimplify_function_tree): Ditto.
	* calls.c (emit_call_1): Ditto.
	* tree-nested.c (convert_nl_goto_reference): Ditto.
	(convert_tramp_reference_op): Ditto.
	(finalize_nesting_tree_1): Ditto.
	* tree-ssa-loop-prefetch.c (issue_prefetch_ref): Ditto.
	(tree_ssa_prefetch_arrays): Ditto.
	* tree-streamer-in.c (streamer_get_builtin_tree): Ditto.
	* config/sparc/sparc.c (sparc_gimplify_va_arg): Ditto.
	* config/i386/i386.c (ix86_gimplify_va_arg): Ditto.
	(ix86_veclibabi_svml): Ditto.
	(ix86_veclibabi_acml): Ditto.
	* config/vms/vms.c (vms_patch_builtins): Ditto.
	* config/ia64/ia64.c (ia64_init_builtins): Ditto.
	* config/rs6000/rs6000.c (rs6000_builtin_vectorized_libmass): Ditto.
	(rs6000_gimplify_va_arg): Ditto.
	(rs6000_init_builtins): Ditto.
	* config/darwin.c (darwin_override_options): Ditto.
	(darwin_patch_builtin): Ditto.
	(darwin_rename_builtins): Ditto.
	* config/pa/pa.c (pa_init_builtins): Ditto.

[gcc/ada]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc-interface/utils.c (def_builtin_1):  Change to use new
	builtin accessor macros instead of refering to the built_in_decls
	and implicit_built_in_decls directly.
	* gcc-interface/trans.c (Exception_Handler_to_gnu_zcx): Ditto.
	(gnat_to_gnu): Ditto.

[gcc/c-family]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-common.c (def_builtin_1): Change to use new builtin accessor
	macros instead of refering to the built_in_decls and
	implicit_built_in_decls directly.
	(resolve_overloaded_builtin): Ditto.
	* c-omp.c (c_finish_omp_barrier): Ditto.
	(c_finish_omp_taskwait): Ditto.
	(c_finish_omp_taskyield): Ditto.
	(c_finish_omp_flush): Ditto.

[gcc/fortran]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* trans.c (gfc_call_malloc):  Change to use new builtin accessor
	macros instead of refering to the built_in_decls and
	implicit_built_in_decls directly.
	(gfc_allocate_using_malloc): Ditto.
	(gfc_call_free): Ditto.
	(gfc_deallocate_with_status): Ditto.
	(gfc_deallocate_scalar_with_status): Ditto.
	(gfc_call_realloc): Ditto.
	(gfc_unlikely): Ditto.
	(gfc_likely): Ditto.
	 * f95-lang.c (gfc_define_builtin): Ditto.
	(gfc_init_builtin_functions): Ditto.
	* trans-decl.c (create_main_function): Ditto.
	* trans-intrinsic.c (builtin_decl_for_precision): Ditto.
	(gfc_build_intrinsic_lib_fndecls): Ditto.
	(gfc_conv_intrinsic_minmax): Ditto.
	(gfc_conv_intrinsic_leadz): Ditto.
	(gfc_conv_intrinsic_trailz): Ditto.
	(gfc_conv_intrinsic_popcnt_poppar): Ditto.
	(gfc_conv_intrinsic_isnan): Ditto.
	(gfc_conv_intrinsic_transfer): Ditto.
	(scalar_transfer): Ditto.
	(gfc_conv_intrinsic_repeat): Ditto.

[gcc/java]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* class.c (build_static_field_ref):  Change to use new builtin
	accessor macros instead of refering to the built_in_decls and
	implicit_built_in_decls directly.
	* decl.c (java_init_decl_processing): Ditto.
	* except.c (expand_end_java_handler): Ditto.
	* builtins.c (compareAndSwapInt_builtin): Ditto.
	(compareAndSwapLong_builtin): Ditto.
	(compareAndSwapObject_builtin): Ditto.
	(compareAndSwapObject_builtin): Ditto.
	(putVolatile_builtin): Ditto.
	(getVolatile_builtin): Ditto.
	(define_builtin): Ditto.
	(check_for_builtin): Ditto.
	* expr.c (rewrite_arglist_getcaller): Ditto.
	(expand_java_field_op): Ditto.

[gcc/lto]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* lto-lang.c (def_builtin_1):  Change to use new builtin accessor
	macros instead of refering to the built_in_decls and
	implicit_built_in_decls directly.

[gcc/objc]
2011-09-09  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* objc-next-runtime-abi-01.c (objc_build_exc_ptr): Change to use
	new builtin accessor macros instead of refering to the
	built_in_decls and implicit_built_in_decls directly.
	* objc-next-runtime-abi-02.c (objc_build_exc_ptr): Ditto.
	* objc-gnu-runtime-abi-01.c (objc_build_exc_ptr): Ditto.

Comments

Joseph Myers Sept. 14, 2011, 2:33 p.m. UTC | #1
On Tue, 13 Sep 2011, Michael Meissner wrote:

> 	implicit_built_in_decls to the new macros/functions, and poison
> 	the old names. Make sure 0 is not a legitimate builtin index.

I think the poisoning belongs in system.h; direct dependencies on the host 
compiler (such as GCC_VERSION and __GNUC__ tests) should be kept as local 
as possible, in just a few headers such as system.h and hwint.h, with 
other places testing feature macros defined in system.h (or through 
autoconf) if it's really necessary to have such dependencies there.
Michael Meissner Sept. 14, 2011, 4:08 p.m. UTC | #2
On Wed, Sep 14, 2011 at 02:33:12PM +0000, Joseph S. Myers wrote:
> On Tue, 13 Sep 2011, Michael Meissner wrote:
> 
> > 	implicit_built_in_decls to the new macros/functions, and poison
> > 	the old names. Make sure 0 is not a legitimate builtin index.
> 
> I think the poisoning belongs in system.h; direct dependencies on the host 
> compiler (such as GCC_VERSION and __GNUC__ tests) should be kept as local 
> as possible, in just a few headers such as system.h and hwint.h, with 
> other places testing feature macros defined in system.h (or through 
> autoconf) if it's really necessary to have such dependencies there.

Ok, I wasn't sure where the best place to put the poison.  System.h sounds like
the best place.
Richard Henderson Sept. 14, 2011, 8:38 p.m. UTC | #3
On 09/13/2011 04:27 PM, Michael Meissner wrote:
> This patch touches a bunch of files, but most of the changes are fairly
> mechanical.  What this does is change the infrastructure of how machine
> independent builtin functions are handled.  At this point, there is no change
> to the compiler from a user perspective.  Instead of having two parallel arrays
> that have tree pointers for built-in functions:
> 
> 	built_in_decls
> 	implicit_built_in_decls
> 
> I have replaced these by two macros that call inline functions:
> 
> 	BUILT_IN_DECLS
> 	IMPLICIT_BUILT_IN_DECLS
> 
> and changed the other parts that want to modify the builtins.  By changing it
> to a functional approach instead of an array, we can more easily change the
> code underneath.

Why bother with the case change and poisoning?  Merely changing the type of the symbol from object to function ought to be sufficient to catch all users at compile time.

I say this because I'm not keen on functions using all-caps names...


r~
Richard Biener Sept. 26, 2011, 2:40 p.m. UTC | #4
On Wed, Sep 14, 2011 at 10:38 PM, Richard Henderson <rth@redhat.com> wrote:
> On 09/13/2011 04:27 PM, Michael Meissner wrote:
>> This patch touches a bunch of files, but most of the changes are fairly
>> mechanical.  What this does is change the infrastructure of how machine
>> independent builtin functions are handled.  At this point, there is no change
>> to the compiler from a user perspective.  Instead of having two parallel arrays
>> that have tree pointers for built-in functions:
>>
>>       built_in_decls
>>       implicit_built_in_decls
>>
>> I have replaced these by two macros that call inline functions:
>>
>>       BUILT_IN_DECLS
>>       IMPLICIT_BUILT_IN_DECLS
>>
>> and changed the other parts that want to modify the builtins.  By changing it
>> to a functional approach instead of an array, we can more easily change the
>> code underneath.
>
> Why bother with the case change and poisoning?  Merely changing the type of the symbol from object to function ought to be sufficient to catch all users at compile time.
>
> I say this because I'm not keen on functions using all-caps names...

Yeah, I agree.

Richard.

>
> r~
>
diff mbox

Patch

Index: gcc/tree-complex.c
===================================================================
--- gcc/tree-complex.c	(revision 178642)
+++ gcc/tree-complex.c	(working copy)
@@ -956,7 +956,7 @@  expand_complex_libcall (gimple_stmt_iter
 	     (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
   else
     gcc_unreachable ();
-  fn = built_in_decls[bcode];
+  fn = BUILT_IN_DECLS (bcode);
 
   stmt = gimple_build_call (fn, 4, ar, ai, br, bi);
   gimple_call_set_lhs (stmt, lhs);
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 178699)
+++ gcc/c-family/c-common.c	(working copy)
@@ -5173,9 +5173,7 @@  def_builtin_1 (enum built_in_function fn
     add_builtin_function (libname, libtype, fncode, fnclass,
 			  NULL, fnattrs);
 
-  built_in_decls[(int) fncode] = decl;
-  if (implicit_p)
-    implicit_built_in_decls[(int) fncode] = decl;
+  built_in_set_decl (fncode, decl, implicit_p ? decl : NULL_TREE);
 }
 
 /* Nonzero if the type T promotes to int.  This is (nearly) the
@@ -9147,7 +9145,7 @@  resolve_overloaded_builtin (location_t l
 	if (n == 0)
 	  return error_mark_node;
 
-	new_function = built_in_decls[orig_code + exact_log2 (n) + 1];
+	new_function = BUILT_IN_DECLS_ADD (orig_code, exact_log2 (n) + 1);
 	if (!sync_resolve_params (function, new_function, params))
 	  return error_mark_node;
 
Index: gcc/c-family/c-omp.c
===================================================================
--- gcc/c-family/c-omp.c	(revision 178642)
+++ gcc/c-family/c-omp.c	(working copy)
@@ -77,7 +77,7 @@  c_finish_omp_barrier (location_t loc)
 {
   tree x;
 
-  x = built_in_decls[BUILT_IN_GOMP_BARRIER];
+  x = BUILT_IN_DECLS (BUILT_IN_GOMP_BARRIER);
   x = build_call_expr_loc (loc, x, 0);
   add_stmt (x);
 }
@@ -91,7 +91,7 @@  c_finish_omp_taskwait (location_t loc)
 {
   tree x;
 
-  x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
+  x = BUILT_IN_DECLS (BUILT_IN_GOMP_TASKWAIT);
   x = build_call_expr_loc (loc, x, 0);
   add_stmt (x);
 }
@@ -105,7 +105,7 @@  c_finish_omp_taskyield (location_t loc)
 {
   tree x;
 
-  x = built_in_decls[BUILT_IN_GOMP_TASKYIELD];
+  x = BUILT_IN_DECLS (BUILT_IN_GOMP_TASKYIELD);
   x = build_call_expr_loc (loc, x, 0);
   add_stmt (x);
 }
@@ -260,7 +260,7 @@  c_finish_omp_flush (location_t loc)
 {
   tree x;
 
-  x = built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE];
+  x = BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE);
   x = build_call_expr_loc (loc, x, 0);
   add_stmt (x);
 }
Index: gcc/tree-loop-distribution.c
===================================================================
--- gcc/tree-loop-distribution.c	(revision 178642)
+++ gcc/tree-loop-distribution.c	(working copy)
@@ -289,7 +289,7 @@  generate_memset_zero (gimple stmt, tree 
   mem = force_gimple_operand (addr_base, &stmts, true, NULL);
   gimple_seq_add_seq (&stmt_list, stmts);
 
-  fn = build_fold_addr_expr (implicit_built_in_decls [BUILT_IN_MEMSET]);
+  fn = build_fold_addr_expr (IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMSET));
   fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes);
   gimple_seq_add_stmt (&stmt_list, fn_call);
   gsi_insert_seq_after (&bsi, stmt_list, GSI_CONTINUE_LINKING);
Index: gcc/java/class.c
===================================================================
--- gcc/java/class.c	(revision 178642)
+++ gcc/java/class.c	(working copy)
@@ -1266,7 +1266,7 @@  build_static_field_ref (tree fdecl)
       int cpool_index = alloc_constant_fieldref (output_class, fdecl);
       tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl);
       tree test
-        = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2,
+        = build_call_expr (BUILT_IN_DECLS (BUILT_IN_EXPECT), 2,
 			   build2 (EQ_EXPR, boolean_type_node,
 				   cache_entry, null_pointer_node),
 			   boolean_false_node);
Index: gcc/java/decl.c
===================================================================
--- gcc/java/decl.c	(revision 178642)
+++ gcc/java/decl.c	(working copy)
@@ -1135,7 +1135,7 @@  java_init_decl_processing (void)
 
   initialize_builtins ();
 
-  soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
+  soft_fmod_node = BUILT_IN_DECLS (BUILT_IN_FMOD);
 
   parse_version ();
 }
Index: gcc/java/except.c
===================================================================
--- gcc/java/except.c	(revision 178642)
+++ gcc/java/except.c	(working copy)
@@ -520,7 +520,7 @@  expand_end_java_handler (struct eh_range
 	    type = throwable_type_node;
 	  eh_type = prepare_eh_table_type (type);
 
-	  x = build_call_expr (built_in_decls[BUILT_IN_EH_POINTER],
+	  x = build_call_expr (BUILT_IN_DECLS (BUILT_IN_EH_POINTER),
 				1, integer_zero_node);
 	  x = build2 (MODIFY_EXPR, void_type_node, exc_obj, x);
 	  tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING);
Index: gcc/java/builtins.c
===================================================================
--- gcc/java/builtins.c	(revision 178642)
+++ gcc/java/builtins.c	(working copy)
@@ -329,8 +329,8 @@  compareAndSwapInt_builtin (tree method_r
 
       addr = build_addr_sum (int_type_node, obj_arg, offset_arg);
       stmt = build_call_expr 
-			(built_in_decls[BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4],
-			 3, addr, expected_arg, value_arg);
+		       (BUILT_IN_DECLS (BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4),
+			3, addr, expected_arg, value_arg);
 
       return build_check_this (stmt, this_arg);
     }
@@ -356,8 +356,8 @@  compareAndSwapLong_builtin (tree method_
 
       addr = build_addr_sum (long_type_node, obj_arg, offset_arg);
       stmt = build_call_expr 
-			(built_in_decls[BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8],
-			 3, addr, expected_arg, value_arg);
+		       (BUILT_IN_DECLS (BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8),
+			3, addr, expected_arg, value_arg);
 
       return build_check_this (stmt, this_arg);
     }
@@ -373,7 +373,7 @@  compareAndSwapObject_builtin (tree metho
       || flag_use_atomic_builtins)
   {
     tree addr, stmt;
-    int builtin;
+    enum built_in_function builtin;
 
     UNMARSHAL5 (orig_call);
     builtin = (POINTER_SIZE == 32 
@@ -381,7 +381,7 @@  compareAndSwapObject_builtin (tree metho
 	       : BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8);
 
     addr = build_addr_sum (value_type, obj_arg, offset_arg);
-    stmt = build_call_expr (built_in_decls[builtin],
+    stmt = build_call_expr (BUILT_IN_DECLS (builtin),
 			    3, addr, expected_arg, value_arg);
 
     return build_check_this (stmt, this_arg);
@@ -401,7 +401,7 @@  putVolatile_builtin (tree method_return_
     = fold_convert (build_pointer_type (build_type_variant (value_type, 0, 1)),
 		    addr);
   
-  stmt = build_call_expr (built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE], 0);
+  stmt = build_call_expr (BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE), 0);
   modify_stmt = fold_build2 (MODIFY_EXPR, value_type,
 			     build_java_indirect_ref (value_type, addr,
 						      flag_check_references),
@@ -425,7 +425,7 @@  getVolatile_builtin (tree method_return_
     = fold_convert (build_pointer_type (build_type_variant 
 					(method_return_type, 0, 1)), addr);
   
-  stmt = build_call_expr (built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE], 0);
+  stmt = build_call_expr (BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE), 0);
   
   tmp = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL, method_return_type);
   DECL_IGNORED_P (tmp) = 1;
@@ -483,8 +483,7 @@  define_builtin (enum built_in_function v
   if (flags & BUILTIN_CONST)
     TREE_READONLY (decl) = 1;
 
-  implicit_built_in_decls[val] = decl;
-  built_in_decls[val] = decl;
+  built_in_set_decl (val, decl, decl);
 }
 
 
@@ -627,7 +626,7 @@  check_for_builtin (tree method, tree cal
 	         with the BC-ABI.  */
 	      if (flag_indirect_dispatch)
 	        return call;
-	      fn = built_in_decls[java_builtins[i].builtin_code];
+	      fn = BUILT_IN_DECLS (java_builtins[i].builtin_code);
 	      if (fn == NULL_TREE)
 		return call;
 	      return java_build_function_call_expr (fn, call);
Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c	(revision 178642)
+++ gcc/java/expr.c	(working copy)
@@ -2073,7 +2073,7 @@  static void
 rewrite_arglist_getcaller (VEC(tree,gc) **arglist)
 {
   tree retaddr 
-    = build_call_expr (built_in_decls[BUILT_IN_RETURN_ADDRESS],
+    = build_call_expr (BUILT_IN_DECLS (BUILT_IN_RETURN_ADDRESS),
 		       1, integer_zero_node);
 
   DECL_UNINLINABLE (current_function_decl) = 1;
@@ -2934,7 +2934,7 @@  expand_java_field_op (int is_static, int
 
       if (TREE_THIS_VOLATILE (field_decl))
 	java_add_stmt
-	  (build_call_expr (built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE], 0));
+	  (build_call_expr (BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE), 0));
       	  
       java_add_stmt (modify_expr);
     }
@@ -2953,7 +2953,7 @@  expand_java_field_op (int is_static, int
 
       if (TREE_THIS_VOLATILE (field_decl))
 	java_add_stmt 
-	  (build_call_expr (built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE], 0));
+	  (build_call_expr (BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE), 0));
 
       push_value (temp);
     }      
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 178642)
+++ gcc/tree.c	(working copy)
@@ -6864,6 +6864,7 @@  iterative_hash_expr (const_tree t, hashv
   int i;
   enum tree_code code;
   char tclass;
+  tree bfn;
 
   if (t == NULL_TREE)
     return iterative_hash_hashval_t (0, val);
@@ -6942,9 +6943,9 @@  iterative_hash_expr (const_tree t, hashv
 	 or front end builtins, since the function code is overloaded in those
 	 cases.  */
       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
-	  && built_in_decls[DECL_FUNCTION_CODE (t)])
+	  && (bfn = BUILT_IN_DECLS (DECL_FUNCTION_CODE (t))) != NULL_TREE)
 	{
-	  t = built_in_decls[DECL_FUNCTION_CODE (t)];
+	  t = bfn;
 	  code = TREE_CODE (t);
 	}
       /* FALL THROUGH */
@@ -9429,8 +9430,7 @@  local_define_builtin (const char *name, 
     DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
 					NULL, DECL_ATTRIBUTES (decl));
 
-  built_in_decls[code] = decl;
-  implicit_built_in_decls[code] = decl;
+  built_in_set_decl (code, decl, decl);
 }
 
 /* Call this function after instantiating all builtins that the language
@@ -9442,22 +9442,22 @@  build_common_builtin_nodes (void)
 {
   tree tmp, ftype;
 
-  if (built_in_decls[BUILT_IN_MEMCPY] == NULL
-      || built_in_decls[BUILT_IN_MEMMOVE] == NULL)
+  if (BUILT_IN_DECLS (BUILT_IN_MEMCPY) == NULL
+      || BUILT_IN_DECLS (BUILT_IN_MEMMOVE) == NULL)
     {
       ftype = build_function_type_list (ptr_type_node,
 					ptr_type_node, const_ptr_type_node,
 					size_type_node, NULL_TREE);
 
-      if (built_in_decls[BUILT_IN_MEMCPY] == NULL)
+      if (BUILT_IN_DECLS (BUILT_IN_MEMCPY) == NULL)
 	local_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
 			      "memcpy", ECF_NOTHROW | ECF_LEAF);
-      if (built_in_decls[BUILT_IN_MEMMOVE] == NULL)
+      if (BUILT_IN_DECLS (BUILT_IN_MEMMOVE) == NULL)
 	local_define_builtin ("__builtin_memmove", ftype, BUILT_IN_MEMMOVE,
 			      "memmove", ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_MEMCMP] == NULL)
+  if (BUILT_IN_DECLS (BUILT_IN_MEMCMP) == NULL)
     {
       ftype = build_function_type_list (integer_type_node, const_ptr_type_node,
 					const_ptr_type_node, size_type_node,
@@ -9466,7 +9466,7 @@  build_common_builtin_nodes (void)
 			    "memcmp", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_MEMSET] == NULL)
+  if (BUILT_IN_DECLS (BUILT_IN_MEMSET) == NULL)
     {
       ftype = build_function_type_list (ptr_type_node,
 					ptr_type_node, integer_type_node,
@@ -9475,7 +9475,7 @@  build_common_builtin_nodes (void)
 			    "memset", ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_ALLOCA] == NULL)
+  if (BUILT_IN_DECLS (BUILT_IN_ALLOCA) == NULL)
     {
       ftype = build_function_type_list (ptr_type_node,
 					size_type_node, NULL_TREE);
@@ -9485,7 +9485,7 @@  build_common_builtin_nodes (void)
 
   /* If we're checking the stack, `alloca' can throw.  */
   if (flag_stack_check)
-    TREE_NOTHROW (built_in_decls[BUILT_IN_ALLOCA]) = 0;
+    TREE_NOTHROW (BUILT_IN_DECLS (BUILT_IN_ALLOCA)) = 0;
 
   ftype = build_function_type_list (void_type_node,
 				    ptr_type_node, ptr_type_node,
@@ -9551,7 +9551,7 @@  build_common_builtin_nodes (void)
 			 ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
 			ECF_NORETURN);
 
-  if (built_in_decls[BUILT_IN_RETURN_ADDRESS] == NULL_TREE)
+  if (BUILT_IN_DECLS (BUILT_IN_RETURN_ADDRESS) == NULL_TREE)
     {
       ftype = build_function_type_list (ptr_type_node, integer_type_node,
 					NULL_TREE);
@@ -9561,16 +9561,16 @@  build_common_builtin_nodes (void)
 			    ECF_NOTHROW);
     }
 
-  if (built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER] == NULL_TREE
-      || built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT] == NULL_TREE)
+  if (BUILT_IN_DECLS (BUILT_IN_PROFILE_FUNC_ENTER) == NULL_TREE
+      || BUILT_IN_DECLS (BUILT_IN_PROFILE_FUNC_EXIT) == NULL_TREE)
     {
       ftype = build_function_type_list (void_type_node, ptr_type_node,
 					ptr_type_node, NULL_TREE);
-      if (built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER] == NULL_TREE)
+      if (BUILT_IN_DECLS (BUILT_IN_PROFILE_FUNC_ENTER) == NULL_TREE)
 	local_define_builtin ("__cyg_profile_func_enter", ftype,
 			      BUILT_IN_PROFILE_FUNC_ENTER,
 			      "__cyg_profile_func_enter", 0);
-      if (built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT] == NULL_TREE)
+      if (BUILT_IN_DECLS (BUILT_IN_PROFILE_FUNC_EXIT) == NULL_TREE)
 	local_define_builtin ("__cyg_profile_func_exit", ftype,
 			      BUILT_IN_PROFILE_FUNC_EXIT,
 			      "__cyg_profile_func_exit", 0);
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 178642)
+++ gcc/tree.h	(working copy)
@@ -336,9 +336,70 @@  extern const char * built_in_names[(int)
 #define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R
 #define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL
 
-/* An array of _DECL trees for the above.  */
-extern GTY(()) tree built_in_decls[(int) END_BUILTINS];
-extern GTY(()) tree implicit_built_in_decls[(int) END_BUILTINS];
+/* Functional interface to the builtin functions.  */
+typedef struct GTY(()) built_in_decl_info
+{
+  tree decl;			/* normal declaration for the builtin.  */
+  tree implicit;		/* implicit declaration for the builtin.  */
+} built_in_decl_info;
+
+extern GTY(()) built_in_decl_info built_in_info[(int)END_BUILTINS];
+
+/* Valid builtin number.  */
+#define BUILT_IN_VALID_P(FNCODE) \
+  (IN_RANGE ((int)FNCODE, ((int)BUILT_IN_NONE) + 1, ((int) END_BUILTINS) - 1))
+
+/* Return the tree node for a builtin function or NULL, possibly
+   creating the tree node.  */
+static inline tree
+built_in_get_decl (enum built_in_function fncode, bool implicit_p)
+{
+  built_in_decl_info *info;
+
+  gcc_assert (BUILT_IN_VALID_P (fncode));
+  info = &built_in_info[(int)fncode];
+  return ((implicit_p) ? info->implicit : info->decl);
+}
+
+#define BUILT_IN_DECLS(FNCODE) built_in_get_decl (FNCODE, false)
+#define IMPLICIT_BUILT_IN_DECLS(FNCODE) built_in_get_decl (FNCODE, true)
+
+#define BUILT_IN_DECLS_ADD(FNCODE, ADDEND) \
+  built_in_get_decl ((enum built_in_function)((int)(FNCODE) + (ADDEND)), false)
+
+/* Initialize a builtin function.  */
+static inline void
+built_in_set_decl (enum built_in_function fncode, tree decl, tree implicit)
+{
+  built_in_decl_info *info;
+
+  gcc_assert (BUILT_IN_VALID_P (fncode));
+  info = &built_in_info[(int)fncode];
+  info->decl = decl;
+  info->implicit = implicit;
+}
+
+/* Copy a builtin function.  */
+static inline void
+built_in_copy_decl (enum built_in_function dest, enum built_in_function src)
+{
+  gcc_assert (BUILT_IN_VALID_P (dest));
+  gcc_assert (BUILT_IN_VALID_P (src));
+  built_in_info[(int)dest] = built_in_info[(int)src];
+}
+
+/* Turn off an implicit builtin function, but keep the explict version.  */
+static inline void
+built_in_no_implicit (enum built_in_function fncode)
+{
+  gcc_assert (BUILT_IN_VALID_P (fncode));
+  built_in_info[(int)fncode].implicit = (tree)0;
+}
+
+/* Poison old names.  */
+#if (GCC_VERSION >= 3000) && defined (IN_GCC)
+ #pragma GCC poison built_in_decls implicit_built_in_decls
+#endif
 
 /* In an OMP_CLAUSE node.  */
 
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 178642)
+++ gcc/builtins.c	(working copy)
@@ -75,11 +75,7 @@  const char * built_in_names[(int) END_BU
 
 /* Setup an array of _DECL trees, make sure each element is
    initialized to NULL_TREE.  */
-tree built_in_decls[(int) END_BUILTINS];
-/* Declarations used when constructing the builtin implicitly in the compiler.
-   It may be NULL_TREE when this is invalid (for instance runtime is not
-   required to implement the function call in all cases).  */
-tree implicit_built_in_decls[(int) END_BUILTINS];
+built_in_decl_info built_in_info[(int)END_BUILTINS];
 
 static const char *c_getstr (tree);
 static rtx c_readstr (const char *, enum machine_mode);
@@ -1791,17 +1787,15 @@  expand_builtin_classify_type (tree exp)
   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
   fcodel = BUILT_IN_MATHFN##L_R ; break;
 
-/* Return mathematic function equivalent to FN but operating directly
-   on TYPE, if available.  If IMPLICIT is true find the function in
-   implicit_built_in_decls[], otherwise use built_in_decls[].  If we
-   can't do the conversion, return zero.  */
+/* Return mathematic function equivalent to FN but operating directly on TYPE,
+   if available.  If IMPLICIT is true find the function as an implicit builtin
+   function instead of a normal builtin function.  If we can't do the
+   conversion, return zero.  */
 
 static tree
 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
 {
-  tree const *const fn_arr
-    = implicit ? implicit_built_in_decls : built_in_decls;
-  enum built_in_function fcode, fcodef, fcodel;
+  enum built_in_function fcode, fcodef, fcodel, fcode2;
 
   switch (fn)
     {
@@ -1898,13 +1892,15 @@  mathfn_built_in_1 (tree type, enum built
       }
 
   if (TYPE_MAIN_VARIANT (type) == double_type_node)
-    return fn_arr[fcode];
+    fcode2 = fcode;
   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
-    return fn_arr[fcodef];
+    fcode2 = fcodef;
   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
-    return fn_arr[fcodel];
+    fcode2 = fcodel;
   else
     return NULL_TREE;
+
+  return built_in_get_decl (fcode2, implicit);
 }
 
 /* Like mathfn_built_in_1(), but always use the implicit array.  */
@@ -2552,16 +2548,18 @@  expand_builtin_cexpi (tree exp, rtx targ
       tree call, fn = NULL_TREE;
       tree top1, top2;
       rtx op1a, op2a;
+      enum built_in_function fcode;
 
       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
-	fn = built_in_decls[BUILT_IN_SINCOSF];
+	fcode = BUILT_IN_SINCOSF;
       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
-	fn = built_in_decls[BUILT_IN_SINCOS];
+	fcode = BUILT_IN_SINCOS;
       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
-	fn = built_in_decls[BUILT_IN_SINCOSL];
+	fcode = BUILT_IN_SINCOSL;
       else
 	gcc_unreachable ();
 
+      fn = BUILT_IN_DECLS (fcode);
       op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
       op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
       op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
@@ -2578,16 +2576,19 @@  expand_builtin_cexpi (tree exp, rtx targ
     {
       tree call, fn = NULL_TREE, narg;
       tree ctype = build_complex_type (type);
+      enum built_in_function fcode;
 
       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
-	fn = built_in_decls[BUILT_IN_CEXPF];
+	fcode = BUILT_IN_CEXPF;
       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
-	fn = built_in_decls[BUILT_IN_CEXP];
+	fcode = BUILT_IN_CEXP;
       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
-	fn = built_in_decls[BUILT_IN_CEXPL];
+	fcode = BUILT_IN_CEXPL;
       else
 	gcc_unreachable ();
 
+      fn = BUILT_IN_DECLS (fcode);
+
       /* If we don't have a decl for cexp create one.  This is the
 	 friendliest fallback if the user calls __builtin_cexpi
 	 without full target C99 function support.  */
@@ -3129,9 +3130,9 @@  expand_builtin_mempcpy_args (tree dest, 
 			     rtx target, enum machine_mode mode, int endp)
 {
     /* If return value is ignored, transform mempcpy into memcpy.  */
-  if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
+  if (target == const0_rtx && IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY))
     {
-      tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
       tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
 					   dest, src, len);
       return expand_expr (result, target, mode, EXPAND_NORMAL);
@@ -3292,9 +3293,9 @@  expand_builtin_stpcpy (tree exp, rtx tar
   src = CALL_EXPR_ARG (exp, 1);
 
   /* If return value is ignored, transform stpcpy into strcpy.  */
-  if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
+  if (target == const0_rtx && IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY))
     {
-      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
       tree result = build_call_nofold_loc (loc, fn, 2, dst, src);
       return expand_expr (result, target, mode, EXPAND_NORMAL);
     }
@@ -4353,7 +4354,7 @@  gimplify_va_arg_expr (tree *expr_p, gimp
 	 expression to exit or longjmp.  */
       gimplify_and_add (valist, pre_p);
       t = build_call_expr_loc (loc,
-			       implicit_built_in_decls[BUILT_IN_TRAP], 0);
+			       IMPLICIT_BUILT_IN_DECLS (BUILT_IN_TRAP), 0);
       gimplify_and_add (t, pre_p);
 
       /* This is dead code, but go ahead and finish so that the
@@ -5113,7 +5114,7 @@  expand_builtin_sync_operation (enum mach
 	  if (warned_f_a_n)
 	    break;
 
-	  fndecl = implicit_built_in_decls[BUILT_IN_SYNC_FETCH_AND_NAND_N];
+	  fndecl = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_SYNC_FETCH_AND_NAND_N);
 	  inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
 	  warned_f_a_n = true;
 	  break;
@@ -5127,7 +5128,7 @@  expand_builtin_sync_operation (enum mach
 	  if (warned_n_a_f)
 	    break;
 
-	  fndecl = implicit_built_in_decls[BUILT_IN_SYNC_NAND_AND_FETCH_N];
+	  fndecl = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_SYNC_NAND_AND_FETCH_N);
 	  inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
 	  warned_n_a_f = true;
 	  break;
@@ -6232,7 +6233,7 @@  build_builtin_expect_predicate (location
 {
   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
 
-  fn = built_in_decls[BUILT_IN_EXPECT];
+  fn = BUILT_IN_DECLS (BUILT_IN_EXPECT);
   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
   ret_type = TREE_TYPE (TREE_TYPE (fn));
   pred_type = TREE_VALUE (arg_types);
@@ -8024,7 +8025,7 @@  fold_builtin_memory_op (location_t loc, 
 		  && (MIN (src_align, dest_align) / BITS_PER_UNIT
 		      >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
 	    {
-	      tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+	      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
 	      if (!fn)
 		return NULL_TREE;
               return build_call_expr_loc (loc, fn, 3, dest, src, len);
@@ -8083,7 +8084,7 @@  fold_builtin_memory_op (location_t loc, 
 	      else
 		return NULL_TREE;
 
-	      fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+	      fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
 	      if (!fn)
 		return NULL_TREE;
 	      return build_call_expr_loc (loc, fn, 3, dest, src, len);
@@ -8102,7 +8103,7 @@  fold_builtin_memory_op (location_t loc, 
 	      if (!refs_may_alias_p_1 (&destr, &srcr, false))
 		{
 		  tree fn;
-		  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+		  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
 		  if (!fn)
 		    return NULL_TREE;
 		  return build_call_expr_loc (loc, fn, 3, dest, src, len);
@@ -8277,7 +8278,7 @@  fold_builtin_strcpy (location_t loc, tre
   if (optimize_function_for_size_p (cfun))
     return NULL_TREE;
 
-  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
   if (!fn)
     return NULL_TREE;
 
@@ -8315,7 +8316,7 @@  fold_builtin_stpcpy (location_t loc, tre
       && !integer_zerop (len))
     return NULL_TREE;
 
-  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
   if (!fn)
     return NULL_TREE;
 
@@ -8372,7 +8373,7 @@  fold_builtin_strncpy (location_t loc, tr
     return NULL_TREE;
 
   /* OK transform into builtin memcpy.  */
-  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
   if (!fn)
     return NULL_TREE;
   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
@@ -9193,7 +9194,7 @@  fold_builtin_interclass_mathfn (location
     CASE_FLT_FN (BUILT_IN_ISINF):
       {
 	/* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
-	tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
+	tree const isgr_fn = BUILT_IN_DECLS (BUILT_IN_ISGREATER);
 	tree const type = TREE_TYPE (arg);
 	REAL_VALUE_TYPE r;
 	char buf[128];
@@ -9209,7 +9210,7 @@  fold_builtin_interclass_mathfn (location
     case BUILT_IN_ISFINITE:
       {
 	/* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
-	tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
+	tree const isle_fn = BUILT_IN_DECLS (BUILT_IN_ISLESSEQUAL);
 	tree const type = TREE_TYPE (arg);
 	REAL_VALUE_TYPE r;
 	char buf[128];
@@ -9232,8 +9233,8 @@  fold_builtin_interclass_mathfn (location
       {
 	/* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
 	   islessequal(fabs(x),DBL_MAX).  */
-	tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
-	tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
+	tree const isle_fn = BUILT_IN_DECLS (BUILT_IN_ISLESSEQUAL);
+	tree const isge_fn = BUILT_IN_DECLS (BUILT_IN_ISGREATEREQUAL);
 	tree const type = TREE_TYPE (arg);
 	REAL_VALUE_TYPE rmax, rmin;
 	char buf[128];
@@ -9294,7 +9295,7 @@  fold_builtin_classify (location_t loc, t
 	   1.  So e.g. "if (isinf_sign(x))" would be folded to just
 	   "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
 	tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
-	tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
+	tree isinf_fn = BUILT_IN_DECLS (BUILT_IN_ISINF);
 	tree tmp = NULL_TREE;
 
 	arg = builtin_save_expr (arg);
@@ -10017,7 +10018,7 @@  fold_builtin_2 (location_t loc, tree fnd
     case BUILT_IN_STPCPY:
       if (ignore)
 	{
-	  tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+	  tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
 	  if (!fn)
 	    break;
 
@@ -10817,7 +10818,7 @@  fold_builtin_strstr (location_t loc, tre
       if (p2[1] != '\0')
 	return NULL_TREE;
 
-      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
+      fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCHR);
       if (!fn)
 	return NULL_TREE;
 
@@ -10937,7 +10938,7 @@  fold_builtin_strrchr (location_t loc, tr
       if (! integer_zerop (s2))
 	return NULL_TREE;
 
-      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
+      fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCHR);
       if (!fn)
 	return NULL_TREE;
 
@@ -11001,7 +11002,7 @@  fold_builtin_strpbrk (location_t loc, tr
       if (p2[1] != '\0')
 	return NULL_TREE;  /* Really call strpbrk.  */
 
-      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
+      fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCHR);
       if (!fn)
 	return NULL_TREE;
 
@@ -11048,8 +11049,8 @@  fold_builtin_strcat (location_t loc ATTR
 	{
 	  /* See if we can store by pieces into (dst + strlen(dst)).  */
 	  tree newdst, call;
-	  tree strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
-	  tree strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+	  tree strlen_fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRLEN);
+	  tree strcpy_fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
 
 	  if (!strlen_fn || !strcpy_fn)
 	    return NULL_TREE;
@@ -11122,7 +11123,7 @@  fold_builtin_strncat (location_t loc, tr
       if (TREE_CODE (len) == INTEGER_CST && p
 	  && compare_tree_int (len, strlen (p)) >= 0)
 	{
-	  tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
+	  tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCAT);
 
 	  /* If the replacement _DECL isn't initialized, don't do the
 	     transformation.  */
@@ -11227,7 +11228,7 @@  fold_builtin_strcspn (location_t loc, tr
       /* If the second argument is "", return __builtin_strlen(s1).  */
       if (p2 && *p2 == '\0')
 	{
-	  tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
+	  tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRLEN);
 
 	  /* If the replacement _DECL isn't initialized, don't do the
 	     transformation.  */
@@ -11253,10 +11254,10 @@  fold_builtin_fputs (location_t loc, tree
 {
   /* If we're using an unlocked function, assume the other unlocked
      functions exist explicitly.  */
-  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
-    : implicit_built_in_decls[BUILT_IN_FPUTC];
-  tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
-    : implicit_built_in_decls[BUILT_IN_FWRITE];
+  tree const fn_fputc = unlocked ? BUILT_IN_DECLS (BUILT_IN_FPUTC_UNLOCKED)
+    : IMPLICIT_BUILT_IN_DECLS (BUILT_IN_FPUTC);
+  tree const fn_fwrite = unlocked ? BUILT_IN_DECLS (BUILT_IN_FWRITE_UNLOCKED)
+    : IMPLICIT_BUILT_IN_DECLS (BUILT_IN_FWRITE);
 
   /* If the return value is used, don't do the transformation.  */
   if (!ignore)
@@ -11450,7 +11451,7 @@  fold_builtin_sprintf (location_t loc, tr
   /* If the format doesn't contain % args or %%, use strcpy.  */
   if (strchr (fmt_str, target_percent) == NULL)
     {
-      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
 
       if (!fn)
 	return NULL_TREE;
@@ -11470,7 +11471,7 @@  fold_builtin_sprintf (location_t loc, tr
   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
     {
       tree fn;
-      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+      fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
 
       if (!fn)
 	return NULL_TREE;
@@ -11491,9 +11492,8 @@  fold_builtin_sprintf (location_t loc, tr
 
   if (call && retval)
     {
-      retval = fold_convert_loc
-	(loc, TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
-	 retval);
+      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_SPRINTF);
+      retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
     }
   else
@@ -11545,7 +11545,7 @@  fold_builtin_snprintf (location_t loc, t
   /* If the format doesn't contain % args or %%, use strcpy.  */
   if (strchr (fmt_str, target_percent) == NULL)
     {
-      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
       size_t len = strlen (fmt_str);
 
       /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
@@ -11577,7 +11577,7 @@  fold_builtin_snprintf (location_t loc, t
   /* If the format is "%s", use strcpy if the result isn't used.  */
   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
     {
-      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+      tree fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STRCPY);
       unsigned HOST_WIDE_INT origlen;
 
       /* Don't crash on snprintf (str1, cst, "%s").  */
@@ -11612,7 +11612,7 @@  fold_builtin_snprintf (location_t loc, t
 
   if (call && retval)
     {
-      tree fn = built_in_decls[BUILT_IN_SNPRINTF];
+      tree fn = BUILT_IN_DECLS (BUILT_IN_SNPRINTF);
       retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
     }
@@ -11700,16 +11700,16 @@  expand_builtin_memory_chk (tree exp, rtx
       switch (fcode)
 	{
 	case BUILT_IN_MEMCPY_CHK:
-	  fn = built_in_decls[BUILT_IN_MEMCPY];
+	  fn = BUILT_IN_DECLS (BUILT_IN_MEMCPY);
 	  break;
 	case BUILT_IN_MEMPCPY_CHK:
-	  fn = built_in_decls[BUILT_IN_MEMPCPY];
+	  fn = BUILT_IN_DECLS (BUILT_IN_MEMPCPY);
 	  break;
 	case BUILT_IN_MEMMOVE_CHK:
-	  fn = built_in_decls[BUILT_IN_MEMMOVE];
+	  fn = BUILT_IN_DECLS (BUILT_IN_MEMMOVE);
 	  break;
 	case BUILT_IN_MEMSET_CHK:
-	  fn = built_in_decls[BUILT_IN_MEMSET];
+	  fn = BUILT_IN_DECLS (BUILT_IN_MEMSET);
 	  break;
 	default:
 	  break;
@@ -11761,7 +11761,7 @@  expand_builtin_memory_chk (tree exp, rtx
 	     normal __memcpy_chk.  */
 	  if (readonly_data_expr (src))
 	    {
-	      tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
+	      tree fn = BUILT_IN_DECLS (BUILT_IN_MEMCPY_CHK);
 	      if (!fn)
 		return NULL_RTX;
 	      fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4,
@@ -12025,7 +12025,7 @@  fold_builtin_memory_chk (location_t loc,
 		{
 		  /* (void) __mempcpy_chk () can be optimized into
 		     (void) __memcpy_chk ().  */
-		  fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
+		  fn = BUILT_IN_DECLS (BUILT_IN_MEMCPY_CHK);
 		  if (!fn)
 		    return NULL_TREE;
 
@@ -12047,16 +12047,16 @@  fold_builtin_memory_chk (location_t loc,
   switch (fcode)
     {
     case BUILT_IN_MEMCPY_CHK:
-      fn = built_in_decls[BUILT_IN_MEMCPY];
+      fn = BUILT_IN_DECLS (BUILT_IN_MEMCPY);
       break;
     case BUILT_IN_MEMPCPY_CHK:
-      fn = built_in_decls[BUILT_IN_MEMPCPY];
+      fn = BUILT_IN_DECLS (BUILT_IN_MEMPCPY);
       break;
     case BUILT_IN_MEMMOVE_CHK:
-      fn = built_in_decls[BUILT_IN_MEMMOVE];
+      fn = BUILT_IN_DECLS (BUILT_IN_MEMMOVE);
       break;
     case BUILT_IN_MEMSET_CHK:
-      fn = built_in_decls[BUILT_IN_MEMSET];
+      fn = BUILT_IN_DECLS (BUILT_IN_MEMSET);
       break;
     default:
       break;
@@ -12111,7 +12111,7 @@  fold_builtin_stxcpy_chk (location_t loc,
 
 		  /* If return value of __stpcpy_chk is ignored,
 		     optimize into __strcpy_chk.  */
-		  fn = built_in_decls[BUILT_IN_STRCPY_CHK];
+		  fn = BUILT_IN_DECLS (BUILT_IN_STRCPY_CHK);
 		  if (!fn)
 		    return NULL_TREE;
 
@@ -12123,7 +12123,7 @@  fold_builtin_stxcpy_chk (location_t loc,
 
 	      /* If c_strlen returned something, but not a constant,
 		 transform __strcpy_chk into __memcpy_chk.  */
-	      fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
+	      fn = BUILT_IN_DECLS (BUILT_IN_MEMCPY_CHK);
 	      if (!fn)
 		return NULL_TREE;
 
@@ -12141,8 +12141,8 @@  fold_builtin_stxcpy_chk (location_t loc,
     }
 
   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
-  fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
-		      ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
+  fn = BUILT_IN_DECLS (fcode == BUILT_IN_STPCPY_CHK
+		       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
   if (!fn)
     return NULL_TREE;
 
@@ -12186,7 +12186,7 @@  fold_builtin_strncpy_chk (location_t loc
     }
 
   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
-  fn = built_in_decls[BUILT_IN_STRNCPY];
+  fn = BUILT_IN_DECLS (BUILT_IN_STRNCPY);
   if (!fn)
     return NULL_TREE;
 
@@ -12217,7 +12217,7 @@  fold_builtin_strcat_chk (location_t loc,
     return NULL_TREE;
 
   /* If __builtin_strcat_chk is used, assume strcat is available.  */
-  fn = built_in_decls[BUILT_IN_STRCAT];
+  fn = BUILT_IN_DECLS (BUILT_IN_STRCAT);
   if (!fn)
     return NULL_TREE;
 
@@ -12259,7 +12259,7 @@  fold_builtin_strncat_chk (location_t loc
 	  && ! tree_int_cst_lt (len, src_len))
 	{
 	  /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
-	  fn = built_in_decls[BUILT_IN_STRCAT_CHK];
+	  fn = BUILT_IN_DECLS (BUILT_IN_STRCAT_CHK);
 	  if (!fn)
 	    return NULL_TREE;
 
@@ -12269,7 +12269,7 @@  fold_builtin_strncat_chk (location_t loc
     }
 
   /* If __builtin_strncat_chk is used, assume strncat is available.  */
-  fn = built_in_decls[BUILT_IN_STRNCAT];
+  fn = BUILT_IN_DECLS (BUILT_IN_STRNCAT);
   if (!fn)
     return NULL_TREE;
 
@@ -12360,8 +12360,8 @@  fold_builtin_sprintf_chk_1 (location_t l
     }
 
   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
-  fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
-		      ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
+  fn = BUILT_IN_DECLS (fcode == BUILT_IN_VSPRINTF_CHK
+		       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
   if (!fn)
     return NULL_TREE;
 
@@ -12449,8 +12449,8 @@  fold_builtin_snprintf_chk_1 (location_t 
 
   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
      available.  */
-  fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
-		      ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
+  fn = BUILT_IN_DECLS (fcode == BUILT_IN_VSNPRINTF_CHK
+		       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
   if (!fn)
     return NULL_TREE;
 
@@ -12504,13 +12504,13 @@  fold_builtin_printf (location_t loc, tre
     {
       /* If we're using an unlocked function, assume the other
 	 unlocked functions exist explicitly.  */
-      fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
-      fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
+      fn_putchar = BUILT_IN_DECLS (BUILT_IN_PUTCHAR_UNLOCKED);
+      fn_puts = BUILT_IN_DECLS (BUILT_IN_PUTS_UNLOCKED);
     }
   else
     {
-      fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
-      fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
+      fn_putchar = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_PUTCHAR);
+      fn_puts = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_PUTS);
     }
 
   if (!init_target_chars ())
@@ -12655,13 +12655,13 @@  fold_builtin_fprintf (location_t loc, tr
     {
       /* If we're using an unlocked function, assume the other
 	 unlocked functions exist explicitly.  */
-      fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
-      fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
+      fn_fputc = BUILT_IN_DECLS (BUILT_IN_FPUTC_UNLOCKED);
+      fn_fputs = BUILT_IN_DECLS (BUILT_IN_FPUTS_UNLOCKED);
     }
   else
     {
-      fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
-      fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
+      fn_fputc = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_FPUTC);
+      fn_fputs = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_FPUTS);
     }
 
   if (!init_target_chars ())
@@ -13463,9 +13463,9 @@  fold_call_stmt (gimple stmt, bool ignore
   return NULL_TREE;
 }
 
-/* Look up the function in built_in_decls that corresponds to DECL
-   and set ASMSPEC as its user assembler name.  DECL must be a
-   function decl that declares a builtin.  */
+/* Look up the function in built_in_decl_info that corresponds to DECL and set
+   ASMSPEC as its user assembler name.  DECL must be a function decl that
+   declares a builtin.  */
 
 void
 set_builtin_user_assembler_name (tree decl, const char *asmspec)
@@ -13475,7 +13475,7 @@  set_builtin_user_assembler_name (tree de
 	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
 	      && asmspec != 0);
 
-  builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
+  builtin = BUILT_IN_DECLS (DECL_FUNCTION_CODE (decl));
   set_user_assembler_name (builtin, asmspec);
   switch (DECL_FUNCTION_CODE (decl))
     {
Index: gcc/tree-emutls.c
===================================================================
--- gcc/tree-emutls.c	(revision 178642)
+++ gcc/tree-emutls.c	(working copy)
@@ -387,7 +387,7 @@  emutls_common_1 (tree tls_decl, tree con
 
   word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
 
-  x = build_call_expr (built_in_decls[BUILT_IN_EMUTLS_REGISTER_COMMON], 4,
+  x = build_call_expr (BUILT_IN_DECLS (BUILT_IN_EMUTLS_REGISTER_COMMON), 4,
 		       build_fold_addr_expr (control_decl),
 		       fold_convert (word_type_node,
 				     DECL_SIZE_UNIT (tls_decl)),
@@ -622,7 +622,7 @@  lower_emutls_function_body (struct cgrap
   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
 
   d.cfun_node = node;
-  d.builtin_decl = built_in_decls[BUILT_IN_EMUTLS_GET_ADDRESS];
+  d.builtin_decl = BUILT_IN_DECLS (BUILT_IN_EMUTLS_GET_ADDRESS);
   /* This is where we introduce the declaration to the IL and so we have to
      create a node for it.  */
   d.builtin_node = cgraph_get_create_node (d.builtin_decl);
Index: gcc/omp-low.c
===================================================================
--- gcc/omp-low.c	(revision 178642)
+++ gcc/omp-low.c	(working copy)
@@ -2059,7 +2059,7 @@  scan_omp (gimple_seq body, omp_context *
 static tree
 build_omp_barrier (void)
 {
-  return build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
+  return build_call_expr (BUILT_IN_DECLS (BUILT_IN_GOMP_BARRIER), 0);
 }
 
 /* If a context was created for STMT when it was scanned, return it.  */
@@ -2309,8 +2309,8 @@  lower_rec_input_clauses (tree clauses, g
 		  x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
 
 		  /* void *tmp = __builtin_alloca */
-		  stmt
-		    = gimple_build_call (built_in_decls[BUILT_IN_ALLOCA], 1, x);
+		  stmt = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_ALLOCA),
+					    1, x);
 		  tmp = create_tmp_var_raw (ptr_type_node, NULL);
 		  gimple_add_tmp_var (tmp);
 		  gimple_call_set_lhs (stmt, tmp);
@@ -2355,7 +2355,8 @@  lower_rec_input_clauses (tree clauses, g
 	      else
 		{
 		  x = build_call_expr_loc (clause_loc,
-				       built_in_decls[BUILT_IN_ALLOCA], 1, x);
+					   BUILT_IN_DECLS (BUILT_IN_ALLOCA),
+					   1, x);
 		}
 
 	      x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
@@ -2493,7 +2494,7 @@  lower_rec_input_clauses (tree clauses, g
      but it certainly is to C++ operator=.  */
   if (copyin_seq)
     {
-      x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
+      x = build_call_expr (BUILT_IN_DECLS (BUILT_IN_OMP_GET_THREAD_NUM), 0);
       x = build2 (NE_EXPR, boolean_type_node, x,
 		  build_int_cst (TREE_TYPE (x), 0));
       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
@@ -2688,12 +2689,12 @@  lower_reduction_clauses (tree clauses, g
 	}
     }
 
-  stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
+  stmt = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_GOMP_ATOMIC_START), 0);
   gimple_seq_add_stmt (stmt_seqp, stmt);
 
   gimple_seq_add_seq (stmt_seqp, sub_seq);
 
-  stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
+  stmt = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_GOMP_ATOMIC_END), 0);
   gimple_seq_add_stmt (stmt_seqp, stmt);
 }
 
@@ -2917,9 +2918,10 @@  expand_parallel_call (struct omp_region 
   tree t, t1, t2, val, cond, c, clauses;
   gimple_stmt_iterator gsi;
   gimple stmt;
-  int start_ix;
+  enum built_in_function start_ix;
   location_t clause_loc;
   VEC(tree,gc) *args;
+  int ix;
 
   clauses = gimple_omp_parallel_clauses (entry_stmt);
 
@@ -2932,10 +2934,10 @@  expand_parallel_call (struct omp_region 
 	{
 	case GIMPLE_OMP_FOR:
 	  gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
-	  start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
-		     + (region->inner->sched_kind
-			== OMP_CLAUSE_SCHEDULE_RUNTIME
-			? 3 : region->inner->sched_kind);
+	  ix = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
+		+ ((region->inner->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
+		   ? 3 : region->inner->sched_kind));
+	  start_ix = (enum built_in_function)ix;
 	  break;
 	case GIMPLE_OMP_SECTIONS:
 	  start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
@@ -3057,7 +3059,7 @@  expand_parallel_call (struct omp_region 
   VEC_splice (tree, args, ws_args);
 
   t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
-			       built_in_decls[start_ix], args);
+			       BUILT_IN_DECLS (start_ix), args);
 
   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
 			    false, GSI_CONTINUE_LINKING);
@@ -3073,7 +3075,7 @@  expand_parallel_call (struct omp_region 
 			    false, GSI_CONTINUE_LINKING);
 
   t = build_call_expr_loc (gimple_location (entry_stmt),
-			   built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
+			   BUILT_IN_DECLS (BUILT_IN_GOMP_PARALLEL_END), 0);
   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
 			    false, GSI_CONTINUE_LINKING);
 }
@@ -3125,7 +3127,7 @@  expand_task_call (basic_block bb, gimple
   else
     t3 = build_fold_addr_expr_loc (loc, t);
 
-  t = build_call_expr (built_in_decls[BUILT_IN_GOMP_TASK], 7, t1, t2, t3,
+  t = build_call_expr (BUILT_IN_DECLS (BUILT_IN_GOMP_TASK), 7, t1, t2, t3,
 		       gimple_omp_task_arg_size (entry_stmt),
 		       gimple_omp_task_arg_align (entry_stmt), cond, flags);
 
@@ -3150,7 +3152,7 @@  maybe_catch_exception (gimple_seq body)
   if (lang_hooks.eh_protect_cleanup_actions != NULL)
     decl = lang_hooks.eh_protect_cleanup_actions ();
   else
-    decl = built_in_decls[BUILT_IN_TRAP];
+    decl = BUILT_IN_DECLS (BUILT_IN_TRAP);
 
   g = gimple_build_eh_must_not_throw (decl);
   g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
@@ -3298,9 +3300,9 @@  optimize_omp_library_calls (gimple entry
   basic_block bb;
   gimple_stmt_iterator gsi;
   tree thr_num_id
-    = DECL_ASSEMBLER_NAME (built_in_decls [BUILT_IN_OMP_GET_THREAD_NUM]);
+    = DECL_ASSEMBLER_NAME (BUILT_IN_DECLS (BUILT_IN_OMP_GET_THREAD_NUM));
   tree num_thr_id
-    = DECL_ASSEMBLER_NAME (built_in_decls [BUILT_IN_OMP_GET_NUM_THREADS]);
+    = DECL_ASSEMBLER_NAME (BUILT_IN_DECLS (BUILT_IN_OMP_GET_NUM_THREADS));
   bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
 		      && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
 					  OMP_CLAUSE_UNTIED) != NULL);
@@ -3325,10 +3327,10 @@  optimize_omp_library_calls (gimple entry
 		   during the execution of the task region.  */
 		if (untied_task)
 		  continue;
-		built_in = built_in_decls [BUILT_IN_OMP_GET_THREAD_NUM];
+		built_in = BUILT_IN_DECLS (BUILT_IN_OMP_GET_THREAD_NUM);
 	      }
 	    else if (DECL_NAME (decl) == num_thr_id)
-	      built_in = built_in_decls [BUILT_IN_OMP_GET_NUM_THREADS];
+	      built_in = BUILT_IN_DECLS (BUILT_IN_OMP_GET_NUM_THREADS);
 	    else
 	      continue;
 
@@ -3812,7 +3814,7 @@  expand_omp_for_generic (struct omp_regio
     {
       /* In a combined parallel loop, emit a call to
 	 GOMP_loop_foo_next.  */
-      t = build_call_expr (built_in_decls[next_fn], 2,
+      t = build_call_expr (BUILT_IN_DECLS (next_fn), 2,
 			   build_fold_addr_expr (istart0),
 			   build_fold_addr_expr (iend0));
     }
@@ -3848,11 +3850,11 @@  expand_omp_for_generic (struct omp_regio
 	  if (fd->chunk_size)
 	    {
 	      t = fold_convert (fd->iter_type, fd->chunk_size);
-	      t = build_call_expr (built_in_decls[start_fn], 6,
+	      t = build_call_expr (BUILT_IN_DECLS (start_fn), 6,
 				   t0, t1, t2, t, t3, t4);
 	    }
 	  else
-	    t = build_call_expr (built_in_decls[start_fn], 5,
+	    t = build_call_expr (BUILT_IN_DECLS (start_fn), 5,
 				 t0, t1, t2, t3, t4);
 	}
       else
@@ -3864,17 +3866,17 @@  expand_omp_for_generic (struct omp_regio
 	     argument, true for < loops and false for > loops.
 	     In Fortran, the C bool type can be different from
 	     boolean_type_node.  */
-	  c_bool_type = TREE_TYPE (TREE_TYPE (built_in_decls[start_fn]));
+	  c_bool_type = TREE_TYPE (TREE_TYPE (BUILT_IN_DECLS (start_fn)));
 	  t5 = build_int_cst (c_bool_type,
 			      fd->loop.cond_code == LT_EXPR ? 1 : 0);
 	  if (fd->chunk_size)
 	    {
 	      t = fold_convert (fd->iter_type, fd->chunk_size);
-	      t = build_call_expr (built_in_decls[start_fn], 7,
+	      t = build_call_expr (BUILT_IN_DECLS (start_fn), 7,
 				   t5, t0, t1, t2, t, t3, t4);
 	    }
 	  else
-	    t = build_call_expr (built_in_decls[start_fn], 6,
+	    t = build_call_expr (BUILT_IN_DECLS (start_fn), 6,
 				 t5, t0, t1, t2, t3, t4);
 	}
     }
@@ -4031,7 +4033,7 @@  expand_omp_for_generic (struct omp_regio
       /* Emit code to get the next parallel iteration in L2_BB.  */
       gsi = gsi_start_bb (l2_bb);
 
-      t = build_call_expr (built_in_decls[next_fn], 2,
+      t = build_call_expr (BUILT_IN_DECLS (next_fn), 2,
 			   build_fold_addr_expr (istart0),
 			   build_fold_addr_expr (iend0));
       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
@@ -4046,9 +4048,9 @@  expand_omp_for_generic (struct omp_regio
   /* Add the loop cleanup function.  */
   gsi = gsi_last_bb (exit_bb);
   if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
-    t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
+    t = BUILT_IN_DECLS (BUILT_IN_GOMP_LOOP_END_NOWAIT);
   else
-    t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
+    t = BUILT_IN_DECLS (BUILT_IN_GOMP_LOOP_END);
   stmt = gimple_build_call (t, 0);
   gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
   gsi_remove (&gsi, true);
@@ -4169,12 +4171,12 @@  expand_omp_for_static_nochunk (struct om
   gsi = gsi_last_bb (entry_bb);
   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
 
-  t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
+  t = build_call_expr (BUILT_IN_DECLS (BUILT_IN_OMP_GET_NUM_THREADS), 0);
   t = fold_convert (itype, t);
   nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
 				       true, GSI_SAME_STMT);
 
-  t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
+  t = build_call_expr (BUILT_IN_DECLS (BUILT_IN_OMP_GET_THREAD_NUM), 0);
   t = fold_convert (itype, t);
   threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
 				       true, GSI_SAME_STMT);
@@ -4391,12 +4393,12 @@  expand_omp_for_static_chunk (struct omp_
   si = gsi_last_bb (entry_bb);
   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
 
-  t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
+  t = build_call_expr (BUILT_IN_DECLS (BUILT_IN_OMP_GET_NUM_THREADS), 0);
   t = fold_convert (itype, t);
   nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
 				       true, GSI_SAME_STMT);
 
-  t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
+  t = build_call_expr (BUILT_IN_DECLS(BUILT_IN_OMP_GET_THREAD_NUM), 0);
   t = fold_convert (itype, t);
   threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
 				       true, GSI_SAME_STMT);
@@ -4778,13 +4780,13 @@  expand_omp_sections (struct omp_region *
 	 call GOMP_sections_start.  */
       t = build_int_cst (unsigned_type_node,
 			 exit_reachable ? len - 1 : len);
-      u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
+      u = BUILT_IN_DECLS (BUILT_IN_GOMP_SECTIONS_START);
       stmt = gimple_build_call (u, 1, t);
     }
   else
     {
       /* Otherwise, call GOMP_sections_next.  */
-      u = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
+      u = BUILT_IN_DECLS (BUILT_IN_GOMP_SECTIONS_NEXT);
       stmt = gimple_build_call (u, 0);
     }
   gimple_call_set_lhs (stmt, vin);
@@ -4866,7 +4868,7 @@  expand_omp_sections (struct omp_region *
   VEC_free (tree, heap, label_vec);
 
   si = gsi_start_bb (default_bb);
-  stmt = gimple_build_call (built_in_decls[BUILT_IN_TRAP], 0);
+  stmt = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_TRAP), 0);
   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
 
   if (exit_reachable)
@@ -4875,7 +4877,7 @@  expand_omp_sections (struct omp_region *
       si = gsi_last_bb (l1_bb);
       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
 
-      stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
+      stmt = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_GOMP_SECTIONS_NEXT), 0);
       gimple_call_set_lhs (stmt, vnext);
       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
       gsi_remove (&si, true);
@@ -4885,9 +4887,9 @@  expand_omp_sections (struct omp_region *
       /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
       si = gsi_last_bb (l2_bb);
       if (gimple_omp_return_nowait_p (gsi_stmt (si)))
-	t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
+	t = BUILT_IN_DECLS (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
       else
-	t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
+	t = BUILT_IN_DECLS (BUILT_IN_GOMP_SECTIONS_END);
       stmt = gimple_build_call (t, 0);
       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
       gsi_remove (&si, true);
@@ -5085,7 +5087,7 @@  expand_omp_atomic_fetch_op (basic_block 
   else
     return false;
 
-  decl = built_in_decls[(need_new ? newbase : oldbase) + index + 1];
+  decl = BUILT_IN_DECLS_ADD ((need_new ? newbase : oldbase), index + 1);
   if (decl == NULL_TREE)
     return false;
   itype = TREE_TYPE (TREE_TYPE (decl));
@@ -5167,7 +5169,8 @@  expand_omp_atomic_pipeline (basic_block 
   gimple phi, stmt;
   edge e;
 
-  cmpxchg = built_in_decls[BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N + index + 1];
+  cmpxchg = BUILT_IN_DECLS_ADD (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N,
+				index + 1);
   if (cmpxchg == NULL_TREE)
     return false;
   type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
@@ -5355,7 +5358,7 @@  expand_omp_atomic_mutex (basic_block loa
   si = gsi_last_bb (load_bb);
   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
 
-  t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
+  t = BUILT_IN_DECLS (BUILT_IN_GOMP_ATOMIC_START);
   t = build_call_expr (t, 0);
   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
 
@@ -5370,7 +5373,7 @@  expand_omp_atomic_mutex (basic_block loa
 			      stored_val);
   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
 
-  t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
+  t = BUILT_IN_DECLS (BUILT_IN_GOMP_ATOMIC_END);
   t = build_call_expr (t, 0);
   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
   gsi_remove (&si, true);
@@ -5806,7 +5809,7 @@  lower_omp_single_simple (gimple single_s
   gimple call, cond;
   tree lhs, decl;
 
-  decl = built_in_decls[BUILT_IN_GOMP_SINGLE_START];
+  decl = BUILT_IN_DECLS (BUILT_IN_GOMP_SINGLE_START);
   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
   call = gimple_build_call (decl, 0);
   gimple_call_set_lhs (call, lhs);
@@ -5855,7 +5858,7 @@  lower_omp_single_simple (gimple single_s
 static void
 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
 {
-  tree ptr_type, t, l0, l1, l2;
+  tree ptr_type, t, l0, l1, l2, bfn;
   gimple_seq copyin_seq;
   location_t loc = gimple_location (single_stmt);
 
@@ -5868,7 +5871,8 @@  lower_omp_single_copy (gimple single_stm
   l1 = create_artificial_label (loc);
   l2 = create_artificial_label (loc);
 
-  t = build_call_expr_loc (loc, built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
+  bfn = BUILT_IN_DECLS (BUILT_IN_GOMP_SINGLE_COPY_START);
+  t = build_call_expr_loc (loc, bfn, 0);
   t = fold_convert_loc (loc, ptr_type, t);
   gimplify_assign (ctx->receiver_decl, t, pre_p);
 
@@ -5887,8 +5891,8 @@  lower_omp_single_copy (gimple single_stm
 			      &copyin_seq, ctx);
 
   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
-  t = build_call_expr_loc (loc, built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END],
-		       1, t);
+  bfn = BUILT_IN_DECLS (BUILT_IN_GOMP_SINGLE_COPY_END);
+  t = build_call_expr_loc (loc, bfn, 1, t);
   gimplify_and_add (t, pre_p);
 
   t = build_and_jump (&l2);
@@ -5955,7 +5959,7 @@  lower_omp_single (gimple_stmt_iterator *
 static void
 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 {
-  tree block, lab = NULL, x;
+  tree block, lab = NULL, x, bfn;
   gimple stmt = gsi_stmt (*gsi_p), bind;
   location_t loc = gimple_location (stmt);
   gimple_seq tseq;
@@ -5967,7 +5971,8 @@  lower_omp_master (gimple_stmt_iterator *
   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
       				 block);
 
-  x = build_call_expr_loc (loc, built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
+  bfn = BUILT_IN_DECLS (BUILT_IN_OMP_GET_THREAD_NUM);
+  x = build_call_expr_loc (loc, bfn, 0);
   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
   tseq = NULL;
@@ -6006,7 +6011,7 @@  lower_omp_ordered (gimple_stmt_iterator 
   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
       				   block);
 
-  x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
+  x = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_GOMP_ORDERED_START), 0);
   gimple_bind_add_stmt (bind, x);
 
   lower_omp (gimple_omp_body (stmt), ctx);
@@ -6014,7 +6019,7 @@  lower_omp_ordered (gimple_stmt_iterator 
   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   gimple_omp_set_body (stmt, NULL);
 
-  x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
+  x = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_GOMP_ORDERED_END), 0);
   gimple_bind_add_stmt (bind, x);
 
   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
@@ -6080,19 +6085,19 @@  lower_omp_critical (gimple_stmt_iterator
       else
 	decl = (tree) n->value;
 
-      lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
+      lock = BUILT_IN_DECLS (BUILT_IN_GOMP_CRITICAL_NAME_START);
       lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
 
-      unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
+      unlock = BUILT_IN_DECLS (BUILT_IN_GOMP_CRITICAL_NAME_END);
       unlock = build_call_expr_loc (loc, unlock, 1,
 				build_fold_addr_expr_loc (loc, decl));
     }
   else
     {
-      lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
+      lock = BUILT_IN_DECLS (BUILT_IN_GOMP_CRITICAL_START);
       lock = build_call_expr_loc (loc, lock, 0);
 
-      unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
+      unlock = BUILT_IN_DECLS (BUILT_IN_GOMP_CRITICAL_END);
       unlock = build_call_expr_loc (loc, unlock, 0);
     }
 
Index: gcc/objc/objc-next-runtime-abi-01.c
===================================================================
--- gcc/objc/objc-next-runtime-abi-01.c	(revision 178642)
+++ gcc/objc/objc-next-runtime-abi-01.c	(working copy)
@@ -2919,7 +2919,7 @@  objc_build_exc_ptr (struct objc_try_cont
   else
     {
       tree t;
-      t = built_in_decls[BUILT_IN_EH_POINTER];
+      t = BUILT_IN_DECLS (BUILT_IN_EH_POINTER);
       t = build_call_expr (t, 1, integer_zero_node);
       return fold_convert (objc_object_type, t);
     }
Index: gcc/objc/objc-next-runtime-abi-02.c
===================================================================
--- gcc/objc/objc-next-runtime-abi-02.c	(revision 178642)
+++ gcc/objc/objc-next-runtime-abi-02.c	(working copy)
@@ -3676,7 +3676,7 @@  static tree
 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
 {
   tree t;
-  t = built_in_decls[BUILT_IN_EH_POINTER];
+  t = BUILT_IN_DECLS (BUILT_IN_EH_POINTER);
   t = build_call_expr (t, 1, integer_zero_node);
   return fold_convert (objc_object_type, t);
 }
Index: gcc/objc/objc-gnu-runtime-abi-01.c
===================================================================
--- gcc/objc/objc-gnu-runtime-abi-01.c	(revision 178642)
+++ gcc/objc/objc-gnu-runtime-abi-01.c	(working copy)
@@ -2226,7 +2226,7 @@  static tree
 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
 {
   tree t;
-  t = built_in_decls[BUILT_IN_EH_POINTER];
+  t = BUILT_IN_DECLS (BUILT_IN_EH_POINTER);
   t = build_call_expr (t, 1, integer_zero_node);
   return fold_convert (objc_object_type, t);
 }
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 178699)
+++ gcc/cp/decl.c	(working copy)
@@ -1187,7 +1187,7 @@  duplicate_decls (tree newdecl, tree oldd
   unsigned olddecl_uid = DECL_UID (olddecl);
   int olddecl_friend = 0, types_match = 0, hidden_friend = 0;
   int new_defines_function = 0;
-  tree new_template_info;
+  tree new_template_info, bfn;
 
   if (newdecl == olddecl)
     return olddecl;
@@ -1358,10 +1358,10 @@  duplicate_decls (tree newdecl, tree oldd
 	  && DECL_ANTICIPATED (olddecl)
 	  && TREE_NOTHROW (newdecl)
 	  && !TREE_NOTHROW (olddecl)
-	  && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != NULL_TREE
-	  && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != olddecl
+	  && (bfn = BUILT_IN_DECLS (DECL_FUNCTION_CODE (olddecl))) != NULL_TREE
+	  && bfn != olddecl
 	  && types_match)
-	TREE_NOTHROW (built_in_decls [DECL_FUNCTION_CODE (olddecl)]) = 1;
+	TREE_NOTHROW (bfn) = 1;
 
       /* Whether or not the builtin can throw exceptions has no
 	 bearing on this declarator.  */
Index: gcc/cp/except.c
===================================================================
--- gcc/cp/except.c	(revision 178642)
+++ gcc/cp/except.c	(working copy)
@@ -140,7 +140,7 @@  build_eh_type_type (tree type)
 tree
 build_exc_ptr (void)
 {
-  return build_call_n (built_in_decls [BUILT_IN_EH_POINTER],
+  return build_call_n (BUILT_IN_DECLS (BUILT_IN_EH_POINTER),
 		       1, integer_zero_node);
 }
 
@@ -333,7 +333,7 @@  choose_personality_routine (enum languag
 
     case lang_java:
       state = chose_java;
-      terminate_node = built_in_decls [BUILT_IN_ABORT];
+      terminate_node = BUILT_IN_DECLS (BUILT_IN_ABORT);
       pragma_java_exceptions = true;
       break;
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 178643)
+++ gcc/cp/semantics.c	(working copy)
@@ -4797,7 +4797,7 @@  finish_omp_atomic (enum tree_code code, 
 void
 finish_omp_barrier (void)
 {
-  tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
+  tree fn = BUILT_IN_DECLS (BUILT_IN_GOMP_BARRIER);
   VEC(tree,gc) *vec = make_tree_vector ();
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
   release_tree_vector (vec);
@@ -4807,7 +4807,7 @@  finish_omp_barrier (void)
 void
 finish_omp_flush (void)
 {
-  tree fn = built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE];
+  tree fn = BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE);
   VEC(tree,gc) *vec = make_tree_vector ();
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
   release_tree_vector (vec);
@@ -4817,7 +4817,7 @@  finish_omp_flush (void)
 void
 finish_omp_taskwait (void)
 {
-  tree fn = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
+  tree fn = BUILT_IN_DECLS (BUILT_IN_GOMP_TASKWAIT);
   VEC(tree,gc) *vec = make_tree_vector ();
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
   release_tree_vector (vec);
@@ -4827,7 +4827,7 @@  finish_omp_taskwait (void)
 void
 finish_omp_taskyield (void)
 {
-  tree fn = built_in_decls[BUILT_IN_GOMP_TASKYIELD];
+  tree fn = BUILT_IN_DECLS (BUILT_IN_GOMP_TASKYIELD);
   VEC(tree,gc) *vec = make_tree_vector ();
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
   release_tree_vector (vec);
Index: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c	(revision 178643)
+++ gcc/tree-ssa-ccp.c	(working copy)
@@ -2161,7 +2161,7 @@  optimize_stdarg_builtin (gimple call)
     case BUILT_IN_VA_START:
       if (!va_list_simple_ptr
 	  || targetm.expand_builtin_va_start != NULL
-          || built_in_decls[BUILT_IN_NEXT_ARG] == NULL)
+          || BUILT_IN_DECLS (BUILT_IN_NEXT_ARG) == NULL)
 	return NULL_TREE;
 
       if (gimple_call_num_args (call) != 2)
@@ -2174,7 +2174,7 @@  optimize_stdarg_builtin (gimple call)
 	return NULL_TREE;
 
       lhs = build_fold_indirect_ref_loc (loc, lhs);
-      rhs = build_call_expr_loc (loc, built_in_decls[BUILT_IN_NEXT_ARG],
+      rhs = build_call_expr_loc (loc, BUILT_IN_DECLS (BUILT_IN_NEXT_ARG),
                              1, integer_zero_node);
       rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
       return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 178642)
+++ gcc/builtins.def	(working copy)
@@ -173,6 +173,9 @@  along with GCC; see the file COPYING3.  
 #undef ATTR_MATHFN_FPROUNDING_STORE
 #define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LEAF_LIST
 
+/* Make sure 0 is not a legitimate builtin index.  */
+DEF_BUILTIN_STUB (BUILT_IN_NONE, (const char *)0)
+
 /* Category: math builtins.  */
 DEF_LIB_BUILTIN        (BUILT_IN_ACOS, "acos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSF, "acosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 178642)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -1803,9 +1803,9 @@  execute_optimize_bswap (void)
   if (sizeof (HOST_WIDEST_INT) < 8)
     return 0;
 
-  bswap32_p = (built_in_decls[BUILT_IN_BSWAP32]
+  bswap32_p = (BUILT_IN_DECLS (BUILT_IN_BSWAP32)
 	       && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing);
-  bswap64_p = (built_in_decls[BUILT_IN_BSWAP64]
+  bswap64_p = (BUILT_IN_DECLS (BUILT_IN_BSWAP64)
 	       && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing
 		   || (bswap32_p && word_mode == SImode)));
 
@@ -1816,13 +1816,13 @@  execute_optimize_bswap (void)
      assumes that the return and argument type are the same.  */
   if (bswap32_p)
     {
-      tree fndecl = built_in_decls[BUILT_IN_BSWAP32];
+      tree fndecl = BUILT_IN_DECLS (BUILT_IN_BSWAP32);
       bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
     }
 
   if (bswap64_p)
     {
-      tree fndecl = built_in_decls[BUILT_IN_BSWAP64];
+      tree fndecl = BUILT_IN_DECLS (BUILT_IN_BSWAP64);
       bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
     }
 
@@ -1856,14 +1856,14 @@  execute_optimize_bswap (void)
 	    case 32:
 	      if (bswap32_p)
 		{
-		  fndecl = built_in_decls[BUILT_IN_BSWAP32];
+		  fndecl = BUILT_IN_DECLS (BUILT_IN_BSWAP32);
 		  bswap_type = bswap32_type;
 		}
 	      break;
 	    case 64:
 	      if (bswap64_p)
 		{
-		  fndecl = built_in_decls[BUILT_IN_BSWAP64];
+		  fndecl = BUILT_IN_DECLS (BUILT_IN_BSWAP64);
 		  bswap_type = bswap64_type;
 		}
 	      break;
Index: gcc/gimple-low.c
===================================================================
--- gcc/gimple-low.c	(revision 178642)
+++ gcc/gimple-low.c	(working copy)
@@ -169,7 +169,7 @@  lower_function_body (void)
 	 and insert.  */
       disp_var = create_tmp_var (ptr_type_node, "setjmpvar");
       arg = build_addr (disp_label, current_function_decl);
-      t = implicit_built_in_decls[BUILT_IN_SETJMP_DISPATCHER];
+      t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_SETJMP_DISPATCHER);
       x = gimple_build_call (t, 1, arg);
       gimple_call_set_lhs (x, disp_var);
 
@@ -861,7 +861,7 @@  lower_builtin_setjmp (gimple_stmt_iterat
 
   /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert.  */
   arg = build_addr (next_label, current_function_decl);
-  t = implicit_built_in_decls[BUILT_IN_SETJMP_SETUP];
+  t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_SETJMP_SETUP);
   g = gimple_build_call (t, 2, gimple_call_arg (stmt, 0), arg);
   gimple_set_location (g, loc);
   gimple_set_block (g, gimple_block (stmt));
@@ -886,7 +886,7 @@  lower_builtin_setjmp (gimple_stmt_iterat
 
   /* Build '__builtin_setjmp_receiver (NEXT_LABEL)' and insert.  */
   arg = build_addr (next_label, current_function_decl);
-  t = implicit_built_in_decls[BUILT_IN_SETJMP_RECEIVER];
+  t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_SETJMP_RECEIVER);
   g = gimple_build_call (t, 1, arg);
   gimple_set_location (g, loc);
   gimple_set_block (g, gimple_block (stmt));
Index: gcc/go/gofrontend/gogo-tree.cc
===================================================================
--- gcc/go/gofrontend/gogo-tree.cc	(revision 178642)
+++ gcc/go/gofrontend/gogo-tree.cc	(working copy)
@@ -69,8 +69,7 @@  define_builtin(built_in_function bcode, 
 				   libname, NULL_TREE);
   if (const_p)
     TREE_READONLY(decl) = 1;
-  built_in_decls[bcode] = decl;
-  implicit_built_in_decls[bcode] = decl;
+  built_in_set_decl (bcode, decl, implicit);
   builtin_functions[name] = decl;
   if (libname != NULL)
     {
@@ -2316,13 +2315,13 @@  Gogo::make_trampoline(tree fnaddr, tree 
   x = save_expr(x);
 
   // Initialize the trampoline.
-  tree ini = build_call_expr(implicit_built_in_decls[BUILT_IN_INIT_TRAMPOLINE],
+  tree ini = build_call_expr(IMPLICIT_BUILT_IN_DECLS(BUILT_IN_INIT_TRAMPOLINE),
 			     3, x, fnaddr, closure);
 
   // On some targets the trampoline address needs to be adjusted.  For
   // example, when compiling in Thumb mode on the ARM, the address
   // needs to have the low bit set.
-  x = build_call_expr(implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE],
+  x = build_call_expr(IMPLICIT_BUILT_IN_DECLS(BUILT_IN_ADJUST_TRAMPOLINE),
 		      1, x);
   x = fold_convert(TREE_TYPE(fnaddr), x);
 
Index: gcc/ada/gcc-interface/utils.c
===================================================================
--- gcc/ada/gcc-interface/utils.c	(revision 178642)
+++ gcc/ada/gcc-interface/utils.c	(working copy)
@@ -5557,7 +5557,7 @@  def_builtin_1 (enum built_in_function fn
 
   /* Preserve an already installed decl.  It most likely was setup in advance
      (e.g. as part of the internal builtins) for specific reasons.  */
-  if (built_in_decls[(int) fncode] != NULL_TREE)
+  if (BUILT_IN_DECLS (fncode) != NULL_TREE)
     return;
 
   gcc_assert ((!both_p && !fallback_p)
@@ -5574,9 +5574,7 @@  def_builtin_1 (enum built_in_function fn
     add_builtin_function (libname, libtype, fncode, fnclass,
 			  NULL, fnattrs);
 
-  built_in_decls[(int) fncode] = decl;
-  if (implicit_p)
-    implicit_built_in_decls[(int) fncode] = decl;
+  built_in_set_decl (fncode, decl, implicit_p ? decl : NULL_TREE);
 }
 
 static int flag_isoc94 = 0;
Index: gcc/ada/gcc-interface/trans.c
===================================================================
--- gcc/ada/gcc-interface/trans.c	(revision 178643)
+++ gcc/ada/gcc-interface/trans.c	(working copy)
@@ -3853,7 +3853,7 @@  Exception_Handler_to_gnu_zcx (Node_Id gn
      time, and reuse it to feed the end_handler hook's argument at exit.  */
 
   gnu_current_exc_ptr
-    = build_call_expr (built_in_decls [BUILT_IN_EH_POINTER],
+    = build_call_expr (BUILT_IN_DECLS (BUILT_IN_EH_POINTER),
 		       1, integer_zero_node);
   prev_gnu_incoming_exc_ptr = gnu_incoming_exc_ptr;
   gnu_incoming_exc_ptr = create_var_decl (get_identifier ("EXPTR"), NULL_TREE,
@@ -5143,7 +5143,7 @@  gnat_to_gnu (Node_Id gnat_node)
 	      to_ptr = build_fold_addr_expr (to);
 	      from_ptr = build_fold_addr_expr (from);
 
-	      t = implicit_built_in_decls[BUILT_IN_MEMMOVE];
+	      t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMMOVE);
 	      gnu_result = build_call_expr (t, 3, to_ptr, from_ptr, size);
 	   }
 	}
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 178699)
+++ gcc/c-decl.c	(working copy)
@@ -4324,7 +4324,7 @@  finish_decl (tree decl, location_t init_
     }
 
   /* If this is a function and an assembler name is specified, reset DECL_RTL
-     so we can give it its new name.  Also, update built_in_decls if it
+     so we can give it its new name.  Also, update built_in_decl_info if it
      was a normal built-in.  */
   if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
     {
Index: gcc/tree-eh.c
===================================================================
--- gcc/tree-eh.c	(revision 178642)
+++ gcc/tree-eh.c	(working copy)
@@ -2934,7 +2934,7 @@  lower_resx (basic_block bb, gimple stmt,
 
 	 Resolve this by expanding the resx node to an abort.  */
 
-      fn = implicit_built_in_decls[BUILT_IN_TRAP];
+      fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_TRAP);
       x = gimple_build_call (fn, 0);
       gsi_insert_before (&gsi, x, GSI_SAME_STMT);
 
@@ -2991,7 +2991,7 @@  lower_resx (basic_block bb, gimple stmt,
 	  edge_iterator ei;
 	  tree dst_nr = build_int_cst (integer_type_node, dst_r->index);
 
-	  fn = implicit_built_in_decls[BUILT_IN_EH_COPY_VALUES];
+	  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_EH_COPY_VALUES);
 	  src_nr = build_int_cst (integer_type_node, src_r->index);
 	  x = gimple_build_call (fn, 2, dst_nr, src_nr);
 	  gsi_insert_before (&gsi, x, GSI_SAME_STMT);
@@ -3026,13 +3026,13 @@  lower_resx (basic_block bb, gimple stmt,
 	 with no arguments for C++ and Java.  Check for that.  */
       if (src_r->use_cxa_end_cleanup)
 	{
-	  fn = implicit_built_in_decls[BUILT_IN_CXA_END_CLEANUP];
+	  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_CXA_END_CLEANUP);
 	  x = gimple_build_call (fn, 0);
 	  gsi_insert_before (&gsi, x, GSI_SAME_STMT);
 	}
       else
 	{
-	  fn = implicit_built_in_decls[BUILT_IN_EH_POINTER];
+	  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_EH_POINTER);
 	  src_nr = build_int_cst (integer_type_node, src_r->index);
 	  x = gimple_build_call (fn, 1, src_nr);
 	  var = create_tmp_var (ptr_type_node, NULL);
@@ -3040,7 +3040,7 @@  lower_resx (basic_block bb, gimple stmt,
 	  gimple_call_set_lhs (x, var);
 	  gsi_insert_before (&gsi, x, GSI_SAME_STMT);
 
-	  fn = implicit_built_in_decls[BUILT_IN_UNWIND_RESUME];
+	  fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_UNWIND_RESUME);
 	  x = gimple_build_call (fn, 1, var);
 	  gsi_insert_before (&gsi, x, GSI_SAME_STMT);
 	}
@@ -3206,7 +3206,7 @@  lower_eh_dispatch (basic_block src, gimp
 	  }
 	else
 	  {
-	    fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
+	    fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_EH_FILTER);
 	    x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
 							 region_nr));
 	    filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
@@ -3232,7 +3232,7 @@  lower_eh_dispatch (basic_block src, gimp
 	edge b_e = BRANCH_EDGE (src);
 	edge f_e = FALLTHRU_EDGE (src);
 
-	fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
+	fn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_EH_FILTER);
 	x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
 						     region_nr));
 	filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 178699)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -1124,22 +1124,22 @@  gfc_conv_power_op (gfc_se * se, gfc_expr
 	      switch (kind)
 		{
 		case 0:
-		  fndecl = built_in_decls[BUILT_IN_POWIF];
+		  fndecl = BUILT_IN_DECLS (BUILT_IN_POWIF);
 		  break;
 		
 		case 1:
-		  fndecl = built_in_decls[BUILT_IN_POWI];
+		  fndecl = BUILT_IN_DECLS (BUILT_IN_POWI);
 		  break;
 
 		case 2:
-		  fndecl = built_in_decls[BUILT_IN_POWIL];
+		  fndecl = BUILT_IN_DECLS (BUILT_IN_POWIL);
 		  break;
 
 		case 3:
 		  /* Use the __builtin_powil() only if real(kind=16) is 
 		     actually the C long double type.  */
 		  if (!gfc_real16_is_float128)
-		    fndecl = built_in_decls[BUILT_IN_POWIL];
+		    fndecl = BUILT_IN_DECLS (BUILT_IN_POWIL);
 		  break;
 
 		default:
@@ -3855,7 +3855,7 @@  fill_with_spaces (tree start, tree type,
   /* For a simple char type, we can call memset().  */
   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
     return build_call_expr_loc (input_location,
-			    built_in_decls[BUILT_IN_MEMSET], 3, start,
+			    BUILT_IN_DECLS (BUILT_IN_MEMSET), 3, start,
 			    build_int_cst (gfc_get_int_type (gfc_c_int_kind),
 					   lang_hooks.to_target_charset (' ')),
 			    size);
@@ -4015,12 +4015,12 @@  gfc_trans_string_copy (stmtblock_t * blo
   cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
 			   dlen);
   tmp2 = build_call_expr_loc (input_location,
-			  built_in_decls[BUILT_IN_MEMMOVE],
+			  BUILT_IN_DECLS (BUILT_IN_MEMMOVE),
 			  3, dest, src, dlen);
 
   /* Else copy and pad with spaces.  */
   tmp3 = build_call_expr_loc (input_location,
-			  built_in_decls[BUILT_IN_MEMMOVE],
+			  BUILT_IN_DECLS (BUILT_IN_MEMMOVE),
 			  3, dest, src, slen);
 
   tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
@@ -5816,7 +5816,7 @@  gfc_trans_zero_assign (gfc_expr * expr)
 
   /* Construct call to __builtin_memset.  */
   tmp = build_call_expr_loc (input_location,
-			 built_in_decls[BUILT_IN_MEMSET],
+			 BUILT_IN_DECLS (BUILT_IN_MEMSET),
 			 3, dest, integer_zero_node, len);
   return fold_convert (void_type_node, tmp);
 }
@@ -5845,7 +5845,7 @@  gfc_build_memcpy_call (tree dst, tree sr
 
   /* Construct call to __builtin_memcpy.  */
   tmp = build_call_expr_loc (input_location,
-			 built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
+			 BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3, dst, src, len);
   return fold_convert (void_type_node, tmp);
 }
 
@@ -6056,7 +6056,7 @@  alloc_scalar_allocatable_for_assignment 
     }
 
   tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_MALLOC], 1,
+			     BUILT_IN_DECLS (BUILT_IN_MALLOC), 1,
 			     size_in_bytes);
   tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
   gfc_add_modify (block, lse.expr, tmp);
@@ -6083,7 +6083,7 @@  alloc_scalar_allocatable_for_assignment 
 		      build_empty_stmt (input_location));
       gfc_add_expr_to_block (block, tmp);
       tmp = build_call_expr_loc (input_location,
-				 built_in_decls[BUILT_IN_REALLOC], 2,
+				 BUILT_IN_DECLS (BUILT_IN_REALLOC), 2,
 				 fold_convert (pvoid_type_node, lse.expr),
 				 size_in_bytes);
       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c	(revision 178699)
+++ gcc/fortran/trans-array.c	(working copy)
@@ -1470,8 +1470,8 @@  gfc_trans_array_constructor_value (stmtb
 	      size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
 	      bound = build_int_cst (size_type_node, n * size);
 	      tmp = build_call_expr_loc (input_location,
-				     built_in_decls[BUILT_IN_MEMCPY], 3,
-				     tmp, init, bound);
+					 BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3,
+					 tmp, init, bound);
 	      gfc_add_expr_to_block (&body, tmp);
 
 	      *poffset = fold_build2_loc (input_location, PLUS_EXPR,
@@ -6632,7 +6632,7 @@  duplicate_allocatable (tree dest, tree s
 	  gfc_add_expr_to_block (&block, tmp);
 	}
 
-      tmp = built_in_decls[BUILT_IN_MEMCPY];
+      tmp = BUILT_IN_DECLS (BUILT_IN_MEMCPY);
       tmp = build_call_expr_loc (input_location, tmp, 3,
 				 dest, src, size);
     }
@@ -6656,7 +6656,7 @@  duplicate_allocatable (tree dest, tree s
 
       /* We know the temporary and the value will be the same length,
 	 so can use memcpy.  */
-      tmp = built_in_decls[BUILT_IN_MEMCPY];
+      tmp = BUILT_IN_DECLS (BUILT_IN_MEMCPY);
       tmp = build_call_expr_loc (input_location,
 			tmp, 3, gfc_conv_descriptor_data_get (dest),
 			gfc_conv_descriptor_data_get (src), size);
@@ -7412,7 +7412,7 @@  gfc_alloc_allocatable_for_assignment (gf
      in the array reference - (*desc.data)[<element>]. */
   gfc_init_block (&realloc_block);
   tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_REALLOC], 2,
+			     BUILT_IN_DECLS (BUILT_IN_REALLOC), 2,
 			     fold_convert (pvoid_type_node, array1),
 			     size2);
   gfc_conv_descriptor_data_set (&realloc_block,
@@ -7428,7 +7428,7 @@  gfc_alloc_allocatable_for_assignment (gf
   /* Malloc expression.  */
   gfc_init_block (&alloc_block);
   tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_MALLOC], 1,
+			     BUILT_IN_DECLS (BUILT_IN_MALLOC), 1,
 			     size2);
   gfc_conv_descriptor_data_set (&alloc_block,
 				desc, tmp);
Index: gcc/fortran/trans-openmp.c
===================================================================
--- gcc/fortran/trans-openmp.c	(revision 178642)
+++ gcc/fortran/trans-openmp.c	(working copy)
@@ -249,7 +249,7 @@  gfc_omp_clause_copy_ctor (tree clause, t
   gfc_conv_descriptor_data_set (&cond_block, dest, ptr);
 
   call = build_call_expr_loc (input_location,
-			  built_in_decls[BUILT_IN_MEMCPY], 3, ptr,
+			  BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3, ptr,
 			  fold_convert (pvoid_type_node,
 					gfc_conv_descriptor_data_get (src)),
 			  size);
@@ -300,7 +300,7 @@  gfc_omp_clause_assign_op (tree clause AT
 			  size, esize);
   size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
   call = build_call_expr_loc (input_location,
-			  built_in_decls[BUILT_IN_MEMCPY], 3,
+			  BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3,
 			  fold_convert (pvoid_type_node,
 					gfc_conv_descriptor_data_get (dest)),
 			  fold_convert (pvoid_type_node,
@@ -1273,7 +1273,7 @@  gfc_trans_omp_atomic (gfc_code *code)
 static tree
 gfc_trans_omp_barrier (void)
 {
-  tree decl = built_in_decls [BUILT_IN_GOMP_BARRIER];
+  tree decl = BUILT_IN_DECLS (BUILT_IN_GOMP_BARRIER);
   return build_call_expr_loc (input_location, decl, 0);
 }
 
@@ -1547,7 +1547,7 @@  gfc_trans_omp_do (gfc_code *code, stmtbl
 static tree
 gfc_trans_omp_flush (void)
 {
-  tree decl = built_in_decls [BUILT_IN_SYNC_SYNCHRONIZE];
+  tree decl = BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE);
   return build_call_expr_loc (input_location, decl, 0);
 }
 
@@ -1738,14 +1738,14 @@  gfc_trans_omp_task (gfc_code *code)
 static tree
 gfc_trans_omp_taskwait (void)
 {
-  tree decl = built_in_decls [BUILT_IN_GOMP_TASKWAIT];
+  tree decl = BUILT_IN_DECLS (BUILT_IN_GOMP_TASKWAIT);
   return build_call_expr_loc (input_location, decl, 0);
 }
 
 static tree
 gfc_trans_omp_taskyield (void)
 {
-  tree decl = built_in_decls [BUILT_IN_GOMP_TASKYIELD];
+  tree decl = BUILT_IN_DECLS (BUILT_IN_GOMP_TASKYIELD);
   return build_call_expr_loc (input_location, decl, 0);
 }
 
Index: gcc/fortran/trans-stmt.c
===================================================================
--- gcc/fortran/trans-stmt.c	(revision 178699)
+++ gcc/fortran/trans-stmt.c	(working copy)
@@ -602,7 +602,7 @@  gfc_trans_stop (gfc_code *code, bool err
   if (gfc_option.coarray == GFC_FCOARRAY_LIB && !error_stop)
     {
       /* Per F2008, 8.5.1 STOP implies a SYNC MEMORY.  */
-      tmp = built_in_decls [BUILT_IN_SYNC_SYNCHRONIZE];
+      tmp = BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE);
       tmp = build_call_expr_loc (input_location, tmp, 0);
       gfc_add_expr_to_block (&se.pre, tmp);
 
@@ -774,7 +774,7 @@  gfc_trans_sync (gfc_code *code, gfc_exec
       image control statements SYNC IMAGES and SYNC ALL.  */
    if (gfc_option.coarray == GFC_FCOARRAY_LIB)
      {
-	tmp = built_in_decls [BUILT_IN_SYNC_SYNCHRONIZE];
+	tmp = BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE);
 	tmp = build_call_expr_loc (input_location, tmp, 0);
 	gfc_add_expr_to_block (&se.pre, tmp);
      }
@@ -5076,7 +5076,7 @@  gfc_trans_allocate (gfc_code * code)
 			      slen);
 
       dlen = build_call_expr_loc (input_location,
-			      built_in_decls[BUILT_IN_MEMCPY], 3,
+			      BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3,
 		gfc_build_addr_expr (pvoid_type_node, se.expr), errmsg, slen);
 
       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
@@ -5251,7 +5251,7 @@  gfc_trans_deallocate (gfc_code *code)
 			      slen);
 
       dlen = build_call_expr_loc (input_location,
-			      built_in_decls[BUILT_IN_MEMCPY], 3,
+			      BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3,
 		gfc_build_addr_expr (pvoid_type_node, se.expr), errmsg, slen);
 
       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, astat,
Index: gcc/fortran/trans.c
===================================================================
--- gcc/fortran/trans.c	(revision 178699)
+++ gcc/fortran/trans.c	(working copy)
@@ -532,7 +532,7 @@  gfc_call_malloc (stmtblock_t * block, tr
   gfc_add_modify (&block2, res,
 		  fold_convert (prvoid_type_node,
 				build_call_expr_loc (input_location,
-				   built_in_decls[BUILT_IN_MALLOC], 1, size)));
+						     BUILT_IN_DECLS (BUILT_IN_MALLOC), 1, size)));
 
   /* Optionally check whether malloc was successful.  */
   if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
@@ -604,7 +604,7 @@  gfc_allocate_using_malloc (stmtblock_t *
   gfc_add_modify (block, pointer,
 	  fold_convert (TREE_TYPE (pointer),
 		build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_MALLOC], 1,
+			     BUILT_IN_DECLS (BUILT_IN_MALLOC), 1,
 			     fold_build2_loc (input_location,
 				      MAX_EXPR, size_type_node, size,
 				      build_int_cst (size_type_node, 1)))));
@@ -783,7 +783,7 @@  gfc_call_free (tree var)
   cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, var,
 			  build_int_cst (pvoid_type_node, 0));
   call = build_call_expr_loc (input_location,
-			      built_in_decls[BUILT_IN_FREE], 1, var);
+			      BUILT_IN_DECLS (BUILT_IN_FREE), 1, var);
   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, call,
 			 build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block, tmp);
@@ -871,7 +871,7 @@  gfc_deallocate_with_status (tree pointer
   /* When POINTER is not NULL, we free it.  */
   gfc_start_block (&non_null);
   tmp = build_call_expr_loc (input_location,
-			 built_in_decls[BUILT_IN_FREE], 1,
+			 BUILT_IN_DECLS (BUILT_IN_FREE), 1,
 			 fold_convert (pvoid_type_node, pointer));
   gfc_add_expr_to_block (&non_null, tmp);
 
@@ -968,7 +968,7 @@  gfc_deallocate_scalar_with_status (tree 
     }
   
   tmp = build_call_expr_loc (input_location,
-			 built_in_decls[BUILT_IN_FREE], 1,
+			 BUILT_IN_DECLS (BUILT_IN_FREE), 1,
 			 fold_convert (pvoid_type_node, pointer));
   gfc_add_expr_to_block (&non_null, tmp);
 
@@ -1026,7 +1026,7 @@  gfc_call_realloc (stmtblock_t * block, t
 
   /* Call realloc and check the result.  */
   tmp = build_call_expr_loc (input_location,
-			 built_in_decls[BUILT_IN_REALLOC], 2,
+			 BUILT_IN_DECLS (BUILT_IN_REALLOC), 2,
 			 fold_convert (pvoid_type_node, mem), size);
   gfc_add_modify (block, res, fold_convert (type, tmp));
   null_result = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
@@ -1593,7 +1593,7 @@  gfc_unlikely (tree cond)
   cond = fold_convert (long_integer_type_node, cond);
   tmp = build_zero_cst (long_integer_type_node);
   cond = build_call_expr_loc (input_location,
-			      built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
+			      BUILT_IN_DECLS (BUILT_IN_EXPECT), 2, cond, tmp);
   cond = fold_convert (boolean_type_node, cond);
   return cond;
 }
@@ -1609,7 +1609,7 @@  gfc_likely (tree cond)
   cond = fold_convert (long_integer_type_node, cond);
   tmp = build_one_cst (long_integer_type_node);
   cond = build_call_expr_loc (input_location,
-			      built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
+			      BUILT_IN_DECLS (BUILT_IN_EXPECT), 2, cond, tmp);
   cond = fold_convert (boolean_type_node, cond);
   return cond;
 }
Index: gcc/fortran/f95-lang.c
===================================================================
--- gcc/fortran/f95-lang.c	(revision 178642)
+++ gcc/fortran/f95-lang.c	(working copy)
@@ -653,8 +653,7 @@  gfc_define_builtin (const char *name, tr
     DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
 					NULL, DECL_ATTRIBUTES (decl));
 
-  built_in_decls[code] = decl;
-  implicit_built_in_decls[code] = decl;
+  built_in_set_decl ((enum built_in_function)code, decl, decl);
 }
 
 
@@ -1005,7 +1004,7 @@  gfc_init_builtin_functions (void)
                                     size_type_node, NULL_TREE);
   gfc_define_builtin ("__builtin_malloc", ftype, BUILT_IN_MALLOC,
 		      "malloc", ATTR_NOTHROW_LEAF_LIST);
-  DECL_IS_MALLOC (built_in_decls[BUILT_IN_MALLOC]) = 1;
+  DECL_IS_MALLOC (BUILT_IN_DECLS (BUILT_IN_MALLOC)) = 1;
 
   ftype = build_function_type_list (pvoid_type_node,
                                     size_type_node, pvoid_type_node,
@@ -1121,7 +1120,7 @@  gfc_init_builtin_functions (void)
 
   gfc_define_builtin ("__builtin_trap", builtin_types[BT_FN_VOID],
 		      BUILT_IN_TRAP, NULL, ATTR_NOTHROW_LEAF_LIST);
-  TREE_THIS_VOLATILE (built_in_decls[BUILT_IN_TRAP]) = 1;
+  TREE_THIS_VOLATILE (BUILT_IN_DECLS (BUILT_IN_TRAP)) = 1;
 
   gfc_define_builtin ("__emutls_get_address",
 		      builtin_types[BT_FN_PTR_PTR],
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c	(revision 178642)
+++ gcc/fortran/trans-decl.c	(working copy)
@@ -4986,7 +4986,7 @@  create_main_function (tree fndecl)
     { 
       /* Per F2008, 8.5.1 END of the main program implies a
 	 SYNC MEMORY.  */ 
-      tmp = built_in_decls [BUILT_IN_SYNC_SYNCHRONIZE];
+      tmp = BUILT_IN_DECLS (BUILT_IN_SYNC_SYNCHRONIZE);
       tmp = build_call_expr_loc (input_location, tmp, 0);
       gfc_add_expr_to_block (&body, tmp);
 
Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c	(revision 178699)
+++ gcc/fortran/trans-intrinsic.c	(working copy)
@@ -139,7 +139,7 @@  static tree
 builtin_decl_for_precision (enum built_in_function base_built_in,
 			    int precision)
 {
-  int i = END_BUILTINS;
+  enum built_in_function i = END_BUILTINS;
 
   gfc_intrinsic_map_t *m;
   for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
@@ -158,7 +158,7 @@  builtin_decl_for_precision (enum built_i
       return m->real16_decl;
     }
 
-  return (i == END_BUILTINS ? NULL_TREE : built_in_decls[i]);
+  return (i == END_BUILTINS ? NULL_TREE : BUILT_IN_DECLS (i));
 }
 
 
@@ -679,26 +679,26 @@  gfc_build_intrinsic_lib_fndecls (void)
        m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
     {
       if (m->float_built_in != END_BUILTINS)
-	m->real4_decl = built_in_decls[m->float_built_in];
+	m->real4_decl = BUILT_IN_DECLS (m->float_built_in);
       if (m->complex_float_built_in != END_BUILTINS)
-	m->complex4_decl = built_in_decls[m->complex_float_built_in];
+	m->complex4_decl = BUILT_IN_DECLS (m->complex_float_built_in);
       if (m->double_built_in != END_BUILTINS)
-	m->real8_decl = built_in_decls[m->double_built_in];
+	m->real8_decl = BUILT_IN_DECLS (m->double_built_in);
       if (m->complex_double_built_in != END_BUILTINS)
-	m->complex8_decl = built_in_decls[m->complex_double_built_in];
+	m->complex8_decl = BUILT_IN_DECLS (m->complex_double_built_in);
 
       /* If real(kind=10) exists, it is always long double.  */
       if (m->long_double_built_in != END_BUILTINS)
-	m->real10_decl = built_in_decls[m->long_double_built_in];
+	m->real10_decl = BUILT_IN_DECLS (m->long_double_built_in);
       if (m->complex_long_double_built_in != END_BUILTINS)
-	m->complex10_decl = built_in_decls[m->complex_long_double_built_in];
+	m->complex10_decl = BUILT_IN_DECLS (m->complex_long_double_built_in);
 
       if (!gfc_real16_is_float128)
 	{
 	  if (m->long_double_built_in != END_BUILTINS)
-	    m->real16_decl = built_in_decls[m->long_double_built_in];
+	    m->real16_decl = BUILT_IN_DECLS (m->long_double_built_in);
 	  if (m->complex_long_double_built_in != END_BUILTINS)
-	    m->complex16_decl = built_in_decls[m->complex_long_double_built_in];
+	    m->complex16_decl = BUILT_IN_DECLS (m->complex_long_double_built_in);
 	}
       else if (quad_decls[m->double_built_in] != NULL_TREE)
         {
@@ -2202,7 +2202,7 @@  gfc_conv_intrinsic_minmax (gfc_se * se, 
       if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
 	{
 	  isnan = build_call_expr_loc (input_location,
-				   built_in_decls[BUILT_IN_ISNAN], 1, mvar);
+				   BUILT_IN_DECLS (BUILT_IN_ISNAN), 1, mvar);
 	  tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
 				 boolean_type_node, tmp,
 				 fold_convert (boolean_type_node, isnan));
@@ -4079,17 +4079,17 @@  gfc_conv_intrinsic_leadz (gfc_se * se, g
   if (argsize <= INT_TYPE_SIZE)
     {
       arg_type = unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CLZ];
+      func = BUILT_IN_DECLS (BUILT_IN_CLZ);
     }
   else if (argsize <= LONG_TYPE_SIZE)
     {
       arg_type = long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CLZL];
+      func = BUILT_IN_DECLS (BUILT_IN_CLZL);
     }
   else if (argsize <= LONG_LONG_TYPE_SIZE)
     {
       arg_type = long_long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CLZLL];
+      func = BUILT_IN_DECLS (BUILT_IN_CLZLL);
     }
   else
     {
@@ -4148,13 +4148,13 @@  gfc_conv_intrinsic_leadz (gfc_se * se, g
       tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
       tmp1 = fold_convert (result_type,
 			   build_call_expr_loc (input_location,	
-						built_in_decls[BUILT_IN_CLZLL],
+						BUILT_IN_DECLS (BUILT_IN_CLZLL),
 						1, tmp1));
 
       tmp2 = fold_convert (long_long_unsigned_type_node, arg);
       tmp2 = fold_convert (result_type,
 			   build_call_expr_loc (input_location,
-						built_in_decls[BUILT_IN_CLZLL],
+						BUILT_IN_DECLS (BUILT_IN_CLZLL),
 						1, tmp2));
       tmp2 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
 			      tmp2, ullsize);
@@ -4198,17 +4198,17 @@  gfc_conv_intrinsic_trailz (gfc_se * se, 
   if (argsize <= INT_TYPE_SIZE)
     {
       arg_type = unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CTZ];
+      func = BUILT_IN_DECLS (BUILT_IN_CTZ);
     }
   else if (argsize <= LONG_TYPE_SIZE)
     {
       arg_type = long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CTZL];
+      func = BUILT_IN_DECLS (BUILT_IN_CTZL);
     }
   else if (argsize <= LONG_LONG_TYPE_SIZE)
     {
       arg_type = long_long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CTZLL];
+      func = BUILT_IN_DECLS (BUILT_IN_CTZLL);
     }
   else
     {
@@ -4259,7 +4259,7 @@  gfc_conv_intrinsic_trailz (gfc_se * se, 
       tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
       tmp1 = fold_convert (result_type,
 			   build_call_expr_loc (input_location,	
-						built_in_decls[BUILT_IN_CTZLL],
+						BUILT_IN_DECLS (BUILT_IN_CTZLL),
 						1, tmp1));
       tmp1 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
 			      tmp1, ullsize);
@@ -4267,7 +4267,7 @@  gfc_conv_intrinsic_trailz (gfc_se * se, 
       tmp2 = fold_convert (long_long_unsigned_type_node, arg);
       tmp2 = fold_convert (result_type,
 			   build_call_expr_loc (input_location,
-						built_in_decls[BUILT_IN_CTZLL],
+						BUILT_IN_DECLS (BUILT_IN_CTZLL),
 						1, tmp2));
 
       trailz = fold_build3_loc (input_location, COND_EXPR, result_type,
@@ -4304,17 +4304,17 @@  gfc_conv_intrinsic_popcnt_poppar (gfc_se
   if (argsize <= INT_TYPE_SIZE)
     {
       arg_type = unsigned_type_node;
-      func = built_in_decls[parity ? BUILT_IN_PARITY : BUILT_IN_POPCOUNT];
+      func = BUILT_IN_DECLS (parity ? BUILT_IN_PARITY : BUILT_IN_POPCOUNT);
     }
   else if (argsize <= LONG_TYPE_SIZE)
     {
       arg_type = long_unsigned_type_node;
-      func = built_in_decls[parity ? BUILT_IN_PARITYL : BUILT_IN_POPCOUNTL];
+      func = BUILT_IN_DECLS (parity ? BUILT_IN_PARITYL : BUILT_IN_POPCOUNTL);
     }
   else if (argsize <= LONG_LONG_TYPE_SIZE)
     {
       arg_type = long_long_unsigned_type_node;
-      func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
+      func = BUILT_IN_DECLS (parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL);
     }
   else
     {
@@ -4327,7 +4327,7 @@  gfc_conv_intrinsic_popcnt_poppar (gfc_se
 	 as 'long long'.  */
       gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
 
-      func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
+      func = BUILT_IN_DECLS (parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL);
 
       /* Convert it to an integer, and store into a variable.  */
       utype = gfc_build_uint_type (argsize);
@@ -4580,7 +4580,7 @@  gfc_conv_intrinsic_isnan (gfc_se * se, g
 
   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
   se->expr = build_call_expr_loc (input_location,
-			      built_in_decls[BUILT_IN_ISNAN], 1, arg);
+			      BUILT_IN_DECLS (BUILT_IN_ISNAN), 1, arg);
   STRIP_TYPE_NOPS (se->expr);
   se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
 }
@@ -5490,7 +5490,7 @@  gfc_conv_intrinsic_transfer (gfc_se * se
 
   /* Use memcpy to do the transfer.  */
   tmp = build_call_expr_loc (input_location,
-			 built_in_decls[BUILT_IN_MEMCPY],
+			 BUILT_IN_DECLS (BUILT_IN_MEMCPY),
 			 3,
 			 tmp,
 			 fold_convert (pvoid_type_node, source),
@@ -5535,7 +5535,7 @@  scalar_transfer:
       gfc_add_modify (&block, tmpdecl,
 		      fold_convert (TREE_TYPE (ptr), tmp));
       tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_MEMCPY], 3,
+			     BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3,
 			     fold_convert (pvoid_type_node, tmpdecl),
 			     fold_convert (pvoid_type_node, ptr),
 			     extent);
@@ -5560,7 +5560,7 @@  scalar_transfer:
       /* Use memcpy to do the transfer.  */
       tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
       tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_MEMCPY], 3,
+			     BUILT_IN_DECLS (BUILT_IN_MEMCPY), 3,
 			     fold_convert (pvoid_type_node, tmp),
 			     fold_convert (pvoid_type_node, ptr),
 			     extent);
@@ -6001,7 +6001,7 @@  gfc_conv_intrinsic_repeat (gfc_se * se, 
   tmp = fold_build_pointer_plus_loc (input_location,
 				     fold_convert (pvoid_type_node, dest), tmp);
   tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
+			     BUILT_IN_DECLS (BUILT_IN_MEMMOVE), 3, tmp, src,
 			     fold_build2_loc (input_location, MULT_EXPR,
 					      size_type_node, slen,
 					      fold_convert (size_type_node,
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 178642)
+++ gcc/function.c	(working copy)
@@ -3638,7 +3638,7 @@  gimplify_parameters (void)
 		  DECL_IGNORED_P (addr) = 0;
 		  local = build_fold_indirect_ref (addr);
 
-		  t = built_in_decls[BUILT_IN_ALLOCA];
+		  t = BUILT_IN_DECLS (BUILT_IN_ALLOCA);
 		  t = build_call_expr (t, 1, DECL_SIZE_UNIT (parm));
 		  /* The call has been built for a variable-sized object.  */
 		  CALL_ALLOCA_FOR_VAR_P (t) = 1;
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 178642)
+++ gcc/c-typeck.c	(working copy)
@@ -2766,7 +2766,7 @@  build_function_call_vec (location_t loc,
       && !comptypes (fntype, TREE_TYPE (tem)))
     {
       tree return_type = TREE_TYPE (fntype);
-      tree trap = build_function_call (loc, built_in_decls[BUILT_IN_TRAP],
+      tree trap = build_function_call (loc, BUILT_IN_DECLS (BUILT_IN_TRAP),
 				       NULL_TREE);
       int i;
 
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	(revision 178642)
+++ gcc/gimplify.c	(working copy)
@@ -1109,12 +1109,12 @@  build_stack_save_restore (gimple *save, 
 {
   tree tmp_var;
 
-  *save = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0);
+  *save = gimple_build_call (IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STACK_SAVE), 0);
   tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
   gimple_call_set_lhs (*save, tmp_var);
 
   *restore
-    = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
+    = gimple_build_call (IMPLICIT_BUILT_IN_DECLS (BUILT_IN_STACK_RESTORE),
 			 1, tmp_var);
 }
 
@@ -1329,7 +1329,7 @@  gimplify_vla_decl (tree decl, gimple_seq
   SET_DECL_VALUE_EXPR (decl, t);
   DECL_HAS_VALUE_EXPR_P (decl) = 1;
 
-  t = built_in_decls[BUILT_IN_ALLOCA];
+  t = BUILT_IN_DECLS (BUILT_IN_ALLOCA);
   t = build_call_expr (t, 1, DECL_SIZE_UNIT (decl));
   /* The call has been built for a variable-sized object.  */
   CALL_ALLOCA_FOR_VAR_P (t) = 1;
@@ -3210,7 +3210,7 @@  gimplify_modify_expr_to_memcpy (tree *ex
   to_ptr = build_fold_addr_expr_loc (loc, to);
   gimplify_arg (&to_ptr, seq_p, loc);
 
-  t = implicit_built_in_decls[BUILT_IN_MEMCPY];
+  t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
 
   gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
 
@@ -3257,7 +3257,7 @@  gimplify_modify_expr_to_memset (tree *ex
 
   to_ptr = build_fold_addr_expr_loc (loc, to);
   gimplify_arg (&to_ptr, seq_p, loc);
-  t = implicit_built_in_decls[BUILT_IN_MEMSET];
+  t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMSET);
 
   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
 
@@ -4680,7 +4680,7 @@  gimplify_variable_sized_compare (tree *e
   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
   src = build_fold_addr_expr_loc (loc, op1);
   dest = build_fold_addr_expr_loc (loc, op0);
-  t = implicit_built_in_decls[BUILT_IN_MEMCMP];
+  t = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCMP);
   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
 
   expr
@@ -7978,24 +7978,24 @@  gimplify_function_tree (tree fndecl)
       tree tmp_var;
       gimple call;
 
-      x = implicit_built_in_decls[BUILT_IN_RETURN_ADDRESS];
+      x = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_RETURN_ADDRESS);
       call = gimple_build_call (x, 1, integer_zero_node);
       tmp_var = create_tmp_var (ptr_type_node, "return_addr");
       gimple_call_set_lhs (call, tmp_var);
       gimplify_seq_add_stmt (&cleanup, call);
-      x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
+      x = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_PROFILE_FUNC_EXIT);
       call = gimple_build_call (x, 2,
 				build_fold_addr_expr (current_function_decl),
 				tmp_var);
       gimplify_seq_add_stmt (&cleanup, call);
       tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
 
-      x = implicit_built_in_decls[BUILT_IN_RETURN_ADDRESS];
+      x = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_RETURN_ADDRESS);
       call = gimple_build_call (x, 1, integer_zero_node);
       tmp_var = create_tmp_var (ptr_type_node, "return_addr");
       gimple_call_set_lhs (call, tmp_var);
       gimplify_seq_add_stmt (&body, call);
-      x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
+      x = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_PROFILE_FUNC_ENTER);
       call = gimple_build_call (x, 2,
 				build_fold_addr_expr (current_function_decl),
 				tmp_var);
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	(revision 178642)
+++ gcc/calls.c	(working copy)
@@ -274,6 +274,7 @@  emit_call_1 (rtx funexp, tree fntree ATT
   if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL)
     {
       tree t = fndecl;
+      tree bfndecl;
       /* Although a built-in FUNCTION_DECL and its non-__builtin
 	 counterpart compare equal and get a shared mem_attrs, they
 	 produce different dump output in compare-debug compilations,
@@ -282,8 +283,8 @@  emit_call_1 (rtx funexp, tree fntree ATT
 	 doesn't run the garbage collector at the same spot and then
 	 shares the mem_attr with the equivalent entry. */
       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
-	  && built_in_decls[DECL_FUNCTION_CODE (t)])
-	t = built_in_decls[DECL_FUNCTION_CODE (t)];
+	  && (bfndecl = BUILT_IN_DECLS (DECL_FUNCTION_CODE (t))) != NULL_TREE)
+	t = bfndecl;
       set_mem_expr (funmem, t);
     }
   else if (fntree)
Index: gcc/lto/lto-lang.c
===================================================================
--- gcc/lto/lto-lang.c	(revision 178642)
+++ gcc/lto/lto-lang.c	(working copy)
@@ -499,9 +499,7 @@  def_builtin_1 (enum built_in_function fn
     add_builtin_function (libname, libtype, fncode, fnclass,
 			  NULL, fnattrs);
 
-  built_in_decls[(int) fncode] = decl;
-  if (implicit_p)
-    implicit_built_in_decls[(int) fncode] = decl;
+  built_in_set_decl (fncode, decl, implicit_p ? decl : NULL_TREE);
 }
 
 
Index: gcc/tree-ssa-forwprop.c
===================================================================
--- gcc/tree-ssa-forwprop.c	(revision 178643)
+++ gcc/tree-ssa-forwprop.c	(working copy)
@@ -1600,7 +1600,7 @@  simplify_builtin_call (gimple_stmt_itera
 	      if (!is_gimple_val (ptr1))
 		ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE,
 						 true, GSI_SAME_STMT);
-	      gimple_call_set_fndecl (stmt2, built_in_decls [BUILT_IN_MEMCPY]);
+	      gimple_call_set_fndecl (stmt2, BUILT_IN_DECLS (BUILT_IN_MEMCPY));
 	      gimple_call_set_arg (stmt2, 0, ptr1);
 	      gimple_call_set_arg (stmt2, 1, new_str_cst);
 	      gimple_call_set_arg (stmt2, 2,
Index: gcc/tree-nested.c
===================================================================
--- gcc/tree-nested.c	(revision 178642)
+++ gcc/tree-nested.c	(working copy)
@@ -1811,8 +1811,8 @@  convert_nl_goto_reference (gimple_stmt_i
   x = get_frame_field (info, target_context, field, &wi->gsi);
   x = build_addr (x, target_context);
   x = gsi_gimplify_val (info, x, &wi->gsi);
-  call = gimple_build_call (implicit_built_in_decls[BUILT_IN_NONLOCAL_GOTO], 2,
-			    build_addr (new_label, target_context), x);
+  call = gimple_build_call (IMPLICIT_BUILT_IN_DECLS (BUILT_IN_NONLOCAL_GOTO),
+			    2, build_addr (new_label, target_context), x);
   gsi_replace (&wi->gsi, call, false);
 
   /* We have handled all of STMT's operands, no need to keep going.  */
@@ -1924,7 +1924,7 @@  convert_tramp_reference_op (tree *tp, in
 
       /* Do machine-specific ugliness.  Normally this will involve
 	 computing extra alignment, but it can really be anything.  */
-      builtin = implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE];
+      builtin = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_ADJUST_TRAMPOLINE);
       call = gimple_build_call (builtin, 1, x);
       x = init_tmp_var_with_call (info, &wi->gsi, call);
 
@@ -2399,7 +2399,7 @@  finalize_nesting_tree_1 (struct nesting_
 		      root->frame_decl, field, NULL_TREE);
 	  arg1 = build_addr (x, context);
 
-	  x = implicit_built_in_decls[BUILT_IN_INIT_TRAMPOLINE];
+	  x = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_INIT_TRAMPOLINE);
 	  stmt = gimple_build_call (x, 3, arg1, arg2, arg3);
 	  gimple_seq_add_stmt (&stmt_list, stmt);
 	}
Index: gcc/tree-ssa-loop-prefetch.c
===================================================================
--- gcc/tree-ssa-loop-prefetch.c	(revision 178642)
+++ gcc/tree-ssa-loop-prefetch.c	(working copy)
@@ -1117,7 +1117,7 @@  issue_prefetch_ref (struct mem_ref *ref,
 					   NULL, true, GSI_SAME_STMT);
       }
       /* Create the prefetch instruction.  */
-      prefetch = gimple_build_call (built_in_decls[BUILT_IN_PREFETCH],
+      prefetch = gimple_build_call (BUILT_IN_DECLS (BUILT_IN_PREFETCH),
 				    3, addr, write_p, local);
       gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT);
     }
@@ -1909,7 +1909,7 @@  tree_ssa_prefetch_arrays (void)
 
   initialize_original_copy_tables ();
 
-  if (!built_in_decls[BUILT_IN_PREFETCH])
+  if (!BUILT_IN_DECLS (BUILT_IN_PREFETCH))
     {
       tree type = build_function_type_list (void_type_node,
 					    const_ptr_type_node, NULL_TREE);
@@ -1917,7 +1917,7 @@  tree_ssa_prefetch_arrays (void)
 					BUILT_IN_PREFETCH, BUILT_IN_NORMAL,
 					NULL, NULL_TREE);
       DECL_IS_NOVOPS (decl) = true;
-      built_in_decls[BUILT_IN_PREFETCH] = decl;
+      built_in_set_decl (BUILT_IN_PREFETCH, decl, NULL_TREE);
     }
 
   /* We assume that size of cache line is a power of two, so verify this
Index: gcc/tree-streamer-in.c
===================================================================
--- gcc/tree-streamer-in.c	(revision 178642)
+++ gcc/tree-streamer-in.c	(working copy)
@@ -1049,7 +1049,7 @@  streamer_get_builtin_tree (struct lto_in
     {
       if (fcode >= END_BUILTINS)
 	fatal_error ("machine independent builtin code out of range");
-      result = built_in_decls[fcode];
+      result = BUILT_IN_DECLS (fcode);
       gcc_assert (result);
     }
   else if (fclass == BUILT_IN_MD)
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	(revision 178643)
+++ gcc/config/sparc/sparc.c	(working copy)
@@ -6718,7 +6718,7 @@  sparc_gimplify_va_arg (tree valist, tree
     {
       tree tmp = create_tmp_var (type, "va_arg_tmp");
       tree dest_addr = build_fold_addr_expr (tmp);
-      tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
+      tree copy = build_call_expr (IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY),
 				   3, dest_addr, addr, size_int (rsize));
       TREE_ADDRESSABLE (tmp) = 1;
       gimplify_and_add (copy, pre_p);
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 178699)
+++ gcc/config/i386/i386.c	(working copy)
@@ -7958,10 +7958,9 @@  ix86_gimplify_va_arg (tree valist, tree 
 		}
 	      else
 		{
-		  tree copy
-		    = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
-				       3, dest_addr, src_addr,
-				       size_int (cur_size));
+		  tree bfn = IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY);
+		  tree copy = build_call_expr (bfn, 3, dest_addr, src_addr,
+					       size_int (cur_size));
 		  gimplify_and_add (copy, pre_p);
 		}
 	      prev_size += cur_size;
@@ -28742,7 +28741,7 @@  ix86_veclibabi_svml (enum built_in_funct
       return NULL_TREE;
     }
 
-  bname = IDENTIFIER_POINTER (DECL_NAME (implicit_built_in_decls[fn]));
+  bname = IDENTIFIER_POINTER (DECL_NAME (IMPLICIT_BUILT_IN_DECLS (fn)));
 
   if (fn == BUILT_IN_LOGF)
     strcpy (name, "vmlsLn4");
@@ -28760,7 +28759,7 @@  ix86_veclibabi_svml (enum built_in_funct
   name[4] &= ~0x20;
 
   arity = 0;
-  for (args = DECL_ARGUMENTS (implicit_built_in_decls[fn]); args;
+  for (args = DECL_ARGUMENTS (IMPLICIT_BUILT_IN_DECLS (fn)); args;
        args = TREE_CHAIN (args))
     arity++;
 
@@ -28841,11 +28840,11 @@  ix86_veclibabi_acml (enum built_in_funct
       return NULL_TREE;
     }
 
-  bname = IDENTIFIER_POINTER (DECL_NAME (implicit_built_in_decls[fn]));
+  bname = IDENTIFIER_POINTER (DECL_NAME (IMPLICIT_BUILT_IN_DECLS (fn)));
   sprintf (name + 7, "%s", bname+10);
 
   arity = 0;
-  for (args = DECL_ARGUMENTS (implicit_built_in_decls[fn]); args;
+  for (args = DECL_ARGUMENTS (IMPLICIT_BUILT_IN_DECLS (fn)); args;
        args = TREE_CHAIN (args))
     arity++;
 
Index: gcc/config/vms/vms.c
===================================================================
--- gcc/config/vms/vms.c	(revision 178642)
+++ gcc/config/vms/vms.c	(working copy)
@@ -99,8 +99,8 @@  vms_patch_builtins (void)
   unsigned int i;
 
   /* Fwrite on VMS is non-standard.  */
-  implicit_built_in_decls[(int) BUILT_IN_FWRITE] = NULL_TREE;
-  implicit_built_in_decls[(int) BUILT_IN_FWRITE_UNLOCKED] = NULL_TREE;
+  built_in_no_implicit (BUILT_IN_WRITE);
+  built_in_no_implicit (BUILT_IN_WRITE_UNLOCKED);
 
   /* Define aliases for names.  */
   for (i = 0; i < NBR_CRTL_NAMES; i++)
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 178642)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -10100,15 +10100,13 @@  ia64_init_builtins (void)
 
   if (TARGET_HPUX)
     {
-      if (built_in_decls [BUILT_IN_FINITE])
-	set_user_assembler_name (built_in_decls [BUILT_IN_FINITE],
-	  "_Isfinite");
-      if (built_in_decls [BUILT_IN_FINITEF])
-	set_user_assembler_name (built_in_decls [BUILT_IN_FINITEF],
-	  "_Isfinitef");
-      if (built_in_decls [BUILT_IN_FINITEL])
-	set_user_assembler_name (built_in_decls [BUILT_IN_FINITEL],
-	  "_Isfinitef128");
+      tree bfn;
+      if ((bfn = BUILT_IN_DECLS (BUILT_IN_FINITE)) != NULL_TREE)
+	set_user_assembler_name (bfn, "_Isfinite");
+      if ((bfn = BUILT_IN_DECLS (BUILT_IN_FINITEF)) != NULL_TREE)
+	set_user_assembler_name (bfn, "_Isfinitef");
+      if ((bfn = BUILT_IN_DECLS (BUILT_IN_FINITEL)) != NULL_TREE)
+	set_user_assembler_name (bfn, "_Isfinitef128");
     }
 }
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 178643)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3739,7 +3739,7 @@  rs6000_builtin_vectorized_libmass (tree 
 	case BUILT_IN_SQRT:
 	case BUILT_IN_TAN:
 	case BUILT_IN_TANH:
-	  bdecl = implicit_built_in_decls[fn];
+	  bdecl = IMPLICIT_BUILT_IN_DECLS (fn);
 	  suffix = "d2";				/* pow -> powd2 */
 	  if (el_mode != DFmode
 	      || n != 2)
@@ -3776,7 +3776,7 @@  rs6000_builtin_vectorized_libmass (tree 
 	case BUILT_IN_SQRTF:
 	case BUILT_IN_TANF:
 	case BUILT_IN_TANHF:
-	  bdecl = implicit_built_in_decls[fn];
+	  bdecl = IMPLICIT_BUILT_IN_DECLS (fn);
 	  suffix = "4";					/* powf -> powf4 */
 	  if (el_mode != SFmode
 	      || n != 4)
@@ -9400,7 +9400,7 @@  rs6000_gimplify_va_arg (tree valist, tre
       tree tmp = create_tmp_var (type, "va_arg_tmp");
       tree dest_addr = build_fold_addr_expr (tmp);
 
-      tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
+      tree copy = build_call_expr (IMPLICIT_BUILT_IN_DECLS (BUILT_IN_MEMCPY),
 				   3, dest_addr, addr, size_int (rsize * 4));
 
       gimplify_and_add (copy, pre_p);
@@ -12213,8 +12213,11 @@  rs6000_init_builtins (void)
 
 #if TARGET_XCOFF
   /* AIX libm provides clog as __clog.  */
-  if (built_in_decls [BUILT_IN_CLOG])
-    set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
+  {
+    tree bfn = BUILT_IN_DECLS (BUILT_IN_CLOG);
+    if (bfn)
+      set_user_assembler_name (bfn, "__clog");
+  }
 #endif
 
 #ifdef SUBTARGET_INIT_BUILTINS
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	(revision 178642)
+++ gcc/config/darwin.c	(working copy)
@@ -2962,7 +2962,7 @@  darwin_override_options (void)
 static void
 darwin_patch_builtin (int fncode)
 {
-  tree fn = built_in_decls[fncode];
+  tree fn = BUILT_IN_DECLS ((enum built_in_function)fncode);
   tree sym;
   char *newname;
 
@@ -2974,7 +2974,7 @@  darwin_patch_builtin (int fncode)
 
   set_user_assembler_name (fn, newname);
 
-  fn = implicit_built_in_decls[fncode];
+  fn = IMPLICIT_BUILT_IN_DECLS ((enum built_in_function)fncode);
   if (fn)
     set_user_assembler_name (fn, newname);
 }
@@ -3149,9 +3149,8 @@  darwin_rename_builtins (void)
      use the faster version.  */
   if (!flag_unsafe_math_optimizations)
     {
-      int dcode = (BUILT_IN_COMPLEX_DIV_MIN
-		   + DCmode - MIN_MODE_COMPLEX_FLOAT);
-      tree fn = built_in_decls[dcode];
+      tree fn = BUILT_IN_DECLS_ADD (BUILT_IN_COMPLEX_DIV_MIN,
+				    DCmode - MIN_MODE_COMPLEX_FLOAT);
       /* Fortran and c call TARGET_INIT_BUILTINS and
 	 TARGET_INIT_LIBFUNCS at different times, so we have to put a
 	 call into each to ensure that at least one of them is called
@@ -3159,7 +3158,7 @@  darwin_rename_builtins (void)
 	 new hook to run after build_common_builtin_nodes runs.  */
       if (fn)
 	set_user_assembler_name (fn, "___ieee_divdc3");
-      fn = implicit_built_in_decls[dcode];
+      fn = IMPLICIT_BUILT_IN_DECLS (dcode);
       if (fn)
 	set_user_assembler_name (fn, "___ieee_divdc3");
     }
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	(revision 178643)
+++ gcc/config/pa/pa.c	(working copy)
@@ -555,16 +555,17 @@  static void
 pa_init_builtins (void)
 {
 #ifdef DONT_HAVE_FPUTC_UNLOCKED
-  built_in_decls[(int) BUILT_IN_FPUTC_UNLOCKED] =
-    built_in_decls[(int) BUILT_IN_PUTC_UNLOCKED];
-  implicit_built_in_decls[(int) BUILT_IN_FPUTC_UNLOCKED]
-    = implicit_built_in_decls[(int) BUILT_IN_PUTC_UNLOCKED];
+  buil_in_copy_decl (BUILT_IN_FPUTC_UNLOAD, BUILT_IN_PUTC_UNLOCKED);
 #endif
 #if TARGET_HPUX_11
-  if (built_in_decls [BUILT_IN_FINITE])
-    set_user_assembler_name (built_in_decls [BUILT_IN_FINITE], "_Isfinite");
-  if (built_in_decls [BUILT_IN_FINITEF])
-    set_user_assembler_name (built_in_decls [BUILT_IN_FINITEF], "_Isfinitef");
+  {
+    tree bfn;
+
+    if ((bfn = built_in_decls [BUILT_IN_FINITE]) != NULL_TREE)
+      set_user_assembler_name (bfn, "_Isfinite");
+    if ((bfn = built_in_decls [BUILT_IN_FINITEF]) != NULL_TREE)
+      set_user_assembler_name (bfn, "_Isfinitef");
+  }
 #endif
 
   if (HPUX_LONG_DOUBLE_LIBRARY)