Commit 41a6da2d by Ian Lance Taylor

compiler: support go:noescape cross package

    
    CL 83876 added support of go:noescape pragma, but it only works
    for functions called from the same package. The pragma did not
    take effect for exported functions that are not called from
    the same package. The reason is that top level function
    declarations are not traversed, and only reached from calls
    from other functions. This CL adds this support. The Traverse
    class is extended with a mode to traverse function declarations.
    
    Reviewed-on: https://go-review.googlesource.com/85637

From-SVN: r256405
parent e732b424
b361bec95927fd6209c286906f98deeedcfe1da3 cf5a64066fa21b20beae0b895c05d26af53e13e0
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -997,7 +997,7 @@ class Escape_analysis_discover : public Traverse ...@@ -997,7 +997,7 @@ class Escape_analysis_discover : public Traverse
{ {
public: public:
Escape_analysis_discover(Gogo* gogo) Escape_analysis_discover(Gogo* gogo)
: Traverse(traverse_functions), : Traverse(traverse_functions | traverse_func_declarations),
gogo_(gogo), component_ids_() gogo_(gogo), component_ids_()
{ } { }
...@@ -1005,6 +1005,9 @@ class Escape_analysis_discover : public Traverse ...@@ -1005,6 +1005,9 @@ class Escape_analysis_discover : public Traverse
function(Named_object*); function(Named_object*);
int int
function_declaration(Named_object*);
int
visit(Named_object*); visit(Named_object*);
int int
...@@ -1036,6 +1039,13 @@ Escape_analysis_discover::function(Named_object* fn) ...@@ -1036,6 +1039,13 @@ Escape_analysis_discover::function(Named_object* fn)
return TRAVERSE_CONTINUE; return TRAVERSE_CONTINUE;
} }
int
Escape_analysis_discover::function_declaration(Named_object* fn)
{
this->visit(fn);
return TRAVERSE_CONTINUE;
}
// Visit a function FN, adding it to the current stack of functions // Visit a function FN, adding it to the current stack of functions
// in this connected component. If this is the root of the component, // in this connected component. If this is the root of the component,
// create a set of functions to be analyzed later. // create a set of functions to be analyzed later.
......
...@@ -7912,6 +7912,21 @@ Bindings::traverse(Traverse* traverse, bool is_global) ...@@ -7912,6 +7912,21 @@ Bindings::traverse(Traverse* traverse, bool is_global)
} }
} }
// Traverse function declarations when needed.
if ((traverse_mask & Traverse::traverse_func_declarations) != 0)
{
for (Bindings::const_declarations_iterator p = this->begin_declarations();
p != this->end_declarations();
++p)
{
if (p->second->is_function_declaration())
{
if (traverse->function_declaration(p->second) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
}
}
return TRAVERSE_CONTINUE; return TRAVERSE_CONTINUE;
} }
...@@ -8221,6 +8236,12 @@ Traverse::type(Type*) ...@@ -8221,6 +8236,12 @@ Traverse::type(Type*)
go_unreachable(); go_unreachable();
} }
int
Traverse::function_declaration(Named_object*)
{
go_unreachable();
}
// Class Statement_inserter. // Class Statement_inserter.
void void
......
...@@ -3271,13 +3271,14 @@ class Traverse ...@@ -3271,13 +3271,14 @@ class Traverse
{ {
public: public:
// These bitmasks say what to traverse. // These bitmasks say what to traverse.
static const unsigned int traverse_variables = 0x1; static const unsigned int traverse_variables = 0x1;
static const unsigned int traverse_constants = 0x2; static const unsigned int traverse_constants = 0x2;
static const unsigned int traverse_functions = 0x4; static const unsigned int traverse_functions = 0x4;
static const unsigned int traverse_blocks = 0x8; static const unsigned int traverse_blocks = 0x8;
static const unsigned int traverse_statements = 0x10; static const unsigned int traverse_statements = 0x10;
static const unsigned int traverse_expressions = 0x20; static const unsigned int traverse_expressions = 0x20;
static const unsigned int traverse_types = 0x40; static const unsigned int traverse_types = 0x40;
static const unsigned int traverse_func_declarations = 0x80;
Traverse(unsigned int traverse_mask) Traverse(unsigned int traverse_mask)
: traverse_mask_(traverse_mask), types_seen_(NULL), expressions_seen_(NULL) : traverse_mask_(traverse_mask), types_seen_(NULL), expressions_seen_(NULL)
...@@ -3342,6 +3343,11 @@ class Traverse ...@@ -3342,6 +3343,11 @@ class Traverse
virtual int virtual int
type(Type*); type(Type*);
// If traverse_func_declarations is set in the mask, this is called
// for every function declarations in the tree.
virtual int
function_declaration(Named_object*);
private: private:
// A hash table for types we have seen during this traversal. Note // A hash table for types we have seen during this traversal. Note
// that this uses the default hash functions for pointers rather // that this uses the default hash functions for pointers rather
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment