diff mbox

Go patch committed: Use backend interface for built-in functions

Message ID mcr7g66kbn7.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor April 30, 2014, 4:47 p.m. UTC
This patch from Chris Manghane changes the Go frontend to use the
backend interface for built-in functions.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2014-04-30  Chris Manghane  <cmang@google.com>

	* go-gcc.cc: #include "langhooks.h".
	(Gcc_backend::Gcc_backend): Add constructor.
	(Gcc_backend::lookup_function): New function.
	(Gcc_backend::define_builtin): New private function.
	(Gcc_backend::gcc_backend): Remove.
	(go_get_backend): Use new to create new Gcc_backend.
diff mbox

Patch

Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 209819)
+++ gcc/go/go-gcc.cc	(working copy)
@@ -34,6 +34,7 @@ 
 #include "basic-block.h"
 #include "gimple-expr.h"
 #include "gimplify.h"
+#include "langhooks.h"
 #include "toplev.h"
 #include "output.h"
 #include "real.h"
@@ -131,6 +132,8 @@  class Blabel : public Gcc_tree
 class Gcc_backend : public Backend
 {
  public:
+  Gcc_backend();
+
   // Types.
 
   Btype*
@@ -425,6 +428,9 @@  class Gcc_backend : public Backend
   bool
   function_set_body(Bfunction* function, Bstatement* code_stmt);
 
+  Bfunction*
+  lookup_builtin(const std::string&);
+
   void
   write_global_definitions(const std::vector<Btype*>&,
                            const std::vector<Bexpression*>&,
@@ -459,6 +465,14 @@  class Gcc_backend : public Backend
 
   tree
   non_zero_size_type(tree);
+
+private:
+  void
+  define_builtin(built_in_function bcode, const char* name, const char* libname,
+		 tree fntype, bool const_p);
+
+  // A mapping of the GCC built-ins exposed to GCCGo.
+  std::map<std::string, Bfunction*> builtin_functions_;
 };
 
 // A helper function.
@@ -469,6 +483,172 @@  get_identifier_from_string(const std::st
   return get_identifier_with_length(str.data(), str.length());
 }
 
+// Define the built-in functions that are exposed to GCCGo.
+
+Gcc_backend::Gcc_backend()
+{
+  /* We need to define the fetch_and_add functions, since we use them
+     for ++ and --.  */
+  tree t = this->integer_type(BITS_PER_UNIT, 1)->get_tree();
+  tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
+  this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
+		       NULL, build_function_type_list(t, p, t, NULL_TREE),
+		       false);
+
+  t = this->integer_type(BITS_PER_UNIT * 2, 1)->get_tree();
+  p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
+  this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
+		       NULL, build_function_type_list(t, p, t, NULL_TREE),
+		       false);
+
+  t = this->integer_type(BITS_PER_UNIT * 4, 1)->get_tree();
+  p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
+  this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
+		       NULL, build_function_type_list(t, p, t, NULL_TREE),
+		       false);
+
+  t = this->integer_type(BITS_PER_UNIT * 8, 1)->get_tree();
+  p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
+  this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
+		       NULL, build_function_type_list(t, p, t, NULL_TREE),
+		       false);
+
+  // We use __builtin_expect for magic import functions.
+  this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
+		       build_function_type_list(long_integer_type_node,
+						long_integer_type_node,
+						long_integer_type_node,
+						NULL_TREE),
+		       true);
+
+  // We use __builtin_memcmp for struct comparisons.
+  this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
+		       build_function_type_list(integer_type_node,
+						const_ptr_type_node,
+						const_ptr_type_node,
+						size_type_node,
+						NULL_TREE),
+		       false);
+
+  // We provide some functions for the math library.
+  tree math_function_type = build_function_type_list(double_type_node,
+						     double_type_node,
+						     NULL_TREE);
+  tree math_function_type_long =
+    build_function_type_list(long_double_type_node, long_double_type_node,
+			     long_double_type_node, NULL_TREE);
+  tree math_function_type_two = build_function_type_list(double_type_node,
+							 double_type_node,
+							 double_type_node,
+							 NULL_TREE);
+  tree math_function_type_long_two =
+    build_function_type_list(long_double_type_node, long_double_type_node,
+			     long_double_type_node, NULL_TREE);
+  this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
+		       math_function_type_two, true);
+  this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
+		       math_function_type_long_two, true);
+  this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
+		       math_function_type_two, true);
+  this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
+		       math_function_type_long_two, true);
+  this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
+		       build_function_type_list(double_type_node,
+						double_type_node,
+						integer_type_node,
+						NULL_TREE),
+		       true);
+  this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
+		       build_function_type_list(long_double_type_node,
+						long_double_type_node,
+						integer_type_node,
+						NULL_TREE),
+		       true);
+  this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
+		       math_function_type_long, true);
+  this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
+		       math_function_type, true);
+  this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
+		       math_function_type_long, true);
+
+  // We use __builtin_return_address in the thunk we build for
+  // functions which call recover.
+  this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
+		       NULL,
+		       build_function_type_list(ptr_type_node,
+						unsigned_type_node,
+						NULL_TREE),
+		       false);
+
+  // The compiler uses __builtin_trap for some exception handling
+  // cases.
+  this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
+		       build_function_type(void_type_node, void_list_node),
+		       false);
+}
+
 // Get an unnamed integer type.
 
 Btype*
