From 0e94da57dc1e5712c60a876545a0c09a4d672002 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 23 Apr 2016 04:58:00 +0000 Subject: [PATCH] compiler: Expose runtime code through Func_expression. Enables us to easily check if a Call_expression is a call to a runtime function and, if so, which runtime function is corresponds to. This will be used during escape analysis. Reviewed-on: https://go-review.googlesource.com/18544 From-SVN: r235383 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 8 ++++++- gcc/go/gofrontend/expressions.h | 23 +++++++++++++++++++- gcc/go/gofrontend/runtime.cc | 36 ++++++++++++++++++++++++++++++++ gcc/go/gofrontend/runtime.h | 4 ++++ 5 files changed, 70 insertions(+), 3 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5c8cd7d6f18..6b2e105a2d3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -97b358f525584e45fa2e3d83fc7d3a091900927a +944c3ca6ac7c204585fd73936894fe05de535b94 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/expressions.cc b/gcc/go/gofrontend/expressions.cc index 09ab5bf8f7e..170d95703c6 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1141,7 +1141,13 @@ Expression* Expression::make_func_reference(Named_object* function, Expression* closure, Location location) { - return new Func_expression(function, closure, location); + Func_expression* fe = new Func_expression(function, closure, location); + + // Detect references to builtin functions and set the runtime code if + // appropriate. + if (function->is_function_declaration()) + fe->set_runtime_code(Runtime::name_to_code(function->name())); + return fe; } // Class Func_descriptor_expression. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index c33e63653e6..6c780607f2d 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -11,6 +11,7 @@ #include #include "operator.h" +#include "runtime.h" class Gogo; class Translate_context; @@ -2149,7 +2150,8 @@ class Func_expression : public Expression Func_expression(Named_object* function, Expression* closure, Location location) : Expression(EXPRESSION_FUNC_REFERENCE, location), - function_(function), closure_(closure) + function_(function), closure_(closure), + runtime_code_(Runtime::NUMBER_OF_FUNCTIONS) { } // Return the object associated with the function. @@ -2163,6 +2165,23 @@ class Func_expression : public Expression closure() { return this->closure_; } + // Return whether this is a reference to a runtime function. + bool + is_runtime_function() const + { return this->runtime_code_ != Runtime::NUMBER_OF_FUNCTIONS; } + + // Return the runtime code for this function expression. + // Returns Runtime::NUMBER_OF_FUNCTIONS if this is not a reference to a + // runtime function. + Runtime::Function + runtime_code() const + { return this->runtime_code_; } + + // Set the runtime code for this function expression. + void + set_runtime_code(Runtime::Function code) + { this->runtime_code_ = code; } + // Return a backend expression for the code of a function. static Bexpression* get_code_pointer(Gogo*, Named_object* function, Location loc); @@ -2204,6 +2223,8 @@ class Func_expression : public Expression // be a struct holding pointers to all the variables referenced by // this function and defined in enclosing functions. Expression* closure_; + // The runtime code for the referenced function. + Runtime::Function runtime_code_; }; // A function descriptor. A function descriptor is a struct with a diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc index de68f64b593..64920250e43 100644 --- a/gcc/go/gofrontend/runtime.cc +++ b/gcc/go/gofrontend/runtime.cc @@ -402,3 +402,39 @@ Runtime::map_iteration_type() Linemap::predeclared_location()); return Type::make_array_type(runtime_function_type(RFT_POINTER), iexpr); } + + +// Get the runtime code for a named builtin function. This is used as a helper +// when creating function references for call expressions. Every reference to +// a builtin runtime function should have the associated runtime code. If the +// name is ambiguous and can refer to many runtime codes, return +// NUMBER_OF_FUNCTIONS. + +Runtime::Function +Runtime::name_to_code(const std::string& name) +{ + Function code = Runtime::NUMBER_OF_FUNCTIONS; + + // Aliases seen in function declaration code. + // TODO(cmang): Add other aliases. + if (name == "new") + code = Runtime::NEW; + else if (name == "close") + code = Runtime::CLOSE; + else if (name == "copy") + code = Runtime::COPY; + else if (name == "append") + code = Runtime::APPEND; + else if (name == "delete") + code = Runtime::MAPDELETE; + else + { + // Look through the known names for a match. + for (size_t i = 0; i < Runtime::NUMBER_OF_FUNCTIONS; i++) + { + if (strcmp(runtime_functions[i].name, name.c_str()) == 0) + code = static_cast(i); + } + } + return code; +} diff --git a/gcc/go/gofrontend/runtime.h b/gcc/go/gofrontend/runtime.h index be5dcbe25d0..636e1965006 100644 --- a/gcc/go/gofrontend/runtime.h +++ b/gcc/go/gofrontend/runtime.h @@ -43,6 +43,10 @@ class Runtime static Type* map_iteration_type(); + // Return the runtime code for a named builtin function. + static Function + name_to_code(const std::string&); + private: static Named_object* runtime_declaration(Function); -- 2.30.2