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:
parent
c8aa46d6b2
commit
3db5773f70
@ -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
@ -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_;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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*)
|
||||
|
Loading…
Reference in New Issue
Block a user