#include "test.h" #include "codon/cir/analyze/dataflow/cfg.h" #include "codon/cir/analyze/dataflow/reaching.h" using namespace codon::ir; TEST_F(CIRCoreTest, RDAnalysisSimple) { auto *f = module->Nr("test_f"); auto *b = module->Nr(); f->setBody(b); auto *v = module->Nr(module->getIntType()); f->push_back(v); auto *first = module->getInt(1); auto *second = module->getInt(2); auto *start = module->getBool(false); auto *firstAssign = module->Nr(v, first); auto *secondAssign = module->Nr(v, second); auto *end = module->getBool(false); b->push_back(start); b->push_back(firstAssign); b->push_back(secondAssign); b->push_back(end); auto c = analyze::dataflow::buildCFGraph(f); analyze::dataflow::RDInspector rd(c.get()); rd.analyze(); auto startRd = rd.getReachingDefinitions(v, start); auto firstRd = rd.getReachingDefinitions(v, firstAssign); auto secondRd = rd.getReachingDefinitions(v, secondAssign); auto endRd = rd.getReachingDefinitions(v, end); auto firstRhsRd = rd.getReachingDefinitions(v, first); auto secondRhsRd = rd.getReachingDefinitions(v, second); ASSERT_EQ(0, startRd.size()); ASSERT_EQ(1, firstRd.size()); ASSERT_EQ(1, secondRd.size()); ASSERT_EQ(1, endRd.size()); ASSERT_EQ(0, firstRhsRd.size()); ASSERT_EQ(1, secondRhsRd.size()); ASSERT_EQ(first->getId(), *firstRd.begin()); ASSERT_EQ(second->getId(), *secondRd.begin()); ASSERT_EQ(second->getId(), *endRd.begin()); } TEST_F(CIRCoreTest, RDAnalysisIfConditional) { auto *f = module->Nr("test_f"); auto *trueBranch = module->Nr(); auto *falseBranch = module->Nr(); auto *ifFlow = module->Nr(module->getBool(false), trueBranch, falseBranch); auto *b = module->Nr(); f->setBody(b); auto *v = module->Nr(module->getIntType()); f->push_back(v); auto *first = module->getInt(1); auto *second = module->getInt(2); auto *start = module->getBool(false); auto *firstAssign = module->Nr(v, first); auto *secondAssign = module->Nr(v, second); auto *end = module->getBool(false); b->push_back(start); b->push_back(ifFlow); trueBranch->push_back(firstAssign); falseBranch->push_back(secondAssign); b->push_back(end); auto c = analyze::dataflow::buildCFGraph(f); analyze::dataflow::RDInspector rd(c.get()); rd.analyze(); auto startRd = rd.getReachingDefinitions(v, start); auto endRd = rd.getReachingDefinitions(v, end); ASSERT_EQ(0, startRd.size()); ASSERT_EQ(2, endRd.size()); ASSERT_TRUE(endRd.find(first->getId()) != endRd.end()); ASSERT_TRUE(endRd.find(second->getId()) != endRd.end()); } TEST_F(CIRCoreTest, RDAnalysisTryCatch) { auto *f = module->Nr("test_f"); auto *body = module->Nr(); auto *except = module->Nr(); auto *finally = module->Nr(); auto *tc = module->Nr(body, finally); tc->emplace_back(except, nullptr); auto *b = module->Nr(); f->setBody(b); auto *v = module->Nr(module->getIntType()); f->push_back(v); auto *first = module->getInt(1); auto *second = module->getInt(2); auto *third = module->getInt(3); auto *initial = module->getInt(0); auto *zeroAssign = module->Nr(v, initial); auto *start = module->getBool(false); auto *firstAssign = module->Nr(v, first); auto *secondAssign = module->Nr(v, second); auto *middle = module->getBool(false); auto *thirdAssign = module->Nr(v, third); auto *end = module->getBool(false); b->push_back(start); b->push_back(zeroAssign); b->push_back(tc); body->push_back(firstAssign); except->push_back(thirdAssign); finally->push_back(middle); finally->push_back(secondAssign); b->push_back(end); auto c = analyze::dataflow::buildCFGraph(f); analyze::dataflow::RDInspector rd(c.get()); rd.analyze(); auto startRd = rd.getReachingDefinitions(v, start); auto middleRd = rd.getReachingDefinitions(v, middle); auto endRd = rd.getReachingDefinitions(v, end); ASSERT_EQ(0, startRd.size()); ASSERT_EQ(1, endRd.size()); ASSERT_TRUE(endRd.find(second->getId()) != endRd.end()); ASSERT_TRUE(middleRd.find(first->getId()) != endRd.end()); ASSERT_TRUE(middleRd.find(third->getId()) != endRd.end()); ASSERT_TRUE(middleRd.find(initial->getId()) != endRd.end()); } TEST_F(CIRCoreTest, RDAnalysisWhileLoop) { auto *f = module->Nr("test_f"); auto *loopBody = module->Nr(); auto *whileFlow = module->Nr(module->getBool(false), loopBody); auto *b = module->Nr(); f->setBody(b); auto *v = module->Nr(module->getIntType()); f->push_back(v); auto *first = module->getInt(1); auto *second = module->getInt(2); auto *start = module->getBool(false); auto *firstAssign = module->Nr(v, first); auto *secondAssign = module->Nr(v, second); auto *end = module->getBool(false); b->push_back(start); b->push_back(firstAssign); b->push_back(whileFlow); loopBody->push_back(secondAssign); b->push_back(end); auto c = analyze::dataflow::buildCFGraph(f); analyze::dataflow::RDInspector rd(c.get()); rd.analyze(); auto startRd = rd.getReachingDefinitions(v, start); auto endRd = rd.getReachingDefinitions(v, end); ASSERT_EQ(0, startRd.size()); ASSERT_EQ(2, endRd.size()); ASSERT_TRUE(endRd.find(first->getId()) != endRd.end()); ASSERT_TRUE(endRd.find(second->getId()) != endRd.end()); }