13f30b6202dd5ad6ff66959131d216405850ed152Yang Ni/*
23f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * Copyright 2017, The Android Open Source Project
33f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *
43f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * Licensed under the Apache License, Version 2.0 (the "License");
53f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * you may not use this file except in compliance with the License.
63f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * You may obtain a copy of the License at
73f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *
83f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *     http://www.apache.org/licenses/LICENSE-2.0
93f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *
103f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * Unless required by applicable law or agreed to in writing, software
113f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * distributed under the License is distributed on an "AS IS" BASIS,
123f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * See the License for the specific language governing permissions and
143f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * limitations under the License.
153f30b6202dd5ad6ff66959131d216405850ed152Yang Ni */
163f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
173f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "pass_queue.h"
183f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
193f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "file_utils.h"
203f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "spirit.h"
213f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "test_utils.h"
223f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "transformer.h"
233f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "gtest/gtest.h"
243f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
253f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include <stdint.h>
263f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
273f30b6202dd5ad6ff66959131d216405850ed152Yang Ninamespace android {
283f30b6202dd5ad6ff66959131d216405850ed152Yang Ninamespace spirit {
293f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
303f30b6202dd5ad6ff66959131d216405850ed152Yang Ninamespace {
313f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
323f30b6202dd5ad6ff66959131d216405850ed152Yang Niclass MulToAddTransformer : public Transformer {
333f30b6202dd5ad6ff66959131d216405850ed152Yang Nipublic:
343f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  Instruction *transform(IMulInst *mul) override {
353f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    auto ret = new IAddInst(mul->mResultType, mul->mOperand1, mul->mOperand2);
363f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    ret->setId(mul->getId());
373f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    return ret;
383f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  }
393f30b6202dd5ad6ff66959131d216405850ed152Yang Ni};
403f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
413f30b6202dd5ad6ff66959131d216405850ed152Yang Niclass AddToDivTransformer : public Transformer {
423f30b6202dd5ad6ff66959131d216405850ed152Yang Nipublic:
433f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  Instruction *transform(IAddInst *add) override {
443f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    auto ret = new SDivInst(add->mResultType, add->mOperand1, add->mOperand2);
453f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    ret->setId(add->getId());
463f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    return ret;
473f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  }
483f30b6202dd5ad6ff66959131d216405850ed152Yang Ni};
493f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
503f30b6202dd5ad6ff66959131d216405850ed152Yang Niclass AddMulAfterAddTransformer : public Transformer {
513f30b6202dd5ad6ff66959131d216405850ed152Yang Nipublic:
523f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  Instruction *transform(IAddInst *add) override {
533f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    insert(add);
543f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    auto ret = new IMulInst(add->mResultType, add, add);
553f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    ret->setId(add->getId());
563f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    return ret;
573f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  }
583f30b6202dd5ad6ff66959131d216405850ed152Yang Ni};
593f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
603f30b6202dd5ad6ff66959131d216405850ed152Yang Niclass Deleter : public Transformer {
613f30b6202dd5ad6ff66959131d216405850ed152Yang Nipublic:
623f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  Instruction *transform(IMulInst *) override { return nullptr; }
633f30b6202dd5ad6ff66959131d216405850ed152Yang Ni};
643f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
653f30b6202dd5ad6ff66959131d216405850ed152Yang Niclass InPlaceModifyingPass : public Pass {
663f30b6202dd5ad6ff66959131d216405850ed152Yang Nipublic:
673f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  Module *run(Module *m, int *error) override {
683f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    m->getFloatType(64);
693f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    if (error) {
703f30b6202dd5ad6ff66959131d216405850ed152Yang Ni      *error = 0;
713f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    }
723f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    return m;
733f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  }
743f30b6202dd5ad6ff66959131d216405850ed152Yang Ni};
753f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
763f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} // annonymous namespace
773f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
783f30b6202dd5ad6ff66959131d216405850ed152Yang Niclass PassQueueTest : public ::testing::Test {
793f30b6202dd5ad6ff66959131d216405850ed152Yang Niprotected:
803f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  virtual void SetUp() { mWordsGreyscale = readWords("greyscale.spv"); }
813f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
823f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  std::vector<uint32_t> mWordsGreyscale;
833f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
843f30b6202dd5ad6ff66959131d216405850ed152Yang Niprivate:
853f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  std::vector<uint32_t> readWords(const char *testFile) {
863f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    static const std::string testDataPath(
873f30b6202dd5ad6ff66959131d216405850ed152Yang Ni        "frameworks/rs/rsov/compiler/spirit/test_data/");
883f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    const std::string &fullPath = getAbsolutePath(testDataPath + testFile);
893f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    return readFile<uint32_t>(fullPath);
903f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  }
913f30b6202dd5ad6ff66959131d216405850ed152Yang Ni};
923f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
933f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testMulToAdd) {
943e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
953f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
963f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
973f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
983f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
993f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
1003f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1013f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
1023f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new MulToAddTransformer());
1033f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto m1 = passes.run(m.get());
1043f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1053f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
1063f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1073f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
1083f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1093f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<IAddInst>(m1));
1103f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IMulInst>(m1));
1113f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
1123f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1133f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testInPlaceModifying) {
1143e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
1153f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1163f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
1173f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1183f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
1193f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
1203f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
1213f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1223f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
1233f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new InPlaceModifyingPass());
1243f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto m1 = passes.run(m.get());
1253f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1263f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
1273f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1283f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
1293f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1303f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m1));
1313f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m1));
1323f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<TypeFloatInst>(m1));
1333f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
1343f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1353f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testDeletion) {
1363e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
1373f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1383f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m.get());
1393f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1403f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
1413f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1423f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
1433f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new Deleter());
1443f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto m1 = passes.run(m.get());
1453f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1463f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  // One of the ids from the input module is missing now.
1473f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_EQ(nullptr, m1);
1483f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
1493f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1503f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testMulToAddToDiv) {
1513e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
1523f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1533f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
1543f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1553f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
1563f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
1573f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1583f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
1593f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new MulToAddTransformer());
1603f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new AddToDivTransformer());
1613f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto m1 = passes.run(m.get());
1623f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1633f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
1643f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1653f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
1663f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1673f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IAddInst>(m1));
1683f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IMulInst>(m1));
1693f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<SDivInst>(m1));
1703f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
1713f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1723f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testAMix) {
1733e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
1743f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1753f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
1763f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1773f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
1783f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
1793f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<SDivInst>(m.get()));
1803f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
1813f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1823f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
1833f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new MulToAddTransformer());
1843f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new AddToDivTransformer());
1853f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new InPlaceModifyingPass());
1863f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1873f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  std::unique_ptr<Module> m1(passes.run(m.get()));
1883f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1893f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
1903f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1913f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
1923f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1933f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
1943f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
1953f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
1963f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<TypeFloatInst>(m1.get()));
1973f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
1983f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
1993f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testAnotherMix) {
2003e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
2013f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2023f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
2033f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2043f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
2053f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
2063f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<SDivInst>(m.get()));
2073f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
2083f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2093f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
2103f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new InPlaceModifyingPass());
2113f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new MulToAddTransformer());
2123f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new AddToDivTransformer());
2133f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto outputWords = passes.runAndSerialize(m.get());
2143f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2153e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
2163f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2173f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
2183f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2193f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
2203f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2213f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
2223f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
2233f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
2243f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<TypeFloatInst>(m1.get()));
2253f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
2263f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2273f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testMulToAddToDivFromWords) {
2283f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
2293f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new MulToAddTransformer());
2303f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new AddToDivTransformer());
2313f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto outputWords = passes.run(std::move(mWordsGreyscale));
2323f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2333e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
2343f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2353f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
2363f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2373f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
2383f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2393f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
2403f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
2413f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
2423f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
2433f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2443f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testMulToAddToDivToWords) {
2453e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
2463f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2473f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
2483f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2493f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
2503f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
2513f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2523f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
2533f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new MulToAddTransformer());
2543f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  passes.append(new AddToDivTransformer());
2553f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto outputWords = passes.runAndSerialize(m.get());
2563f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2573e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
2583f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2593f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
2603f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2613f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
2623f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2633f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
2643f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
2653f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
2663f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
2673f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2683f30b6202dd5ad6ff66959131d216405850ed152Yang NiTEST_F(PassQueueTest, testAddMulAfterAdd) {
2693e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
2703f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2713f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m);
2723f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2733f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
2743f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
2753f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2763f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  constexpr int kNumMulToAdd = 100;
2773f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2783f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  PassQueue passes;
2793f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  for (int i = 0; i < kNumMulToAdd; i++) {
2803f30b6202dd5ad6ff66959131d216405850ed152Yang Ni    passes.append(new AddMulAfterAddTransformer());
2813f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  }
2823f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  auto outputWords = passes.runAndSerialize(m.get());
2833f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2843e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
2853f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2863f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_NE(nullptr, m1);
2873f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2883f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  ASSERT_TRUE(m1->resolveIds());
2893f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2903f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1, countEntity<IAddInst>(m1.get()));
2913f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  EXPECT_EQ(1 + kNumMulToAdd, countEntity<IMulInst>(m1.get()));
2923f30b6202dd5ad6ff66959131d216405850ed152Yang Ni}
2933f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
2943f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} // namespace spirit
2953f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} // namespace android
296