From: Chris Manghane Date: Tue, 22 Apr 2014 23:46:30 +0000 (+0000) Subject: compiler: Use backend interface for initialization functions. X-Git-Tag: upstream/12.2.0~63699 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aa4929209a17cc4070b900d9bd2947b50c6f83d1;p=platform%2Fupstream%2Fgcc.git compiler: Use backend interface for initialization functions. * go-gcc.cc (Gcc_backend::temporary_variable): Push cfun around call to create_tmp_var. Require that function be non-NULL. From-SVN: r209665 --- diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index c8beaec..966fd42 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2014-04-22 Chris Manghane + + * go-gcc.cc (Gcc_backend::temporary_variable): Push cfun around + call to create_tmp_var. Require that function be non-NULL. + 2014-04-17 Chris Manghane * go-gcc.cc (Gcc_backend::named_constant_expression): New diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 1af639e..376e4dc 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -2214,10 +2214,21 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock, 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(Bfunction* function, Bblock* bblock, 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(); diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 32a7f38..c00e7d1 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -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& var_gc, 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(); + if (initfn == NULL) + initfn = 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; + Bfunction* fndecl = initfn->func_value()->get_or_make_decl(this, initfn); + Location loc = this->package_->location(); + std::vector vars; + this->backend()->block(fndecl, NULL, vars, loc, loc); - gimplify_function_tree(fndecl); - - 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); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 6df4b6b..ac9510e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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, Named_object* no) ; 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* context) 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_); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 3dc401d..dd43d26 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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