diff mbox

Go patch committed: Use alloca for non-escaping new expressions

Message ID CAOyqgcWdYMSqAPhUL7Y7AZqAG1OaoAj1qdsGbz6J=TBPABY0Xg@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor April 30, 2015, 8:44 p.m. UTC
This patch from Chris Manghane changes the Go frontend to use allocate
for non-escaping new expressions.  Previously it was using a temporary
variable, which failed when the new expression was in a loop.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian


2015-04-30  Chris Manghane  <cmang@google.com>

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

Patch

Index: go-gcc.cc
===================================================================
--- go-gcc.cc	(revision 222656)
+++ go-gcc.cc	(working copy)
@@ -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
   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: gofrontend/backend.h
===================================================================
--- gofrontend/backend.h	(revision 222656)
+++ gofrontend/backend.h	(working copy)
@@ -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: gofrontend/expressions.cc
===================================================================
--- gofrontend/expressions.cc	(revision 222656)
+++ gofrontend/expressions.cc	(working copy)
@@ -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(Tr
   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: gofrontend/expressions.h
===================================================================
--- gofrontend/expressions.h	(revision 222656)
+++ gofrontend/expressions.h	(working copy)
@@ -2786,7 +2786,7 @@  class Allocation_expression : public Exp
  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 Exp
   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 Exp
   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.