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:
parent
6d158d9a6b
commit
4f576c83fb
|
@ -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.
|
||||||
|
|
|
@ -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*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue