ir::ModuleHeader header;
res = GenerateHeader(consumer, modules, max_id_bound, &header);
if (res != SPV_SUCCESS) return res;
- IRContext linked_context(consumer);
+ IRContext linked_context(impl_->context->target_env, consumer);
linked_context.module()->SetHeader(header);
// Phase 3: Merge all the binaries into a single one.
Pass::Status AggressiveDCEPass::ProcessImpl() {
// Current functionality assumes shader capability
// TODO(greg-lunarg): Handle additional capabilities
- if (!get_module()->HasCapability(SpvCapabilityShader))
+ if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
return Status::SuccessWithoutChange;
// Current functionality assumes relaxed logical addressing (see
// instruction.h)
// TODO(greg-lunarg): Handle non-logical addressing
- if (get_module()->HasCapability(SpvCapabilityAddresses))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
// If any extensions in the module are not explicitly supported,
// return unmodified.
auto context = spvContextCreate(env);
libspirv::SetContextMessageConsumer(context, consumer);
- auto irContext = MakeUnique<ir::IRContext>(consumer);
+ auto irContext = MakeUnique<ir::IRContext>(env, consumer);
ir::IrLoader loader(consumer, irContext->module());
spv_result_t status = spvBinaryParse(context, &loader, binary, size,
#include "cfg.h"
#include "cfa.h"
+#include "ir_context.h"
#include "module.h"
namespace spvtools {
void CFG::ComputeStructuredOrder(ir::Function* func, ir::BasicBlock* root,
std::list<ir::BasicBlock*>* order) {
- assert(module_->HasCapability(SpvCapabilityShader) &&
+ assert(module_->context()->get_feature_mgr()->HasCapability(
+ SpvCapabilityShader) &&
"This only works on structured control flow");
// Compute structured successors and do DFS.
Pass::Status CommonUniformElimPass::ProcessImpl() {
// Assumes all control flow structured.
// TODO(greg-lunarg): Do SSA rewrite for non-structured control flow
- if (!get_module()->HasCapability(SpvCapabilityShader))
+ if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
return Status::SuccessWithoutChange;
// Assumes logical addressing only
// TODO(greg-lunarg): Add support for physical addressing
- if (get_module()->HasCapability(SpvCapabilityAddresses))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
// Do not process if any disallowed extensions are enabled
if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
Pass::Status DeadBranchElimPass::ProcessImpl() {
// Current functionality assumes structured control flow.
// TODO(greg-lunarg): Handle non-structured control-flow.
- if (!get_module()->HasCapability(SpvCapabilityShader))
+ if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
return Status::SuccessWithoutChange;
// Do not process if module contains OpGroupDecorate. Additional
// support required in KillNamesAndDecorates().
// limitations under the License.
#include "feature_manager.h"
+#include <queue>
+#include <stack>
#include "enum_string_mapping.h"
namespace opt {
void FeatureManager::Analyze(ir::Module* module) {
+ AddExtensions(module);
+ AddCapabilities(module);
+}
+
+void FeatureManager::AddExtensions(ir::Module* module) {
for (auto ext : module->extensions()) {
const std::string name =
reinterpret_cast<const char*>(ext.GetInOperand(0u).words.data());
}
}
+void FeatureManager::AddCapability(SpvCapability cap) {
+ if (capabilities_.Contains(cap)) return;
+
+ capabilities_.Add(cap);
+
+ spv_operand_desc desc = {};
+ if (SPV_SUCCESS ==
+ grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) {
+ libspirv::CapabilitySet(desc->numCapabilities, desc->capabilities)
+ .ForEach([this](SpvCapability c) { AddCapability(c); });
+ }
+}
+
+void FeatureManager::AddCapabilities(ir::Module* module) {
+ for (ir::Instruction& inst : module->capabilities()) {
+ AddCapability(static_cast<SpvCapability>(inst.GetSingleWordInOperand(0)));
+ }
+}
+
} // namespace opt
} // namespace spvtools
#ifndef LIBSPIRV_OPT_FEATURE_MANAGER_H_
#define LIBSPIRV_OPT_FEATURE_MANAGER_H_
+#include "assembly_grammar.h"
#include "extensions.h"
#include "module.h"
// Tracks features enabled by a module. The IRContext has a FeatureManager.
class FeatureManager {
public:
- FeatureManager() = default;
+ explicit FeatureManager(const libspirv::AssemblyGrammar& grammar)
+ : grammar_(grammar) {}
// Returns true if |ext| is an enabled extension in the module.
bool HasExtension(libspirv::Extension ext) const {
return extensions_.Contains(ext);
}
- // Analyzes |module| and records enabled extensions.
+ // Returns true if |cap| is an enabled capability in the module.
+ bool HasCapability(SpvCapability cap) const {
+ return capabilities_.Contains(cap);
+ }
+
+ // Analyzes |module| and records enabled extensions and capabilities.
void Analyze(ir::Module* module);
private:
+ // Analyzes |module| and records enabled extensions.
+ void AddExtensions(ir::Module* module);
+
+ // Adds the given |capability| and all implied capabilities into the current
+ // FeatureManager.
+ void AddCapability(SpvCapability capability);
+
+ // Analyzes |module| and records enabled capabilities.
+ void AddCapabilities(ir::Module* module);
+
+ // Auxiliary object for querying SPIR-V grammar facts.
+ const libspirv::AssemblyGrammar& grammar_;
+
// The enabled extensions.
libspirv::ExtensionSet extensions_;
+
+ // The enabled capabilities.
+ libspirv::CapabilitySet capabilities_;
};
} // namespace opt
bool InlinePass::HasNoReturnInLoop(ir::Function* func) {
// If control not structured, do not do loop/return analysis
// TODO: Analyze returns in non-structured control flow
- if (!get_module()->HasCapability(SpvCapabilityShader)) return false;
+ if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
+ return false;
// Compute structured block order. This order has the property
// that dominators are before all blocks they dominate and merge blocks
// are after all blocks that are in the control constructs of their header.
}
bool Instruction::IsReadOnlyVariable() const {
- if (context()->module()->HasCapability(SpvCapabilityShader))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
return IsReadOnlyVariableShaders();
else
return IsReadOnlyVariableKernel();
return false;
}
- if (context()->module()->HasCapability(SpvCapabilityAddresses)) {
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) {
// TODO: The rules here could be more restrictive.
return true;
}
#ifndef SPIRV_TOOLS_IR_CONTEXT_H
#define SPIRV_TOOLS_IR_CONTEXT_H
+#include "assembly_grammar.h"
#include "cfg.h"
#include "constants.h"
#include "decoration_manager.h"
friend inline Analysis& operator<<=(Analysis& a, int shift);
// Creates an |IRContext| that contains an owned |Module|
- IRContext(spvtools::MessageConsumer c)
- : unique_id_(0),
+ IRContext(spv_target_env env, spvtools::MessageConsumer c)
+ : syntax_context_(spvContextCreate(env)),
+ grammar_(syntax_context_),
+ unique_id_(0),
module_(new Module()),
consumer_(std::move(c)),
def_use_mgr_(nullptr),
valid_analyses_(kAnalysisNone),
constant_mgr_(nullptr),
type_mgr_(nullptr) {
+ libspirv::SetContextMessageConsumer(syntax_context_, consumer_);
module_->SetContext(this);
}
- IRContext(std::unique_ptr<Module>&& m, spvtools::MessageConsumer c)
- : unique_id_(0),
+ IRContext(spv_target_env env, std::unique_ptr<Module>&& m,
+ spvtools::MessageConsumer c)
+ : syntax_context_(spvContextCreate(env)),
+ grammar_(syntax_context_),
+ unique_id_(0),
module_(std::move(m)),
consumer_(std::move(c)),
def_use_mgr_(nullptr),
valid_analyses_(kAnalysisNone),
constant_mgr_(nullptr),
type_mgr_(nullptr) {
+ libspirv::SetContextMessageConsumer(syntax_context_, consumer_);
module_->SetContext(this);
InitializeCombinators();
}
+
+ ~IRContext() { spvContextDestroy(syntax_context_); }
+
Module* module() const { return module_.get(); }
// Returns a vector of pointers to constant-creation instructions in this
// Analyzes the features in the owned module. Builds the manager if required.
void AnalyzeFeatures() {
- feature_mgr_.reset(new opt::FeatureManager());
+ feature_mgr_.reset(new opt::FeatureManager(grammar_));
feature_mgr_->Analyze(module());
}
// Add the combinator opcode for the given extension to combinator_ops_.
void AddCombinatorsForExtension(ir::Instruction* extension);
+ // The SPIR-V syntax context containing grammar tables for opcodes and
+ // operands.
+ spv_context syntax_context_;
+
+ // Auxiliary object for querying SPIR-V grammar facts.
+ libspirv::AssemblyGrammar grammar_;
+
// An unique identifier for instructions in |module_|. Can be used to order
// instructions in a container.
//
Pass::Status LocalSingleBlockLoadStoreElimPass::ProcessImpl() {
// Assumes relaxed logical addressing only (see instruction.h).
- if (get_module()->HasCapability(SpvCapabilityAddresses))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
// Do not process if module contains OpGroupDecorate. Additional
// support required in KillNamesAndDecorates().
Pass::Status LocalSingleStoreElimPass::ProcessImpl() {
// Assumes relaxed logical addressing only (see instruction.h)
- if (get_module()->HasCapability(SpvCapabilityAddresses))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
// Do not process if module contains OpGroupDecorate. Additional
// support required in KillNamesAndDecorates().
Pass::Status LocalMultiStoreElimPass::ProcessImpl() {
// Assumes all control flow structured.
// TODO(greg-lunarg): Do SSA rewrite for non-structured control flow
- if (!get_module()->HasCapability(SpvCapabilityShader))
+ if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
return Status::SuccessWithoutChange;
// Assumes relaxed logical addressing only (see instruction.h)
// TODO(greg-lunarg): Add support for physical addressing
- if (get_module()->HasCapability(SpvCapabilityAddresses))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
// Do not process if module contains OpGroupDecorate. Additional
// support required in KillNamesAndDecorates().
// TODO(dnovillo) the current Phi placement mechanism assumes structured
// control-flow. This should be generalized
// (https://github.com/KhronosGroup/SPIRV-Tools/issues/893).
- assert(get_module()->HasCapability(SpvCapabilityShader) &&
+ assert(context()->get_feature_mgr()->HasCapability(SpvCapabilityShader) &&
"This only works on structured control flow");
// Initialize the data structures used to insert Phi instructions.
// TODO (alanbaker): Support structured control flow. Bail out in the
// meantime.
- if (get_module()->HasCapability(SpvCapabilityShader))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
return Status::SuccessWithoutChange;
bool modified = false;
return highest + 1;
}
-bool Module::HasCapability(uint32_t cap) {
+bool Module::HasExplicitCapability(uint32_t cap) {
for (auto& ci : capabilities_) {
uint32_t tcap = ci.GetSingleWordOperand(0);
if (tcap == cap) {
uint32_t ComputeIdBound() const;
// Returns true if module has capability |cap|
- bool HasCapability(uint32_t cap);
+ bool HasExplicitCapability(uint32_t cap);
// Returns id for OpExtInst instruction for extension |extstr|.
// Returns 0 if not found.
// Private variables require the shader capability. If this is not a shader,
// there is no work to do.
- if (get_module()->HasCapability(SpvCapabilityAddresses))
+ if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
std::vector<std::pair<ir::Instruction*, ir::Function*>> variables_to_move;
};
TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffOpcodes) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpDecorate %1 Constant
Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
}
TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDeco) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpDecorate %1 Constant
Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
}
TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetAllowed) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpDecorate %1 Constant
Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
}
TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetDisallowed) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpDecorate %1 Constant
Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
}
TEST_F(DecorationManagerTest, ComparingMemberDecorationsOnSameTypeDiffMember) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpMemberDecorate %1 0 Constant
Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
TEST_F(DecorationManagerTest,
ComparingSameMemberDecorationsOnDiffTargetAllowed) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpMemberDecorate %1 0 Constant
Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
TEST_F(DecorationManagerTest,
ComparingSameMemberDecorationsOnDiffTargetDisallowed) {
- spvtools::ir::IRContext ir_context(GetConsumer());
+ spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
// OpMemberDecorate %1 0 Constant
Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {1u}},
using AnalyzeInstDefUse = ::testing::Test;
TEST(AnalyzeInstDefUse, UseWithNoResultId) {
- ir::IRContext context(nullptr);
+ ir::IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
// Analyze the instructions.
opt::analysis::DefUseManager manager(context.module());
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
- ASSERT_FALSE(context->get_feature_mgr()->HasExtension(
+ EXPECT_FALSE(context->get_feature_mgr()->HasExtension(
libspirv::Extension::kSPV_KHR_variable_pointers));
}
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
- ASSERT_TRUE(context->get_feature_mgr()->HasExtension(
+ EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
libspirv::Extension::kSPV_KHR_variable_pointers));
}
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
- ASSERT_FALSE(context->get_feature_mgr()->HasExtension(
+ EXPECT_FALSE(context->get_feature_mgr()->HasExtension(
libspirv::Extension::kSPV_KHR_storage_buffer_storage_class));
}
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ASSERT_NE(context, nullptr);
- ASSERT_TRUE(context->get_feature_mgr()->HasExtension(
+ EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
libspirv::Extension::kSPV_KHR_variable_pointers));
- ASSERT_TRUE(context->get_feature_mgr()->HasExtension(
+ EXPECT_TRUE(context->get_feature_mgr()->HasExtension(
libspirv::Extension::kSPV_KHR_storage_buffer_storage_class));
}
+
+// Test capability checks.
+TEST_F(FeatureManagerTest, ExplicitlyPresent1) {
+ const std::string text = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+ )";
+
+ std::unique_ptr<ir::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+ ASSERT_NE(context, nullptr);
+
+ EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityShader));
+ EXPECT_FALSE(context->get_feature_mgr()->HasCapability(SpvCapabilityKernel));
+}
+
+TEST_F(FeatureManagerTest, ExplicitlyPresent2) {
+ const std::string text = R"(
+OpCapability Kernel
+OpMemoryModel Logical GLSL450
+ )";
+
+ std::unique_ptr<ir::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+ ASSERT_NE(context, nullptr);
+
+ EXPECT_FALSE(context->get_feature_mgr()->HasCapability(SpvCapabilityShader));
+ EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityKernel));
+}
+
+TEST_F(FeatureManagerTest, ImplicitlyPresent) {
+ const std::string text = R"(
+OpCapability Tessellation
+OpMemoryModel Logical GLSL450
+ )";
+
+ std::unique_ptr<ir::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+ ASSERT_NE(context, nullptr);
+
+ // Check multiple levels of indirection. Tessellation implies Shader, which
+ // implies Matrix.
+ EXPECT_TRUE(
+ context->get_feature_mgr()->HasCapability(SpvCapabilityTessellation));
+ EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityShader));
+ EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityMatrix));
+ EXPECT_FALSE(context->get_feature_mgr()->HasCapability(SpvCapabilityKernel));
+}
}
TEST(InstructionTest, CreateWithOpcodeAndNoOperands) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, SpvOpReturn);
EXPECT_EQ(SpvOpReturn, inst.opcode());
EXPECT_EQ(0u, inst.type_id());
3};
TEST(InstructionTest, CreateWithOpcodeAndOperands) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleParsedInstruction);
EXPECT_EQ(SpvOpTypeInt, inst.opcode());
EXPECT_EQ(0u, inst.type_id());
}
TEST(InstructionTest, GetOperand) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleParsedInstruction);
EXPECT_THAT(inst.GetOperand(0).words, Eq(std::vector<uint32_t>{44}));
EXPECT_THAT(inst.GetOperand(1).words, Eq(std::vector<uint32_t>{32}));
}
TEST(InstructionTest, GetInOperand) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleParsedInstruction);
EXPECT_THAT(inst.GetInOperand(0).words, Eq(std::vector<uint32_t>{32}));
EXPECT_THAT(inst.GetInOperand(1).words, Eq(std::vector<uint32_t>{1}));
}
TEST(InstructionTest, OperandConstIterators) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleParsedInstruction);
// Spot check iteration across operands.
auto cbegin = inst.cbegin();
}
TEST(InstructionTest, OperandIterators) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleParsedInstruction);
// Spot check iteration across operands, with mutable iterators.
auto begin = inst.begin();
}
TEST(InstructionTest, ForInIdStandardIdTypes) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleAccessChainInstruction);
std::vector<uint32_t> ids;
}
TEST(InstructionTest, ForInIdNonstandardIdTypes) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context, kSampleControlBarrierInstruction);
std::vector<uint32_t> ids;
}
TEST(InstructionTest, UniqueIds) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst1(&context);
Instruction inst2(&context);
EXPECT_NE(inst1.unique_id(), inst2.unique_id());
}
TEST(InstructionTest, CloneUniqueIdDifferent) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&context);
std::unique_ptr<Instruction> clone(inst.Clone(&context));
EXPECT_EQ(inst.context(), clone->context());
}
TEST(InstructionTest, CloneDifferentContext) {
- IRContext c1(nullptr);
- IRContext c2(nullptr);
+ IRContext c1(SPV_ENV_UNIVERSAL_1_2, nullptr);
+ IRContext c2(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&c1);
std::unique_ptr<Instruction> clone(inst.Clone(&c2));
EXPECT_EQ(&c1, inst.context());
}
TEST(InstructionTest, CloneDifferentContextDifferentUniqueId) {
- IRContext c1(nullptr);
- IRContext c2(nullptr);
+ IRContext c1(SPV_ENV_UNIVERSAL_1_2, nullptr);
+ IRContext c2(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction inst(&c1);
Instruction other(&c2);
std::unique_ptr<Instruction> clone(inst.Clone(&c2));
}
TEST(InstructionTest, EqualsEqualsOperator) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction i1(&context);
Instruction i2(&context);
std::unique_ptr<Instruction> clone(i1.Clone(&context));
}
TEST(InstructionTest, LessThanOperator) {
- IRContext context(nullptr);
+ IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
Instruction i1(&context);
Instruction i2(&context);
std::unique_ptr<Instruction> clone(i1.Clone(&context));
TEST_F(IRContextTest, IndividualValidAfterBuild) {
std::unique_ptr<ir::Module> module(new ir::Module());
- IRContext localContext(std::move(module), spvtools::MessageConsumer());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
i <<= 1) {
TEST_F(IRContextTest, AllValidAfterBuild) {
std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
- IRContext localContext(std::move(module), spvtools::MessageConsumer());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
Analysis built_analyses = IRContext::kAnalysisNone;
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
TEST_F(IRContextTest, AllValidAfterPassNoChange) {
std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
- IRContext localContext(std::move(module), spvtools::MessageConsumer());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
Analysis built_analyses = IRContext::kAnalysisNone;
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
TEST_F(IRContextTest, NoneValidAfterPassWithChange) {
std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
- IRContext localContext(std::move(module), spvtools::MessageConsumer());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
i <<= 1) {
TEST_F(IRContextTest, AllPreservedAfterPassWithChange) {
std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
- IRContext localContext(std::move(module), spvtools::MessageConsumer());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
i <<= 1) {
TEST_F(IRContextTest, PreserveFirstOnlyAfterPassWithChange) {
std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
- IRContext localContext(std::move(module), spvtools::MessageConsumer());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
i <<= 1) {
TEST_F(IRContextTest, TakeNextUniqueIdIncrementing) {
const uint32_t NUM_TESTS = 1000;
- IRContext localContext(nullptr);
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, nullptr);
for (uint32_t i = 1; i < NUM_TESTS; ++i)
EXPECT_EQ(i, localContext.TakeNextUniqueId());
}
TEST(PassManager, RecomputeIdBoundAutomatically) {
opt::PassManager manager;
std::unique_ptr<ir::Module> module(new ir::Module());
- ir::IRContext context(std::move(module), manager.consumer());
+ ir::IRContext context(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ manager.consumer());
EXPECT_THAT(GetIdBound(*context.module()), Eq(0u));
manager.Run(&context);