1/* 2 * Copyright 2017, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "transformer.h" 18 19#include "file_utils.h" 20#include "spirit.h" 21#include "test_utils.h" 22#include "gtest/gtest.h" 23 24#include <stdint.h> 25 26namespace android { 27namespace spirit { 28 29namespace { 30 31class MulToAddTransformer : public Transformer { 32public: 33 Instruction *transform(IMulInst *mul) override { 34 auto ret = new IAddInst(mul->mResultType, mul->mOperand1, mul->mOperand2); 35 ret->setId(mul->getId()); 36 return ret; 37 } 38}; 39 40class Deleter : public Transformer { 41public: 42 Instruction *transform(IMulInst *) override { return nullptr; } 43}; 44 45class NewDataTypeTransformer : public Transformer { 46public: 47 Instruction *transform(IMulInst *mul) override { 48 insert(mul); 49 auto *DoubleTy = getModule()->getFloatType(64); 50 ConstantInst *ConstDouble2 = getModule()->getConstant(DoubleTy, 2.0); 51 auto ret = new IAddInst(DoubleTy, mul, ConstDouble2); 52 53 IdResult id = ret->getId(); 54 ret->setId(mul->getId()); 55 mul->setId(id); 56 57 return ret; 58 } 59}; 60 61} // annonymous namespace 62 63class TransformerTest : public ::testing::Test { 64protected: 65 virtual void SetUp() { mWordsGreyscale = readWords("greyscale.spv"); } 66 67 std::vector<uint32_t> mWordsGreyscale; 68 69private: 70 std::vector<uint32_t> readWords(const char *testFile) { 71 static const std::string testDataPath( 72 "frameworks/rs/rsov/compiler/spirit/test_data/"); 73 const std::string &fullPath = getAbsolutePath(testDataPath + testFile); 74 return readFile<uint32_t>(fullPath); 75 } 76}; 77 78TEST_F(TransformerTest, testMulToAdd) { 79 std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale)); 80 81 ASSERT_NE(nullptr, m); 82 83 EXPECT_EQ(1, countEntity<IAddInst>(m.get())); 84 EXPECT_EQ(1, countEntity<IMulInst>(m.get())); 85 86 MulToAddTransformer trans; 87 std::unique_ptr<Module> m1(trans.run(m.get())); 88 89 ASSERT_NE(nullptr, m1); 90 91 ASSERT_TRUE(m1->resolveIds()); 92 93 EXPECT_EQ(2, countEntity<IAddInst>(m1.get())); 94 EXPECT_EQ(0, countEntity<IMulInst>(m1.get())); 95} 96 97TEST_F(TransformerTest, testDeletion) { 98 std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale)); 99 100 ASSERT_NE(nullptr, m.get()); 101 102 EXPECT_EQ(1, countEntity<IMulInst>(m.get())); 103 104 Deleter trans; 105 std::unique_ptr<Module> m1(trans.run(m.get())); 106 107 ASSERT_NE(nullptr, m1.get()); 108 109 EXPECT_EQ(1, countEntity<IAddInst>(m1.get())); 110 EXPECT_EQ(0, countEntity<IMulInst>(m1.get())); 111} 112 113TEST_F(TransformerTest, testAddInstructionUsingNewDataType) { 114 std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale)); 115 116 ASSERT_NE(nullptr, m.get()); 117 118 EXPECT_EQ(5, countEntity<ConstantInst>(m.get())); 119 EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get())); 120 EXPECT_EQ(1, countEntity<IMulInst>(m.get())); 121 122 NewDataTypeTransformer trans; 123 std::unique_ptr<Module> m1(trans.run(m.get())); 124 125 ASSERT_NE(nullptr, m1.get()); 126 127 EXPECT_EQ(6, countEntity<ConstantInst>(m.get())); 128 EXPECT_EQ(2, countEntity<TypeFloatInst>(m1.get())); 129 EXPECT_EQ(2, countEntity<IAddInst>(m1.get())); 130 EXPECT_EQ(1, countEntity<IMulInst>(m1.get())); 131} 132 133} // namespace spirit 134} // namespace android 135