From a4e30bef6446858bba7222afcf233c2d92e5c774 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 29 Oct 2018 19:25:57 +0000 Subject: [PATCH] compiler: pass a single flags argument to Backend::function Reviewed-on: https://go-review.googlesource.com/c/145319 * go-gcc.cc (Gcc_backend::function): Change to use a single flags parameter. From-SVN: r265599 --- gcc/go/ChangeLog | 5 ++++ gcc/go/go-gcc.cc | 22 +++++++---------- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/backend.h | 49 ++++++++++++++++++++++++------------- gcc/go/gofrontend/gogo.cc | 43 +++++++++++++++++++------------- 5 files changed, 73 insertions(+), 48 deletions(-) diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 915630daec9..e6f8644441f 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2018-10-29 Ian Lance Taylor + + * go-gcc.cc (Gcc_backend::function): Change to use a single flags + parameter. + 2018-10-29 Ian Lance Taylor * go-linemap.cc (Gcc_linemap::location_file): New method. diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 1a449b7cc47..9c317e06a92 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -482,9 +482,7 @@ class Gcc_backend : public Backend Bfunction* function(Btype* fntype, const std::string& name, const std::string& asm_name, - bool is_visible, bool is_declaration, bool is_inlinable, - bool disable_split_stack, bool does_not_return, - bool in_unique_section, Location); + unsigned int flags, Location); Bstatement* function_defer_statement(Bfunction* function, Bexpression* undefer, @@ -3047,10 +3045,8 @@ Gcc_backend::label_address(Blabel* label, Location location) Bfunction* Gcc_backend::function(Btype* fntype, const std::string& name, - const std::string& asm_name, bool is_visible, - bool is_declaration, bool is_inlinable, - bool disable_split_stack, bool does_not_return, - bool in_unique_section, Location location) + const std::string& asm_name, unsigned int flags, + Location location) { tree functype = fntype->get_tree(); if (functype != error_mark_node) @@ -3065,9 +3061,9 @@ Gcc_backend::function(Btype* fntype, const std::string& name, tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype); if (! asm_name.empty()) SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name)); - if (is_visible) + if ((flags & function_is_visible) != 0) TREE_PUBLIC(decl) = 1; - if (is_declaration) + if ((flags & function_is_declaration) != 0) DECL_EXTERNAL(decl) = 1; else { @@ -3079,16 +3075,16 @@ Gcc_backend::function(Btype* fntype, const std::string& name, DECL_CONTEXT(resdecl) = decl; DECL_RESULT(decl) = resdecl; } - if (!is_inlinable) + if ((flags & function_is_inlinable) == 0) DECL_UNINLINABLE(decl) = 1; - if (disable_split_stack) + if ((flags & function_no_split_stack) != 0) { tree attr = get_identifier ("no_split_stack"); DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); } - if (does_not_return) + if ((flags & function_does_not_return) != 0) TREE_THIS_VOLATILE(decl) = 1; - if (in_unique_section) + if ((flags & function_in_unique_section) != 0) resolve_unique_section(decl, 0, 1); go_preserve_from_gc(decl); diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7074d3e508a..90ba4494aa6 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -e4a421a01ad1fcc4315e530e79272604f3683051 +8dae05f57f3c8249319e3360b10f07dcc2cd57a7 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h index 5cc0dec4a88..d2e93d24f49 100644 --- a/gcc/go/gofrontend/backend.h +++ b/gcc/go/gofrontend/backend.h @@ -699,26 +699,41 @@ class Backend virtual Bfunction* error_function() = 0; + // Bit flags to pass to the function method. + + // Set if the function should be visible outside of the current + // compilation unit. + static const unsigned int function_is_visible = 1 << 0; + + // Set if this is a function declaration rather than a definition; + // the definition will be in another compilation unit. + static const unsigned int function_is_declaration = 1 << 1; + + // Set if the function can be inlined. This is normally set, but is + // false for functions that may not be inlined because they call + // recover and must be visible for correct panic recovery. + static const unsigned int function_is_inlinable = 1 << 2; + + // Set if the function may not split the stack. This is set for the + // implementation of recover itself, among other things. + static const unsigned int function_no_split_stack = 1 << 3; + + // Set if the function does not return. This is set for the + // implementation of panic. + static const unsigned int function_does_not_return = 1 << 4; + + // Set if the function should be put in a unique section if + // possible. This is used for field tracking. + static const unsigned int function_in_unique_section = 1 << 5; + // Declare or define a function of FNTYPE. - // NAME is the Go name of the function. ASM_NAME, if not the empty string, is - // the name that should be used in the symbol table; this will be non-empty if - // a magic extern comment is used. - // IS_VISIBLE is true if this function should be visible outside of the - // current compilation unit. IS_DECLARATION is true if this is a function - // declaration rather than a definition; the function definition will be in - // another compilation unit. - // IS_INLINABLE is true if the function can be inlined. - // DISABLE_SPLIT_STACK is true if this function may not split the stack; this - // is used for the implementation of recover. - // DOES_NOT_RETURN is true for a function that does not return; this is used - // for the implementation of panic. - // IN_UNIQUE_SECTION is true if this function should be put into a unique - // location if possible; this is used for field tracking. + // NAME is the Go name of the function. ASM_NAME, if not the empty + // string, is the name that should be used in the symbol table; this + // will be non-empty if a magic extern comment is used. FLAGS is + // bit flags described above. virtual Bfunction* function(Btype* fntype, const std::string& name, const std::string& asm_name, - bool is_visible, bool is_declaration, bool is_inlinable, - bool disable_split_stack, bool does_not_return, - bool in_unique_section, Location) = 0; + unsigned int flags, Location) = 0; // Create a statement that runs all deferred calls for FUNCTION. This should // be a statement that looks like this in C++: diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 70af6273b01..6ea247a989f 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -719,10 +719,12 @@ Gogo::init_imports(std::vector& init_stmts, Bfunction *bfunction) const Import_init* ii = *p; std::string user_name = ii->package_name() + ".init"; const std::string& init_name(ii->init_name()); - + const unsigned int flags = + (Backend::function_is_visible + | Backend::function_is_declaration + | Backend::function_is_inlinable); Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name, - true, true, true, false, - false, false, unknown_loc); + flags, unknown_loc); Bexpression* pfunc_code = this->backend()->function_code_expression(pfunc, unknown_loc); Bexpression* pfunc_call = @@ -5521,7 +5523,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) { if (this->fndecl_ == NULL) { - bool is_visible = false; + unsigned int flags = 0; bool is_init_fn = false; Type* rtype = NULL; if (no->package() != NULL) @@ -5533,12 +5535,12 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) ; else if (no->name() == gogo->get_init_fn_name()) { - is_visible = true; + flags |= Backend::function_is_visible; is_init_fn = true; } else if (Gogo::unpack_hidden_name(no->name()) == "main" && gogo->is_main_package()) - is_visible = true; + flags |= Backend::function_is_visible; // Methods have to be public even if they are hidden because // they can be pulled into type descriptors when using // anonymous fields. @@ -5546,7 +5548,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) || this->type_->is_method()) { if (!this->is_unnamed_type_stub_method_) - is_visible = true; + flags |= Backend::function_is_visible; if (this->type_->is_method()) rtype = this->type_->receiver()->type(); } @@ -5559,7 +5561,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) // If an assembler name is explicitly specified, there must // be some reason to refer to the symbol from a different // object file. - is_visible = true; + flags |= Backend::function_is_visible; } else if (is_init_fn) { @@ -5591,6 +5593,9 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) if ((this->pragmas_ & GOPRAGMA_NOINLINE) != 0) is_inlinable = false; + if (is_inlinable) + flags |= Backend::function_is_inlinable; + // If this is a thunk created to call a function which calls // the predeclared recover function, we need to disable // stack splitting for the thunk. @@ -5600,20 +5605,22 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) if ((this->pragmas_ & GOPRAGMA_NOSPLIT) != 0) disable_split_stack = true; + if (disable_split_stack) + flags |= Backend::function_no_split_stack; + // This should go into a unique section if that has been // requested elsewhere, or if this is a nointerface function. // We want to put a nointerface function into a unique section // because there is a good chance that the linker garbage // collection can discard it. - bool in_unique_section = (this->in_unique_section_ - || (this->is_method() && this->nointerface())); + if (this->in_unique_section_ + || (this->is_method() && this->nointerface())) + flags |= Backend::function_in_unique_section; Btype* functype = this->type_->get_backend_fntype(gogo); this->fndecl_ = gogo->backend()->function(functype, no->get_id(gogo), asm_name, - is_visible, false, is_inlinable, - disable_split_stack, false, - in_unique_section, this->location()); + flags, this->location()); } return this->fndecl_; } @@ -5625,7 +5632,10 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) { if (this->fndecl_ == NULL) { - bool does_not_return = false; + unsigned int flags = + (Backend::function_is_visible + | Backend::function_is_declaration + | Backend::function_is_inlinable); // Let Go code use an asm declaration to pick up a builtin // function. @@ -5641,7 +5651,7 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) if (this->asm_name_ == "runtime.gopanic" || this->asm_name_ == "__go_runtime_error") - does_not_return = true; + flags |= Backend::function_does_not_return; } std::string asm_name; @@ -5658,8 +5668,7 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) Btype* functype = this->fntype_->get_backend_fntype(gogo); this->fndecl_ = gogo->backend()->function(functype, no->get_id(gogo), asm_name, - true, true, true, false, does_not_return, - false, this->location()); + flags, this->location()); } return this->fndecl_; -- 2.30.2