From: Ian Lance Taylor Date: Mon, 7 Feb 2022 02:25:25 +0000 (-0800) Subject: compiler: recognize Go 1.18 runtime/internal/atomic methods X-Git-Tag: upstream/12.2.0~1576 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=869fb813039e8933a85f5f2a3a53cde156030b0a;p=platform%2Fupstream%2Fgcc.git 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 --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 6319960..f3de7a8 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -898,6 +898,20 @@ Gcc_backend::Gcc_backend() 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, integer_type_node, diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5f4adf9..9cd22ef 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 1e6890a..d7b6476 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 87a2708..b7dd445 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))