@@ -2598,6 +2778,17 @@  Gcc_backend::function_set_body(Bfunction
   return true;
 }
 
+// Look up a named built-in function in the current backend implementation.
+// Returns NULL if no built-in function by that name exists.
+
+Bfunction*
+Gcc_backend::lookup_builtin(const std::string& name)
+{
+  if (this->builtin_functions_.count(name) != 0)
+    return this->builtin_functions_[name];
+  return NULL;
+}
+
 // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
 // FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
 
@@ -2680,16 +2871,38 @@  Gcc_backend::write_global_definitions(
   delete[] defs;
 }
 
-// The single backend.
+// Define a builtin function.  BCODE is the builtin function code
+// defined by builtins.def.  NAME is the name of the builtin function.
+// LIBNAME is the name of the corresponding library function, and is
+// NULL if there isn't one.  FNTYPE is the type of the function.
+// CONST_P is true if the function has the const attribute.
 
-static Gcc_backend gcc_backend;
+void
+Gcc_backend::define_builtin(built_in_function bcode, const char* name,
+			    const char* libname, tree fntype, bool const_p)
+{
+  tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
+				   libname, NULL_TREE);
+  if (const_p)
+    TREE_READONLY(decl) = 1;
+  set_builtin_decl(bcode, decl, true);
+  this->builtin_functions_[name] = this->make_function(decl);
+  if (libname != NULL)
+    {
+      decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
+				  NULL, NULL_TREE);
+      if (const_p)
+	TREE_READONLY(decl) = 1;
+      this->builtin_functions_[libname] = this->make_function(decl);
+    }
+}
 
 // Return the backend generator.
 
 Backend*
 go_get_backend()
 {
-  return &gcc_backend;
+  return new Gcc_backend();
 }
 
 // FIXME: Temporary functions while converting to the new backend
Index: gcc/go/gofrontend/backend.h
===================================================================
--- gcc/go/gofrontend/backend.h	(revision 209819)
+++ gcc/go/gofrontend/backend.h	(working copy)
@@ -660,6 +660,11 @@  class Backend
   virtual bool
   function_set_body(Bfunction* function, Bstatement* code_stmt) = 0;
 
+  // Look up a named built-in function in the current backend implementation.
+  // Returns NULL if no built-in function by that name exists.
+  virtual Bfunction*
+  lookup_builtin(const std::string&) = 0;
+
   // Utility.
 
   // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 209819)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -575,35 +575,10 @@  class Gogo
   void
   write_globals();
 
-  // Create trees for implicit builtin functions.
-  void
-  define_builtin_function_trees();
-
-  // Build a call to a builtin function.  PDECL should point to a NULL
-  // initialized static pointer which will hold the fndecl.  NAME is
-  // the name of the function.  NARGS is the number of arguments.
-  // RETTYPE is the return type.  It is followed by NARGS pairs of
-  // type and argument (both trees).
-  static tree
-  call_builtin(tree* pdecl, Location, const char* name, int nargs,
-	       tree rettype, ...);
-
   // Build a call to the runtime error function.
   Expression*
   runtime_error(int code, Location);
 
-  // Mark a function declaration as a builtin library function.
-  static void
-  mark_fndecl_as_builtin_library(tree fndecl);
-
-  // Build a constructor for a slice.  SLICE_TYPE_TREE is the type of
-  // the slice.  VALUES points to the values.  COUNT is the size,
-  // CAPACITY is the capacity.  If CAPACITY is NULL, it is set to
-  // COUNT.
-  static tree
-  slice_constructor(tree slice_type_tree, tree values, tree count,
-		    tree capacity);
-
   // Build required interface method tables.
   void
   build_interface_method_tables();
