mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
Add forwarding so that passes' ctor can have args.
Also removed the default argument value of `skip_nop` for function `SinglePassRunAndCheck()` and `SinglePassRunAndDisassemble()`. This is required to support variadic arguments.
This commit is contained in:
parent
273920c554
commit
2ce67252c8
@ -50,9 +50,11 @@ class PassManager {
|
||||
void AddPass(std::unique_ptr<Pass> pass) {
|
||||
passes_.push_back(std::move(pass));
|
||||
}
|
||||
template <typename PassT>
|
||||
void AddPass() {
|
||||
passes_.emplace_back(new PassT);
|
||||
// Uses the argument to construct a pass instance of type PassT, and adds the
|
||||
// pass instance to this pass manger.
|
||||
template <typename PassT, typename... Args>
|
||||
void AddPass(Args&&... args) {
|
||||
passes_.emplace_back(new PassT(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
// Returns the number of passes added.
|
||||
|
0
test/opt/assembly_builder.h
Executable file → Normal file
0
test/opt/assembly_builder.h
Executable file → Normal file
@ -34,9 +34,9 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "opt/libspirv.hpp"
|
||||
#include "opt/make_unique.h"
|
||||
#include "opt/pass_manager.h"
|
||||
#include "opt/passes.h"
|
||||
#include "opt/make_unique.h"
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
@ -57,10 +57,10 @@ class PassTest : public TestT {
|
||||
// disassebles the optimized binary. Returns a tuple of disassembly string
|
||||
// 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 = false) {
|
||||
opt::Pass* pass, const std::string& original, bool skip_nop) {
|
||||
std::unique_ptr<ir::Module> module = tools_.BuildModule(original);
|
||||
EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n" << original
|
||||
<< std::endl;
|
||||
EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
|
||||
<< original << std::endl;
|
||||
if (!module) {
|
||||
return std::make_tuple(std::string(), false);
|
||||
}
|
||||
@ -71,17 +71,18 @@ class PassTest : public TestT {
|
||||
module->ToBinary(&binary, skip_nop);
|
||||
std::string optimized;
|
||||
EXPECT_EQ(SPV_SUCCESS, tools_.Disassemble(binary, &optimized))
|
||||
<< "Disassembling failed for shader:\n" << original << std::endl;
|
||||
<< "Disassembling failed for shader:\n"
|
||||
<< original << std::endl;
|
||||
return std::make_tuple(optimized, modified);
|
||||
}
|
||||
|
||||
// Runs a single pass of class |PassT| on the binary assembled from the
|
||||
// |assembly|, disassembles the optimized binary. Returns a tuple of
|
||||
// disassembly string and the boolean value from the pass Process() function.
|
||||
template <typename PassT>
|
||||
template <typename PassT, typename... Args>
|
||||
std::tuple<std::string, bool> SinglePassRunAndDisassemble(
|
||||
const std::string& assembly, bool skip_nop = false) {
|
||||
auto pass = MakeUnique<PassT>();
|
||||
const std::string& assembly, bool skip_nop, Args&&... args) {
|
||||
auto pass = MakeUnique<PassT>(std::forward<Args>(args)...);
|
||||
return OptimizeAndDisassemble(pass.get(), assembly, skip_nop);
|
||||
}
|
||||
|
||||
@ -89,23 +90,23 @@ class PassTest : public TestT {
|
||||
// |original| assembly, and checks whether the optimized binary can be
|
||||
// disassembled to the |expected| assembly. This does *not* involve pass
|
||||
// manager. Callers are suggested to use SCOPED_TRACE() for better messages.
|
||||
template <typename PassT>
|
||||
template <typename PassT, typename... Args>
|
||||
void SinglePassRunAndCheck(const std::string& original,
|
||||
const std::string& expected,
|
||||
bool skip_nop = false) {
|
||||
const std::string& expected, bool skip_nop,
|
||||
Args&&... args) {
|
||||
std::string optimized;
|
||||
bool modified = false;
|
||||
std::tie(optimized, modified) =
|
||||
SinglePassRunAndDisassemble<PassT>(original, skip_nop);
|
||||
std::tie(optimized, modified) = SinglePassRunAndDisassemble<PassT>(
|
||||
original, skip_nop, std::forward<Args>(args)...);
|
||||
// Check whether the pass returns the correct modification indication.
|
||||
EXPECT_EQ(original != expected, modified);
|
||||
EXPECT_EQ(expected, optimized);
|
||||
}
|
||||
|
||||
// Adds a pass to be run.
|
||||
template <typename PassT>
|
||||
void AddPass() {
|
||||
manager_->AddPass<PassT>();
|
||||
template <typename PassT, typename... Args>
|
||||
void AddPass(Args&&... args) {
|
||||
manager_->AddPass<PassT>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Renews the pass manager, including clearing all previously added passes.
|
||||
|
@ -57,7 +57,8 @@ TEST_F(AssemblyBuilderTest, MinimalShader) {
|
||||
};
|
||||
|
||||
SinglePassRunAndCheck<opt::NullPass>(builder.GetCode(),
|
||||
JoinAllInsts(expected));
|
||||
JoinAllInsts(expected),
|
||||
/* skip_nop = */ false);
|
||||
}
|
||||
|
||||
TEST_F(AssemblyBuilderTest, ShaderWithConstants) {
|
||||
@ -170,7 +171,8 @@ TEST_F(AssemblyBuilderTest, ShaderWithConstants) {
|
||||
// clang-format on
|
||||
};
|
||||
SinglePassRunAndCheck<opt::NullPass>(builder.GetCode(),
|
||||
JoinAllInsts(expected));
|
||||
JoinAllInsts(expected),
|
||||
/* skip_nop = */ false);
|
||||
}
|
||||
|
||||
TEST_F(AssemblyBuilderTest, SpecConstants) {
|
||||
@ -250,7 +252,8 @@ TEST_F(AssemblyBuilderTest, SpecConstants) {
|
||||
};
|
||||
|
||||
SinglePassRunAndCheck<opt::NullPass>(builder.GetCode(),
|
||||
JoinAllInsts(expected));
|
||||
JoinAllInsts(expected),
|
||||
/* skip_nop = */ false);
|
||||
}
|
||||
|
||||
TEST_F(AssemblyBuilderTest, AppendNames) {
|
||||
@ -283,7 +286,8 @@ TEST_F(AssemblyBuilderTest, AppendNames) {
|
||||
};
|
||||
|
||||
SinglePassRunAndCheck<opt::NullPass>(builder.GetCode(),
|
||||
JoinAllInsts(expected));
|
||||
JoinAllInsts(expected),
|
||||
/* skip_nop = */ false);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -53,7 +53,7 @@ TEST_P(FreezeSpecConstantValueTypeTest, PrimaryType) {
|
||||
"OpCapability Shader", "OpMemoryModel Logical GLSL450",
|
||||
test_case.type_decl, test_case.expected_frozen_const};
|
||||
SinglePassRunAndCheck<opt::FreezeSpecConstantValuePass>(
|
||||
JoinAllInsts(text), JoinAllInsts(expected));
|
||||
JoinAllInsts(text), JoinAllInsts(expected), /* skip_nop = */ false);
|
||||
}
|
||||
|
||||
// Test each primary type.
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
#include "module_utils.h"
|
||||
#include "opt/make_unique.h"
|
||||
#include "pass_fixture.h"
|
||||
@ -36,6 +38,17 @@ using namespace spvtools;
|
||||
using spvtest::GetIdBound;
|
||||
using ::testing::Eq;
|
||||
|
||||
// A null pass whose construtors accept arguments
|
||||
class NullPassWithArgs : public opt::NullPass {
|
||||
public:
|
||||
NullPassWithArgs(uint32_t) : NullPass() {}
|
||||
NullPassWithArgs(std::string) : NullPass() {}
|
||||
NullPassWithArgs(const std::vector<int>&) : NullPass() {}
|
||||
NullPassWithArgs(const std::vector<int>&, uint32_t) : NullPass() {}
|
||||
|
||||
const char* name() const override { return "null-with-args"; }
|
||||
};
|
||||
|
||||
TEST(PassManager, Interface) {
|
||||
opt::PassManager manager;
|
||||
EXPECT_EQ(0u, manager.NumPasses());
|
||||
@ -54,6 +67,19 @@ TEST(PassManager, Interface) {
|
||||
EXPECT_STREQ("strip-debug", manager.GetPass(0)->name());
|
||||
EXPECT_STREQ("null", manager.GetPass(1)->name());
|
||||
EXPECT_STREQ("strip-debug", manager.GetPass(2)->name());
|
||||
|
||||
manager.AddPass<NullPassWithArgs>(1u);
|
||||
manager.AddPass<NullPassWithArgs>("null pass args");
|
||||
manager.AddPass<NullPassWithArgs>(std::initializer_list<int>{1, 2});
|
||||
manager.AddPass<NullPassWithArgs>(std::initializer_list<int>{1, 2}, 3);
|
||||
EXPECT_EQ(7u, manager.NumPasses());
|
||||
EXPECT_STREQ("strip-debug", manager.GetPass(0)->name());
|
||||
EXPECT_STREQ("null", manager.GetPass(1)->name());
|
||||
EXPECT_STREQ("strip-debug", manager.GetPass(2)->name());
|
||||
EXPECT_STREQ("null-with-args", manager.GetPass(3)->name());
|
||||
EXPECT_STREQ("null-with-args", manager.GetPass(4)->name());
|
||||
EXPECT_STREQ("null-with-args", manager.GetPass(5)->name());
|
||||
EXPECT_STREQ("null-with-args", manager.GetPass(6)->name());
|
||||
}
|
||||
|
||||
// A pass that appends an OpNop instruction to the debug section.
|
||||
@ -66,6 +92,24 @@ class AppendOpNopPass : public opt::Pass {
|
||||
}
|
||||
};
|
||||
|
||||
// A pass that appends specified number of OpNop instructions to the debug
|
||||
// section.
|
||||
class AppendMultipleOpNopPass : public opt::Pass {
|
||||
public:
|
||||
AppendMultipleOpNopPass(uint32_t num_nop) : num_nop_(num_nop) {}
|
||||
const char* name() const override { return "AppendOpNop"; }
|
||||
bool Process(ir::Module* module) override {
|
||||
for (uint32_t i = 0; i < num_nop_; i++) {
|
||||
auto inst = MakeUnique<ir::Instruction>();
|
||||
module->AddDebugInst(std::move(inst));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t num_nop_;
|
||||
};
|
||||
|
||||
// A pass that duplicates the last instruction in the debug section.
|
||||
class DuplicateInstPass : public opt::Pass {
|
||||
const char* name() const override { return "DuplicateInst"; }
|
||||
@ -94,6 +138,10 @@ TEST_F(PassManagerTest, Run) {
|
||||
AddPass<DuplicateInstPass>();
|
||||
AddPass<AppendOpNopPass>();
|
||||
RunAndCheck(text.c_str(), (text + "OpSource ESSL 310\nOpNop\n").c_str());
|
||||
|
||||
RenewPassManger();
|
||||
AddPass<AppendMultipleOpNopPass>(3);
|
||||
RunAndCheck(text.c_str(), (text + "OpNop\nOpNop\nOpNop\n").c_str());
|
||||
}
|
||||
|
||||
// A pass that appends an OpTypeVoid instruction that uses a given id.
|
||||
|
@ -61,7 +61,8 @@ TEST_F(StripLineDebugInfoTest, LineNoLine) {
|
||||
// clang-format on
|
||||
};
|
||||
SinglePassRunAndCheck<opt::StripDebugInfoPass>(JoinAllInsts(text),
|
||||
JoinNonDebugInsts(text));
|
||||
JoinNonDebugInsts(text),
|
||||
/* skip_nop = */ false);
|
||||
|
||||
// Let's add more debug instruction before the "OpString" instruction.
|
||||
const std::vector<const char*> more_text = {
|
||||
@ -79,7 +80,8 @@ TEST_F(StripLineDebugInfoTest, LineNoLine) {
|
||||
};
|
||||
text.insert(text.begin() + 4, more_text.cbegin(), more_text.cend());
|
||||
SinglePassRunAndCheck<opt::StripDebugInfoPass>(JoinAllInsts(text),
|
||||
JoinNonDebugInsts(text));
|
||||
JoinNonDebugInsts(text),
|
||||
/* skip_nop = */ false);
|
||||
}
|
||||
|
||||
using StripDebugInfoTest = PassTest<::testing::TestWithParam<const char*>>;
|
||||
@ -89,7 +91,8 @@ TEST_P(StripDebugInfoTest, Kind) {
|
||||
"OpCapability Shader", "OpMemoryModel Logical GLSL450", GetParam(),
|
||||
};
|
||||
SinglePassRunAndCheck<opt::StripDebugInfoPass>(JoinAllInsts(text),
|
||||
JoinNonDebugInsts(text));
|
||||
JoinNonDebugInsts(text),
|
||||
/* skip_nop = */ false);
|
||||
}
|
||||
|
||||
// Test each possible non-line debug instruction.
|
||||
|
Loading…
Reference in New Issue
Block a user