Merge changes Icd615355,I590a161a
* changes:
Update SPIR-V Tools to 2f2e72bae
Squashed 'third_party/SPIRV-Tools/' changes from 0174dd11f..e9dc2c8ce
diff --git a/third_party/SPIRV-Tools/.bazelrc b/third_party/SPIRV-Tools/.bazelrc
new file mode 100644
index 0000000..5b3d13f
--- /dev/null
+++ b/third_party/SPIRV-Tools/.bazelrc
@@ -0,0 +1 @@
+build --cxxopt=-std=c++17
diff --git a/third_party/SPIRV-Tools/.bazelversion b/third_party/SPIRV-Tools/.bazelversion
index 28cbf7c..0062ac9 100644
--- a/third_party/SPIRV-Tools/.bazelversion
+++ b/third_party/SPIRV-Tools/.bazelversion
@@ -1 +1 @@
-5.0.0
\ No newline at end of file
+5.0.0
diff --git a/third_party/SPIRV-Tools/BUILD.bazel b/third_party/SPIRV-Tools/BUILD.bazel
index 255d4e7..71399b2 100644
--- a/third_party/SPIRV-Tools/BUILD.bazel
+++ b/third_party/SPIRV-Tools/BUILD.bazel
@@ -104,11 +104,11 @@
genrule(
name = "build_version_inc",
- srcs = ["CHANGES"],
outs = ["build-version.inc"],
- cmd = "SOURCE_DATE_EPOCH=0 $(location :update_build_version) $(location CHANGES) $(location build-version.inc)",
- cmd_bat = "set SOURCE_DATE_EPOCH=0 && $(location :update_build_version) $(location CHANGES) $(location build-version.inc)",
+ cmd = "SOURCE_DATE_EPOCH=0 $(location :update_build_version) $(RULEDIR) $(location build-version.inc)",
+ cmd_bat = "set SOURCE_DATE_EPOCH=0 && $(location :update_build_version) $(RULEDIR) $(location build-version.inc)",
exec_tools = [":update_build_version"],
+ local = True,
)
# Libraries
diff --git a/third_party/SPIRV-Tools/BUILD.gn b/third_party/SPIRV-Tools/BUILD.gn
index fb662c1..81d122d 100644
--- a/third_party/SPIRV-Tools/BUILD.gn
+++ b/third_party/SPIRV-Tools/BUILD.gn
@@ -265,12 +265,12 @@
action("spvtools_build_version") {
script = "utils/update_build_version.py"
- changes_file = "CHANGES"
+ repo_path = "."
inc_file = "${target_gen_dir}/build-version.inc"
outputs = [ inc_file ]
args = [
- rebase_path(changes_file, root_build_dir),
+ rebase_path(repo_path, root_build_dir),
rebase_path(inc_file, root_build_dir),
]
}
diff --git a/third_party/SPIRV-Tools/DEPS b/third_party/SPIRV-Tools/DEPS
index f1866ea..c6be512 100644
--- a/third_party/SPIRV-Tools/DEPS
+++ b/third_party/SPIRV-Tools/DEPS
@@ -5,14 +5,12 @@
'effcee_revision': 'c7b4db79f340f7a9981e8a484f6d5785e24242d1',
- # Pin to the last version of googletest that supports C++11.
- # Anything later requires C++14
- 'googletest_revision': 'v1.12.0',
+ 'googletest_revision': '2f2e72bae991138cedd0e3d06a115022736cd568',
# Use protobufs before they gained the dependency on abseil
'protobuf_revision': 'v3.13.0.1',
- 're2_revision': '8afcf7fcc481692197e33612446d69e8f5777c54',
+ 're2_revision': 'b025c6a3ae05995660e3b882eb3277f4399ced1a',
'spirv_headers_revision': 'aa331ab0ffcb3a67021caa1a0c1c9017712f2f31',
}
diff --git a/third_party/SPIRV-Tools/build_defs.bzl b/third_party/SPIRV-Tools/build_defs.bzl
index 3a69de5..4d6f15c 100644
--- a/third_party/SPIRV-Tools/build_defs.bzl
+++ b/third_party/SPIRV-Tools/build_defs.bzl
@@ -4,13 +4,10 @@
"-DSPIRV_CHECK_CONTEXT",
"-DSPIRV_COLOR_TERMINAL",
] + select({
- # On Windows, assume MSVC.
- # C++14 is the default in VisualStudio 2017.
"@platforms//os:windows": [],
"//conditions:default": [
"-DSPIRV_LINUX",
"-DSPIRV_TIMER_ENABLED",
- "-std=c++11",
"-fvisibility=hidden",
"-fno-exceptions",
"-fno-rtti",
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h b/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h
index b549efb..84a7726 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h
+++ b/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h
@@ -441,6 +441,8 @@
typedef struct spv_fuzzer_options_t spv_fuzzer_options_t;
+typedef struct spv_optimizer_t spv_optimizer_t;
+
// Type Definitions
typedef spv_const_binary_t* spv_const_binary;
@@ -900,6 +902,63 @@
const size_t num_words, spv_parsed_header_fn_t parse_header,
spv_parsed_instruction_fn_t parse_instruction, spv_diagnostic* diagnostic);
+// The optimizer interface.
+
+// A pointer to a function that accepts a log message from an optimizer.
+typedef void (*spv_message_consumer)(
+ spv_message_level_t, const char*, const spv_position_t*, const char*);
+
+// Creates and returns an optimizer object. This object must be passed to
+// optimizer APIs below and is valid until passed to spvOptimizerDestroy.
+SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env);
+
+// Destroys the given optimizer object.
+SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer);
+
+// Sets an spv_message_consumer on an optimizer object.
+SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer(
+ spv_optimizer_t* optimizer, spv_message_consumer consumer);
+
+// Registers passes that attempt to legalize the generated code.
+SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses(
+ spv_optimizer_t* optimizer);
+
+// Registers passes that attempt to improve performance of generated code.
+SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses(
+ spv_optimizer_t* optimizer);
+
+// Registers passes that attempt to improve the size of generated code.
+SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses(
+ spv_optimizer_t* optimizer);
+
+// Registers a pass specified by a flag in an optimizer object.
+SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag(
+ spv_optimizer_t* optimizer, const char* flag);
+
+// Registers passes specified by length number of flags in an optimizer object.
+SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags(
+ spv_optimizer_t* optimizer, const char** flags, const size_t flag_count);
+
+// Optimizes the SPIR-V code of size |word_count| pointed to by |binary| and
+// returns an optimized spv_binary in |optimized_binary|.
+//
+// Returns SPV_SUCCESS on successful optimization, whether or not the module is
+// modified. Returns an SPV_ERROR_* if the module fails to validate or if
+// errors occur when processing using any of the registered passes. In that
+// case, no further passes are executed and the |optimized_binary| contents may
+// be invalid.
+//
+// By default, the binary is validated before any transforms are performed,
+// and optionally after each transform. Validation uses SPIR-V spec rules
+// for the SPIR-V version named in the binary's header (at word offset 1).
+// Additionally, if the target environment is a client API (such as
+// Vulkan 1.1), then validate for that client API version, to the extent
+// that it is verifiable from data in the binary itself, or from the
+// validator options set on the optimizer options.
+SPIRV_TOOLS_EXPORT spv_result_t spvOptimizerRun(
+ spv_optimizer_t* optimizer, const uint32_t* binary, const size_t word_count,
+ spv_binary* optimized_binary, const spv_optimizer_options options);
+
#ifdef __cplusplus
}
#endif
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat b/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat
deleted file mode 100644
index 25783a9..0000000
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-:: Copyright (c) 2018 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.
-::
-:: Windows Build Script.
-
-@echo on
-
-:: Find out the directory of the common build script.
-set SCRIPT_DIR=%~dp0
-
-:: Call with correct parameter
-call %SCRIPT_DIR%\..\scripts\windows\build.bat Debug 2017
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/continuous.cfg b/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/continuous.cfg
deleted file mode 100644
index 25c5e11..0000000
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/continuous.cfg
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (c) 2018 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.
-
-# Continuous build configuration.
-build_file: "SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat"
-
-action {
- define_artifacts {
- regex: "install.zip"
- }
-}
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/presubmit.cfg b/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/presubmit.cfg
deleted file mode 100644
index a7a553a..0000000
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-debug/presubmit.cfg
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2018 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.
-
-# Presubmit build configuration.
-build_file: "SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat"
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/build.bat b/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/build.bat
deleted file mode 100644
index c1945e2..0000000
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/build.bat
+++ /dev/null
@@ -1,57 +0,0 @@
-:: Copyright (c) 2019 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.
-::
-:: Windows Build Script.
-
-@echo on
-
-set SRC=%cd%\github\SPIRV-Tools
-
-:: Force usage of python 3.6
-set PATH=C:\python36;%PATH%
-
-:: Get dependencies
-cd %SRC%
-git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers
-git clone https://github.com/google/googletest external/googletest
-cd external && cd googletest && git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7 && cd .. && cd ..
-git clone --depth=1 https://github.com/google/effcee external/effcee
-git clone --depth=1 https://github.com/google/re2 external/re2
-
-:: REM Install Bazel.
-wget -q https://github.com/bazelbuild/bazel/releases/download/5.0.0/bazel-5.0.0-windows-x86_64.zip
-unzip -q bazel-5.0.0-windows-x86_64.zip
-
-:: Set up MSVC
-call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
-set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
-
-:: #########################################
-:: Start building.
-:: #########################################
-echo "Build everything... %DATE% %TIME%"
-bazel.exe build :all
-if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
-echo "Build Completed %DATE% %TIME%"
-
-:: ##############
-:: Run the tests
-:: ##############
-echo "Running Tests... %DATE% %TIME%"
-bazel.exe test :all
-if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
-echo "Tests Completed %DATE% %TIME%"
-
-exit /b 0
-
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/continuous.cfg b/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/continuous.cfg
deleted file mode 100644
index f2387a6..0000000
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/continuous.cfg
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2019 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.
-
-# Continuous build configuration.
-build_file: "SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/build.bat"
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/presubmit.cfg b/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/presubmit.cfg
deleted file mode 100644
index 13394b4..0000000
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/presubmit.cfg
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2019 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.
-
-# Presubmit build configuration.
-build_file: "SPIRV-Tools/kokoro/windows-msvc-2017-release-bazel/build.bat"
diff --git a/third_party/SPIRV-Tools/source/CMakeLists.txt b/third_party/SPIRV-Tools/source/CMakeLists.txt
index acfa0c1..b5924f5 100644
--- a/third_party/SPIRV-Tools/source/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/source/CMakeLists.txt
@@ -195,14 +195,11 @@
${spirv-tools_BINARY_DIR}/build-version.inc)
set(SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR
${spirv-tools_SOURCE_DIR}/utils/update_build_version.py)
-set(SPIRV_TOOLS_CHANGES_FILE
- ${spirv-tools_SOURCE_DIR}/CHANGES)
add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC}
COMMAND ${PYTHON_EXECUTABLE}
${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
- ${SPIRV_TOOLS_CHANGES_FILE} ${SPIRV_TOOLS_BUILD_VERSION_INC}
+ ${spirv-tools_SOURCE_DIR} ${SPIRV_TOOLS_BUILD_VERSION_INC}
DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
- ${SPIRV_TOOLS_CHANGES_FILE}
COMMENT "Update build-version.inc in the SPIRV-Tools build directory (if necessary).")
# Convenience target for standalone generation of the build-version.inc file.
# This is not required for any dependence chain.
diff --git a/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp b/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
index 14f2208..516c34b 100644
--- a/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
+++ b/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
@@ -145,12 +145,17 @@
if (composite->AsNullConstant()) {
// Make new composite so it can be inserted in the index with the
// non-null value
- const auto new_composite = const_mgr->GetNullCompositeConstant(type);
- // Keep track of any indexes along the way to last index
- if (i != final_index) {
- chain.push_back(new_composite);
+ if (const auto new_composite =
+ const_mgr->GetNullCompositeConstant(type)) {
+ // Keep track of any indexes along the way to last index
+ if (i != final_index) {
+ chain.push_back(new_composite);
+ }
+ components = new_composite->AsCompositeConstant()->GetComponents();
+ } else {
+ // Unsupported input type (such as structs)
+ return nullptr;
}
- components = new_composite->AsCompositeConstant()->GetComponents();
} else {
// Keep track of any indexes along the way to last index
if (i != final_index) {
diff --git a/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp b/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp
index ad581e1..cd712f0 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp
@@ -497,8 +497,8 @@
if (sum_id == 0)
sum_id = curr_offset_id;
else {
- Instruction* sum_inst = builder->AddBinaryOp(GetUintId(), spv::Op::OpIAdd,
- sum_id, curr_offset_id);
+ Instruction* sum_inst =
+ builder->AddIAdd(GetUintId(), sum_id, curr_offset_id);
sum_id = sum_inst->result_id();
}
++ac_in_idx;
@@ -507,8 +507,7 @@
uint32_t bsize = ByteSize(curr_ty_id, matrix_stride, col_major, in_matrix);
uint32_t last = bsize - 1;
uint32_t last_id = builder->GetUintConstantId(last);
- Instruction* sum_inst =
- builder->AddBinaryOp(GetUintId(), spv::Op::OpIAdd, sum_id, last_id);
+ Instruction* sum_inst = builder->AddIAdd(GetUintId(), sum_id, last_id);
return sum_inst->result_id();
}
diff --git a/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp b/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp
index 97d25f3..c18f91d 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp
@@ -257,9 +257,7 @@
uint32_t hdr_blk_id = TakeNextId();
// Branch to search loop header
std::unique_ptr<Instruction> hdr_blk_label(NewLabel(hdr_blk_id));
- (void)builder.AddInstruction(MakeUnique<Instruction>(
- context(), spv::Op::OpBranch, 0, 0,
- std::initializer_list<Operand>{{SPV_OPERAND_TYPE_ID, {hdr_blk_id}}}));
+ (void)builder.AddBranch(hdr_blk_id);
input_func->AddBasicBlock(std::move(first_blk_ptr));
// Linear search loop header block
// TODO(greg-lunarg): Implement binary search
@@ -293,17 +291,10 @@
uint32_t bound_test_blk_id = TakeNextId();
std::unique_ptr<Instruction> bound_test_blk_label(
NewLabel(bound_test_blk_id));
- (void)builder.AddInstruction(MakeUnique<Instruction>(
- context(), spv::Op::OpLoopMerge, 0, 0,
- std::initializer_list<Operand>{
- {SPV_OPERAND_TYPE_ID, {bound_test_blk_id}},
- {SPV_OPERAND_TYPE_ID, {cont_blk_id}},
- {SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::LoopControlMask::MaskNone)}}}));
+ (void)builder.AddLoopMerge(bound_test_blk_id, cont_blk_id,
+ uint32_t(spv::LoopControlMask::MaskNone));
// Branch to continue/work block
- (void)builder.AddInstruction(MakeUnique<Instruction>(
- context(), spv::Op::OpBranch, 0, 0,
- std::initializer_list<Operand>{{SPV_OPERAND_TYPE_ID, {cont_blk_id}}}));
+ (void)builder.AddBranch(cont_blk_id);
input_func->AddBasicBlock(std::move(hdr_blk_ptr));
// Continue/Work Block. Read next buffer pointer and break if greater
// than ref_ptr arg.
@@ -386,10 +377,8 @@
GetBoolId(), spv::Op::OpULessThanEqual, ref_end_inst->result_id(),
len_load_inst->result_id());
// Return test result
- (void)builder.AddInstruction(MakeUnique<Instruction>(
- context(), spv::Op::OpReturnValue, 0, 0,
- std::initializer_list<Operand>{
- {SPV_OPERAND_TYPE_ID, {len_test_inst->result_id()}}}));
+ (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
+ len_test_inst->result_id());
// Close block
input_func->AddBasicBlock(std::move(bound_test_blk_ptr));
// Close function and add function to module
@@ -422,10 +411,8 @@
uint32_t ref_len = GetTypeLength(ref_ptr_ty_inst->GetSingleWordInOperand(1));
uint32_t ref_len_id = builder->GetUintConstantId(ref_len);
// Gen call to search and test function
- const std::vector<uint32_t> args = {GetSearchAndTestFuncId(), *ref_uptr_id,
- ref_len_id};
- Instruction* call_inst =
- builder->AddNaryOp(GetBoolId(), spv::Op::OpFunctionCall, args);
+ Instruction* call_inst = builder->AddFunctionCall(
+ GetBoolId(), GetSearchAndTestFuncId(), {*ref_uptr_id, ref_len_id});
uint32_t retval = call_inst->result_id();
return retval;
}
diff --git a/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp b/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp
index 151b94c..4f97277 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp
@@ -34,8 +34,8 @@
const analysis::Type* c_ty = v_ty->element_type();
uint32_t c_ty_id = type_mgr->GetId(c_ty);
for (uint32_t c = 0; c < v_ty->element_count(); ++c) {
- Instruction* c_inst = builder->AddIdLiteralOp(
- c_ty_id, spv::Op::OpCompositeExtract, val_inst->result_id(), c);
+ Instruction* c_inst =
+ builder->AddCompositeExtract(c_ty_id, val_inst->result_id(), {c});
GenOutputValues(c_inst, val_ids, builder);
}
return;
@@ -44,9 +44,8 @@
// Select between uint32 zero or one
uint32_t zero_id = builder->GetUintConstantId(0);
uint32_t one_id = builder->GetUintConstantId(1);
- Instruction* sel_inst =
- builder->AddTernaryOp(GetUintId(), spv::Op::OpSelect,
- val_inst->result_id(), one_id, zero_id);
+ Instruction* sel_inst = builder->AddSelect(
+ GetUintId(), val_inst->result_id(), one_id, zero_id);
val_ids->push_back(sel_inst->result_id());
return;
}
diff --git a/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp b/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp
index 441d943..c6e4050 100644
--- a/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp
@@ -54,7 +54,6 @@
void InstrumentPass::MovePostludeCode(
UptrVectorIterator<BasicBlock> ref_block_itr, BasicBlock* new_blk_ptr) {
- // new_blk_ptr->reset(new BasicBlock(NewLabel(ref_block_itr->id())));
// Move contents of original ref block.
for (auto cii = ref_block_itr->begin(); cii != ref_block_itr->end();
cii = ref_block_itr->begin()) {
@@ -77,21 +76,62 @@
}
std::unique_ptr<Instruction> InstrumentPass::NewLabel(uint32_t label_id) {
- std::unique_ptr<Instruction> newLabel(
- new Instruction(context(), spv::Op::OpLabel, 0, label_id, {}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*newLabel);
- return newLabel;
+ auto new_label =
+ MakeUnique<Instruction>(context(), spv::Op::OpLabel, 0, label_id,
+ std::initializer_list<Operand>{});
+ get_def_use_mgr()->AnalyzeInstDefUse(&*new_label);
+ return new_label;
+}
+
+std::unique_ptr<Function> InstrumentPass::StartFunction(
+ uint32_t func_id, const analysis::Type* return_type,
+ const std::vector<const analysis::Type*>& param_types) {
+ analysis::TypeManager* type_mgr = context()->get_type_mgr();
+ analysis::Function* func_type = GetFunction(return_type, param_types);
+
+ const std::vector<Operand> operands{
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
+ {uint32_t(spv::FunctionControlMask::MaskNone)}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_mgr->GetId(func_type)}},
+ };
+ auto func_inst =
+ MakeUnique<Instruction>(context(), spv::Op::OpFunction,
+ type_mgr->GetId(return_type), func_id, operands);
+ get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst);
+ return MakeUnique<Function>(std::move(func_inst));
+}
+
+std::unique_ptr<Instruction> InstrumentPass::EndFunction() {
+ auto end = MakeUnique<Instruction>(context(), spv::Op::OpFunctionEnd, 0, 0,
+ std::initializer_list<Operand>{});
+ get_def_use_mgr()->AnalyzeInstDefUse(end.get());
+ return end;
+}
+
+std::vector<uint32_t> InstrumentPass::AddParameters(
+ Function& func, const std::vector<const analysis::Type*>& param_types) {
+ std::vector<uint32_t> param_ids;
+ param_ids.reserve(param_types.size());
+ for (const analysis::Type* param : param_types) {
+ uint32_t pid = TakeNextId();
+ param_ids.push_back(pid);
+ auto param_inst =
+ MakeUnique<Instruction>(context(), spv::Op::OpFunctionParameter,
+ context()->get_type_mgr()->GetId(param), pid,
+ std::initializer_list<Operand>{});
+ get_def_use_mgr()->AnalyzeInstDefUse(param_inst.get());
+ func.AddParameter(std::move(param_inst));
+ }
+ return param_ids;
}
std::unique_ptr<Instruction> InstrumentPass::NewName(
uint32_t id, const std::string& name_str) {
- std::unique_ptr<Instruction> new_name(new Instruction(
+ return MakeUnique<Instruction>(
context(), spv::Op::OpName, 0, 0,
std::initializer_list<Operand>{
{SPV_OPERAND_TYPE_ID, {id}},
- {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}));
-
- return new_name;
+ {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}});
}
std::unique_ptr<Instruction> InstrumentPass::NewGlobalName(
@@ -118,14 +158,12 @@
std::unique_ptr<Instruction> InstrumentPass::NewMemberName(
uint32_t id, uint32_t member_index, const std::string& name_str) {
- std::unique_ptr<Instruction> new_name(new Instruction(
+ return MakeUnique<Instruction>(
context(), spv::Op::OpMemberName, 0, 0,
std::initializer_list<Operand>{
{SPV_OPERAND_TYPE_ID, {id}},
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}},
- {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}));
-
- return new_name;
+ {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}});
}
uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id,
@@ -167,17 +205,15 @@
// Cast value to 32-bit unsigned if necessary
uint32_t val_id = GenUintCastCode(field_value_id, builder);
// Store value
- Instruction* data_idx_inst =
- builder->AddBinaryOp(GetUintId(), spv::Op::OpIAdd, base_offset_id,
- builder->GetUintConstantId(field_offset));
+ Instruction* data_idx_inst = builder->AddIAdd(
+ GetUintId(), base_offset_id, builder->GetUintConstantId(field_offset));
uint32_t buf_id = GetOutputBufferId();
uint32_t buf_uint_ptr_id = GetOutputBufferPtrId();
- Instruction* achain_inst =
- builder->AddTernaryOp(buf_uint_ptr_id, spv::Op::OpAccessChain, buf_id,
- builder->GetUintConstantId(kDebugOutputDataOffset),
- data_idx_inst->result_id());
- (void)builder->AddBinaryOp(0, spv::Op::OpStore, achain_inst->result_id(),
- val_id);
+ Instruction* achain_inst = builder->AddAccessChain(
+ buf_uint_ptr_id, buf_id,
+ {builder->GetUintConstantId(kDebugOutputDataOffset),
+ data_idx_inst->result_id()});
+ (void)builder->AddStore(achain_inst->result_id(), val_id);
}
void InstrumentPass::GenCommonStreamWriteCode(uint32_t record_sz,
@@ -202,8 +238,8 @@
void InstrumentPass::GenFragCoordEltDebugOutputCode(
uint32_t base_offset_id, uint32_t uint_frag_coord_id, uint32_t element,
InstructionBuilder* builder) {
- Instruction* element_val_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, uint_frag_coord_id, element);
+ Instruction* element_val_inst =
+ builder->AddCompositeExtract(GetUintId(), uint_frag_coord_id, {element});
GenDebugOutputFieldCode(base_offset_id, kInstFragOutFragCoordX + element,
element_val_inst->result_id(), builder);
}
@@ -212,8 +248,7 @@
InstructionBuilder* builder) {
Instruction* var_inst = get_def_use_mgr()->GetDef(var_id);
uint32_t type_id = GetPointeeTypeId(var_inst);
- Instruction* load_inst =
- builder->AddUnaryOp(type_id, spv::Op::OpLoad, var_id);
+ Instruction* load_inst = builder->AddLoad(type_id, var_id);
return load_inst->result_id();
}
@@ -249,12 +284,12 @@
uint32_t load_id = GenVarLoad(context()->GetBuiltinInputVarId(uint32_t(
spv::BuiltIn::GlobalInvocationId)),
builder);
- Instruction* x_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, load_id, 0);
- Instruction* y_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, load_id, 1);
- Instruction* z_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, load_id, 2);
+ Instruction* x_inst =
+ builder->AddCompositeExtract(GetUintId(), load_id, {0});
+ Instruction* y_inst =
+ builder->AddCompositeExtract(GetUintId(), load_id, {1});
+ Instruction* z_inst =
+ builder->AddCompositeExtract(GetUintId(), load_id, {2});
GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdX,
x_inst->result_id(), builder);
GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdY,
@@ -291,10 +326,10 @@
Instruction* uvec3_cast_inst =
builder->AddUnaryOp(GetVec3UintId(), spv::Op::OpBitcast, load_id);
uint32_t uvec3_cast_id = uvec3_cast_inst->result_id();
- Instruction* u_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, uvec3_cast_id, 0);
- Instruction* v_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, uvec3_cast_id, 1);
+ Instruction* u_inst =
+ builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {0});
+ Instruction* v_inst =
+ builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {1});
GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordU,
u_inst->result_id(), builder);
GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordV,
@@ -302,8 +337,8 @@
} break;
case spv::ExecutionModel::Fragment: {
// Load FragCoord and convert to Uint
- Instruction* frag_coord_inst = builder->AddUnaryOp(
- GetVec4FloatId(), spv::Op::OpLoad,
+ Instruction* frag_coord_inst = builder->AddLoad(
+ GetVec4FloatId(),
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::FragCoord)));
Instruction* uint_frag_coord_inst = builder->AddUnaryOp(
GetVec4UintId(), spv::Op::OpBitcast, frag_coord_inst->result_id());
@@ -321,12 +356,12 @@
uint32_t launch_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::LaunchIdNV)),
builder);
- Instruction* x_launch_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, launch_id, 0);
- Instruction* y_launch_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, launch_id, 1);
- Instruction* z_launch_inst = builder->AddIdLiteralOp(
- GetUintId(), spv::Op::OpCompositeExtract, launch_id, 2);
+ Instruction* x_launch_inst =
+ builder->AddCompositeExtract(GetUintId(), launch_id, {0});
+ Instruction* y_launch_inst =
+ builder->AddCompositeExtract(GetUintId(), launch_id, {1});
+ Instruction* z_launch_inst =
+ builder->AddCompositeExtract(GetUintId(), launch_id, {2});
GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdX,
x_launch_inst->result_id(), builder);
GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdY,
@@ -344,11 +379,10 @@
// Call debug output function. Pass func_idx, instruction_idx and
// validation ids as args.
uint32_t val_id_cnt = static_cast<uint32_t>(validation_ids.size());
- uint32_t output_func_id = GetStreamWriteFunctionId(stage_idx, val_id_cnt);
- std::vector<uint32_t> args = {output_func_id,
- builder->GetUintConstantId(instruction_idx)};
+ std::vector<uint32_t> args = {builder->GetUintConstantId(instruction_idx)};
(void)args.insert(args.end(), validation_ids.begin(), validation_ids.end());
- (void)builder->AddNaryOp(GetVoidId(), spv::Op::OpFunctionCall, args);
+ (void)builder->AddFunctionCall(
+ GetVoidId(), GetStreamWriteFunctionId(stage_idx, val_id_cnt), args);
}
bool InstrumentPass::AllConstant(const std::vector<uint32_t>& ids) {
@@ -360,33 +394,38 @@
}
uint32_t InstrumentPass::GenDebugDirectRead(
- const std::vector<uint32_t>& offset_ids, InstructionBuilder* ref_builder) {
+ const std::vector<uint32_t>& offset_ids, InstructionBuilder* builder) {
// Call debug input function. Pass func_idx and offset ids as args.
- uint32_t off_id_cnt = static_cast<uint32_t>(offset_ids.size());
- uint32_t input_func_id = GetDirectReadFunctionId(off_id_cnt);
- std::vector<uint32_t> args = {input_func_id};
- (void)args.insert(args.end(), offset_ids.begin(), offset_ids.end());
+ const uint32_t off_id_cnt = static_cast<uint32_t>(offset_ids.size());
+ const uint32_t input_func_id = GetDirectReadFunctionId(off_id_cnt);
+ return GenReadFunctionCall(input_func_id, offset_ids, builder);
+}
+
+uint32_t InstrumentPass::GenReadFunctionCall(
+ uint32_t func_id, const std::vector<uint32_t>& func_call_args,
+ InstructionBuilder* ref_builder) {
// If optimizing direct reads and the call has already been generated,
// use its result
if (opt_direct_reads_) {
- uint32_t res_id = call2id_[args];
+ uint32_t res_id = call2id_[func_call_args];
if (res_id != 0) return res_id;
}
- // If the offsets are all constants, the call can be moved to the first block
- // of the function where its result can be reused. One example where this is
- // profitable is for uniform buffer references, of which there are often many.
+ // If the function arguments are all constants, the call can be moved to the
+ // first block of the function where its result can be reused. One example
+ // where this is profitable is for uniform buffer references, of which there
+ // are often many.
InstructionBuilder builder(ref_builder->GetContext(),
&*ref_builder->GetInsertPoint(),
ref_builder->GetPreservedAnalysis());
- bool insert_in_first_block = opt_direct_reads_ && AllConstant(offset_ids);
+ bool insert_in_first_block = opt_direct_reads_ && AllConstant(func_call_args);
if (insert_in_first_block) {
Instruction* insert_before = &*curr_func_->begin()->tail();
builder.SetInsertPoint(insert_before);
}
uint32_t res_id =
- builder.AddNaryOp(GetUintId(), spv::Op::OpFunctionCall, args)
+ builder.AddFunctionCall(GetUintId(), func_id, func_call_args)
->result_id();
- if (insert_in_first_block) call2id_[args] = res_id;
+ if (insert_in_first_block) call2id_[func_call_args] = res_id;
return res_id;
}
@@ -502,32 +541,61 @@
return 0;
}
-analysis::Type* InstrumentPass::GetUintXRuntimeArrayType(
- uint32_t width, analysis::Type** rarr_ty) {
+analysis::Integer* InstrumentPass::GetInteger(uint32_t width, bool is_signed) {
+ analysis::Integer i(width, is_signed);
+ analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&i);
+ assert(type && type->AsInteger());
+ return type->AsInteger();
+}
+
+analysis::Struct* InstrumentPass::GetStruct(
+ const std::vector<const analysis::Type*>& fields) {
+ analysis::Struct s(fields);
+ analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&s);
+ assert(type && type->AsStruct());
+ return type->AsStruct();
+}
+
+analysis::RuntimeArray* InstrumentPass::GetRuntimeArray(
+ const analysis::Type* element) {
+ analysis::RuntimeArray r(element);
+ analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&r);
+ assert(type && type->AsRuntimeArray());
+ return type->AsRuntimeArray();
+}
+
+analysis::Function* InstrumentPass::GetFunction(
+ const analysis::Type* return_val,
+ const std::vector<const analysis::Type*>& args) {
+ analysis::Function func(return_val, args);
+ analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&func);
+ assert(type && type->AsFunction());
+ return type->AsFunction();
+}
+
+analysis::RuntimeArray* InstrumentPass::GetUintXRuntimeArrayType(
+ uint32_t width, analysis::RuntimeArray** rarr_ty) {
if (*rarr_ty == nullptr) {
- analysis::DecorationManager* deco_mgr = get_decoration_mgr();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- analysis::Integer uint_ty(width, false);
- analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty);
- analysis::RuntimeArray uint_rarr_ty_tmp(reg_uint_ty);
- *rarr_ty = type_mgr->GetRegisteredType(&uint_rarr_ty_tmp);
- uint32_t uint_arr_ty_id = type_mgr->GetTypeInstruction(*rarr_ty);
+ *rarr_ty = GetRuntimeArray(GetInteger(width, false));
+ uint32_t uint_arr_ty_id =
+ context()->get_type_mgr()->GetTypeInstruction(*rarr_ty);
// By the Vulkan spec, a pre-existing RuntimeArray of uint must be part of
// a block, and will therefore be decorated with an ArrayStride. Therefore
// the undecorated type returned here will not be pre-existing and can
// safely be decorated. Since this type is now decorated, it is out of
// sync with the TypeManager and therefore the TypeManager must be
// invalidated after this pass.
- assert(context()->get_def_use_mgr()->NumUses(uint_arr_ty_id) == 0 &&
+ assert(get_def_use_mgr()->NumUses(uint_arr_ty_id) == 0 &&
"used RuntimeArray type returned");
- deco_mgr->AddDecorationVal(
+ get_decoration_mgr()->AddDecorationVal(
uint_arr_ty_id, uint32_t(spv::Decoration::ArrayStride), width / 8u);
}
return *rarr_ty;
}
-analysis::Type* InstrumentPass::GetUintRuntimeArrayType(uint32_t width) {
- analysis::Type** rarr_ty =
+analysis::RuntimeArray* InstrumentPass::GetUintRuntimeArrayType(
+ uint32_t width) {
+ analysis::RuntimeArray** rarr_ty =
(width == 64) ? &uint64_rarr_ty_ : &uint32_rarr_ty_;
return GetUintXRuntimeArrayType(width, rarr_ty);
}
@@ -546,11 +614,10 @@
// If not created yet, create one
analysis::DecorationManager* deco_mgr = get_decoration_mgr();
analysis::TypeManager* type_mgr = context()->get_type_mgr();
- analysis::Type* reg_uint_rarr_ty = GetUintRuntimeArrayType(32);
- analysis::Integer uint_ty(32, false);
- analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty);
- analysis::Struct buf_ty({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty});
- analysis::Type* reg_buf_ty = type_mgr->GetRegisteredType(&buf_ty);
+ analysis::RuntimeArray* reg_uint_rarr_ty = GetUintRuntimeArrayType(32);
+ analysis::Integer* reg_uint_ty = GetInteger(32, false);
+ analysis::Type* reg_buf_ty =
+ GetStruct({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty});
uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty);
// By the Vulkan spec, a pre-existing struct containing a RuntimeArray
// must be a block, and will therefore be decorated with Block. Therefore
@@ -604,8 +671,7 @@
analysis::TypeManager* type_mgr = context()->get_type_mgr();
uint32_t width = (validation_id_ == kInstValidationIdBuffAddr) ? 64u : 32u;
analysis::Type* reg_uint_rarr_ty = GetUintRuntimeArrayType(width);
- analysis::Struct buf_ty({reg_uint_rarr_ty});
- analysis::Type* reg_buf_ty = type_mgr->GetRegisteredType(&buf_ty);
+ analysis::Struct* reg_buf_ty = GetStruct({reg_uint_rarr_ty});
uint32_t ibufTyId = type_mgr->GetTypeInstruction(reg_buf_ty);
// By the Vulkan spec, a pre-existing struct containing a RuntimeArray
// must be a block, and will therefore be decorated with Block. Therefore
@@ -747,37 +813,17 @@
// Create function
param2output_func_id_[param_cnt] = TakeNextId();
analysis::TypeManager* type_mgr = context()->get_type_mgr();
- std::vector<const analysis::Type*> param_types;
- for (uint32_t c = 0; c < param_cnt; ++c)
- param_types.push_back(type_mgr->GetType(GetUintId()));
- analysis::Function func_ty(type_mgr->GetType(GetVoidId()), param_types);
- analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty);
- std::unique_ptr<Instruction> func_inst(
- new Instruction(get_module()->context(), spv::Op::OpFunction,
- GetVoidId(), param2output_func_id_[param_cnt],
- {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::FunctionControlMask::MaskNone)}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {type_mgr->GetTypeInstruction(reg_func_ty)}}}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst);
- std::unique_ptr<Function> output_func =
- MakeUnique<Function>(std::move(func_inst));
- // Add parameters
- std::vector<uint32_t> param_vec;
- for (uint32_t c = 0; c < param_cnt; ++c) {
- uint32_t pid = TakeNextId();
- param_vec.push_back(pid);
- std::unique_ptr<Instruction> param_inst(
- new Instruction(get_module()->context(), spv::Op::OpFunctionParameter,
- GetUintId(), pid, {}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst);
- output_func->AddParameter(std::move(param_inst));
- }
+
+ const std::vector<const analysis::Type*> param_types(param_cnt,
+ GetInteger(32, false));
+ std::unique_ptr<Function> output_func = StartFunction(
+ param2output_func_id_[param_cnt], type_mgr->GetVoidType(), param_types);
+
+ std::vector<uint32_t> param_ids = AddParameters(*output_func, param_types);
+
// Create first block
- uint32_t test_blk_id = TakeNextId();
- std::unique_ptr<Instruction> test_label(NewLabel(test_blk_id));
- std::unique_ptr<BasicBlock> new_blk_ptr =
- MakeUnique<BasicBlock>(std::move(test_label));
+ auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
+
InstructionBuilder builder(
context(), &*new_blk_ptr,
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
@@ -786,9 +832,9 @@
uint32_t obuf_record_sz = val_spec_offset + val_spec_param_cnt;
uint32_t buf_id = GetOutputBufferId();
uint32_t buf_uint_ptr_id = GetOutputBufferPtrId();
- Instruction* obuf_curr_sz_ac_inst =
- builder.AddBinaryOp(buf_uint_ptr_id, spv::Op::OpAccessChain, buf_id,
- builder.GetUintConstantId(kDebugOutputSizeOffset));
+ Instruction* obuf_curr_sz_ac_inst = builder.AddAccessChain(
+ buf_uint_ptr_id, buf_id,
+ {builder.GetUintConstantId(kDebugOutputSizeOffset)});
// Fetch the current debug buffer written size atomically, adding the
// size of the record to be written.
uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz);
@@ -802,8 +848,8 @@
uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id();
// Compute new written size
Instruction* obuf_new_sz_inst =
- builder.AddBinaryOp(GetUintId(), spv::Op::OpIAdd, obuf_curr_sz_id,
- builder.GetUintConstantId(obuf_record_sz));
+ builder.AddIAdd(GetUintId(), obuf_curr_sz_id,
+ builder.GetUintConstantId(obuf_record_sz));
// Fetch the data bound
Instruction* obuf_bnd_inst =
builder.AddIdLiteralOp(GetUintId(), spv::Op::OpArrayLength,
@@ -825,13 +871,13 @@
new_blk_ptr = MakeUnique<BasicBlock>(std::move(write_label));
builder.SetInsertPoint(&*new_blk_ptr);
// Generate common and stage-specific debug record members
- GenCommonStreamWriteCode(obuf_record_sz, param_vec[kInstCommonParamInstIdx],
+ GenCommonStreamWriteCode(obuf_record_sz, param_ids[kInstCommonParamInstIdx],
stage_idx, obuf_curr_sz_id, &builder);
GenStageStreamWriteCode(stage_idx, obuf_curr_sz_id, &builder);
// Gen writes of validation specific data
for (uint32_t i = 0; i < val_spec_param_cnt; ++i) {
GenDebugOutputFieldCode(obuf_curr_sz_id, val_spec_offset + i,
- param_vec[kInstCommonParamCnt + i], &builder);
+ param_ids[kInstCommonParamCnt + i], &builder);
}
// Close write block and gen merge block
(void)builder.AddBranch(merge_blk_id);
@@ -840,11 +886,9 @@
builder.SetInsertPoint(&*new_blk_ptr);
// Close merge block and function and add function to module
(void)builder.AddNullaryOp(0, spv::Op::OpReturn);
+
output_func->AddBasicBlock(std::move(new_blk_ptr));
- std::unique_ptr<Instruction> func_end_inst(new Instruction(
- get_module()->context(), spv::Op::OpFunctionEnd, 0, 0, {}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst);
- output_func->SetFunctionEnd(std::move(func_end_inst));
+ output_func->SetFunctionEnd(EndFunction());
context()->AddFunction(std::move(output_func));
std::string name("stream_write_");
@@ -861,77 +905,48 @@
if (func_id != 0) return func_id;
// Create input function for param_cnt.
func_id = TakeNextId();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- std::vector<const analysis::Type*> param_types;
- for (uint32_t c = 0; c < param_cnt; ++c)
- param_types.push_back(type_mgr->GetType(GetUintId()));
- uint32_t ibuf_type_id = GetInputBufferTypeId();
- analysis::Function func_ty(type_mgr->GetType(ibuf_type_id), param_types);
- analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty);
- std::unique_ptr<Instruction> func_inst(new Instruction(
- get_module()->context(), spv::Op::OpFunction, ibuf_type_id, func_id,
- {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::FunctionControlMask::MaskNone)}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {type_mgr->GetTypeInstruction(reg_func_ty)}}}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst);
+ analysis::Integer* uint_type = GetInteger(32, false);
+ std::vector<const analysis::Type*> param_types(param_cnt, uint_type);
+
std::unique_ptr<Function> input_func =
- MakeUnique<Function>(std::move(func_inst));
- // Add parameters
- std::vector<uint32_t> param_vec;
- for (uint32_t c = 0; c < param_cnt; ++c) {
- uint32_t pid = TakeNextId();
- param_vec.push_back(pid);
- std::unique_ptr<Instruction> param_inst(
- new Instruction(get_module()->context(), spv::Op::OpFunctionParameter,
- GetUintId(), pid, {}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst);
- input_func->AddParameter(std::move(param_inst));
- }
+ StartFunction(func_id, uint_type, param_types);
+ std::vector<uint32_t> param_ids = AddParameters(*input_func, param_types);
+
// Create block
- uint32_t blk_id = TakeNextId();
- std::unique_ptr<Instruction> blk_label(NewLabel(blk_id));
- std::unique_ptr<BasicBlock> new_blk_ptr =
- MakeUnique<BasicBlock>(std::move(blk_label));
+ auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
InstructionBuilder builder(
context(), &*new_blk_ptr,
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
// For each offset parameter, generate new offset with parameter, adding last
// loaded value if it exists, and load value from input buffer at new offset.
// Return last loaded value.
+ uint32_t ibuf_type_id = GetInputBufferTypeId();
uint32_t buf_id = GetInputBufferId();
uint32_t buf_ptr_id = GetInputBufferPtrId();
uint32_t last_value_id = 0;
for (uint32_t p = 0; p < param_cnt; ++p) {
uint32_t offset_id;
if (p == 0) {
- offset_id = param_vec[0];
+ offset_id = param_ids[0];
} else {
if (ibuf_type_id != GetUintId()) {
- Instruction* ucvt_inst =
- builder.AddUnaryOp(GetUintId(), spv::Op::OpUConvert, last_value_id);
- last_value_id = ucvt_inst->result_id();
+ last_value_id =
+ builder.AddUnaryOp(GetUintId(), spv::Op::OpUConvert, last_value_id)
+ ->result_id();
}
- Instruction* offset_inst = builder.AddBinaryOp(
- GetUintId(), spv::Op::OpIAdd, last_value_id, param_vec[p]);
- offset_id = offset_inst->result_id();
+ offset_id = builder.AddIAdd(GetUintId(), last_value_id, param_ids[p])
+ ->result_id();
}
- Instruction* ac_inst = builder.AddTernaryOp(
- buf_ptr_id, spv::Op::OpAccessChain, buf_id,
- builder.GetUintConstantId(kDebugInputDataOffset), offset_id);
- Instruction* load_inst =
- builder.AddUnaryOp(ibuf_type_id, spv::Op::OpLoad, ac_inst->result_id());
- last_value_id = load_inst->result_id();
+ Instruction* ac_inst = builder.AddAccessChain(
+ buf_ptr_id, buf_id,
+ {builder.GetUintConstantId(kDebugInputDataOffset), offset_id});
+ last_value_id =
+ builder.AddLoad(ibuf_type_id, ac_inst->result_id())->result_id();
}
- (void)builder.AddInstruction(MakeUnique<Instruction>(
- context(), spv::Op::OpReturnValue, 0, 0,
- std::initializer_list<Operand>{{SPV_OPERAND_TYPE_ID, {last_value_id}}}));
+ (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, last_value_id);
// Close block and function and add function to module
input_func->AddBasicBlock(std::move(new_blk_ptr));
- std::unique_ptr<Instruction> func_end_inst(new Instruction(
- get_module()->context(), spv::Op::OpFunctionEnd, 0, 0, {}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst);
- input_func->SetFunctionEnd(std::move(func_end_inst));
+ input_func->SetFunctionEnd(EndFunction());
context()->AddFunction(std::move(input_func));
std::string name("direct_read_");
diff --git a/third_party/SPIRV-Tools/source/opt/instrument_pass.h b/third_party/SPIRV-Tools/source/opt/instrument_pass.h
index e98ba88..1311929 100644
--- a/third_party/SPIRV-Tools/source/opt/instrument_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/instrument_pass.h
@@ -214,6 +214,10 @@
uint32_t GenDebugDirectRead(const std::vector<uint32_t>& offset_ids,
InstructionBuilder* builder);
+ uint32_t GenReadFunctionCall(uint32_t func_id,
+ const std::vector<uint32_t>& args,
+ InstructionBuilder* builder);
+
// Generate code to convert integer |value_id| to 32bit, if needed. Return
// an id to the 32bit equivalent.
uint32_t Gen32BitCvtCode(uint32_t value_id, InstructionBuilder* builder);
@@ -222,6 +226,15 @@
// Return an id to the Uint equivalent.
uint32_t GenUintCastCode(uint32_t value_id, InstructionBuilder* builder);
+ std::unique_ptr<Function> StartFunction(
+ uint32_t func_id, const analysis::Type* return_type,
+ const std::vector<const analysis::Type*>& param_types);
+
+ std::vector<uint32_t> AddParameters(
+ Function& func, const std::vector<const analysis::Type*>& param_types);
+
+ std::unique_ptr<Instruction> EndFunction();
+
// Return new label.
std::unique_ptr<Instruction> NewLabel(uint32_t label_id);
@@ -253,12 +266,20 @@
// Return id for void type
uint32_t GetVoidId();
- // Return pointer to type for runtime array of uint
- analysis::Type* GetUintXRuntimeArrayType(uint32_t width,
- analysis::Type** rarr_ty);
+ // Get registered type structures
+ analysis::Integer* GetInteger(uint32_t width, bool is_signed);
+ analysis::Struct* GetStruct(const std::vector<const analysis::Type*>& fields);
+ analysis::RuntimeArray* GetRuntimeArray(const analysis::Type* element);
+ analysis::Function* GetFunction(
+ const analysis::Type* return_val,
+ const std::vector<const analysis::Type*>& args);
// Return pointer to type for runtime array of uint
- analysis::Type* GetUintRuntimeArrayType(uint32_t width);
+ analysis::RuntimeArray* GetUintXRuntimeArrayType(
+ uint32_t width, analysis::RuntimeArray** rarr_ty);
+
+ // Return pointer to type for runtime array of uint
+ analysis::RuntimeArray* GetUintRuntimeArrayType(uint32_t width);
// Return id for buffer uint type
uint32_t GetOutputBufferPtrId();
@@ -448,10 +469,10 @@
bool storage_buffer_ext_defined_;
// runtime array of uint type
- analysis::Type* uint64_rarr_ty_;
+ analysis::RuntimeArray* uint64_rarr_ty_;
// runtime array of uint type
- analysis::Type* uint32_rarr_ty_;
+ analysis::RuntimeArray* uint32_rarr_ty_;
// Pre-instrumentation same-block insts
std::unordered_map<uint32_t, Instruction*> same_block_pre_;
diff --git a/third_party/SPIRV-Tools/source/opt/optimizer.cpp b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
index be0daeb..cbc4b82 100644
--- a/third_party/SPIRV-Tools/source/opt/optimizer.cpp
+++ b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
@@ -1065,3 +1065,95 @@
MakeUnique<opt::FixFuncCallArgumentsPass>());
}
} // namespace spvtools
+
+extern "C" {
+
+SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env) {
+ return reinterpret_cast<spv_optimizer_t*>(new spvtools::Optimizer(env));
+}
+
+SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer) {
+ delete reinterpret_cast<spvtools::Optimizer*>(optimizer);
+}
+
+SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer(
+ spv_optimizer_t* optimizer, spv_message_consumer consumer) {
+ reinterpret_cast<spvtools::Optimizer*>(optimizer)->
+ SetMessageConsumer(
+ [consumer](spv_message_level_t level, const char* source,
+ const spv_position_t& position, const char* message) {
+ return consumer(level, source, &position, message);
+ });
+}
+
+SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses(
+ spv_optimizer_t* optimizer) {
+ reinterpret_cast<spvtools::Optimizer*>(optimizer)->
+ RegisterLegalizationPasses();
+}
+
+SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses(
+ spv_optimizer_t* optimizer) {
+ reinterpret_cast<spvtools::Optimizer*>(optimizer)->
+ RegisterPerformancePasses();
+}
+
+SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses(
+ spv_optimizer_t* optimizer) {
+ reinterpret_cast<spvtools::Optimizer*>(optimizer)->RegisterSizePasses();
+}
+
+SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag(
+ spv_optimizer_t* optimizer, const char* flag)
+{
+ return reinterpret_cast<spvtools::Optimizer*>(optimizer)->
+ RegisterPassFromFlag(flag);
+}
+
+SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags(
+ spv_optimizer_t* optimizer, const char** flags, const size_t flag_count) {
+ std::vector<std::string> opt_flags;
+ for (uint32_t i = 0; i < flag_count; i++) {
+ opt_flags.emplace_back(flags[i]);
+ }
+
+ return reinterpret_cast<spvtools::Optimizer*>(optimizer)->
+ RegisterPassesFromFlags(opt_flags);
+}
+
+SPIRV_TOOLS_EXPORT
+spv_result_t spvOptimizerRun(spv_optimizer_t* optimizer,
+ const uint32_t* binary,
+ const size_t word_count,
+ spv_binary* optimized_binary,
+ const spv_optimizer_options options) {
+ std::vector<uint32_t> optimized;
+
+ if (!reinterpret_cast<spvtools::Optimizer*>(optimizer)->
+ Run(binary, word_count, &optimized, options)) {
+ return SPV_ERROR_INTERNAL;
+ }
+
+ auto result_binary = new spv_binary_t();
+ if (!result_binary) {
+ *optimized_binary = nullptr;
+ return SPV_ERROR_OUT_OF_MEMORY;
+ }
+
+ result_binary->code = new uint32_t[optimized.size()];
+ if (!result_binary->code) {
+ delete result_binary;
+ *optimized_binary = nullptr;
+ return SPV_ERROR_OUT_OF_MEMORY;
+ }
+ result_binary->wordCount = optimized.size();
+
+ memcpy(result_binary->code, optimized.data(),
+ optimized.size() * sizeof(uint32_t));
+
+ *optimized_binary = result_binary;
+
+ return SPV_SUCCESS;
+}
+
+} // extern "C"
diff --git a/third_party/SPIRV-Tools/source/val/validate_bitwise.cpp b/third_party/SPIRV-Tools/source/val/validate_bitwise.cpp
index 87c9556..6ab1fae 100644
--- a/third_party/SPIRV-Tools/source/val/validate_bitwise.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_bitwise.cpp
@@ -206,13 +206,14 @@
<< spvOpcodeString(opcode);
const uint32_t base_type = _.GetOperandTypeId(inst, 2);
- const uint32_t base_dimension = _.GetDimension(base_type);
- const uint32_t result_dimension = _.GetDimension(result_type);
if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
return error;
}
+ const uint32_t base_dimension = _.GetDimension(base_type);
+ const uint32_t result_dimension = _.GetDimension(result_type);
+
if (base_dimension != result_dimension)
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Base dimension to be equal to Result Type "
diff --git a/third_party/SPIRV-Tools/source/val/validate_type.cpp b/third_party/SPIRV-Tools/source/val/validate_type.cpp
index e7adab8..430d819 100644
--- a/third_party/SPIRV-Tools/source/val/validate_type.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_type.cpp
@@ -349,6 +349,15 @@
<< ", OpTypeRuntimeArray must only be used for the last member "
"of an OpTypeStruct";
}
+
+ if (!_.HasDecoration(inst->id(), spv::Decoration::Block) &&
+ !_.HasDecoration(inst->id(), spv::Decoration::BufferBlock)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << _.VkErrorID(4680)
+ << spvLogStringForEnv(_.context()->target_env)
+ << ", OpTypeStruct containing an OpTypeRuntimeArray "
+ << "must be decorated with Block or BufferBlock.";
+ }
}
}
diff --git a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
index af24e65..3b2d384 100644
--- a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
@@ -21,6 +21,7 @@
analyze_live_input_test.cpp
assembly_builder_test.cpp
block_merge_test.cpp
+ c_interface_test.cpp
ccp_test.cpp
cfg_cleanup_test.cpp
cfg_test.cpp
diff --git a/third_party/SPIRV-Tools/test/opt/c_interface_test.cpp b/third_party/SPIRV-Tools/test/opt/c_interface_test.cpp
new file mode 100644
index 0000000..a172525
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/opt/c_interface_test.cpp
@@ -0,0 +1,534 @@
+// Copyright (c) 2023 Nintendo
+//
+// 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 <string>
+#include <iostream>
+
+#include "gtest/gtest.h"
+#include "spirv-tools/libspirv.h"
+
+namespace spvtools {
+namespace {
+
+TEST(OptimizerCInterface, DefaultConsumerWithValidationNoPassesForInvalidInput) {
+ const uint32_t spirv[] = {
+ 0xDEADFEED, // Invalid Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x01000000, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ // Do not register any passes
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, true);
+
+ spv_binary binary = nullptr;
+ EXPECT_NE(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_EQ(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, SpecifyConsumerWithValidationNoPassesForInvalidInput) {
+ const uint32_t spirv[] = {
+ 0xDEADFEED, // Invalid Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x01000000, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ spvOptimizerSetMessageConsumer(
+ optimizer,
+ [](spv_message_level_t, const char*, const spv_position_t*,
+ const char* message) {
+ std::cout << message << std::endl;
+ });
+
+ // Do not register any passes
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, true);
+
+ testing::internal::CaptureStdout();
+
+ spv_binary binary = nullptr;
+ EXPECT_NE(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_EQ(binary, nullptr);
+
+ auto output = testing::internal::GetCapturedStdout();
+ EXPECT_STRNE(output.c_str(), "");
+
+ spvOptimizerOptionsDestroy(options);
+
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerWithValidationNoPassesForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000001, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ // Do not register any passes
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, true);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Should remain unchanged
+ EXPECT_EQ(binary->wordCount, sizeof(spirv) / sizeof(uint32_t));
+ EXPECT_EQ(memcmp(binary->code, spirv, sizeof(spirv) / sizeof(uint32_t)), 0);
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerNoPassesForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000003, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001, // GLSL450
+ 0x00040015, // OpTypeInt
+ 0x00000001, // %1
+ 0x00000020, // 32 Bits
+ 0x00000000, // Unsigned
+ 0x0004002B, // OpConstant
+ 0x00000001, // %1
+ 0x00000002, // %2
+ 0x00000001 // 1
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ // Do not register any passes
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, true);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Should remain unchanged
+ EXPECT_EQ(binary->wordCount, sizeof(spirv) / sizeof(uint32_t));
+ EXPECT_EQ(memcmp(binary->code, spirv, sizeof(spirv) / sizeof(uint32_t)), 0);
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerLegalizationPassesForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000003, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001, // GLSL450
+ 0x00040015, // OpTypeInt
+ 0x00000001, // %1
+ 0x00000020, // 32 Bits
+ 0x00000000, // Unsigned
+ 0x0004002B, // OpConstant
+ 0x00000001, // %1
+ 0x00000002, // %2
+ 0x00000001 // 1
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ spvOptimizerRegisterLegalizationPasses(optimizer);
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, false);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Only check that SPV_SUCCESS is returned, do not verify output
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerPerformancePassesForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000003, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001, // GLSL450
+ 0x00040015, // OpTypeInt
+ 0x00000001, // %1
+ 0x00000020, // 32 Bits
+ 0x00000000, // Unsigned
+ 0x0004002B, // OpConstant
+ 0x00000001, // %1
+ 0x00000002, // %2
+ 0x00000001 // 1
+ };
+ const uint32_t expected_spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000001, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ spvOptimizerRegisterPerformancePasses(optimizer);
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, false);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Unreferenced OpTypeInt and OpConstant should be removed
+ EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
+ EXPECT_EQ(memcmp(binary->code, expected_spirv,
+ sizeof(expected_spirv) / sizeof(uint32_t)), 0);
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerSizePassesForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000003, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001, // GLSL450
+ 0x00040015, // OpTypeInt
+ 0x00000001, // %1
+ 0x00000020, // 32 Bits
+ 0x00000000, // Unsigned
+ 0x0004002B, // OpConstant
+ 0x00000001, // %1
+ 0x00000002, // %2
+ 0x00000001 // 1
+ };
+ const uint32_t expected_spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000001, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ spvOptimizerRegisterSizePasses(optimizer);
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, false);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Unreferenced OpTypeInt and OpConstant should be removed
+ EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
+ EXPECT_EQ(memcmp(binary->code, expected_spirv,
+ sizeof(expected_spirv) / sizeof(uint32_t)), 0);
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerPassFromFlagForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000003, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001, // GLSL450
+ 0x00040015, // OpTypeInt
+ 0x00000001, // %1
+ 0x00000020, // 32 Bits
+ 0x00000000, // Unsigned
+ 0x0004002B, // OpConstant
+ 0x00000001, // %1
+ 0x00000002, // %2
+ 0x00000001 // 1
+ };
+ const uint32_t expected_spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000001, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ EXPECT_TRUE(spvOptimizerRegisterPassFromFlag(
+ optimizer, "--eliminate-dead-code-aggressive"));
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, false);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Unreferenced OpTypeInt and OpConstant should be removed
+ EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
+ EXPECT_EQ(memcmp(binary->code, expected_spirv,
+ sizeof(expected_spirv) / sizeof(uint32_t)), 0);
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerPassesFromFlagsForValidInput) {
+ const uint32_t spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000003, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001, // GLSL450
+ 0x00040015, // OpTypeInt
+ 0x00000001, // %1
+ 0x00000020, // 32 Bits
+ 0x00000000, // Unsigned
+ 0x0004002B, // OpConstant
+ 0x00000001, // %1
+ 0x00000002, // %2
+ 0x00000001 // 1
+ };
+ const uint32_t expected_spirv[] = {
+ 0x07230203, // Magic
+ 0x00010100, // Version 1.1
+ 0x00000000, // No Generator
+ 0x00000001, // Bound
+ 0x00000000, // Schema
+ 0x00020011, // OpCapability
+ 0x00000001, // Shader
+ 0x00020011, // OpCapability
+ 0x00000005, // Linkage
+ 0x0003000E, // OpMemoryModel
+ 0x00000000, // Logical
+ 0x00000001 // GLSL450
+ };
+
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ const char* flags[2] = {
+ "--eliminate-dead-const",
+ "--eliminate-dead-code-aggressive"
+ };
+
+ EXPECT_TRUE(spvOptimizerRegisterPassesFromFlags(
+ optimizer, flags, sizeof(flags) / sizeof(const char*)));
+
+ auto options = spvOptimizerOptionsCreate();
+ ASSERT_NE(options, nullptr);
+ spvOptimizerOptionsSetRunValidator(options, false);
+
+ spv_binary binary = nullptr;
+ EXPECT_EQ(SPV_SUCCESS,
+ spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
+ &binary, options));
+ ASSERT_NE(binary, nullptr);
+
+ spvOptimizerOptionsDestroy(options);
+
+ // Unreferenced OpTypeInt and OpConstant should be removed
+ EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
+ EXPECT_EQ(memcmp(binary->code, expected_spirv,
+ sizeof(expected_spirv) / sizeof(uint32_t)), 0);
+
+ spvBinaryDestroy(binary);
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerInvalidPassFromFlag) {
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ EXPECT_FALSE(spvOptimizerRegisterPassFromFlag(
+ optimizer, "--this-is-not-a-valid-pass"));
+
+ spvOptimizerDestroy(optimizer);
+}
+
+TEST(OptimizerCInterface, DefaultConsumerInvalidPassesFromFlags) {
+ auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
+ ASSERT_NE(optimizer, nullptr);
+
+ const char* flags[2] = {
+ "--eliminate-dead-const",
+ "--this-is-not-a-valid-pass"
+ };
+
+ EXPECT_FALSE(spvOptimizerRegisterPassesFromFlags(
+ optimizer, flags, sizeof(flags) / sizeof(const char*)));
+
+ spvOptimizerDestroy(optimizer);
+}
+
+} // namespace
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/fold_test.cpp b/third_party/SPIRV-Tools/test/opt/fold_test.cpp
index 06b91f3..cc9bcd6 100644
--- a/third_party/SPIRV-Tools/test/opt/fold_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/fold_test.cpp
@@ -7363,7 +7363,16 @@
"%5 = OpCompositeConstruct %v2int %3 %4\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 5, true)
+ 5, true),
+ // Test case 16: Don't fold when type cannot be deduced to a constant.
+ InstructionFoldingCase<bool>(
+ Header() +
+ "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%4 = OpCompositeInsert %struct_v2int_int_int %int_1 %struct_v2int_int_int_null 2\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 4, false)
));
INSTANTIATE_TEST_SUITE_P(DotProductMatchingTest, MatchingInstructionFoldingTest,
diff --git a/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp b/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp
index 3600d0d..d450511 100644
--- a/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp
@@ -1040,10 +1040,6 @@
%i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-; CHECK: uint_0 = OpConstant %uint 0
-; CHECK: bool = OpTypeBool
-; CHECK: %41 = OpTypeFunction %void %uint %uint %uint %uint
-; CHECK: _runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
@@ -2385,14 +2381,7 @@
%_ptr_Input_float = OpTypePointer Input %float
%b = OpVariable %_ptr_Input_float Input
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %uint = OpTypeInt 32 0
-; CHECK: %26 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-; CHECK: %48 = OpTypeFunction %void %uint %uint %uint %uint
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
; CHECK: %v4uint = OpTypeVector %uint 4
; CHECK: %102 = OpTypeFunction %uint %uint %uint %uint %uint
@@ -2508,10 +2497,7 @@
%nu_ii = OpVariable %_ptr_Input_int Input
%int_0 = OpConstant %int 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
; CHECK: %v4float = OpTypeVector %float 4
; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
@@ -2637,11 +2623,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: %v3uint = OpTypeVector %uint 3
; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint
; CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
@@ -2797,12 +2779,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %34 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
)";
@@ -2954,12 +2931,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %34 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
@@ -3112,12 +3084,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %34 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
@@ -3270,12 +3237,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %34 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
@@ -3428,12 +3390,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %34 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
@@ -3586,12 +3543,7 @@
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %34 = OpTypeFunction %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
)";
@@ -3777,8 +3729,6 @@
%_ptr_Output_v4float = OpTypePointer Output %v4float
%outColor = OpVariable %_ptr_Output_v4float Output
%float_0 = OpConstant %float 0
-; CHECK: %bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)" + kInputGlobals + R"(
@@ -3963,11 +3913,7 @@
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
- ;CHECK: %122 = OpTypeFunction %uint %uint %uint %uint
- ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
- )" + kInputGlobals + R"(
- ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
- )" + kOutputGlobals + R"(
+ )" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: %v4uint = OpTypeVector %uint 4
@@ -4154,12 +4100,7 @@
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-;CHECK: %105 = OpTypeFunction %uint %uint %uint %uint
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: %v4uint = OpTypeVector %uint 4
@@ -4296,12 +4237,7 @@
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-;CHECK: %104 = OpTypeFunction %uint %uint %uint %uint %uint
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: %v4uint = OpTypeVector %uint 4
@@ -4436,10 +4372,7 @@
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-;CHECK: %bool = OpTypeBool
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
@@ -4620,12 +4553,7 @@
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-;CHECK: %61 = OpTypeFunction %uint %uint %uint %uint
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
@@ -4750,12 +4678,7 @@
%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
%a_position = OpVariable %_ptr_Input_v4float Input
-;CHECK: %37 = OpTypeFunction %uint %uint %uint %uint
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
@@ -4873,12 +4796,7 @@
%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
%a_position = OpVariable %_ptr_Input_v4float Input
-;CHECK: %37 = OpTypeFunction %uint %uint %uint %uint
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
@@ -5003,12 +4921,7 @@
%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
%a_position = OpVariable %_ptr_Input_v4float Input
-;CHECK: %46 = OpTypeFunction %uint %uint %uint %uint
-;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + R"(
-;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %bool = OpTypeBool
-)" + kOutputGlobals + R"(
+)" + kInputGlobals + kOutputGlobals + R"(
;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
@@ -5202,7 +5115,7 @@
%x = OpVariable %_ptr_Output_v4float Output
;CHECK: %uint = OpTypeInt 32 0
;CHECK: %bool = OpTypeBool
-;CHECK: %34 = OpTypeFunction %void %uint %uint %uint %uint %uint
+;CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint %uint
;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
diff --git a/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp b/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp
index b08f7b0..4a56f60 100644
--- a/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp
@@ -272,7 +272,7 @@
; CHECK: %_runtimearr_ulong = OpTypeRuntimeArray %ulong
)" + kInputGlobals + R"(
; CHECK: %_ptr_StorageBuffer_ulong = OpTypePointer StorageBuffer %ulong
-; CHECK: %70 = OpTypeFunction %void %uint %uint %uint %uint
+; CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint
; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
@@ -524,7 +524,7 @@
%ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704
; CHECK: %47 = OpTypeFunction %bool %ulong %uint
)" + kInputGlobals + R"(
-; CHECK: %90 = OpTypeFunction %void %uint %uint %uint %uint
+; CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint
)" + kOutputGlobals + R"(
; CHECK: %143 = OpConstantNull %Test_0
)";
diff --git a/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp b/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp
index 6a4cbdd..4031480 100644
--- a/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp
@@ -111,7 +111,7 @@
%_ptr_Output_v4float = OpTypePointer Output %v4float
%4 = OpVariable %_ptr_Output_v4float Output
; CHECK: %uint = OpTypeInt 32 0
-; CHECK: %38 = OpTypeFunction %void %uint %uint %uint %uint %uint %uint
+; CHECK: [[func_type:%\w+]] = OpTypeFunction %void %uint %uint %uint %uint %uint %uint
; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
@@ -149,7 +149,7 @@
)";
const std::string output_func = R"(
-; CHECK: %inst_printf_stream_write_6 = OpFunction %void None %38
+; CHECK: %inst_printf_stream_write_6 = OpFunction %void None [[func_type]]
; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint
; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint
diff --git a/third_party/SPIRV-Tools/test/val/val_bitwise_test.cpp b/third_party/SPIRV-Tools/test/val/val_bitwise_test.cpp
index bebaa84..b849e7b 100644
--- a/third_party/SPIRV-Tools/test/val/val_bitwise_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_bitwise_test.cpp
@@ -643,6 +643,32 @@
HasSubstr("Expected 32-bit int type for Base operand: BitCount"));
}
+TEST_F(ValidateBitwise, OpBitCountPointer) {
+ const std::string body = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%ptr_int = OpTypePointer Function %int
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%var = OpVariable %ptr_int Function
+%count = OpBitCount %int %var
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(body);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Expected int scalar or vector type for Base operand: BitCount"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp b/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
index 04d373a..4f90e6b 100644
--- a/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
@@ -5281,6 +5281,37 @@
"rules: member 1 at offset 1 is not aligned to 4"));
}
+TEST_F(ValidateDecorations, VulkanStructWithoutDecorationWithRuntimeArray) {
+ std::string str = R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %func "func"
+ OpExecutionMode %func OriginUpperLeft
+ OpDecorate %array_t ArrayStride 4
+ OpMemberDecorate %struct_t 0 Offset 0
+ OpMemberDecorate %struct_t 1 Offset 4
+ %uint_t = OpTypeInt 32 0
+ %array_t = OpTypeRuntimeArray %uint_t
+ %struct_t = OpTypeStruct %uint_t %array_t
+%struct_ptr = OpTypePointer StorageBuffer %struct_t
+ %2 = OpVariable %struct_ptr StorageBuffer
+ %void = OpTypeVoid
+ %func_t = OpTypeFunction %void
+ %func = OpFunction %void None %func_t
+ %1 = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+
+ CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_1);
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Vulkan, OpTypeStruct containing an OpTypeRuntimeArray "
+ "must be decorated with Block or BufferBlock."));
+}
+
TEST_F(ValidateDecorations, EmptyStructAtNonZeroOffsetGood) {
const std::string spirv = R"(
OpCapability Shader
diff --git a/third_party/SPIRV-Tools/test/val/val_memory_test.cpp b/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
index d0735dc..d575318 100644
--- a/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
@@ -2475,6 +2475,7 @@
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %func "func"
OpExecutionMode %func OriginUpperLeft
+OpDecorate %struct_t Block
%uint_t = OpTypeInt 32 0
%array_t = OpTypeRuntimeArray %uint_t
%struct_t = OpTypeStruct %array_t
@@ -2498,7 +2499,7 @@
"For Vulkan, OpTypeStruct variables containing OpTypeRuntimeArray "
"must have storage class of StorageBuffer, PhysicalStorageBuffer, or "
"Uniform.\n %6 = "
- "OpVariable %_ptr_Workgroup__struct_4 Workgroup\n"));
+ "OpVariable %_ptr_Workgroup__struct_2 Workgroup\n"));
}
TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructWithoutBlockBad) {
@@ -2507,6 +2508,7 @@
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %func "func"
OpExecutionMode %func OriginUpperLeft
+OpDecorate %struct_t BufferBlock
%uint_t = OpTypeInt 32 0
%array_t = OpTypeRuntimeArray %uint_t
%struct_t = OpTypeStruct %array_t
@@ -2529,7 +2531,7 @@
"OpTypeRuntimeArray must be decorated with Block if it "
"has storage class StorageBuffer or "
"PhysicalStorageBuffer.\n %6 = OpVariable "
- "%_ptr_StorageBuffer__struct_4 StorageBuffer\n"));
+ "%_ptr_StorageBuffer__struct_2 StorageBuffer\n"));
}
TEST_F(ValidateMemory, VulkanRTAInsideUniformStructGood) {
@@ -2564,6 +2566,7 @@
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %func "func"
OpExecutionMode %func OriginUpperLeft
+OpDecorate %struct_t Block
%uint_t = OpTypeInt 32 0
%array_t = OpTypeRuntimeArray %uint_t
%struct_t = OpTypeStruct %array_t
@@ -2585,7 +2588,7 @@
HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
"OpTypeRuntimeArray must be decorated with BufferBlock "
"if it has storage class Uniform.\n %6 = OpVariable "
- "%_ptr_Uniform__struct_4 Uniform\n"));
+ "%_ptr_Uniform__struct_2 Uniform\n"));
}
TEST_F(ValidateMemory, VulkanRTAInsideRTABad) {
diff --git a/third_party/SPIRV-Tools/utils/check_copyright.py b/third_party/SPIRV-Tools/utils/check_copyright.py
index aa647af..e3e74bc 100755
--- a/third_party/SPIRV-Tools/utils/check_copyright.py
+++ b/third_party/SPIRV-Tools/utils/check_copyright.py
@@ -41,8 +41,9 @@
'Alastair F. Donaldson',
'Mostafa Ashraf',
'Shiyu Liu',
- 'ZHOU He']
-CURRENT_YEAR = 2022
+ 'ZHOU He',
+ 'Nintendo']
+CURRENT_YEAR = 2023
FIRST_YEAR = 2014
FINAL_YEAR = CURRENT_YEAR + 5
diff --git a/third_party/SPIRV-Tools/utils/roll_deps.sh b/third_party/SPIRV-Tools/utils/roll_deps.sh
index bf6d693..6289c94 100755
--- a/third_party/SPIRV-Tools/utils/roll_deps.sh
+++ b/third_party/SPIRV-Tools/utils/roll_deps.sh
@@ -31,7 +31,7 @@
# We are not rolling google test for now. The latest version requires C++14.
dependencies=("external/effcee/"
-# "external/googletest/")
+ "external/googletest/"
"external/re2/"
"external/spirv-headers/")
diff --git a/third_party/SPIRV-Tools/utils/update_build_version.py b/third_party/SPIRV-Tools/utils/update_build_version.py
index b1c7b21..ec475ea 100755
--- a/third_party/SPIRV-Tools/utils/update_build_version.py
+++ b/third_party/SPIRV-Tools/utils/update_build_version.py
@@ -17,16 +17,13 @@
# Updates an output file with version info unless the new content is the same
# as the existing content.
#
-# Args: <changes-file> <output-file>
+# Args: <repo-path> <output-file>
#
# The output file will contain a line of text consisting of two C source syntax
# string literals separated by a comma:
-# - The software version deduced from the given CHANGES file.
+# - The software version deduced from the last release tag.
# - A longer string with the project name, the software version number, and
-# git commit information for the CHANGES file's directory. The commit
-# information is the output of "git describe" if that succeeds, or "git
-# rev-parse HEAD" if that succeeds, or otherwise a message containing the
-# phrase "unknown hash".
+# git commit information for this release.
# The string contents are escaped as necessary.
import datetime
@@ -39,6 +36,13 @@
import sys
import time
+# Regex to match the SPIR-V version tag.
+# Example of matching tags:
+# - v2020.1
+# - v2020.1-dev
+# - v2020.1.rc1
+VERSION_REGEX = re.compile(r'^v(\d+)\.(\d+)(-dev|rc\d+)?$')
+
# Format of the output generated by this script. Example:
# "v2023.1", "SPIRV-Tools v2023.1 0fc5526f2b01a0cc89192c10cf8bef77f1007a62, 2023-01-18T14:51:49"
OUTPUT_FORMAT = '"{version_tag}", "SPIRV-Tools {version_tag} {description}"\n'
@@ -79,38 +83,66 @@
return False, None
return p.returncode == 0, stdout
-def deduce_software_version(changes_file):
- """Returns a tuple (success, software version number) parsed from the
- given CHANGES file.
+def deduce_last_release(repo_path):
+ """Returns a software version number parsed from git tags."""
- Success is set to True if the software version could be deduced.
- Software version is undefined if success if False.
- Function expects the CHANGES file to describes most recent versions first.
- """
+ success, tag_list = command_output(['git', 'tag', '--sort=-v:refname'], repo_path)
+ if not success:
+ return False, None
- # Match the first well-formed version-and-date line
- # Allow trailing whitespace in the checked-out source code has
- # unexpected carriage returns on a linefeed-only system such as
- # Linux.
- pattern = re.compile(r'^(v\d+\.\d+(-dev)?) \d\d\d\d-\d\d-\d\d\s*$')
- with open(changes_file, mode='r') as f:
- for line in f.readlines():
- match = pattern.match(line)
- if match:
- return True, match.group(1)
+ latest_version_tag = None
+ for tag in tag_list.decode().splitlines():
+ if VERSION_REGEX.match(tag):
+ latest_version_tag = tag
+ break
+
+ if latest_version_tag is None:
+ logging.error("No tag matching version regex matching.")
+ return False, None
+ return True, latest_version_tag
+
+def get_last_release_tuple(repo_path):
+ success, version = deduce_last_release(repo_path)
+ if not success:
return False, None
+ m = VERSION_REGEX.match(version)
+ if len(m.groups()) != 3:
+ return False, None
+ return True, (int(m.groups()[0]), int(m.groups()[1]))
-def describe(repo_path):
+def deduce_current_release(repo_path):
+ status, version_tuple = get_last_release_tuple(repo_path)
+ if not status:
+ return False, None
+
+ last_release_tag = "v{}.{}-dev".format(*version_tuple)
+ success, tag_list = command_output(['git', 'tag', '--contains'], repo_path)
+ if success:
+ if last_release_tag in set(tag_list.decode().splitlines()):
+ return True, last_release_tag
+ else:
+ logging.warning("Could not check tags for commit. Assuming -dev version.")
+
+ now_year = datetime.datetime.now().year
+ if version_tuple[0] == now_year:
+ version_tuple = (now_year, version_tuple[1] + 1)
+ else:
+ version_tuple = (now_year, 1)
+
+ return True, "v{}.{}-dev".format(*version_tuple)
+
+def get_description_for_head(repo_path):
"""Returns a string describing the current Git HEAD version as descriptively
- as possible.
-
- Runs 'git describe', or alternately 'git rev-parse HEAD', in directory. If
- successful, returns the output; otherwise returns 'unknown hash, <date>'."""
+ as possible, in order of priority:
+ - git describe output
+ - git rev-parse HEAD output
+ - "unknown-hash, <date>"
+ """
success, output = command_output(['git', 'describe'], repo_path)
if not success:
- output = command_output(['git', 'rev-parse', 'HEAD'], repo_path)
+ success, output = command_output(['git', 'rev-parse', 'HEAD'], repo_path)
if success:
# decode() is needed here for Python3 compatibility. In Python2,
@@ -126,9 +158,12 @@
# reproducible builds, allow the builder to override the wall
# clock time with environment variable SOURCE_DATE_EPOCH
# containing a (presumably) fixed timestamp.
- timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
- iso_date = datetime.datetime.utcfromtimestamp(timestamp).isoformat()
- return "unknown hash, {}".format(iso_date)
+ if 'SOURCE_DATE_EPOCH' in os.environ:
+ timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
+ iso_date = datetime.datetime.utcfromtimestamp(timestamp).isoformat()
+ else:
+ iso_date = datetime.datetime.now().isoformat()
+ return "unknown_hash, {}".format(iso_date)
def main():
FORMAT = '%(asctime)s %(message)s'
@@ -137,16 +172,15 @@
logging.error("usage: {} <repo-path> <output-file>".format(sys.argv[0]))
sys.exit(1)
- changes_file_path = os.path.realpath(sys.argv[1])
+ repo_path = os.path.realpath(sys.argv[1])
output_file_path = sys.argv[2]
- success, version = deduce_software_version(changes_file_path)
+ success, version = deduce_current_release(repo_path)
if not success:
- logging.error("Could not deduce latest release version from {}.".format(changes_file_path))
- sys.exit(1)
+ logging.warning("Could not deduce latest release version from history.")
+ version = "unknown_version"
- repo_path = os.path.dirname(changes_file_path)
- description = describe(repo_path)
+ description = get_description_for_head(repo_path)
content = OUTPUT_FORMAT.format(version_tag=version, description=description)
# Escape file content.