#include "test.h" #include "codon/sir/util/matching.h" using namespace codon::ir; TEST_F(SIRCoreTest, AssignInstrQueryAndReplace) { auto *var = module->Nr(module->getIntType()); auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(var, val); ASSERT_EQ(var, instr->getLhs()); ASSERT_EQ(val, instr->getRhs()); ASSERT_EQ(module->getVoidType(), instr->getType()); auto usedVals = instr->getUsedValues(); ASSERT_EQ(1, usedVals.size()); ASSERT_EQ(val, usedVals[0]); auto usedVars = instr->getUsedVariables(); ASSERT_EQ(1, usedVars.size()); ASSERT_EQ(var, usedVars[0]); ASSERT_EQ( 1, instr->replaceUsedValue(val, module->Nr(1, module->getIntType()))); ASSERT_EQ(1, instr->replaceUsedVariable(var, module->Nr(module->getIntType()))); } TEST_F(SIRCoreTest, AssignInstrCloning) { auto *var = module->Nr(module->getIntType()); auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(var, val); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, ExtractInstrQueryAndReplace) { auto FIELD = "foo"; auto *type = cast(module->unsafeGetMemberedType("**internal**")); type->realize({module->getIntType()}, {FIELD}); auto *var = module->Nr(type); auto *val = module->Nr(var); auto *instr = module->Nr(val, FIELD); ASSERT_EQ(FIELD, instr->getField()); ASSERT_EQ(val, instr->getVal()); ASSERT_EQ(type->getMemberType(FIELD), instr->getType()); auto usedVals = instr->getUsedValues(); ASSERT_EQ(1, usedVals.size()); ASSERT_EQ(val, usedVals[0]); ASSERT_EQ(1, instr->replaceUsedValue(val, module->Nr(var))); } TEST_F(SIRCoreTest, ExtractInstrCloning) { auto FIELD = "foo"; auto *type = cast(module->unsafeGetMemberedType("**internal**")); type->realize({module->getIntType()}, {FIELD}); auto *var = module->Nr(type); auto *val = module->Nr(var); auto *instr = module->Nr(val, FIELD); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, InsertInstrQueryAndReplace) { auto FIELD = "foo"; auto *type = cast(module->unsafeGetMemberedType("**internal**", true)); type->realize({module->getIntType()}, {FIELD}); auto *var = module->Nr(type); auto *lhs = module->Nr(var); auto *rhs = module->Nr(1, module->getIntType()); auto *instr = module->Nr(lhs, FIELD, rhs); ASSERT_EQ(type, instr->getType()); auto usedVals = instr->getUsedValues(); ASSERT_EQ(2, usedVals.size()); ASSERT_EQ(1, instr->replaceUsedValue(lhs, module->Nr(var))); ASSERT_EQ( 1, instr->replaceUsedValue(rhs, module->Nr(1, module->getIntType()))); } TEST_F(SIRCoreTest, InsertInstrCloning) { auto FIELD = "foo"; auto *type = cast(module->unsafeGetMemberedType("**internal**", true)); type->realize({module->getIntType()}, {FIELD}); auto *var = module->Nr(type); auto *lhs = module->Nr(var); auto *rhs = module->Nr(1, module->getIntType()); auto *instr = module->Nr(lhs, FIELD, rhs); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, CallInstrQueryAndReplace) { auto *type = cast(module->unsafeGetDummyFuncType()); auto *func = module->Nr(); func->realize(type, {}); auto *funcVal = module->Nr(func); auto *instr = module->Nr(funcVal); ASSERT_EQ(funcVal, instr->getCallee()); ASSERT_EQ(type->getReturnType(), instr->getType()); auto usedVals = instr->getUsedValues(); ASSERT_EQ(1, usedVals.size()); ASSERT_EQ(1, instr->replaceUsedValue(funcVal, module->Nr(func))); } TEST_F(SIRCoreTest, CallInstrCloning) { auto *type = module->unsafeGetDummyFuncType(); auto *func = module->Nr(); func->realize(type, {}); auto *funcVal = module->Nr(func); auto *instr = module->Nr(funcVal); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, StackAllocInstrQueryAndReplace) { auto COUNT = 1; auto *arrayType = module->unsafeGetArrayType(module->getIntType()); auto *instr = module->Nr(arrayType, COUNT); ASSERT_EQ(COUNT, instr->getCount()); ASSERT_EQ(arrayType, instr->getType()); auto usedTypes = instr->getUsedTypes(); ASSERT_EQ(1, usedTypes.size()); ASSERT_EQ(arrayType, usedTypes[0]); ASSERT_EQ(1, instr->replaceUsedType( arrayType, module->unsafeGetArrayType(module->getFloatType()))); } TEST_F(SIRCoreTest, StackAllocInstrCloning) { auto COUNT = 1; auto *arrayType = module->unsafeGetArrayType(module->getIntType()); auto *instr = module->Nr(arrayType, COUNT); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, TypePropertyInstrQueryAndReplace) { auto *type = module->unsafeGetArrayType(module->getIntType()); auto *instr = module->Nr(type, TypePropertyInstr::Property::IS_ATOMIC); ASSERT_EQ(type, instr->getInspectType()); ASSERT_EQ(TypePropertyInstr::Property::IS_ATOMIC, instr->getProperty()); ASSERT_EQ(module->getBoolType(), instr->getType()); instr->setProperty(TypePropertyInstr::Property::SIZEOF); ASSERT_EQ(module->getIntType(), instr->getType()); auto usedTypes = instr->getUsedTypes(); ASSERT_EQ(1, usedTypes.size()); ASSERT_EQ(type, usedTypes[0]); ASSERT_EQ(1, instr->replaceUsedType( type, module->unsafeGetArrayType(module->getFloatType()))); } TEST_F(SIRCoreTest, TypePropertyInstrCloning) { auto *type = module->unsafeGetArrayType(module->getIntType()); auto *instr = module->Nr(type, TypePropertyInstr::Property::IS_ATOMIC); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, YieldInInstrQueryAndReplace) { auto *type = module->unsafeGetArrayType(module->getIntType()); auto *instr = module->Nr(type); ASSERT_EQ(type, instr->getType()); auto usedTypes = instr->getUsedTypes(); ASSERT_EQ(1, usedTypes.size()); ASSERT_EQ(type, usedTypes[0]); ASSERT_EQ(1, instr->replaceUsedType( type, module->unsafeGetArrayType(module->getFloatType()))); } TEST_F(SIRCoreTest, YieldInInstrCloning) { auto *type = module->unsafeGetArrayType(module->getIntType()); auto *instr = module->Nr(type); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, TernaryInstrQueryAndReplace) { auto *trueValue = module->Nr(true, module->getBoolType()); auto *falseValue = module->Nr(false, module->getBoolType()); auto *cond = module->Nr(true, module->getBoolType()); auto *instr = module->Nr(cond, trueValue, falseValue); ASSERT_EQ(trueValue, instr->getTrueValue()); ASSERT_EQ(falseValue, instr->getFalseValue()); ASSERT_EQ(cond, instr->getCond()); ASSERT_EQ(3, instr->getUsedValues().size()); ASSERT_EQ(1, instr->replaceUsedValue( cond, module->Nr(true, module->getBoolType()))); ASSERT_EQ(1, instr->replaceUsedValue( trueValue, module->Nr(true, module->getBoolType()))); ASSERT_EQ(1, instr->replaceUsedValue( falseValue, module->Nr(true, module->getBoolType()))); } TEST_F(SIRCoreTest, TernaryInstrCloning) { auto *trueValue = module->Nr(true, module->getBoolType()); auto *falseValue = module->Nr(false, module->getBoolType()); auto *cond = module->Nr(true, module->getBoolType()); auto *instr = module->Nr(cond, trueValue, falseValue); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, ContinueInstrQueryReplaceAndCloning) { auto *instr = module->Nr(); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, BreakInstrQueryReplaceAndCloning) { auto *instr = module->Nr(); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, ReturnInstrQueryReplaceAndCloning) { auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(val); ASSERT_EQ(val, instr->getValue()); ASSERT_EQ(1, instr->getUsedValues().size()); ASSERT_EQ(1, instr->replaceUsedValue(val, nullptr)); ASSERT_EQ(0, instr->getUsedValues().size()); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, YieldInstrQueryReplaceAndCloning) { auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(val); ASSERT_EQ(val, instr->getValue()); ASSERT_EQ(1, instr->getUsedValues().size()); ASSERT_EQ(1, instr->replaceUsedValue(val, nullptr)); ASSERT_EQ(0, instr->getUsedValues().size()); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, ThrowInstrQueryReplaceAndCloning) { auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(val); ASSERT_EQ(val, instr->getValue()); ASSERT_EQ(1, instr->getUsedValues().size()); ASSERT_EQ(1, instr->replaceUsedValue(val, nullptr)); ASSERT_EQ(0, instr->getUsedValues().size()); ASSERT_TRUE(util::match(instr, cv->clone(instr))); } TEST_F(SIRCoreTest, FlowInstrQueryAndReplace) { auto *flow = module->Nr(); auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(flow, val); ASSERT_EQ(module->getIntType(), instr->getType()); ASSERT_EQ(val, instr->getValue()); ASSERT_EQ(flow, instr->getFlow()); ASSERT_EQ(2, instr->getUsedValues().size()); ASSERT_EQ( 1, instr->replaceUsedValue(val, module->Nr(2, module->getIntType()))); ASSERT_EQ(1, instr->replaceUsedValue(flow, module->Nr())); } TEST_F(SIRCoreTest, FlowInstrCloning) { auto *flow = module->Nr(); auto *val = module->Nr(1, module->getIntType()); auto *instr = module->Nr(flow, val); ASSERT_TRUE(util::match(instr, cv->clone(instr))); }