Index: gcc/go/gofrontend/gogo-tree.cc
===================================================================
--- gcc/go/gofrontend/gogo-tree.cc	(revision 209819)
+++ gcc/go/gofrontend/gogo-tree.cc	(working copy)
@@ -36,266 +36,6 @@  saw_errors()
   return errorcount != 0 || sorrycount != 0;
 }
 
-// A helper function.
-
-static inline tree
-get_identifier_from_string(const std::string& str)
-{
-  return get_identifier_with_length(str.data(), str.length());
-}
-
-// Builtin functions.
-
-static std::map<std::string, tree> builtin_functions;
-
-// Define a builtin function.  BCODE is the builtin function code
-// defined by builtins.def.  NAME is the name of the builtin function.
-// LIBNAME is the name of the corresponding library function, and is
-// NULL if there isn't one.  FNTYPE is the type of the function.
-// CONST_P is true if the function has the const attribute.
-
-static void
-define_builtin(built_in_function bcode, const char* name, const char* libname,
-	       tree fntype, bool const_p)
-{
-  tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
-				   libname, NULL_TREE);
-  if (const_p)
-    TREE_READONLY(decl) = 1;
-  set_builtin_decl(bcode, decl, true);
-  builtin_functions[name] = decl;
-  if (libname != NULL)
-    {
-      decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
-				  NULL, NULL_TREE);
-      if (const_p)
-	TREE_READONLY(decl) = 1;
-      builtin_functions[libname] = decl;
-    }
-}
-
-// Create trees for implicit builtin functions.
-
-void
-Gogo::define_builtin_function_trees()
-{
-  /* We need to define the fetch_and_add functions, since we use them
-     for ++ and --.  */
-  tree t = go_type_for_size(BITS_PER_UNIT, 1);
-  tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
-  define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1", NULL,
-		 build_function_type_list(t, p, t, NULL_TREE), false);
-
-  t = go_type_for_size(BITS_PER_UNIT * 2, 1);
-  p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
-  define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2", NULL,
-		  build_function_type_list(t, p, t, NULL_TREE), false);
-
-  t = go_type_for_size(BITS_PER_UNIT * 4, 1);
-  p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
-  define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4", NULL,
-		 build_function_type_list(t, p, t, NULL_TREE), false);
-
-  t = go_type_for_size(BITS_PER_UNIT * 8, 1);
-  p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
-  define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8", NULL,
-		 build_function_type_list(t, p, t, NULL_TREE), false);
-
-  // We use __builtin_expect for magic import functions.
-  define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
-		 build_function_type_list(long_integer_type_node,
-					  long_integer_type_node,
-					  long_integer_type_node,
-					  NULL_TREE),
-		 true);
-
-  // We use __builtin_memcmp for struct comparisons.
-  define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
-		 build_function_type_list(integer_type_node,
-					  const_ptr_type_node,
-					  const_ptr_type_node,
-					  size_type_node,
-					  NULL_TREE),
-		 false);
-
-  // We provide some functions for the math library.
-  tree math_function_type = build_function_type_list(double_type_node,
-						     double_type_node,
-						     NULL_TREE);
-  tree math_function_type_long =
-    build_function_type_list(long_double_type_node, long_double_type_node,
-			     long_double_type_node, NULL_TREE);
-  tree math_function_type_two = build_function_type_list(double_type_node,
-							 double_type_node,
-							 double_type_node,
-							 NULL_TREE);
-  tree math_function_type_long_two =
-    build_function_type_list(long_double_type_node, long_double_type_node,
-			     long_double_type_node, NULL_TREE);
-  define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
-		 math_function_type_two, true);
-  define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
-		 math_function_type_long_two, true);
-  define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
-		 math_function_type_two, true);
-  define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
-		 math_function_type_long_two, true);
-  define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
-		 build_function_type_list(double_type_node,
-					  double_type_node,
-					  integer_type_node,
-					  NULL_TREE),
-		 true);
-  define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
-		 build_function_type_list(long_double_type_node,
-					  long_double_type_node,
-					  integer_type_node,
-					  NULL_TREE),
-		 true);
-  define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
-		 math_function_type_long, true);
-  define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
-		 math_function_type, true);
-  define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
-		 math_function_type_long, true);
-
-  // We use __builtin_return_address in the thunk we build for
-  // functions which call recover.
-  define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address", NULL,
-		 build_function_type_list(ptr_type_node,
-					  unsigned_type_node,
-					  NULL_TREE),
-		 false);
-
-  // The compiler uses __builtin_trap for some exception handling
-  // cases.
-  define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
-		 build_function_type(void_type_node, void_list_node),
-		 false);
-}
-
-// Get the backend representation.
-
-Bfunction*
-Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
-{
-  if (this->fndecl_ == NULL)
-    {
-      // Let Go code use an asm declaration to pick up a builtin
-      // function.
-      if (!this->asm_name_.empty())
-	{
-	  std::map<std::string, tree>::const_iterator p =
-	    builtin_functions.find(this->asm_name_);
-	  if (p != builtin_functions.end())
-	    {
-	      this->fndecl_ = tree_to_function(p->second);
-	      return this->fndecl_;
-	    }
-	}
-
-      std::string asm_name;
-      if (this->asm_name_.empty())
-        {
-          asm_name = (no->package() == NULL
-                                  ? gogo->pkgpath_symbol()
-                                  : no->package()->pkgpath_symbol());
-          asm_name.append(1, '.');
-          asm_name.append(Gogo::unpack_hidden_name(no->name()));
-          if (this->fntype_->is_method())
-            {
-              asm_name.append(1, '.');
-              Type* rtype = this->fntype_->receiver()->type();
-              asm_name.append(rtype->mangled_name(gogo));
-            }
-        }
-
-      Btype* functype = this->fntype_->get_backend_fntype(gogo);
-      this->fndecl_ =
-          gogo->backend()->function(functype, no->get_id(gogo), asm_name,
-                                    true, true, true, false, false,
-                                    this->location());
-    }
-
-  return this->fndecl_;
-}
-
-// Build the descriptor for a function declaration.  This won't
-// necessarily happen if the package has just a declaration for the
-// function and no other reference to it, but we may still need the
-// descriptor for references from other packages.
-void
-Function_declaration::build_backend_descriptor(Gogo* gogo)
-{
-  if (this->descriptor_ != NULL)
-    {
-      Translate_context context(gogo, NULL, NULL, NULL);
-      this->descriptor_->get_tree(&context);
-    }
-}
-
 // Return the integer type to use for a size.
 
 GO_EXTERN_C
