diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-04-30 20:44:03 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-04-30 20:44:03 +0000 |
commit | d5d1c295d3217e4c1d9395f2feb6a5b11f738210 (patch) | |
tree | ea4d7673e4669f048a90928ef154e42a4227260d | |
parent | c3578bfd5b381e1f808a7e2a2c2cc7343ea1203b (diff) | |
download | gcc-d5d1c295d3217e4c1d9395f2feb6a5b11f738210.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@222657 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/go/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 14 | ||||
-rw-r--r-- | gcc/go/gofrontend/backend.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 25 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 8 |
5 files changed, 29 insertions, 27 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 668066ec024..da6c9ef7c2e 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -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> * Make-lang.in (go.mostlyclean): Remove gccgo, gccgo-cross, and go1. diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 08f014fa02e..82ce3ee6d2e 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -324,6 +324,9 @@ class Gcc_backend : public Backend call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, Bexpression* static_chain, Location); + Bexpression* + stack_allocation_expression(int64_t size, Location); + // Statements. Bstatement* @@ -1884,6 +1887,17 @@ Gcc_backend::call_expression(Bexpression* fn_expr, 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. Bstatement* diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h index b5071ae67c5..01540b0d6a9 100644 --- a/gcc/go/gofrontend/backend.h +++ b/gcc/go/gofrontend/backend.h @@ -377,6 +377,10 @@ class Backend call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, 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. // Create an error statement. This is used for cases which should diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 53edb99a2db..379bed47e91 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -11428,20 +11428,6 @@ Allocation_expression::do_copy() 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. Bexpression* @@ -11450,17 +11436,16 @@ Allocation_expression::do_get_backend(Translate_context* context) Gogo* gogo = context->gogo(); Location loc = this->location(); - if (this->stack_temp_ != NULL) + Btype* btype = this->type_->get_backend(gogo); + if (this->allocate_on_stack_) { - Expression* ref = - Expression::make_temporary_reference(this->stack_temp_, loc); - ref = Expression::make_unary(OPERATOR_AND, ref, loc); - return ref->get_backend(context); + int64_t size = gogo->backend()->type_size(btype); + return gogo->backend()->stack_allocation_expression(size, loc); } Bexpression* space = 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); } diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 0d7ad5ae8fe..0c4ea6ba454 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -2786,7 +2786,7 @@ class Allocation_expression : public Expression public: Allocation_expression(Type* type, Location location) : Expression(EXPRESSION_ALLOCATION, location), - type_(type), allocate_on_stack_(false), stack_temp_(NULL) + type_(type), allocate_on_stack_(false) { } void @@ -2807,9 +2807,6 @@ class Allocation_expression : public Expression Expression* do_copy(); - Expression* - do_flatten(Gogo*, Named_object*, Statement_inserter*); - Bexpression* do_get_backend(Translate_context*); @@ -2821,9 +2818,6 @@ class Allocation_expression : public Expression Type* type_; // Whether or not this is a stack allocation. 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. |