This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Use backend interface for initialization function


This patch from Chris Manghane changes the Go frontend to use the
backend interface for the initialization function.  Bootstrapped and ran
Go testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


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

	* go-gcc.cc (Gcc_backend::temporary_variable): Push cfun around
	call to create_tmp_var.  Require that function be non-NULL.


Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 209495)
+++ gcc/go/go-gcc.cc	(working copy)
@@ -2214,10 +2214,21 @@ Gcc_backend::temporary_variable(Bfunctio
       return this->error_variable();
     }
 
+  go_assert(function != NULL);
+  tree decl = function->get_tree();
+
   tree var;
   // We can only use create_tmp_var if the type is not addressable.
   if (!TREE_ADDRESSABLE(type_tree))
-    var = create_tmp_var(type_tree, "GOTMP");
+    {
+      if (DECL_STRUCT_FUNCTION(decl) == NULL)
+      	push_struct_function(decl);
+      else
+      	push_cfun(DECL_STRUCT_FUNCTION(decl));
+
+      var = create_tmp_var(type_tree, "GOTMP");
+      pop_cfun();
+    }
   else
     {
       gcc_assert(bblock != NULL);
@@ -2227,16 +2238,7 @@ Gcc_backend::temporary_variable(Bfunctio
       DECL_ARTIFICIAL(var) = 1;
       DECL_IGNORED_P(var) = 1;
       TREE_USED(var) = 1;
-      // FIXME: Permitting function to be NULL here is a temporary
-      // measure until we have a proper representation of the init
-      // function.
-      if (function != NULL)
-	DECL_CONTEXT(var) = function->get_tree();
-      else
-	{
-	  gcc_assert(current_function_decl != NULL_TREE);
-	  DECL_CONTEXT(var) = current_function_decl;
-	}
+      DECL_CONTEXT(var) = decl;
 
       // We have to add this variable to the BLOCK and the BIND_EXPR.
       tree bind_tree = bblock->get_tree();
Index: gcc/go/gofrontend/gogo-tree.cc
===================================================================
--- gcc/go/gofrontend/gogo-tree.cc	(revision 209495)
+++ gcc/go/gofrontend/gogo-tree.cc	(working copy)
@@ -236,32 +236,6 @@ Gogo::define_builtin_function_trees()
 		 false);
 }
 
-// Get the name to use for the import control function.  If there is a
-// global function or variable, then we know that that name must be
-// unique in the link, and we use it as the basis for our name.
-
-const std::string&
-Gogo::get_init_fn_name()
-{
-  if (this->init_fn_name_.empty())
-    {
-      go_assert(this->package_ != NULL);
-      if (this->is_main_package())
-	{
-	  // Use a name which the runtime knows.
-	  this->init_fn_name_ = "__go_init_main";
-	}
-      else
-	{
-	  std::string s = this->pkgpath_symbol();
-	  s.append("..import");
-	  this->init_fn_name_ = s;
-	}
-    }
-
-  return this->init_fn_name_;
-}
-
 // Add statements to INIT_STMT_LIST which run the initialization
 // functions for imported packages.  This is only used for the "main"
 // package.
@@ -434,65 +408,31 @@ Gogo::register_gc_vars(const std::vector
     append_to_statement_list(call, init_stmt_list);
 }
 
-// Build the decl for the initialization function.
-
-tree
-Gogo::initialization_function_decl()
-{
-  // The tedious details of building your own function.  There doesn't
-  // seem to be a helper function for this.
-  std::string name = this->package_name() + ".init";
-  tree fndecl = build_decl(this->package_->location().gcc_location(),
-			   FUNCTION_DECL, get_identifier_from_string(name),
-			   build_function_type(void_type_node,
-					       void_list_node));
-  const std::string& asm_name(this->get_init_fn_name());
-  SET_DECL_ASSEMBLER_NAME(fndecl, get_identifier_from_string(asm_name));
-
-  tree resdecl = build_decl(this->package_->location().gcc_location(),
-			    RESULT_DECL, NULL_TREE, void_type_node);
-  DECL_ARTIFICIAL(resdecl) = 1;
-  DECL_CONTEXT(resdecl) = fndecl;
-  DECL_RESULT(fndecl) = resdecl;
-
-  TREE_STATIC(fndecl) = 1;
-  TREE_USED(fndecl) = 1;
-  DECL_ARTIFICIAL(fndecl) = 1;
-  TREE_PUBLIC(fndecl) = 1;
-
-  DECL_INITIAL(fndecl) = make_node(BLOCK);
-  TREE_USED(DECL_INITIAL(fndecl)) = 1;
-
-  return fndecl;
-}
-
 // Create the magic initialization function.  INIT_STMT_LIST is the
 // code that it needs to run.
 
 void
-Gogo::write_initialization_function(tree fndecl, tree init_stmt_list)
+Gogo::write_initialization_function(Named_object* initfn, tree init_stmt_list)
 {
   // Make sure that we thought we needed an initialization function,
   // as otherwise we will not have reported it in the export data.
   go_assert(this->is_main_package() || this->need_init_fn_);
 
-  if (fndecl == NULL_TREE)
-    fndecl = this->initialization_function_decl();
-
-  DECL_SAVED_TREE(fndecl) = init_stmt_list;
-
-  if (DECL_STRUCT_FUNCTION(fndecl) == NULL)
-    push_struct_function(fndecl);
-  else
-    push_cfun(DECL_STRUCT_FUNCTION(fndecl));
-  cfun->function_start_locus = this->package_->location().gcc_location();
-  cfun->function_end_locus = cfun->function_start_locus;
+  if (initfn == NULL)
+    initfn = this->initialization_function_decl();
 
-  gimplify_function_tree(fndecl);
+  Bfunction* fndecl = initfn->func_value()->get_or_make_decl(this, initfn);
+  Location loc = this->package_->location();
+  std::vector<Bvariable*> vars;
+  this->backend()->block(fndecl, NULL, vars, loc, loc);
 
-  cgraph_add_new_function(fndecl, false);
-
-  pop_cfun();
+  if (!this->backend()->function_set_body(fndecl, tree_to_stat(init_stmt_list)))
+    {
+      go_assert(saw_errors());
+      return;
+    }
+  gimplify_function_tree(function_to_tree(fndecl));
+  cgraph_add_new_function(function_to_tree(fndecl), false);
 }
 
 // Search for references to VAR in any statements or called functions.
@@ -775,7 +715,7 @@ Gogo::write_globals()
 
   tree* vec = new tree[count];
 
-  tree init_fndecl = NULL_TREE;
+  Named_object* init_fndecl = NULL;
   tree init_stmt_list = NULL_TREE;
 
   if (this->is_main_package())
@@ -902,17 +842,12 @@ Gogo::write_globals()
 	    {
 	      // We are going to create temporary variables which
 	      // means that we need an fndecl.
-	      if (init_fndecl == NULL_TREE)
+	      if (init_fndecl == NULL)
 		init_fndecl = this->initialization_function_decl();
-	      if (DECL_STRUCT_FUNCTION(init_fndecl) == NULL)
-		push_struct_function(init_fndecl);
-	      else
-		push_cfun(DECL_STRUCT_FUNCTION(init_fndecl));
+
 	      Bvariable* var_decl = is_sink ? NULL : var;
               var_init_stmt =
-                  no->var_value()->get_init_block(this, NULL, var_decl);
-
-	      pop_cfun();
+                  no->var_value()->get_init_block(this, init_fndecl, var_decl);
 	    }
 
 	  if (var_init_stmt != NULL)
@@ -975,7 +910,7 @@ Gogo::write_globals()
 
   // Set up a magic function to do all the initialization actions.
   // This will be called if this package is imported.
-  if (init_stmt_list != NULL_TREE
+  if (init_stmt_list != NULL
       || this->need_init_fn_
       || this->is_main_package())
     this->write_initialization_function(init_fndecl, init_stmt_list);
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 209393)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -575,6 +575,45 @@ Gogo::current_bindings() const
     return this->globals_;
 }
 
+// Get the name to use for the import control function.  If there is a
+// global function or variable, then we know that that name must be
+// unique in the link, and we use it as the basis for our name.
+
+const std::string&
+Gogo::get_init_fn_name()
+{
+  if (this->init_fn_name_.empty())
+    {
+      go_assert(this->package_ != NULL);
+      if (this->is_main_package())
+	{
+	  // Use a name which the runtime knows.
+	  this->init_fn_name_ = "__go_init_main";
+	}
+      else
+	{
+	  std::string s = this->pkgpath_symbol();
+	  s.append("..import");
+	  this->init_fn_name_ = s;
+	}
+    }
+
+  return this->init_fn_name_;
+}
+
+// Build the decl for the initialization function.
+
+Named_object*
+Gogo::initialization_function_decl()
+{
+  std::string name = this->get_init_fn_name();
+  Location loc = this->package_->location();
+
+  Function_type* fntype = Type::make_function_type(NULL, NULL, NULL, loc);
+  Function* initfn = new Function(fntype, NULL, NULL, loc);
+  return Named_object::make_function(name, NULL, initfn);
+}
+
 // Return the current block.
 
 Block*
@@ -4071,7 +4110,12 @@ Function::get_or_make_decl(Gogo* gogo, N
         ;
       else if (Gogo::unpack_hidden_name(no->name()) == "init"
                && !this->type_->is_method())
-        ;
+	;
+      else if (no->name() == gogo->get_init_fn_name())
+	{
+	  is_visible = true;
+	  asm_name = no->name();
+	}
       else if (Gogo::unpack_hidden_name(no->name()) == "main"
                && gogo->is_main_package())
         is_visible = true;
@@ -4647,13 +4691,9 @@ Block::get_backend(Translate_context* co
 	vars.push_back((*pv)->get_backend_variable(gogo, function));
     }
 
-  // FIXME: Permitting FUNCTION to be NULL here is a temporary measure
-  // until we have a proper representation of the init function.
-  Bfunction* bfunction;
-  if (function == NULL)
-    bfunction = NULL;
-  else
-    bfunction = tree_to_function(function->func_value()->get_decl());
+  go_assert(function != NULL);
+  Bfunction* bfunction =
+    function->func_value()->get_or_make_decl(gogo, function);
   Bblock* ret = context->backend()->block(bfunction, context->bblock(),
 					  vars, this->start_location_,
 					  this->end_location_);
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 209393)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -616,6 +616,10 @@ class Gogo
   Expression*
   allocate_memory(Type *type, Location);
 
+  // Get the name of the magic initialization function.
+  const std::string&
+  get_init_fn_name();
+
  private:
   // During parsing, we keep a stack of functions.  Each function on
   // the stack is one that we are currently parsing.  For each
@@ -642,17 +646,13 @@ class Gogo
   const Bindings*
   current_bindings() const;
 
-  // Get the name of the magic initialization function.
-  const std::string&
-  get_init_fn_name();
-
   // Get the decl for the magic initialization function.
-  tree
+  Named_object*
   initialization_function_decl();
 
   // Write the magic initialization function.
   void
-  write_initialization_function(tree fndecl, tree init_stmt_list);
+  write_initialization_function(Named_object* fndecl, tree init_stmt_list);
 
   // Initialize imported packages.
   void

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]