compiler: remove LHS/RHS context determination for var exprs
Remove the code that determined LHS/RHS context for var expressions (was needed previously for some instances of the back end). LHS/RHS context is computed by the back end in all cases, so no need to have this code in the front end any more. Reviewed-on: https://go-review.googlesource.com/77510 * go-gcc.cc (var_expression): Remove Varexpr_context parameter. From-SVN: r254748
This commit is contained in:
parent
c2ad9885c0
commit
f60bea11ad
11 changed files with 34 additions and 154 deletions
|
@ -1,3 +1,7 @@
|
|||
2017-11-14 Than McIntosh <thanm@google.com>
|
||||
|
||||
* go-gcc.cc (var_expression): Remove Varexpr_context parameter.
|
||||
|
||||
2017-10-11 Tony Reix <tony.reix@atos.net>
|
||||
|
||||
* go-system.h (__STDC_FORMAT_MACROS): Define before including any
|
||||
|
|
|
@ -276,7 +276,7 @@ class Gcc_backend : public Backend
|
|||
{ return this->make_expression(null_pointer_node); }
|
||||
|
||||
Bexpression*
|
||||
var_expression(Bvariable* var, Varexpr_context, Location);
|
||||
var_expression(Bvariable* var, Location);
|
||||
|
||||
Bexpression*
|
||||
indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
|
||||
|
@ -1256,7 +1256,7 @@ Gcc_backend::zero_expression(Btype* btype)
|
|||
// An expression that references a variable.
|
||||
|
||||
Bexpression*
|
||||
Gcc_backend::var_expression(Bvariable* var, Varexpr_context, Location location)
|
||||
Gcc_backend::var_expression(Bvariable* var, Location location)
|
||||
{
|
||||
tree ret = var->get_tree(location);
|
||||
if (ret == error_mark_node)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
d028451131e92bab5379defb04ead87ca978ed25
|
||||
cb5dc1ce98857884a2215c461dd1d7de530f9f5e
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
|
|
@ -254,7 +254,7 @@ class Backend
|
|||
|
||||
// Create a reference to a variable.
|
||||
virtual Bexpression*
|
||||
var_expression(Bvariable* var, Varexpr_context in_lvalue_pos, Location) = 0;
|
||||
var_expression(Bvariable* var, Location) = 0;
|
||||
|
||||
// Create an expression that indirects through the pointer expression EXPR
|
||||
// (i.e., return the expression for *EXPR). KNOWN_VALID is true if the pointer
|
||||
|
|
|
@ -771,7 +771,7 @@ Var_expression::do_get_backend(Translate_context* context)
|
|||
go_unreachable();
|
||||
|
||||
Bexpression* ret =
|
||||
context->backend()->var_expression(bvar, this->in_lvalue_pos_, loc);
|
||||
context->backend()->var_expression(bvar, loc);
|
||||
if (is_in_heap)
|
||||
ret = context->backend()->indirect_expression(btype, ret, true, loc);
|
||||
return ret;
|
||||
|
@ -898,10 +898,7 @@ Temporary_reference_expression::do_get_backend(Translate_context* context)
|
|||
{
|
||||
Gogo* gogo = context->gogo();
|
||||
Bvariable* bvar = this->statement_->get_backend_variable(context);
|
||||
Varexpr_context ve_ctxt = (this->is_lvalue_ ? VE_lvalue : VE_rvalue);
|
||||
|
||||
Bexpression* ret = gogo->backend()->var_expression(bvar, ve_ctxt,
|
||||
this->location());
|
||||
Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
|
||||
|
||||
// The backend can't always represent the same set of recursive types
|
||||
// that the Go frontend can. In some cases this means that a
|
||||
|
@ -972,7 +969,7 @@ Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
|
|||
Location loc = this->location();
|
||||
Gogo* gogo = context->gogo();
|
||||
Bvariable* bvar = this->statement_->get_backend_variable(context);
|
||||
Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, VE_lvalue, loc);
|
||||
Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc);
|
||||
|
||||
Named_object* fn = context->function();
|
||||
go_assert(fn != NULL);
|
||||
|
@ -980,7 +977,7 @@ Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
|
|||
Bexpression* bexpr = this->expr_->get_backend(context);
|
||||
Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
|
||||
bexpr, loc);
|
||||
Bexpression* var_ref = gogo->backend()->var_expression(bvar, VE_rvalue, loc);
|
||||
Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
|
||||
Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1084,11 +1081,11 @@ Sink_expression::do_get_backend(Translate_context* context)
|
|||
gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
|
||||
false, loc, &decl);
|
||||
Bexpression* var_ref =
|
||||
gogo->backend()->var_expression(this->bvar_, VE_lvalue, loc);
|
||||
gogo->backend()->var_expression(this->bvar_, loc);
|
||||
var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
|
||||
return var_ref;
|
||||
}
|
||||
return gogo->backend()->var_expression(this->bvar_, VE_lvalue, loc);
|
||||
return gogo->backend()->var_expression(this->bvar_, loc);
|
||||
}
|
||||
|
||||
// Ast dump for sink expression.
|
||||
|
@ -1302,7 +1299,7 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
|||
Named_object* no = this->fn_;
|
||||
Location loc = no->location();
|
||||
if (this->dvar_ != NULL)
|
||||
return context->backend()->var_expression(this->dvar_, VE_rvalue, loc);
|
||||
return context->backend()->var_expression(this->dvar_, loc);
|
||||
|
||||
Gogo* gogo = context->gogo();
|
||||
std::string var_name(gogo->function_descriptor_name(no));
|
||||
|
@ -1340,7 +1337,7 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
|||
}
|
||||
|
||||
this->dvar_ = bvar;
|
||||
return gogo->backend()->var_expression(bvar, VE_rvalue, loc);
|
||||
return gogo->backend()->var_expression(bvar, loc);
|
||||
}
|
||||
|
||||
// Print a function descriptor expression.
|
||||
|
@ -4286,7 +4283,7 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
Temporary_statement* temp = sut->temporary();
|
||||
Bvariable* bvar = temp->get_backend_variable(context);
|
||||
Bexpression* bvar_expr =
|
||||
gogo->backend()->var_expression(bvar, VE_lvalue, loc);
|
||||
gogo->backend()->var_expression(bvar, loc);
|
||||
Bexpression* bval = sut->expression()->get_backend(context);
|
||||
|
||||
Named_object* fn = context->function();
|
||||
|
@ -4373,7 +4370,7 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
|
||||
true, copy_to_heap, false,
|
||||
bexpr);
|
||||
bexpr = gogo->backend()->var_expression(implicit, VE_rvalue, loc);
|
||||
bexpr = gogo->backend()->var_expression(implicit, loc);
|
||||
|
||||
// If we are not copying a slice initializer to the heap,
|
||||
// then it can be changed by the program, so if it can
|
||||
|
@ -4383,7 +4380,7 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
&& this->expr_->type()->has_pointer())
|
||||
{
|
||||
Bexpression* root =
|
||||
gogo->backend()->var_expression(implicit, VE_rvalue, loc);
|
||||
gogo->backend()->var_expression(implicit, loc);
|
||||
root = gogo->backend()->address_expression(root, loc);
|
||||
Type* type = Type::make_pointer_type(this->expr_->type());
|
||||
gogo->add_gc_root(Expression::make_backend(root, type, loc));
|
||||
|
@ -4400,7 +4397,7 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
true, false, btype, loc);
|
||||
gogo->backend()->immutable_struct_set_init(decl, var_name, true,
|
||||
false, btype, loc, bexpr);
|
||||
bexpr = gogo->backend()->var_expression(decl, VE_rvalue, loc);
|
||||
bexpr = gogo->backend()->var_expression(decl, loc);
|
||||
}
|
||||
|
||||
go_assert(!this->create_temp_ || this->expr_->is_variable());
|
||||
|
@ -14309,7 +14306,7 @@ Heap_expression::do_get_backend(Translate_context* context)
|
|||
Bstatement* assn;
|
||||
if (!etype->has_pointer())
|
||||
{
|
||||
space = gogo->backend()->var_expression(space_temp, VE_lvalue, loc);
|
||||
space = gogo->backend()->var_expression(space_temp, loc);
|
||||
Bexpression* ref =
|
||||
gogo->backend()->indirect_expression(expr_btype, space, true, loc);
|
||||
assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc);
|
||||
|
@ -14322,12 +14319,12 @@ Heap_expression::do_get_backend(Translate_context* context)
|
|||
expr_btype, bexpr, true, loc,
|
||||
&edecl);
|
||||
Bexpression* btempref = gogo->backend()->var_expression(btemp,
|
||||
VE_lvalue, loc);
|
||||
loc);
|
||||
Bexpression* addr = gogo->backend()->address_expression(btempref, loc);
|
||||
|
||||
Expression* td = Expression::make_type_descriptor(etype, loc);
|
||||
Type* etype_ptr = Type::make_pointer_type(etype);
|
||||
space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc);
|
||||
space = gogo->backend()->var_expression(space_temp, loc);
|
||||
Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
|
||||
Expression* erhs = Expression::make_backend(addr, etype_ptr, loc);
|
||||
Expression* call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
|
||||
|
@ -14337,7 +14334,7 @@ Heap_expression::do_get_backend(Translate_context* context)
|
|||
assn = gogo->backend()->compound_statement(edecl, s);
|
||||
}
|
||||
decl = gogo->backend()->compound_statement(decl, assn);
|
||||
space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc);
|
||||
space = gogo->backend()->var_expression(space_temp, loc);
|
||||
return gogo->backend()->compound_expression(decl, space, loc);
|
||||
}
|
||||
|
||||
|
@ -14661,7 +14658,7 @@ Ptrmask_symbol_expression::do_get_backend(Translate_context* context)
|
|||
|
||||
Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata);
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
Bexpression* bref = gogo->backend()->var_expression(bvar, VE_rvalue, bloc);
|
||||
Bexpression* bref = gogo->backend()->var_expression(bvar, bloc);
|
||||
Bexpression* baddr = gogo->backend()->address_expression(bref, bloc);
|
||||
|
||||
Type* uint8_type = Type::lookup_integer_type("uint8");
|
||||
|
@ -15380,8 +15377,7 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
|
|||
Gogo* gogo = context->gogo();
|
||||
Location loc = Linemap::predeclared_location();
|
||||
if (this->bvar_ != NULL)
|
||||
return gogo->backend()->var_expression(this->bvar_, VE_rvalue,
|
||||
this->location());
|
||||
return gogo->backend()->var_expression(this->bvar_, this->location());
|
||||
|
||||
const Typed_identifier_list* interface_methods = this->itype_->methods();
|
||||
go_assert(!interface_methods->empty());
|
||||
|
@ -15421,8 +15417,7 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
|
|||
this->bvar_ =
|
||||
gogo->backend()->immutable_struct_reference(mangled_name, asm_name,
|
||||
btype, loc);
|
||||
return gogo->backend()->var_expression(this->bvar_, VE_rvalue,
|
||||
this->location());
|
||||
return gogo->backend()->var_expression(this->bvar_, this->location());
|
||||
}
|
||||
|
||||
// The first element is the type descriptor.
|
||||
|
@ -15487,7 +15482,7 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
|
|||
!is_public, btype, loc);
|
||||
gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
|
||||
!is_public, btype, loc, ctor);
|
||||
return gogo->backend()->var_expression(this->bvar_, VE_lvalue, loc);
|
||||
return gogo->backend()->var_expression(this->bvar_, loc);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1298,7 +1298,7 @@ class Var_expression : public Expression
|
|||
public:
|
||||
Var_expression(Named_object* variable, Location location)
|
||||
: Expression(EXPRESSION_VAR_REFERENCE, location),
|
||||
variable_(variable), in_lvalue_pos_(VE_rvalue)
|
||||
variable_(variable)
|
||||
{ }
|
||||
|
||||
// Return the variable.
|
||||
|
@ -1306,16 +1306,6 @@ class Var_expression : public Expression
|
|||
named_object() const
|
||||
{ return this->variable_; }
|
||||
|
||||
// Does this var expression appear in an lvalue (assigned-to) context?
|
||||
bool
|
||||
in_lvalue_pos() const
|
||||
{ return this->in_lvalue_pos_ == VE_lvalue; }
|
||||
|
||||
// Mark a var_expression as appearing in an lvalue context.
|
||||
void
|
||||
set_in_lvalue_pos()
|
||||
{ this->in_lvalue_pos_ = VE_lvalue; }
|
||||
|
||||
protected:
|
||||
Expression*
|
||||
do_lower(Gogo*, Named_object*, Statement_inserter*, int);
|
||||
|
@ -1346,8 +1336,6 @@ class Var_expression : public Expression
|
|||
private:
|
||||
// The variable we are referencing.
|
||||
Named_object* variable_;
|
||||
// Set to TRUE if var expression appears in lvalue context
|
||||
Varexpr_context in_lvalue_pos_;
|
||||
};
|
||||
|
||||
// A reference to a variable within an enclosing function.
|
||||
|
|
|
@ -1394,7 +1394,7 @@ Gogo::write_globals()
|
|||
{
|
||||
Location loc = var->location();
|
||||
Bexpression* var_expr =
|
||||
this->backend()->var_expression(bvar, VE_lvalue, loc);
|
||||
this->backend()->var_expression(bvar, loc);
|
||||
var_init_stmt =
|
||||
this->backend()->assignment_statement(init_bfn, var_expr,
|
||||
var_binit, loc);
|
||||
|
@ -5798,8 +5798,7 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
|
|||
{
|
||||
Named_object* no = (*this->results_)[i];
|
||||
Bvariable* bvar = no->get_backend_variable(gogo, named_function);
|
||||
Bexpression* val = gogo->backend()->var_expression(bvar, VE_rvalue,
|
||||
location);
|
||||
Bexpression* val = gogo->backend()->var_expression(bvar, location);
|
||||
if (no->result_var_value()->is_in_heap())
|
||||
{
|
||||
Btype* bt = no->result_var_value()->type()->get_backend(gogo);
|
||||
|
@ -6632,7 +6631,7 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
|
|||
Expression::make_cast(this->type(), this->init_, loc);
|
||||
Bexpression* val = val_expr->get_backend(&context);
|
||||
Bexpression* var_ref =
|
||||
gogo->backend()->var_expression(var_decl, VE_lvalue, loc);
|
||||
gogo->backend()->var_expression(var_decl, loc);
|
||||
decl_init = gogo->backend()->assignment_statement(bfunction, var_ref,
|
||||
val, loc);
|
||||
}
|
||||
|
|
|
@ -63,10 +63,4 @@ enum Operator
|
|||
OPERATOR_RSQUARE // ]
|
||||
};
|
||||
|
||||
// Whether a variable expression appears in lvalue (assignment) context.
|
||||
enum Varexpr_context {
|
||||
VE_rvalue,
|
||||
VE_lvalue
|
||||
};
|
||||
|
||||
#endif // !defined(GO_OPERATOR_H)
|
||||
|
|
|
@ -836,100 +836,6 @@ Assignment_statement::do_flatten(Gogo*, Named_object*, Block*,
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Helper class to locate a root Var_expression within an expression
|
||||
// tree and mark it as being in an "lvalue" or assignment
|
||||
// context. Examples:
|
||||
//
|
||||
// x, y = 40, foo(w)
|
||||
// x[2] = bar(v)
|
||||
// x.z.w[blah(v + u)], y.another = 2, 3
|
||||
//
|
||||
// In the code above, vars "x" and "y" appear in lvalue / assignment
|
||||
// context, whereas the other vars "v", "u", etc are in rvalue context.
|
||||
//
|
||||
// Note: at the moment the Var_expression version of "do_copy()"
|
||||
// defaults to returning the original object, not a new object,
|
||||
// meaning that a given Var_expression can be referenced from more
|
||||
// than one place in the tree. This means that when we want to mark a
|
||||
// Var_expression as having lvalue semantics, we need to make a copy
|
||||
// of it. Example:
|
||||
//
|
||||
// mystruct.myfield += 42
|
||||
//
|
||||
// When this is lowered to eliminate the += operator, we get a tree
|
||||
//
|
||||
// mystruct.myfield = mystruct.field + 42
|
||||
//
|
||||
// in which the "mystruct" same Var_expression is referenced on both
|
||||
// LHS and RHS subtrees. This in turn means that if we try to mark the
|
||||
// LHS Var_expression the RHS Var_expression will also be marked. To
|
||||
// address this issue, the code below clones any var_expression before
|
||||
// applying an lvalue marking.
|
||||
//
|
||||
|
||||
class Mark_lvalue_varexprs : public Traverse
|
||||
{
|
||||
public:
|
||||
Mark_lvalue_varexprs()
|
||||
: Traverse(traverse_expressions)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
int
|
||||
expression(Expression**);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
int Mark_lvalue_varexprs::expression(Expression** ppexpr)
|
||||
{
|
||||
Expression* e = *ppexpr;
|
||||
|
||||
Var_expression* ve = e->var_expression();
|
||||
if (ve)
|
||||
{
|
||||
ve = new Var_expression(ve->named_object(), ve->location());
|
||||
ve->set_in_lvalue_pos();
|
||||
*ppexpr = ve;
|
||||
return TRAVERSE_EXIT;
|
||||
}
|
||||
|
||||
Field_reference_expression* fre = e->field_reference_expression();
|
||||
if (fre != NULL)
|
||||
return TRAVERSE_CONTINUE;
|
||||
|
||||
Array_index_expression* aie = e->array_index_expression();
|
||||
if (aie != NULL)
|
||||
{
|
||||
Mark_lvalue_varexprs mlve;
|
||||
aie->set_is_lvalue();
|
||||
aie->array()->traverse_subexpressions(&mlve);
|
||||
return TRAVERSE_EXIT;
|
||||
}
|
||||
|
||||
Unary_expression* ue = e->unary_expression();
|
||||
if (ue && ue->op() == OPERATOR_MULT)
|
||||
return TRAVERSE_CONTINUE;
|
||||
|
||||
Type_conversion_expression* ce = e->conversion_expression();
|
||||
if (ce)
|
||||
return TRAVERSE_CONTINUE;
|
||||
|
||||
Temporary_reference_expression* tre =
|
||||
e->temporary_reference_expression();
|
||||
if (tre)
|
||||
{
|
||||
tre = new Temporary_reference_expression(tre->statement(),
|
||||
tre->location());
|
||||
*ppexpr = tre;
|
||||
tre->set_is_lvalue();
|
||||
return TRAVERSE_EXIT;
|
||||
}
|
||||
|
||||
return TRAVERSE_EXIT;
|
||||
}
|
||||
|
||||
// Convert an assignment statement to the backend representation.
|
||||
|
||||
Bstatement*
|
||||
|
@ -942,9 +848,6 @@ Assignment_statement::do_get_backend(Translate_context* context)
|
|||
return context->backend()->expression_statement(bfunction, rhs);
|
||||
}
|
||||
|
||||
Mark_lvalue_varexprs mlve;
|
||||
Expression::traverse(&this->lhs_, &mlve);
|
||||
|
||||
Bexpression* lhs = this->lhs_->get_backend(context);
|
||||
Expression* conv =
|
||||
Expression::convert_for_assignment(context->gogo(), this->lhs_->type(),
|
||||
|
|
|
@ -1206,8 +1206,7 @@ Type::type_descriptor_pointer(Gogo* gogo, Location location)
|
|||
go_assert(t->type_descriptor_var_ != NULL);
|
||||
}
|
||||
Bexpression* var_expr =
|
||||
gogo->backend()->var_expression(t->type_descriptor_var_,
|
||||
VE_rvalue, location);
|
||||
gogo->backend()->var_expression(t->type_descriptor_var_, location);
|
||||
Bexpression* var_addr =
|
||||
gogo->backend()->address_expression(var_expr, location);
|
||||
Type* td_type = Type::make_type_descriptor_type();
|
||||
|
@ -2385,7 +2384,7 @@ Type::gc_symbol_pointer(Gogo* gogo)
|
|||
}
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
Bexpression* var_expr =
|
||||
gogo->backend()->var_expression(t->gc_symbol_var_, VE_rvalue, bloc);
|
||||
gogo->backend()->var_expression(t->gc_symbol_var_, bloc);
|
||||
Bexpression* addr_expr =
|
||||
gogo->backend()->address_expression(var_expr, bloc);
|
||||
|
||||
|
@ -7395,7 +7394,6 @@ Array_type::get_value_pointer(Gogo*, Expression* array, bool is_lvalue) const
|
|||
else if (ve != NULL)
|
||||
{
|
||||
ve = new Var_expression(ve->named_object(), ve->location());
|
||||
ve->set_in_lvalue_pos();
|
||||
array = ve;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,6 @@ Write_barriers::variable(Named_object* no)
|
|||
// Replace the initializer.
|
||||
Location loc = init->location();
|
||||
Expression* ref = Expression::make_var_reference(no, loc);
|
||||
ref->var_expression()->set_in_lvalue_pos();
|
||||
|
||||
Statement_inserter inserter(this->gogo_, var);
|
||||
Statement* s = this->gogo_->assign_with_write_barrier(NULL, NULL, &inserter,
|
||||
|
|
Loading…
Add table
Reference in a new issue