Skip to content

Commit

Permalink
Add Module::ComputeIdBound
Browse files Browse the repository at this point in the history
When IDs change, something should use this utility method
and Module::SetIdBound before writing out the binary.

ForEachInst is more forgiving of cases where a basic block doesn't
have a label, and when a function doesn't have a defining instruction
or end instruction.
  • Loading branch information
dneto0 committed Aug 26, 2016
1 parent 58e1a1e commit 1e539ec
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
19 changes: 19 additions & 0 deletions source/opt/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

#include "module.h"

#include "operand.h"
#include "reflect.h"

namespace spvtools {
Expand Down Expand Up @@ -117,5 +119,22 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
ForEachInst(write_inst, true);
}

uint32_t Module::ComputeIdBound() const {
uint32_t highest = 0;

ForEachInst(
[&highest](const Instruction* inst) {
// Use a const-cast just to access begin() and end() for the range-for.
for (const auto& operand : *const_cast<Instruction*>(inst)) {
if (spvIsIdType(operand.type)) {
highest = std::max(highest, operand.words[0]);
}
}
},
true /* scan debug line insts as well */);

return highest + 1;
}

} // namespace ir
} // namespace spvtools
3 changes: 3 additions & 0 deletions source/opt/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ class Module {
// If |skip_nop| is true and this is a OpNop, do nothing.
void ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const;

// Returns 1 more than the maximum Id value mentioned in the module.
uint32_t ComputeIdBound() const;

private:
ModuleHeader header_; // Module header

Expand Down
1 change: 1 addition & 0 deletions test/opt/test_instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace {
using spvtest::MakeInstruction;
using spvtools::ir::Instruction;
using spvtools::ir::Operand;
using spvtools::ir::Operand;
using ::testing::Eq;

TEST(InstructionTest, CreateTrivial) {
Expand Down
34 changes: 32 additions & 2 deletions test/opt/test_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@

#include <vector>

#include "opt/module.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "opt/libspirv.hpp"
#include "opt/module.h"

namespace {

using spvtools::ir::Module;
using ::testing::Eq;

uint32_t GetIdBound(const Module& m) {
std::vector<uint32_t> binary;
Expand All @@ -55,4 +58,31 @@ TEST(ModuleTest, SetIdBound) {
EXPECT_EQ(102u, GetIdBound(m));
}

// 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);
}

TEST(ModuleTest, ComputeIdBound) {
// Emtpy module case.
EXPECT_EQ(1, BuildModule("")->ComputeIdBound());
// Sensitive to result id
EXPECT_EQ(2, BuildModule("%void = OpTypeVoid")->ComputeIdBound());
// Sensitive to type id
EXPECT_EQ(1000, BuildModule("%a = OpTypeArray !999 3")->ComputeIdBound());
// Sensitive to a regular Id parameter
EXPECT_EQ(2000, BuildModule("OpDecorate !1999 0")->ComputeIdBound());
// Sensitive to a scope Id parameter.
EXPECT_EQ(3000, BuildModule("%f = OpFunction %void None %fntype %a = OpLabel "
"OpMemoryBarrier !2999 %b\n")
->ComputeIdBound());
// Sensitive to a semantics Id parameter
EXPECT_EQ(4000, BuildModule("%f = OpFunction %void None %fntype %a = OpLabel "
"OpMemoryBarrier %b !3999\n")
->ComputeIdBound());
}

} // anonymous namespace

0 comments on commit 1e539ec

Please sign in to comment.