From 4f576c83fb197b74767c536583107b457aead8ef Mon Sep 17 00:00:00 2001 From: Chris Manghane Date: Thu, 30 Apr 2015 20:44:03 +0000 Subject: [PATCH] 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 --- gcc/go/ChangeLog | 5 +++++ gcc/go/go-gcc.cc | 14 ++++++++++++++ gcc/go/gofrontend/backend.h | 4 ++++ gcc/go/gofrontend/expressions.cc | 25 +++++-------------------- 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 + + * go-gcc.cc (Gcc_backend::stack_allocation_expression): New + method. + 2015-04-27 Jim Wilson * 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& 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& 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.