escape: Implement assign phase.

Implementation of the assign/connect phase.
    Statements containing expressions which alias local, parameter,
    and global objects are analyzed and the alias relationship between
    objects containing pointers are captured in a connection graph to
    summarize the assignments within a function.
    
    Reviewed-on: https://go-review.googlesource.com/18302

From-SVN: r237424
This commit is contained in:
Ian Lance Taylor 2016-06-14 04:29:43 +00:00
parent c8aa46d6b2
commit 3db5773f70
7 changed files with 1566 additions and 122 deletions

View File

@ -1,4 +1,4 @@
054ff1ece3dd5888a445efeaf3ae197b16d4186f
f768153eb2a7a72587c9c0997955cdbbc70322d0
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

File diff suppressed because it is too large Load Diff

View File

@ -206,7 +206,9 @@ class Node
void
set_encoding(int enc);
// Is this node a sink?
bool
is_big(Escape_context*) const;
bool
is_sink() const;
@ -250,6 +252,11 @@ class Node
static int
max_encoding(int e, int etype);
// Return a modified encoding for an input parameter that flows into an
// output parameter.
static int
note_inout_flows(int e, int index, Level level);
private:
// The classification of this Node.
Node_classification classification_;

View File

@ -2578,7 +2578,7 @@ class Label
public:
Label(const std::string& name)
: name_(name), location_(Linemap::unknown_location()), snapshot_(NULL),
refs_(), is_used_(false), blabel_(NULL)
refs_(), is_used_(false), blabel_(NULL), depth_(DEPTH_UNKNOWN)
{ }
// Return the label's name.
@ -2601,6 +2601,26 @@ class Label
set_is_used()
{ this->is_used_ = true; }
// Return whether this label is looping.
bool
looping() const
{ return this->depth_ == DEPTH_LOOPING; }
// Set this label as looping.
void
set_looping()
{ this->depth_ = DEPTH_LOOPING; }
// Return whether this label is nonlooping.
bool
nonlooping() const
{ return this->depth_ == DEPTH_NONLOOPING; }
// Set this label as nonlooping.
void
set_nonlooping()
{ this->depth_ = DEPTH_NONLOOPING; }
// Return the location of the definition.
Location
location() const
@ -2660,6 +2680,16 @@ class Label
is_dummy_label() const
{ return this->name_ == "_"; }
// A classification of a label's looping depth.
enum Loop_depth
{
DEPTH_UNKNOWN,
// A label never jumped to.
DEPTH_NONLOOPING,
// A label jumped to.
DEPTH_LOOPING
};
private:
// The name of the label.
std::string name_;
@ -2675,6 +2705,8 @@ class Label
bool is_used_;
// The backend representation.
Blabel* blabel_;
// The looping depth of this label, for escape analysis.
Loop_depth depth_;
};
// An unnamed label. These are used when lowering loops.

View File