@@ -380,121 +120,3 @@  go_type_for_mode(enum machine_mode mode,
   else
     return NULL_TREE;
 }
-
-// Build a constructor for a slice.  SLICE_TYPE_TREE is the type of
-// the slice.  VALUES is the value pointer and COUNT is the number of
-// entries.  If CAPACITY is not NULL, it is the capacity; otherwise
-// the capacity and the count are the same.
-
-tree
-Gogo::slice_constructor(tree slice_type_tree, tree values, tree count,
-			tree capacity)
-{
-  go_assert(TREE_CODE(slice_type_tree) == RECORD_TYPE);
-
-  vec<constructor_elt, va_gc> *init;
-  vec_alloc(init, 3);
-
-  tree field = TYPE_FIELDS(slice_type_tree);
-  go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__values") == 0);
-  constructor_elt empty = {NULL, NULL};
-  constructor_elt* elt = init->quick_push(empty);
-  elt->index = field;
-  go_assert(TYPE_MAIN_VARIANT(TREE_TYPE(field))
-	     == TYPE_MAIN_VARIANT(TREE_TYPE(values)));
-  elt->value = values;
-
-  count = fold_convert(sizetype, count);
-  if (capacity == NULL_TREE)
-    {
-      count = save_expr(count);
-      capacity = count;
-    }
-
-  field = DECL_CHAIN(field);
-  go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__count") == 0);
-  elt = init->quick_push(empty);
-  elt->index = field;
-  elt->value = fold_convert(TREE_TYPE(field), count);
-
-  field = DECL_CHAIN(field);
-  go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__capacity") == 0);
-  elt = init->quick_push(empty);
-  elt->index = field;
-  elt->value = fold_convert(TREE_TYPE(field), capacity);
-
-  return build_constructor(slice_type_tree, init);
-}
-
-// Mark a function as a builtin library function.
-
-void
-Gogo::mark_fndecl_as_builtin_library(tree fndecl)
-{
-  DECL_EXTERNAL(fndecl) = 1;
-  TREE_PUBLIC(fndecl) = 1;
-  DECL_ARTIFICIAL(fndecl) = 1;
-  TREE_NOTHROW(fndecl) = 1;
-  DECL_VISIBILITY(fndecl) = VISIBILITY_DEFAULT;
-  DECL_VISIBILITY_SPECIFIED(fndecl) = 1;
-}
-
-// Build a call to a builtin function.
-
-tree
-Gogo::call_builtin(tree* pdecl, Location location, const char* name,
-		   int nargs, tree rettype, ...)
-{
-  if (rettype == error_mark_node)
-    return error_mark_node;
-
-  tree* types = new tree[nargs];
-  tree* args = new tree[nargs];
-
-  va_list ap;
-  va_start(ap, rettype);
-  for (int i = 0; i < nargs; ++i)
-    {
-      types[i] = va_arg(ap, tree);
-      args[i] = va_arg(ap, tree);
-      if (types[i] == error_mark_node || args[i] == error_mark_node)
-	{
-	  delete[] types;
-	  delete[] args;
-	  return error_mark_node;
-	}
-    }
-  va_end(ap);
-
-  if (*pdecl == NULL_TREE)
-    {
-      tree fnid = get_identifier(name);
-
-      tree argtypes = NULL_TREE;
-      tree* pp = &argtypes;
-      for (int i = 0; i < nargs; ++i)
-	{
-	  *pp = tree_cons(NULL_TREE, types[i], NULL_TREE);
-	  pp = &TREE_CHAIN(*pp);
-	}
-      *pp = void_list_node;
-
-      tree fntype = build_function_type(rettype, argtypes);
-
-      *pdecl = build_decl(BUILTINS_LOCATION, FUNCTION_DECL, fnid, fntype);
-      Gogo::mark_fndecl_as_builtin_library(*pdecl);
-      go_preserve_from_gc(*pdecl);
-    }
-
-  tree fnptr = build_fold_addr_expr(*pdecl);
-  if (CAN_HAVE_LOCATION_P(fnptr))
-    SET_EXPR_LOCATION(fnptr, location.gcc_location());
-
-  tree ret = build_call_array(rettype, fnptr, nargs, args);
-  SET_EXPR_LOCATION(ret, location.gcc_location());
-
-  delete[] types;
-  delete[] args;
-
-  return ret;
-}
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 209819)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -4855,6 +4855,66 @@  Function::get_or_make_decl(Gogo* gogo, N
   return this->fndecl_;
 }
 
