mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-27 13:50:07 +00:00
94dc66b74d
This change will replace a number of the std::vector<std::unique_ptr<Instruction>> member of the module to InstructionList. This is for consistency and to make it easier to delete instructions that are no longer needed.
113 lines
4.2 KiB
C++
113 lines
4.2 KiB
C++
// Copyright (c) 2017 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 <algorithm>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "opt/instruction.h"
|
|
#include "opt/instruction_list.h"
|
|
|
|
namespace {
|
|
|
|
using Instruction = spvtools::ir::Instruction;
|
|
using InstructionList = spvtools::ir::InstructionList;
|
|
using ::testing::ContainerEq;
|
|
using ::testing::ElementsAre;
|
|
using InstructionListTest = ::testing::Test;
|
|
|
|
// A class that overrides the destructor, so we can trace it.
|
|
class TestInstruction : public Instruction {
|
|
public:
|
|
TestInstruction() : Instruction() { created_instructions_.push_back(this); }
|
|
|
|
~TestInstruction() { deleted_instructions_.push_back(this); }
|
|
|
|
static std::vector<TestInstruction*> created_instructions_;
|
|
static std::vector<TestInstruction*> deleted_instructions_;
|
|
};
|
|
|
|
std::vector<TestInstruction*> TestInstruction::created_instructions_;
|
|
std::vector<TestInstruction*> TestInstruction::deleted_instructions_;
|
|
|
|
// Test that the destructor for InstructionList is calling the destructor
|
|
// for every element that is in the list.
|
|
TEST(InstructionListTest, Destructor) {
|
|
InstructionList* list = new InstructionList();
|
|
list->push_back(std::unique_ptr<Instruction>(new Instruction()));
|
|
list->push_back(std::unique_ptr<Instruction>(new Instruction()));
|
|
delete list;
|
|
|
|
// Sorting because we do not care if the order of create and destruction is
|
|
// the same. Using generic sort just incase things are changed above.
|
|
std::sort(TestInstruction::created_instructions_.begin(),
|
|
TestInstruction::created_instructions_.end());
|
|
std::sort(TestInstruction::deleted_instructions_.begin(),
|
|
TestInstruction::deleted_instructions_.end());
|
|
EXPECT_THAT(TestInstruction::created_instructions_,
|
|
ContainerEq(TestInstruction::deleted_instructions_));
|
|
}
|
|
|
|
// Test the |InsertBefore| with a single instruction in the iterator class.
|
|
// Need to make sure the elements are inserted in the correct order, and the
|
|
// return value points to the correct location.
|
|
//
|
|
// Comparing addresses to make sure they remain stable, so other data structures
|
|
// can have pointers to instructions in InstructionList.
|
|
TEST(InstructionListTest, InsertBefore1) {
|
|
InstructionList list;
|
|
std::vector<Instruction*> inserted_instructions;
|
|
for (int i = 0; i < 4; i++) {
|
|
std::unique_ptr<Instruction> inst(new Instruction());
|
|
inserted_instructions.push_back(inst.get());
|
|
auto new_element = list.end().InsertBefore(std::move(inst));
|
|
EXPECT_EQ(&*new_element, inserted_instructions.back());
|
|
}
|
|
|
|
std::vector<Instruction*> output;
|
|
for (auto& i : list) {
|
|
output.push_back(&i);
|
|
}
|
|
EXPECT_THAT(output, ContainerEq(inserted_instructions));
|
|
}
|
|
|
|
// Test inserting an entire vector of instructions using InsertBefore. Checking
|
|
// the order of insertion and the return value.
|
|
//
|
|
// Comparing addresses to make sure they remain stable, so other data structures
|
|
// can have pointers to instructions in InstructionList.
|
|
TEST(InstructionListTest, InsertBefore2) {
|
|
InstructionList list;
|
|
std::vector<std::unique_ptr<Instruction>> new_instructions;
|
|
std::vector<Instruction*> created_instructions;
|
|
for (int i = 0; i < 4; i++) {
|
|
std::unique_ptr<Instruction> inst(new Instruction());
|
|
created_instructions.push_back(inst.get());
|
|
new_instructions.push_back(std::move(inst));
|
|
}
|
|
auto new_element = list.begin().InsertBefore(std::move(new_instructions));
|
|
EXPECT_TRUE(new_instructions.empty());
|
|
EXPECT_EQ(&*new_element, created_instructions.front());
|
|
|
|
std::vector<Instruction*> output;
|
|
for (auto& i : list) {
|
|
output.push_back(&i);
|
|
}
|
|
EXPECT_THAT(output, ContainerEq(created_instructions));
|
|
}
|
|
} // namespace
|