mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-21 19:20:07 +00:00
Implement to_string(uint32_t) without using the locale (#5805)
Using the locale takes a mutex deep in the C++ library. Avoid this on hot compilation paths, e.g. in the validator. Fixed: #5802
This commit is contained in:
parent
7c9210cc1d
commit
4451f6ab13
@ -27,6 +27,7 @@ SPVTOOLS_SRC_FILES := \
|
||||
source/table.cpp \
|
||||
source/text.cpp \
|
||||
source/text_handler.cpp \
|
||||
source/to_string.cpp \
|
||||
source/util/bit_vector.cpp \
|
||||
source/util/parse_number.cpp \
|
||||
source/util/string_utils.cpp \
|
||||
|
3
BUILD.gn
3
BUILD.gn
@ -475,6 +475,8 @@ static_library("spvtools") {
|
||||
"source/text.h",
|
||||
"source/text_handler.cpp",
|
||||
"source/text_handler.h",
|
||||
"source/to_string.cpp",
|
||||
"source/to_string.h",
|
||||
"source/util/bit_vector.cpp",
|
||||
"source/util/bit_vector.h",
|
||||
"source/util/bitutils.h",
|
||||
@ -1416,6 +1418,7 @@ if (build_with_chromium && spvtools_build_executables) {
|
||||
"test/text_to_binary.type_declaration_test.cpp",
|
||||
"test/text_to_binary_test.cpp",
|
||||
"test/text_word_get_test.cpp",
|
||||
"test/to_string_test.cpp",
|
||||
"test/unit_spirv.cpp",
|
||||
"test/unit_spirv.h",
|
||||
]
|
||||
|
@ -266,6 +266,7 @@ set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/table.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/text.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/text_handler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/to_string.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/val/validate.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/util/bit_vector.cpp
|
||||
@ -294,6 +295,7 @@ set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/table.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/text.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/text_handler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/to_string.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/val/validate.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_adjacency.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_annotation.cpp
|
||||
|
@ -25,24 +25,15 @@
|
||||
#include "source/binary.h"
|
||||
#include "source/latest_version_spirv_header.h"
|
||||
#include "source/parsed_operand.h"
|
||||
#include "source/to_string.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace {
|
||||
|
||||
// Converts a uint32_t to its string decimal representation.
|
||||
std::string to_string(uint32_t id) {
|
||||
// Use stringstream, since some versions of Android compilers lack
|
||||
// std::to_string.
|
||||
std::stringstream os;
|
||||
os << id;
|
||||
return os.str();
|
||||
NameMapper GetTrivialNameMapper() {
|
||||
return [](uint32_t i) { return spvtools::to_string(i); };
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NameMapper GetTrivialNameMapper() { return to_string; }
|
||||
|
||||
FriendlyNameMapper::FriendlyNameMapper(const spv_const_context context,
|
||||
const uint32_t* code,
|
||||
const size_t wordCount)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "inst_debug_printf_pass.h"
|
||||
|
||||
#include "source/spirv_constant.h"
|
||||
#include "source/to_string.h"
|
||||
#include "source/util/string_utils.h"
|
||||
#include "spirv/unified1/NonSemanticDebugPrintf.h"
|
||||
|
||||
@ -396,7 +397,7 @@ uint32_t InstDebugPrintfPass::GetStreamWriteFunctionId(uint32_t param_cnt) {
|
||||
context()->AddFunction(std::move(output_func));
|
||||
|
||||
std::string name("stream_write_");
|
||||
name += std::to_string(param_cnt);
|
||||
name += spvtools::to_string(param_cnt);
|
||||
|
||||
context()->AddDebug2Inst(
|
||||
NewGlobalName(param2output_func_id_[param_cnt], name));
|
||||
|
44
source/to_string.cpp
Normal file
44
source/to_string.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/to_string.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
std::string to_string(uint32_t n) {
|
||||
// This implementation avoids using standard library features that access
|
||||
// the locale. Using the locale requires taking a mutex which causes
|
||||
// annoying serialization.
|
||||
|
||||
constexpr int max_digits = 10; // max uint has 10 digits
|
||||
// Contains the resulting digits, with least significant digit in the last
|
||||
// entry.
|
||||
char buf[max_digits];
|
||||
int write_index = max_digits - 1;
|
||||
if (n == 0) {
|
||||
buf[write_index] = '0';
|
||||
} else {
|
||||
while (n > 0) {
|
||||
int units = n % 10;
|
||||
buf[write_index--] = "0123456789"[units];
|
||||
n = (n - units) / 10;
|
||||
}
|
||||
write_index++;
|
||||
}
|
||||
assert(write_index >= 0);
|
||||
return std::string(buf + write_index, max_digits - write_index);
|
||||
}
|
||||
} // namespace spvtools
|
29
source/to_string.h
Normal file
29
source/to_string.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_TO_STRING_H_
|
||||
#define SOURCE_TO_STRING_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
// Returns the decimal representation of a number as a string,
|
||||
// without using the locale.
|
||||
std::string to_string(uint32_t n);
|
||||
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_TO_STRING_H_
|
@ -151,6 +151,7 @@ set(TEST_SOURCES
|
||||
text_to_binary.subgroup_dispatch_test.cpp
|
||||
text_to_binary.reserved_sampling_test.cpp
|
||||
text_word_get_test.cpp
|
||||
to_string_test.cpp
|
||||
|
||||
unit_spirv.cpp
|
||||
)
|
||||
|
28
test/to_string_test.cpp
Normal file
28
test/to_string_test.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/to_string.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(ToString, Uint32) {
|
||||
EXPECT_EQ(spvtools::to_string(0u), "0");
|
||||
EXPECT_EQ(spvtools::to_string(1u), "1");
|
||||
EXPECT_EQ(spvtools::to_string(1234567890u), "1234567890");
|
||||
EXPECT_EQ(spvtools::to_string(0xffffffffu), "4294967295");
|
||||
}
|
||||
|
||||
} // namespace
|
Loading…
Reference in New Issue
Block a user