compiler: Use backend interface for stack allocation.

Stack allocation was being done by making a temporary variable and
taking its address.  This does not work when allocating in a loop
because every allocated variable will refer to the same address.
The backend now provides a way to safely allocate in a loop.

	* go-gcc.cc (Gcc_backend::stack_allocation_expression): New
	method.

From-SVN: r222657
This commit is contained in:
Chris Manghane 2015-04-30 20:44:03 +00:00 committed by Ian Lance Taylor
parent 6d158d9a6b
commit 4f576c83fb
5 changed files with 29 additions and 27 deletions

View File

@ -1,3 +1,8 @@
2015-04-30 Chris Manghane <cmang@google.com>
* go-gcc.cc (Gcc_backend::stack_allocation_expression): New
method.
2015-04-27 Jim Wilson <jim.wilson@linaro.org> 2015-04-27 Jim Wilson <jim.wilson@linaro.org>
* Make-lang.in (go.mostlyclean): Remove gccgo, gccgo-cross, and go1. * Make-lang.in (go.mostlyclean): Remove gccgo, gccgo-cross, and go1.

View File

@ -324,6 +324,9 @@ class Gcc_backend : public Backend
call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, call_expression(Bexpression* fn, const std::vector<Bexpression*>& args,
Bexpression* static_chain, Location); Bexpression* static_chain, Location);
Bexpression*
stack_allocation_expression(int64_t size, Location);
// Statements. // Statements.
Bstatement* Bstatement*
@ -1884,6 +1887,17 @@ Gcc_backend::call_expression(Bexpression* fn_expr,
return this->make_expression(ret); return this->make_expression(ret);
} }
// Return an expression that allocates SIZE bytes on the stack.
Bexpression*
Gcc_backend::stack_allocation_expression(int64_t size, Location location)
{
tree alloca = builtin_decl_explicit(BUILT_IN_ALLOCA);
tree size_tree = build_int_cst(integer_type_node, size);
tree ret = build_call_expr_loc(location.gcc_location(), alloca, 1, size_tree);
return this->make_expression(ret);
}
// An expression as a statement. // An expression as a statement.
Bstatement* Bstatement*

View File

@ -377,6 +377,10 @@ class Backend
call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, call_expression(Bexpression* fn, const std::vector<Bexpression*>& args,
Bexpression* static_chain, Location) = 0; Bexpression* static_chain, Location) = 0;
// Return an expression that allocates SIZE bytes on the stack.
virtual Bexpression*
stack_allocation_expression(int64_t size, Location) = 0;
// Statements. // Statements.
// Create an error statement. This is used for cases which should // Create an error statement. This is used for cases which should

View File

@ -11428,20 +11428,6 @@ Allocation_expression::do_copy()
return alloc; return alloc;
} }
Expression*
Allocation_expression::do_flatten(Gogo*, Named_object*,
Statement_inserter* inserter)
{
if (this->allocate_on_stack_)
{
this->stack_temp_ = Statement::make_temporary(this->type_, NULL,
this->location());
this->stack_temp_->set_is_address_taken();
inserter->insert(this->stack_temp_);
}
return this;
}
// Return the backend representation for an allocation expression. // Return the backend representation for an allocation expression.
Bexpression* Bexpression*
@ -11450,17 +11436,16 @@ Allocation_expression::do_get_backend(Translate_context* context)
Gogo* gogo = context->gogo(); Gogo* gogo = context->gogo();
Location loc = this->location(); Location loc = this->location();
if (this->stack_temp_ != NULL) Btype* btype = this->type_->get_backend(gogo);
if (this->allocate_on_stack_)
{ {
Expression* ref = int64_t size = gogo->backend()->type_size(btype);
Expression::make_temporary_reference(this->stack_temp_, loc); return gogo->backend()->stack_allocation_expression(size, loc);
ref = Expression::make_unary(OPERATOR_AND, ref, loc);
return ref->get_backend(context);
} }
Bexpression* space = Bexpression* space =
gogo->allocate_memory(this->type_, loc)->get_backend(context); gogo->allocate_memory(this->type_, loc)->get_backend(context);
Btype* pbtype = gogo->backend()->pointer_type(this->type_->get_backend(gogo)); Btype* pbtype = gogo->backend()->pointer_type(btype);
return gogo->backend()->convert_expression(pbtype, space, loc); return gogo->backend()->convert_expression(pbtype, space, loc);
} }

View File

@ -2786,7 +2786,7 @@ class Allocation_expression : public Expression
public: public:
Allocation_expression(Type* type, Location location) Allocation_expression(Type* type, Location location)
: Expression(EXPRESSION_ALLOCATION, location), : Expression(EXPRESSION_ALLOCATION, location),
type_(type), allocate_on_stack_(false), stack_temp_(NULL) type_(type), allocate_on_stack_(false)
{ } { }
void void
@ -2807,9 +2807,6 @@ class Allocation_expression : public Expression
Expression* Expression*
do_copy(); do_copy();
Expression*
do_flatten(Gogo*, Named_object*, Statement_inserter*);
Bexpression* Bexpression*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
@ -2821,9 +2818,6 @@ class Allocation_expression : public Expression
Type* type_; Type* type_;
// Whether or not this is a stack allocation. // Whether or not this is a stack allocation.
bool allocate_on_stack_; bool allocate_on_stack_;
// If this memory is stack allocated, it will use the address of STACK_TEMP.
// Otherwise, STACK_TEMP is NULL.
Temporary_statement* stack_temp_;
}; };
// Construct a struct. // Construct a struct.