mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-22 19:50:05 +00:00
Move functions for building modules outside of the C++ interface.
This commit is contained in:
parent
869440ebd4
commit
b54686d017
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
add_library(SPIRV-Tools-opt
|
||||
basic_block.h
|
||||
build_module.h
|
||||
constants.h
|
||||
def_use_manager.h
|
||||
eliminate_dead_constant_pass.h
|
||||
@ -35,6 +36,7 @@ add_library(SPIRV-Tools-opt
|
||||
type_manager.h
|
||||
unify_const_pass.h
|
||||
|
||||
build_module.cpp
|
||||
def_use_manager.cpp
|
||||
eliminate_dead_constant_pass.cpp
|
||||
function.cpp
|
||||
|
74
source/opt/build_module.cpp
Normal file
74
source/opt/build_module.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
//
|
||||
// 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 "build_module.h"
|
||||
|
||||
#include "ir_loader.h"
|
||||
#include "libspirv.hpp"
|
||||
#include "make_unique.h"
|
||||
#include "table.h"
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
namespace {
|
||||
|
||||
// Sets the module header for IrLoader. Meets the interface requirement of
|
||||
// spvBinaryParse().
|
||||
spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic,
|
||||
uint32_t version, uint32_t generator,
|
||||
uint32_t id_bound, uint32_t reserved) {
|
||||
reinterpret_cast<ir::IrLoader*>(builder)->SetModuleHeader(
|
||||
magic, version, generator, id_bound, reserved);
|
||||
return SPV_SUCCESS;
|
||||
};
|
||||
|
||||
// Processes a parsed instruction for IrLoader. Meets the interface requirement
|
||||
// of spvBinaryParse().
|
||||
spv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) {
|
||||
reinterpret_cast<ir::IrLoader*>(builder)->AddInstruction(inst);
|
||||
return SPV_SUCCESS;
|
||||
};
|
||||
|
||||
} // annoymous namespace
|
||||
|
||||
std::unique_ptr<ir::Module> BuildModule(spv_target_env env,
|
||||
MessageConsumer consumer,
|
||||
const std::vector<uint32_t>& binary) {
|
||||
auto context = spvContextCreate(env);
|
||||
SetContextMessageConsumer(context, consumer);
|
||||
|
||||
auto module = MakeUnique<ir::Module>();
|
||||
ir::IrLoader loader(context->consumer, module.get());
|
||||
|
||||
spv_result_t status =
|
||||
spvBinaryParse(context, &loader, binary.data(), binary.size(),
|
||||
SetSpvHeader, SetSpvInst, nullptr);
|
||||
loader.EndModule();
|
||||
|
||||
spvContextDestroy(context);
|
||||
|
||||
return status == SPV_SUCCESS ? std::move(module) : nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ir::Module> BuildModule(spv_target_env env,
|
||||
MessageConsumer consumer,
|
||||
const std::string& text) {
|
||||
SpvTools t(env);
|
||||
t.SetMessageConsumer(consumer);
|
||||
std::vector<uint32_t> binary;
|
||||
if (t.Assemble(text, &binary) != SPV_SUCCESS) return nullptr;
|
||||
return BuildModule(env, consumer, binary);
|
||||
}
|
||||
|
||||
} // namespace spvtools
|
44
source/opt/build_module.h
Normal file
44
source/opt/build_module.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SPIRV_TOOLS_OPT_BUILD_MODULE_H_
|
||||
#define SPIRV_TOOLS_OPT_BUILD_MODULE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "message.h"
|
||||
#include "module.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
// Builds and returns an ir::Module from the given SPIR-V |binary|. The |binary|
|
||||
// will be decoded according to the given target |env|. Returns nullptr if erors
|
||||
// occur and sends the errors to |consumer|.
|
||||
std::unique_ptr<ir::Module> BuildModule(spv_target_env env,
|
||||
MessageConsumer consumer,
|
||||
const std::vector<uint32_t>& binary);
|
||||
|
||||
// Builds and returns an ir::Module from the given SPIR-V assembly |text|.
|
||||
// The |text| will be encoded according to the given target |env|. Returns
|
||||
// nullptr if erors occur and sends the errors to |consumer|.
|
||||
std::unique_ptr<ir::Module> BuildModule(spv_target_env env,
|
||||
MessageConsumer consumer,
|
||||
const std::string& text);
|
||||
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SPIRV_TOOLS_OPT_BUILD_MODULE_H_
|
@ -20,26 +20,6 @@
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
namespace {
|
||||
|
||||
// Sets the module header. Meets the interface requirement of spvBinaryParse().
|
||||
spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic,
|
||||
uint32_t version, uint32_t generator,
|
||||
uint32_t id_bound, uint32_t reserved) {
|
||||
reinterpret_cast<ir::IrLoader*>(builder)
|
||||
->SetModuleHeader(magic, version, generator, id_bound, reserved);
|
||||
return SPV_SUCCESS;
|
||||
};
|
||||
|
||||
// Processes a parsed instruction. Meets the interface requirement of
|
||||
// spvBinaryParse().
|
||||
spv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) {
|
||||
reinterpret_cast<ir::IrLoader*>(builder)->AddInstruction(inst);
|
||||
return SPV_SUCCESS;
|
||||
};
|
||||
|
||||
} // annoymous namespace
|
||||
|
||||
void SpvTools::SetMessageConsumer(MessageConsumer consumer) {
|
||||
SetContextMessageConsumer(context_, std::move(consumer));
|
||||
}
|
||||
@ -78,29 +58,4 @@ spv_result_t SpvTools::Disassemble(const std::vector<uint32_t>& binary,
|
||||
return status;
|
||||
}
|
||||
|
||||
std::unique_ptr<ir::Module> SpvTools::BuildModule(
|
||||
const std::vector<uint32_t>& binary) {
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
|
||||
auto module = MakeUnique<ir::Module>();
|
||||
ir::IrLoader loader(context_->consumer, module.get());
|
||||
|
||||
spv_result_t status =
|
||||
spvBinaryParse(context_, &loader, binary.data(), binary.size(),
|
||||
SetSpvHeader, SetSpvInst, &diagnostic);
|
||||
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
|
||||
loader.EndModule();
|
||||
|
||||
if (status == SPV_SUCCESS) return module;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ir::Module> SpvTools::BuildModule(const std::string& text) {
|
||||
std::vector<uint32_t> binary;
|
||||
if (Assemble(text, &binary) != SPV_SUCCESS) return nullptr;
|
||||
return BuildModule(binary);
|
||||
}
|
||||
|
||||
} // namespace spvtools
|
||||
|
@ -15,12 +15,10 @@
|
||||
#ifndef SPIRV_TOOLS_LIBSPIRV_HPP_
|
||||
#define SPIRV_TOOLS_LIBSPIRV_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "message.h"
|
||||
#include "module.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
namespace spvtools {
|
||||
@ -53,12 +51,6 @@ class SpvTools {
|
||||
uint32_t options = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
|
||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
|
||||
|
||||
// Builds and returns a Module from the given SPIR-V |binary|.
|
||||
std::unique_ptr<ir::Module> BuildModule(const std::vector<uint32_t>& binary);
|
||||
|
||||
// Builds and returns a Module from the given SPIR-V assembly |text|.
|
||||
std::unique_ptr<ir::Module> BuildModule(const std::string& text);
|
||||
|
||||
private:
|
||||
// Context for the current invocation. Thread-safety of this class depends on
|
||||
// the constness of this field.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "opt/libspirv.hpp"
|
||||
#include "spirv/1.1/spirv.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "opt/build_module.h"
|
||||
#include "opt/libspirv.hpp"
|
||||
#include "opt/make_unique.h"
|
||||
#include "opt/pass_manager.h"
|
||||
@ -49,7 +50,8 @@ class PassTest : public TestT {
|
||||
// and the boolean value returned from pass Process() function.
|
||||
std::tuple<std::string, bool> OptimizeAndDisassemble(
|
||||
opt::Pass* pass, const std::string& original, bool skip_nop) {
|
||||
std::unique_ptr<ir::Module> module = tools_.BuildModule(original);
|
||||
std::unique_ptr<ir::Module> module =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, consumer_, original);
|
||||
EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
|
||||
<< original << std::endl;
|
||||
if (!module) {
|
||||
@ -110,7 +112,8 @@ class PassTest : public TestT {
|
||||
void RunAndCheck(const std::string& original, const std::string& expected) {
|
||||
assert(manager_->NumPasses());
|
||||
|
||||
std::unique_ptr<ir::Module> module = tools_.BuildModule(original);
|
||||
std::unique_ptr<ir::Module> module =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, original);
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
manager_->Run(module.get());
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "opt/build_module.h"
|
||||
#include "opt/def_use_manager.h"
|
||||
#include "opt/libspirv.hpp"
|
||||
#include "pass_utils.h"
|
||||
@ -128,7 +129,7 @@ TEST_P(ParseDefUseTest, Case) {
|
||||
// Build module.
|
||||
const std::vector<const char*> text = {tc.text};
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(JoinAllInsts(text));
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, JoinAllInsts(text));
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// Analyze def and use.
|
||||
@ -509,7 +510,7 @@ TEST_P(ReplaceUseTest, Case) {
|
||||
// Build module.
|
||||
const std::vector<const char*> text = {tc.before};
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(JoinAllInsts(text));
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, JoinAllInsts(text));
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// Analyze def and use.
|
||||
@ -811,7 +812,7 @@ TEST_P(KillDefTest, Case) {
|
||||
// Build module.
|
||||
const std::vector<const char*> text = {tc.before};
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(JoinAllInsts(text));
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, JoinAllInsts(text));
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// Analyze def and use.
|
||||
@ -1061,7 +1062,7 @@ TEST(DefUseTest, OpSwitch) {
|
||||
" OpFunctionEnd";
|
||||
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(original_text);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, original_text);
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// Analyze def and use.
|
||||
@ -1184,7 +1185,7 @@ TEST_P(AnalyzeInstDefUseTest, Case) {
|
||||
|
||||
// Build module.
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(tc.module_text);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, tc.module_text);
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// Analyze the instructions.
|
||||
@ -1307,7 +1308,7 @@ TEST_P(KillInstTest, Case) {
|
||||
|
||||
// Build module.
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(tc.before);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, tc.before);
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// KillInst
|
||||
@ -1415,7 +1416,7 @@ TEST_P(GetAnnotationsTest, Case) {
|
||||
|
||||
// Build module.
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(tc.code);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, tc.code);
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
// Get annotations
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "opt/build_module.h"
|
||||
#include "opt/libspirv.hpp"
|
||||
|
||||
namespace {
|
||||
@ -23,7 +24,8 @@ using namespace spvtools;
|
||||
|
||||
void DoRoundTripCheck(const std::string& text) {
|
||||
SpvTools t(SPV_ENV_UNIVERSAL_1_1);
|
||||
std::unique_ptr<ir::Module> module = t.BuildModule(text);
|
||||
std::unique_ptr<ir::Module> module =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, text);
|
||||
ASSERT_NE(nullptr, module) << "Failed to assemble\n" << text;
|
||||
|
||||
std::vector<uint32_t> binary;
|
||||
@ -209,7 +211,8 @@ TEST(IrBuilder, OpUndefOutsideFunction) {
|
||||
// clang-format on
|
||||
|
||||
SpvTools t(SPV_ENV_UNIVERSAL_1_1);
|
||||
std::unique_ptr<ir::Module> module = t.BuildModule(text);
|
||||
std::unique_ptr<ir::Module> module =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, text);
|
||||
ASSERT_NE(nullptr, module);
|
||||
|
||||
const auto opundef_count = std::count_if(
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "opt/build_module.h"
|
||||
#include "opt/libspirv.hpp"
|
||||
#include "opt/module.h"
|
||||
|
||||
@ -42,9 +43,9 @@ TEST(ModuleTest, SetIdBound) {
|
||||
|
||||
// Returns a module formed by assembling the given text,
|
||||
// then loading the result.
|
||||
std::unique_ptr<Module> BuildModule(std::string text) {
|
||||
spvtools::SpvTools t(SPV_ENV_UNIVERSAL_1_1);
|
||||
return t.BuildModule(text);
|
||||
inline std::unique_ptr<Module> BuildModule(std::string text) {
|
||||
return spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, spvtools::IgnoreMessage,
|
||||
text);
|
||||
}
|
||||
|
||||
TEST(ModuleTest, ComputeIdBound) {
|
||||
@ -69,4 +70,3 @@ TEST(ModuleTest, ComputeIdBound) {
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "opt/build_module.h"
|
||||
#include "opt/instruction.h"
|
||||
#include "opt/libspirv.hpp"
|
||||
#include "opt/type_manager.h"
|
||||
|
||||
namespace {
|
||||
@ -89,7 +89,7 @@ TEST(TypeManager, TypeStrings) {
|
||||
};
|
||||
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(text);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, text);
|
||||
opt::analysis::TypeManager manager(IgnoreMessage, *module);
|
||||
|
||||
EXPECT_EQ(type_id_strs.size(), manager.NumTypes());
|
||||
@ -119,7 +119,7 @@ TEST(Struct, DecorationOnStruct) {
|
||||
%struct7 = OpTypeStruct %f32 ; no decoration
|
||||
)";
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(text);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, text);
|
||||
opt::analysis::TypeManager manager(IgnoreMessage, *module);
|
||||
|
||||
ASSERT_EQ(7u, manager.NumTypes());
|
||||
@ -169,7 +169,7 @@ TEST(Struct, DecorationOnMember) {
|
||||
%struct10 = OpTypeStruct %u32 %f32 ; no member decoration
|
||||
)";
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(text);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, text);
|
||||
opt::analysis::TypeManager manager(IgnoreMessage, *module);
|
||||
|
||||
ASSERT_EQ(10u, manager.NumTypes());
|
||||
@ -207,7 +207,7 @@ TEST(Types, DecorationEmpty) {
|
||||
%struct5 = OpTypeStruct %f32
|
||||
)";
|
||||
std::unique_ptr<ir::Module> module =
|
||||
SpvTools(SPV_ENV_UNIVERSAL_1_1).BuildModule(text);
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, IgnoreMessage, text);
|
||||
opt::analysis::TypeManager manager(IgnoreMessage, *module);
|
||||
|
||||
ASSERT_EQ(5u, manager.NumTypes());
|
||||
|
@ -17,8 +17,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "message.h"
|
||||
#include "source/opt/build_module.h"
|
||||
#include "source/opt/ir_loader.h"
|
||||
#include "source/opt/libspirv.hpp"
|
||||
#include "source/opt/pass_manager.h"
|
||||
#include "tools/io.h"
|
||||
|
||||
@ -139,7 +139,8 @@ int main(int argc, char** argv) {
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
spvContextDestroy(context);
|
||||
|
||||
std::unique_ptr<ir::Module> module = SpvTools(target_env).BuildModule(source);
|
||||
std::unique_ptr<ir::Module> module =
|
||||
BuildModule(target_env, pass_manager.consumer(), source);
|
||||
pass_manager.Run(module.get());
|
||||
|
||||
std::vector<uint32_t> target;
|
||||
|
Loading…
Reference in New Issue
Block a user