===================================================================
@@ -1,4 +1,4 @@
-84b8000c32f671c6cc89df1290ed6e0170308644
+4dc60d989293d070702024e7dea52b9849f74775
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
===================================================================
@@ -10432,7 +10432,8 @@ Call_expression::do_flatten(Gogo* gogo,
// Lower to compiler intrinsic if possible.
Func_expression* fe = this->fn_->func_expression();
- if (fe != NULL
+ if (!this->is_concurrent_ && !this->is_deferred_
+ && fe != NULL
&& (fe->named_object()->is_function_declaration()
|| fe->named_object()->is_function()))
{
@@ -10471,6 +10472,73 @@ Call_expression::intrinsify(Gogo* gogo,
int int_size = int_type->named_type()->real_type()->integer_type()->bits() / 8;
int ptr_size = uintptr_type->named_type()->real_type()->integer_type()->bits() / 8;
+ if (package == "sync/atomic")
+ {
+ // sync/atomic functions and runtime/internal/atomic functions
+ // are very similar. In order not to duplicate code, we just
+ // redirect to the latter and let the code below to handle them.
+ // In case there is no equivalent functions (slight variance
+ // in types), we just make an artificial name (begin with '$').
+ // Note: no StorePointer, SwapPointer, and CompareAndSwapPointer,
+ // as they need write barriers.
+ if (name == "LoadInt32")
+ name = "$Loadint32";
+ else if (name == "LoadInt64")
+ name = "Loadint64";
+ else if (name == "LoadUint32")
+ name = "Load";
+ else if (name == "LoadUint64")
+ name = "Load64";
+ else if (name == "LoadUintptr")
+ name = "Loaduintptr";
+ else if (name == "LoadPointer")
+ name = "Loadp";
+ else if (name == "StoreInt32")
+ name = "$Storeint32";
+ else if (name == "StoreInt64")
+ name = "$Storeint64";
+ else if (name == "StoreUint32")
+ name = "Store";
+ else if (name == "StoreUint64")
+ name = "Store64";
+ else if (name == "StoreUintptr")
+ name = "Storeuintptr";
+ else if (name == "AddInt32")
+ name = "$Xaddint32";
+ else if (name == "AddInt64")
+ name = "Xaddint64";
+ else if (name == "AddUint32")
+ name = "Xadd";
+ else if (name == "AddUint64")
+ name = "Xadd64";
+ else if (name == "AddUintptr")
+ name = "Xadduintptr";
+ else if (name == "SwapInt32")
+ name = "$Xchgint32";
+ else if (name == "SwapInt64")
+ name = "$Xchgint64";
+ else if (name == "SwapUint32")
+ name = "Xchg";
+ else if (name == "SwapUint64")
+ name = "Xchg64";
+ else if (name == "SwapUintptr")
+ name = "Xchguintptr";
+ else if (name == "CompareAndSwapInt32")
+ name = "$Casint32";
+ else if (name == "CompareAndSwapInt64")
+ name = "$Casint64";
+ else if (name == "CompareAndSwapUint32")
+ name = "Cas";
+ else if (name == "CompareAndSwapUint64")
+ name = "Cas64";
+ else if (name == "CompareAndSwapUintptr")
+ name = "Casuintptr";
+ else
+ return NULL;
+
+ package = "runtime/internal/atomic";
+ }
+
if (package == "runtime")
{
// Handle a couple of special runtime functions. In the runtime
@@ -10557,7 +10625,8 @@ Call_expression::intrinsify(Gogo* gogo,
int memorder = __ATOMIC_SEQ_CST;
if ((name == "Load" || name == "Load64" || name == "Loadint64" || name == "Loadp"
- || name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq")
+ || name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq"
+ || name == "$Loadint32")
&& this->args_ != NULL && this->args_->size() == 1)
{
if (int_size < 8 && (name == "Load64" || name == "Loadint64"))
@@ -10577,6 +10646,11 @@ Call_expression::intrinsify(Gogo* gogo,
code = Runtime::ATOMIC_LOAD_8;
res_type = uint64_type;
}
+ else if (name == "$Loadint32")
+ {
+ code = Runtime::ATOMIC_LOAD_4;
+ res_type = int32_type;
+ }
else if (name == "Loadint64")
{
code = Runtime::ATOMIC_LOAD_8;
@@ -10618,10 +10692,11 @@ Call_expression::intrinsify(Gogo* gogo,
}
if ((name == "Store" || name == "Store64" || name == "StorepNoWB"
- || name == "Storeuintptr" || name == "StoreRel")
+ || name == "Storeuintptr" || name == "StoreRel"
+ || name == "$Storeint32" || name == "$Storeint64")
&& this->args_ != NULL && this->args_->size() == 2)
{
- if (int_size < 8 && name == "Store64")
+ if (int_size < 8 && (name == "Store64" || name == "$Storeint64"))
return NULL;
Runtime::Function code;
@@ -10631,6 +10706,10 @@ Call_expression::intrinsify(Gogo* gogo,
code = Runtime::ATOMIC_STORE_4;
else if (name == "Store64")
code = Runtime::ATOMIC_STORE_8;
+ else if (name == "$Storeint32")
+ code = Runtime::ATOMIC_STORE_4;
+ else if (name == "$Storeint64")
+ code = Runtime::ATOMIC_STORE_8;
else if (name == "Storeuintptr")
code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
else if (name == "StorepNoWB")
@@ -10650,10 +10729,11 @@ Call_expression::intrinsify(Gogo* gogo,
return Runtime::make_call(code, loc, 3, a1, a2, a3);
}
- if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr")
+ if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr"
+ || name == "$Xchgint32" || name == "$Xchgint64")
&& this->args_ != NULL && this->args_->size() == 2)
{
- if (int_size < 8 && name == "Xchg64")
+ if (int_size < 8 && (name == "Xchg64" || name == "Xchgint64"))
return NULL;
Runtime::Function code;
@@ -10668,6 +10748,16 @@ Call_expression::intrinsify(Gogo* gogo,
code = Runtime::ATOMIC_EXCHANGE_8;
res_type = uint64_type;
}
+ else if (name == "$Xchgint32")
+ {
+ code = Runtime::ATOMIC_EXCHANGE_4;
+ res_type = int32_type;
+ }
+ else if (name == "$Xchgint64")
+ {
+ code = Runtime::ATOMIC_EXCHANGE_8;
+ res_type = int64_type;
+ }
else if (name == "Xchguintptr")
{
code = (ptr_size == 8
@@ -10685,10 +10775,11 @@ Call_expression::intrinsify(Gogo* gogo,
}
if ((name == "Cas" || name == "Cas64" || name == "Casuintptr"
- || name == "Casp1" || name == "CasRel")
+ || name == "Casp1" || name == "CasRel"
+ || name == "$Casint32" || name == "$Casint64")
&& this->args_ != NULL && this->args_->size() == 3)
{
- if (int_size < 8 && name == "Cas64")
+ if (int_size < 8 && (name == "Cas64" || name == "$Casint64"))
return NULL;
Runtime::Function code;
@@ -10707,6 +10798,10 @@ Call_expression::intrinsify(Gogo* gogo,
code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
else if (name == "Cas64")
code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
+ else if (name == "$Casint32")
+ code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
+ else if (name == "$Casint64")
+ code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
else if (name == "Casuintptr")
code = (ptr_size == 8
? Runtime::ATOMIC_COMPARE_EXCHANGE_8
@@ -10733,7 +10828,7 @@ Call_expression::intrinsify(Gogo* gogo,
}
if ((name == "Xadd" || name == "Xadd64" || name == "Xaddint64"
- || name == "Xadduintptr")
+ || name == "Xadduintptr" || name == "$Xaddint32")
&& this->args_ != NULL && this->args_->size() == 2)
{
if (int_size < 8 && (name == "Xadd64" || name == "Xaddint64"))
@@ -10751,6 +10846,11 @@ Call_expression::intrinsify(Gogo* gogo,
code = Runtime::ATOMIC_ADD_FETCH_8;
res_type = uint64_type;
}
+ else if (name == "$Xaddint32")
+ {
+ code = Runtime::ATOMIC_ADD_FETCH_4;
+ res_type = int32_type;
+ }
else if (name == "Xaddint64")
{
code = Runtime::ATOMIC_ADD_FETCH_8;
===================================================================
@@ -2682,8 +2682,6 @@ Thunk_statement::build_thunk(Gogo* gogo,
gogo->add_conversions_in_block(b);
- gogo->flatten_block(function, b);
-
if (may_call_recover
|| recover_arg != NULL
|| this->classification() == STATEMENT_GO)
@@ -2707,6 +2705,8 @@ Thunk_statement::build_thunk(Gogo* gogo,
}
}
+ gogo->flatten_block(function, b);
+
// That is all the thunk has to do.
gogo->finish_function(location);
}