summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_set_function_control.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_set_function_control.cpp')
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_set_function_control.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_set_function_control.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_set_function_control.cpp
new file mode 100644
index 00000000000..d2b61f198a3
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_set_function_control.cpp
@@ -0,0 +1,100 @@
+// 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.
+
+#include "source/fuzz/transformation_set_function_control.h"
+
+namespace spvtools {
+namespace fuzz {
+
+TransformationSetFunctionControl::TransformationSetFunctionControl(
+ const spvtools::fuzz::protobufs::TransformationSetFunctionControl& message)
+ : message_(message) {}
+
+TransformationSetFunctionControl::TransformationSetFunctionControl(
+ uint32_t function_id, uint32_t function_control) {
+ message_.set_function_id(function_id);
+ message_.set_function_control(function_control);
+}
+
+bool TransformationSetFunctionControl::IsApplicable(
+ opt::IRContext* context, const FactManager& /*unused*/) const {
+ opt::Instruction* function_def_instruction =
+ FindFunctionDefInstruction(context);
+ if (!function_def_instruction) {
+ // The given function id does not correspond to any function.
+ return false;
+ }
+ uint32_t existing_function_control_mask =
+ function_def_instruction->GetSingleWordInOperand(0);
+
+ // Check (via an assertion) that function control mask doesn't have any bad
+ // bits set.
+ uint32_t acceptable_function_control_bits =
+ SpvFunctionControlInlineMask | SpvFunctionControlDontInlineMask |
+ SpvFunctionControlPureMask | SpvFunctionControlConstMask;
+ // The following is to keep release-mode compilers happy as this variable is
+ // only used in an assertion.
+ (void)(acceptable_function_control_bits);
+ assert(!(message_.function_control() & ~acceptable_function_control_bits) &&
+ "Nonsensical loop control bits were found.");
+
+ // Check (via an assertion) that function control mask does not have both
+ // Inline and DontInline bits set.
+ assert(!((message_.function_control() & SpvFunctionControlInlineMask) &&
+ (message_.function_control() & SpvFunctionControlDontInlineMask)) &&
+ "It is not OK to set both the 'Inline' and 'DontInline' bits of a "
+ "function control mask");
+
+ // Check that Const and Pure are only present if they were present on the
+ // original function
+ for (auto mask_bit :
+ {SpvFunctionControlPureMask, SpvFunctionControlConstMask}) {
+ if ((message_.function_control() & mask_bit) &&
+ !(existing_function_control_mask & mask_bit)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void TransformationSetFunctionControl::Apply(opt::IRContext* context,
+ FactManager* /*unused*/) const {
+ opt::Instruction* function_def_instruction =
+ FindFunctionDefInstruction(context);
+ function_def_instruction->SetInOperand(0, {message_.function_control()});
+}
+
+protobufs::Transformation TransformationSetFunctionControl::ToMessage() const {
+ protobufs::Transformation result;
+ *result.mutable_set_function_control() = message_;
+ return result;
+}
+
+opt::Instruction* TransformationSetFunctionControl ::FindFunctionDefInstruction(
+ opt::IRContext* context) const {
+ // Look through all functions for a function whose defining instruction's
+ // result id matches |message_.function_id|, returning the defining
+ // instruction if found.
+ for (auto& function : *context->module()) {
+ if (function.DefInst().result_id() == message_.function_id()) {
+ return &function.DefInst();
+ }
+ }
+ // A nullptr result indicates that no match was found.
+ return nullptr;
+}
+
+} // namespace fuzz
+} // namespace spvtools