@ -1793,40 +1793,6 @@ Statement::make_statement(Expression* expr, bool is_ignored)
return new Expression_statement(expr, is_ignored);
}
// A block statement--a list of statements which may include variable
// definitions.
class Block_statement : public Statement
{
public:
Block_statement(Block* block, Location location)
: Statement(STATEMENT_BLOCK, location),
block_(block)
{ }
protected:
int
do_traverse(Traverse* traverse)
{ return this->block_->traverse(traverse); }
void
do_determine_types()
{ this->block_->determine_types(); }
bool
do_may_fall_through() const
{ return this->block_->may_fall_through(); }
Bstatement*
do_get_backend(Translate_context* context);
void
do_dump_statement(Ast_dump_context*) const;
private:
Block* block_;
};
// Convert a block to the backend representation of a statement.
Bstatement*
@ -2944,37 +2910,13 @@ Statement::make_continue_statement(Unnamed_label* label,
return new Bc_statement(false, label, location);
}
// A goto statement.
// Class Goto_statement.
class Goto_statement : public Statement
int
Goto_statement::do_traverse(Traverse*)
{
public:
Goto_statement(Label* label, Location location)
: Statement(STATEMENT_GOTO, location),
label_(label)
{ }
protected:
int
do_traverse(Traverse*)
{ return TRAVERSE_CONTINUE; }
void
do_check_types(Gogo*);
bool
do_may_fall_through() const
{ return false; }
Bstatement*
do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private:
Label* label_;
};
return TRAVERSE_CONTINUE;
}
// Check types for a label. There aren't any types per se, but we use
// this to give an error if the label was never defined.
@ -3016,35 +2958,21 @@ Statement::make_goto_statement(Label* label, Location location)
return new Goto_statement(label, location);
}
// A goto statement to an unnamed label.
// Class Goto_unnamed_statement.
class Goto_unnamed_statement : public Statement
int
Goto_unnamed_statement::do_traverse(Traverse*)
{
public:
Goto_unnamed_statement(Unnamed_label* label, Location location)
: Statement(STATEMENT_GOTO_UNNAMED, location),
label_(label)
{ }
return TRAVERSE_CONTINUE;
}
protected:
int
do_traverse(Traverse*)
{ return TRAVERSE_CONTINUE; }
// Convert the goto unnamed statement to the backend representation.
bool
do_may_fall_through() const
{ return false; }
Bstatement*
do_get_backend(Translate_context* context)
{ return this->label_->get_goto(context, this->location()); }
void
do_dump_statement(Ast_dump_context*) const;
private:
Unnamed_label* label_;
};
Bstatement*
Goto_unnamed_statement::do_get_backend(Translate_context* context)
{
return this->label_->get_goto(context, this->location());
}
// Dump the AST representation for an unnamed goto statement
@ -3109,32 +3037,27 @@ Statement::make_label_statement(Label* label, Location location)
return new Label_statement(label, location);
}
// An unnamed label statement.
// Class Unnamed_label_statement.
class Unnamed_label_statement : public Statement
Unnamed_label_statement::Unnamed_label_statement(Unnamed_label* label)
: Statement(STATEMENT_UNNAMED_LABEL, label->location()),
label_(label)
{ }
int
Unnamed_label_statement::do_traverse(Traverse*)
{
public:
Unnamed_label_statement(Unnamed_label* label)
: Statement(STATEMENT_UNNAMED_LABEL, label->location()),
label_(label)
{ }
return TRAVERSE_CONTINUE;
}
protected:
int
do_traverse(Traverse*)
{ return TRAVERSE_CONTINUE; }
// Get the backend definition for this unnamed label statement.
Bstatement*
do_get_backend(Translate_context* context)
{ return this->label_->get_definition(context); }
Bstatement*
Unnamed_label_statement::do_get_backend(Translate_context* context)
{
return this->label_->get_definition(context);
}
void
do_dump_statement(Ast_dump_context*) const;
private:
// The label.
Unnamed_label* label_;
};
// Dump the AST representation for an unnamed label definition statement.
@ -5209,7 +5132,9 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
b->set_end_location(end_loc);
return Statement::make_block_statement(b, loc);
Statement* bs = Statement::make_block_statement(b, loc);
bs->block_statement()->set_is_lowered_for_statement();
return bs;
}
// Return the break label, creating it if necessary.

View File

