* Go patch committed: Use alloca for non-escaping new expressions
@ 2015-04-30 21:11 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2015-04-30 21:11 UTC (permalink / raw)
To: gcc-patches, gofrontend-dev
[-- Attachment #1: Type: text/plain, Size: 413 bytes --]
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.
[-- Attachment #2: foo.txt --]
[-- Type: text/plain, Size: 4274 bytes --]
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.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-04-30 20:44 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-30 21:11 Go patch committed: Use alloca for non-escaping new expressions Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).