compiler: Use backend interface for stack allocation.
authorChris Manghane <cmang@google.com>
Thu, 30 Apr 2015 20:44:03 +0000 (20:44 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 30 Apr 2015 20:44:03 +0000 (20:44 +0000)
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
gcc/go/go-gcc.cc
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h

index 668066ec024c3b4b5ee3381a9e4b2c1601d3a676..da6c9ef7c2e1299a734309a9468216300d8ed31a 100644 (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>
 
        * Make-lang.in (go.mostlyclean): Remove gccgo, gccgo-cross, and go1.
index 08f014fa02e0693e14f8f3e337e6e7b7ec456d56..82ce3ee6d2eef7acaaf86ccdb662b5d55b697858 100644 (file)
@@ -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*
index b5071ae67c56493ff2bf3d4222a7c9549a61d7a7..01540b0d6a9b177a97c1664615c45f7ac55c8334 100644 (file)
@@ -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
index 53edb99a2db2a4bb24454790b534983159905b06..379bed47e9102065bd567e1ad77a16431bbb47d8 100644 (file)
@@ -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);
 }
 
index 0d7ad5ae8fe2e2e9e443b73b0b26aae857ef1908..0c4ea6ba454b64b5b522d11834a06704f77a5232 100644 (file)
@@ -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.