+// Get the backend representation.
+
+Bfunction*
+Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
+{
+  if (this->fndecl_ == NULL)
+    {
+      // Let Go code use an asm declaration to pick up a builtin
+      // function.
+      if (!this->asm_name_.empty())
+	{
+	  Bfunction* builtin_decl =
+	    gogo->backend()->lookup_builtin(this->asm_name_);
+	  if (builtin_decl != NULL)
+	    {
+	      this->fndecl_ = builtin_decl;
+	      return this->fndecl_;
+	    }
+	}
+
+      std::string asm_name;
+      if (this->asm_name_.empty())
+        {
+          asm_name = (no->package() == NULL
+                                  ? gogo->pkgpath_symbol()
+                                  : no->package()->pkgpath_symbol());
+          asm_name.append(1, '.');
+          asm_name.append(Gogo::unpack_hidden_name(no->name()));
+          if (this->fntype_->is_method())
+            {
+              asm_name.append(1, '.');
+              Type* rtype = this->fntype_->receiver()->type();
+              asm_name.append(rtype->mangled_name(gogo));
+            }
+        }
+
+      Btype* functype = this->fntype_->get_backend_fntype(gogo);
+      this->fndecl_ =
+          gogo->backend()->function(functype, no->get_id(gogo), asm_name,
+                                    true, true, true, false, false,
+                                    this->location());
+    }
+
+  return this->fndecl_;
+}
+
+// Build the descriptor for a function declaration.  This won't
+// necessarily happen if the package has just a declaration for the
+// function and no other reference to it, but we may still need the
+// descriptor for references from other packages.
+void
+Function_declaration::build_backend_descriptor(Gogo* gogo)
+{
+  if (this->descriptor_ != NULL)
+    {
+      Translate_context context(gogo, NULL, NULL, NULL);
+      this->descriptor_->get_tree(&context);
+    }
+}
+
 // Return the function's decl after it has been built.
 
 Bfunction*
Index: gcc/go/gofrontend/go.cc
===================================================================
--- gcc/go/gofrontend/go.cc	(revision 209392)
+++ gcc/go/gofrontend/go.cc	(working copy)
@@ -34,9 +34,6 @@  go_create_gogo(int int_type_size, int po
 
   if (relative_import_path != NULL)
     ::gogo->set_relative_import_path(relative_import_path);
-
-  // FIXME: This should be in the gcc dependent code.
-  ::gogo->define_builtin_function_trees();
 }
 
 // Parse the input files.