public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-7121] compiler: recognize Go 1.18 runtime/internal/atomic methods
@ 2022-02-09 4:14 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2022-02-09 4:14 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:869fb813039e8933a85f5f2a3a53cde156030b0a
commit r12-7121-g869fb813039e8933a85f5f2a3a53cde156030b0a
Author: Ian Lance Taylor <iant@golang.org>
Date: Sun Feb 6 18:25:25 2022 -0800
compiler: recognize Go 1.18 runtime/internal/atomic methods
The Go 1.18 library introduces specific types in runtime/internal/atomic.
Recognize and optimize the methods on those types, as we do with the
functions in runtime/internal/atomic.
While we're here avoid getting confused by methods in any other
package that we recognize specially.
* go-gcc.cc (Gcc_backend::Gcc_backend): Define builtins
__atomic_load_1 and __atomic_store_1.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/383654
Diff:
---
gcc/go/go-gcc.cc | 14 ++++
gcc/go/gofrontend/MERGE | 2 +-
gcc/go/gofrontend/expressions.cc | 156 ++++++++++++++++++++++++++++++++++++++-
gcc/go/gofrontend/runtime.def | 4 +
4 files changed, 174 insertions(+), 2 deletions(-)
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 631996073f4..f3de7a8c183 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -897,6 +897,20 @@ Gcc_backend::Gcc_backend()
this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", NULL,
t, 0);
+ t = build_function_type_list(unsigned_char_type_node,
+ ptr_type_node,
+ integer_type_node,
+ NULL_TREE);
+ this->define_builtin(BUILT_IN_ATOMIC_LOAD_1, "__atomic_load_1", NULL, t, 0);
+
+ t = build_function_type_list(void_type_node,
+ ptr_type_node,
+ unsigned_char_type_node,
+ integer_type_node,
+ NULL_TREE);
+ this->define_builtin(BUILT_IN_ATOMIC_STORE_1, "__atomic_store_1", NULL,
+ t, 0);
+
t = build_function_type_list(unsigned_char_type_node,
ptr_type_node,
unsigned_char_type_node,
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 5f4adf9d0e7..9cd22ef011e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-262cb89fd5ed82ab135a3933b2ddf4eb67683149
+3b1e46937d11b043d0986a3dfefaee27454c3da0
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 1e6890a3cc5..d7b64767a00 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -11613,12 +11613,16 @@ Call_expression::intrinsify(Gogo* gogo,
std::string package = (no->package() != NULL
? no->package()->pkgpath()
: gogo->pkgpath());
+ bool is_method = ((no->is_function() && no->func_value()->is_method())
+ || (no->is_function_declaration()
+ && no->func_declaration_value()->is_method()));
Location loc = this->location();
Type* int_type = Type::lookup_integer_type("int");
Type* int32_type = Type::lookup_integer_type("int32");
Type* int64_type = Type::lookup_integer_type("int64");
Type* uint_type = Type::lookup_integer_type("uint");
+ Type* uint8_type = Type::lookup_integer_type("uint8");
Type* uint32_type = Type::lookup_integer_type("uint32");
Type* uint64_type = Type::lookup_integer_type("uint64");
Type* uintptr_type = Type::lookup_integer_type("uintptr");
@@ -11629,6 +11633,9 @@ Call_expression::intrinsify(Gogo* gogo,
if (package == "sync/atomic")
{
+ if (is_method)
+ return NULL;
+
// 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.
@@ -11694,6 +11701,9 @@ Call_expression::intrinsify(Gogo* gogo,
if (package == "runtime/internal/sys")
{
+ if (is_method)
+ return NULL;
+
// runtime/internal/sys functions and math/bits functions
// are very similar. In order not to duplicate code, we just
// redirect to the latter and let the code below to handle them.
@@ -11713,6 +11723,9 @@ Call_expression::intrinsify(Gogo* gogo,
if (package == "runtime")
{
+ if (is_method)
+ return NULL;
+
// Handle a couple of special runtime functions. In the runtime
// package, getcallerpc returns the PC of the caller, and
// getcallersp returns the frame pointer of the caller. Implement
@@ -11743,6 +11756,9 @@ Call_expression::intrinsify(Gogo* gogo,
}
else if (package == "math/bits")
{
+ if (is_method)
+ return NULL;
+
if ((name == "ReverseBytes16" || name == "ReverseBytes32"
|| name == "ReverseBytes64" || name == "ReverseBytes")
&& this->args_ != NULL && this->args_->size() == 1)
@@ -11913,9 +11929,137 @@ Call_expression::intrinsify(Gogo* gogo,
{
int memorder = __ATOMIC_SEQ_CST;
+ if (is_method)
+ {
+ Function_type* ftype = (no->is_function()
+ ? no->func_value()->type()
+ : no->func_declaration_value()->type());
+ Type* rtype = ftype->receiver()->type()->deref();
+ go_assert(rtype->named_type() != NULL);
+ const std::string& rname(rtype->named_type()->name());
+ if (rname == "Int32")
+ {
+ if (name == "Load")
+ name = "LoadInt32";
+ else if (name == "Store")
+ name = "Storeint32";
+ else if (name == "CompareAndSwap")
+ name = "Casint32";
+ else if (name == "Swap")
+ name = "Xchgint32";
+ else if (name == "Add")
+ name = "Xaddint32";
+ else
+ go_unreachable();
+ }
+ else if (rname == "Int64")
+ {
+ if (name == "Load")
+ name = "LoadInt64";
+ else if (name == "Store")
+ name = "Storeint64";
+ else if (name == "CompareAndSwap")
+ name = "Casint64";
+ else if (name == "Swap")
+ name = "Xchgint64";
+ else if (name == "Add")
+ name = "Xaddint64";
+ else
+ go_unreachable();
+ }
+ else if (rname == "Uint8")
+ {
+ if (name == "Load")
+ name = "Load8";
+ else if (name == "Store")
+ name = "Store8";
+ else if (name == "And")
+ name = "And8";
+ else if (name == "Or")
+ name = "Or8";
+ else
+ go_unreachable();
+ }
+ else if (rname == "Uint32")
+ {
+ if (name == "Load")
+ name = "Load";
+ else if (name == "LoadAcquire")
+ name = "LoadAcq";
+ else if (name == "Store")
+ name = "Store";
+ else if (name == "CompareAndSwap")
+ name = "Cas";
+ else if (name == "CompareAndSwapRelease")
+ name = "CasRel";
+ else if (name == "Swap")
+ name = "Xchg";
+ else if (name == "And")
+ name = "And";
+ else if (name == "Or")
+ name = "Or";
+ else if (name == "Add")
+ name = "Xadd";
+ else
+ go_unreachable();
+ }
+ else if (rname == "Uint64")
+ {
+ if (name == "Load")
+ name = "Load64";
+ else if (name == "Store")
+ name = "Store64";
+ else if (name == "CompareAndSwap")
+ name = "Cas64";
+ else if (name == "Swap")
+ name = "Xchgt64";
+ else if (name == "Add")
+ name = "Xadd64";
+ else
+ go_unreachable();
+ }
+ else if (rname == "Uintptr")
+ {
+ if (name == "Load")
+ name = "Loaduintptr";
+ else if (name == "LoadAcquire")
+ name = "Loadacquintptr";
+ else if (name == "Store")
+ name = "Storeuintptr";
+ else if (name == "StoreRelease")
+ name = "StoreReluintptr";
+ else if (name == "CompareAndSwap")
+ name = "Casuintptr";
+ else if (name == "Swap")
+ name = "Xchguintptr";
+ else if (name == "Add")
+ name = "Xadduintptr";
+ else
+ go_unreachable();
+ }
+ else if (rname == "Float64")
+ {
+ // Needs unsafe type conversion. Don't intrinsify for now.
+ return NULL;
+ }
+ else if (rname == "UnsafePointer")
+ {
+ if (name == "Load")
+ name = "Loadp";
+ else if (name == "StoreNoWB")
+ name = "StorepoWB";
+ else if (name == "CompareAndSwapNoWB")
+ name = "Casp1";
+ else
+ go_unreachable();
+ }
+ else
+ go_unreachable();
+ }
+
if ((name == "Load" || name == "Load64" || name == "Loadint64" || name == "Loadp"
|| name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq"
- || name == "Loadint32")
+ || name == "Loadint32" || name == "Load8")
&& this->args_ != NULL && this->args_->size() == 1)
{
if (int_size < 8 && (name == "Load64" || name == "Loadint64"))
@@ -11972,6 +12116,11 @@ Call_expression::intrinsify(Gogo* gogo,
res_type = uint32_type;
memorder = __ATOMIC_ACQUIRE;
}
+ else if (name == "Load8")
+ {
+ code = Runtime::ATOMIC_LOAD_1;
+ res_type = uint8_type;
+ }
else
go_unreachable();
Expression* a1 = this->args_->front();
@@ -12012,6 +12161,8 @@ Call_expression::intrinsify(Gogo* gogo,
code = Runtime::ATOMIC_STORE_4;
memorder = __ATOMIC_RELEASE;
}
+ else if (name == "Store8")
+ code = Runtime::ATOMIC_STORE_1;
else
go_unreachable();
Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
@@ -12179,6 +12330,9 @@ Call_expression::intrinsify(Gogo* gogo,
}
else if (package == "internal/abi")
{
+ if (is_method)
+ return NULL;
+
if ((name == "FuncPCABI0" || name == "FuncPCABIInternal")
&& this->args_ != NULL
&& this->args_->size() == 1)
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index 87a27085d60..b7dd4456a25 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -478,6 +478,10 @@ DEF_GO_RUNTIME(ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
DEF_GO_RUNTIME(ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
P3(POINTER, UINT64, INT32),
R1(UINT64))
+DEF_GO_RUNTIME(ATOMIC_LOAD_1, "__atomic_load_1", P2(POINTER, INT32),
+ R1(UINT8))
+DEF_GO_RUNTIME(ATOMIC_STORE_1, "__atomic_store_1", P3(POINTER, UINT8, INT32),
+ R0())
DEF_GO_RUNTIME(ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1",
P3(POINTER, UINT8, INT32),
R1(UINT8))
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-02-09 4:14 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-09 4:14 [gcc r12-7121] compiler: recognize Go 1.18 runtime/internal/atomic methods 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).