@ -19,9 +19,13 @@ class Assignment_statement;
class Temporary_statement;
class Variable_declaration_statement;
class Expression_statement;
class Block_statement;
class Return_statement;
class Thunk_statement;
class Goto_statement;
class Goto_unnamed_statement;
class Label_statement;
class Unnamed_label_statement;
class If_statement;
class For_statement;
class For_range_statement;
@ -366,6 +370,12 @@ class Statement
return this->convert<Expression_statement, STATEMENT_EXPRESSION>();
}
// If this is an block statement, return it. Otherwise return
// NULL.
Block_statement*
block_statement()
{ return this->convert<Block_statement, STATEMENT_BLOCK>(); }
// If this is a return statement, return it. Otherwise return NULL.
Return_statement*
return_statement()
@ -376,11 +386,26 @@ class Statement
Thunk_statement*
thunk_statement();
// If this is a goto statement, return it. Otherwise return NULL.
Goto_statement*
goto_statement()
{ return this->convert<Goto_statement, STATEMENT_GOTO>(); }
// If this is a goto_unnamed statement, return it. Otherwise return NULL.
Goto_unnamed_statement*
goto_unnamed_statement()
{ return this->convert<Goto_unnamed_statement, STATEMENT_GOTO_UNNAMED>(); }
// If this is a label statement, return it. Otherwise return NULL.
Label_statement*
label_statement()
{ return this->convert<Label_statement, STATEMENT_LABEL>(); }
// If this is an unnamed_label statement, return it. Otherwise return NULL.
Unnamed_label_statement*
unnamed_label_statement()
{ return this->convert<Unnamed_label_statement, STATEMENT_UNNAMED_LABEL>(); }
// If this is an if statement, return it. Otherwise return NULL.
If_statement*
if_statement()
@ -762,6 +787,50 @@ class Expression_statement : public Statement
bool is_ignored_;
};
// A block statement--a list of statements which may include variable
// definitions.
class Block_statement : public Statement
{
public:
Block_statement(Block* block, Location location)
: Statement(STATEMENT_BLOCK, location),
block_(block), is_lowered_for_statement_(false)
{ }
void
set_is_lowered_for_statement()
{ this->is_lowered_for_statement_ = true; }
bool
is_lowered_for_statement()
{ return this->is_lowered_for_statement_; }
protected:
int
do_traverse(Traverse* traverse)
{ return this->block_->traverse(traverse); }
void
do_determine_types()
{ this->block_->determine_types(); }
bool
do_may_fall_through() const
{ return this->block_->may_fall_through(); }
Bstatement*
do_get_backend(Translate_context* context);
void
do_dump_statement(Ast_dump_context*) const;
private:
Block* block_;
// True if this block statement represents a lowered for statement.
bool is_lowered_for_statement_;
};
// A send statement.
class Send_statement : public Statement
@ -1162,6 +1231,74 @@ class Defer_statement : public Thunk_statement
do_dump_statement(Ast_dump_context*) const;
};
// A goto statement.
class Goto_statement : public Statement
{
public:
Goto_statement(Label* label, Location location)
: Statement(STATEMENT_GOTO, location),
label_(label)
{ }
// Return the label being jumped to.
Label*
label() const
{ return this->label_; }
protected:
int
do_traverse(Traverse*);
void
do_check_types(Gogo*);
bool
do_may_fall_through() const
{ return false; }
Bstatement*
do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private:
Label* label_;
};
// A goto statement to an unnamed label.
class Goto_unnamed_statement : public Statement
{
public:
Goto_unnamed_statement(Unnamed_label* label, Location location)
: Statement(STATEMENT_GOTO_UNNAMED, location),
label_(label)
{ }
Unnamed_label*
unnamed_label() const
{ return this->label_; }
protected:
int
do_traverse(Traverse*);
bool
do_may_fall_through() const
{ return false; }
Bstatement*
do_get_backend(Translate_context* context);
void
do_dump_statement(Ast_dump_context*) const;
private:
Unnamed_label* label_;
};
// A label statement.
class Label_statement : public Statement
@ -1173,7 +1310,7 @@ class Label_statement : public Statement
{ }
// Return the label itself.
const Label*
Label*
label() const
{ return this->label_; }
@ -1192,6 +1329,28 @@ class Label_statement : public Statement
Label* label_;
};
// An unnamed label statement.
class Unnamed_label_statement : public Statement
{
public:
Unnamed_label_statement(Unnamed_label* label);
protected:
int
do_traverse(Traverse*);
Bstatement*
do_get_backend(Translate_context* context);
void
do_dump_statement(Ast_dump_context*) const;
private:
// The label.
Unnamed_label* label_;
};
// An if statement.
class If_statement : public Statement

View File

@ -4502,10 +4502,7 @@ class Call_multiple_result_type : public Type
protected:
bool
do_has_pointer() const
{
go_assert(saw_errors());
return false;
}
{ return false; }
bool
do_compare_is_identity(Gogo*)