| //===- FunctionComparator.cpp - Unit tests for FunctionComparator ---------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Transforms/Utils/FunctionComparator.h" | |
| #include "llvm/IR/BasicBlock.h" | |
| #include "llvm/IR/IRBuilder.h" | |
| #include "llvm/IR/Instructions.h" | |
| #include "llvm/IR/LLVMContext.h" | |
| #include "llvm/IR/Module.h" | |
| #include "gtest/gtest.h" | |
| using namespace llvm; | |
| /// Generates a simple test function. | |
| struct TestFunction { | |
| Function *F; | |
| BasicBlock *BB; | |
| Constant *C; | |
| Instruction *I; | |
| Type *T; | |
| TestFunction(LLVMContext &Ctx, Module &M, int addVal) { | |
| IRBuilder<> B(Ctx); | |
| T = B.getInt8Ty(); | |
| F = Function::Create(FunctionType::get(T, {B.getInt8PtrTy()}, false), | |
| GlobalValue::ExternalLinkage, "F", &M); | |
| BB = BasicBlock::Create(Ctx, "", F); | |
| B.SetInsertPoint(BB); | |
| Argument *PointerArg = &*F->arg_begin(); | |
| LoadInst *LoadInst = B.CreateLoad(PointerArg); | |
| C = B.getInt8(addVal); | |
| I = cast<Instruction>(B.CreateAdd(LoadInst, C)); | |
| B.CreateRet(I); | |
| } | |
| }; | |
| /// A class for testing the FunctionComparator API. | |
| /// | |
| /// The main purpose is to test if the required protected functions are | |
| /// accessible from a derived class of FunctionComparator. | |
| class TestComparator : public FunctionComparator { | |
| public: | |
| TestComparator(const Function *F1, const Function *F2, | |
| GlobalNumberState *GN) | |
| : FunctionComparator(F1, F2, GN) { | |
| } | |
| bool testFunctionAccess(const Function *F1, const Function *F2) { | |
| // Test if FnL and FnR are accessible. | |
| return F1 == FnL && F2 == FnR; | |
| } | |
| int testCompare() { | |
| return compare(); | |
| } | |
| int testCompareSignature() { | |
| beginCompare(); | |
| return compareSignature(); | |
| } | |
| int testCmpBasicBlocks(BasicBlock *BBL, BasicBlock *BBR) { | |
| beginCompare(); | |
| return cmpBasicBlocks(BBL, BBR); | |
| } | |
| int testCmpConstants(const Constant *L, const Constant *R) { | |
| beginCompare(); | |
| return cmpConstants(L, R); | |
| } | |
| int testCmpGlobalValues(GlobalValue *L, GlobalValue *R) { | |
| beginCompare(); | |
| return cmpGlobalValues(L, R); | |
| } | |
| int testCmpValues(const Value *L, const Value *R) { | |
| beginCompare(); | |
| return cmpValues(L, R); | |
| } | |
| int testCmpOperations(const Instruction *L, const Instruction *R, | |
| bool &needToCmpOperands) { | |
| beginCompare(); | |
| return cmpOperations(L, R, needToCmpOperands); | |
| } | |
| int testCmpTypes(Type *TyL, Type *TyR) { | |
| beginCompare(); | |
| return cmpTypes(TyL, TyR); | |
| } | |
| int testCmpPrimitives() { | |
| beginCompare(); | |
| return | |
| cmpNumbers(2, 3) + | |
| cmpAPInts(APInt(32, 2), APInt(32, 3)) + | |
| cmpAPFloats(APFloat(2.0), APFloat(3.0)) + | |
| cmpMem("2", "3"); | |
| } | |
| }; | |
| /// A sanity check for the FunctionComparator API. | |
| TEST(FunctionComparatorTest, TestAPI) { | |
| LLVMContext C; | |
| Module M("test", C); | |
| TestFunction F1(C, M, 27); | |
| TestFunction F2(C, M, 28); | |
| GlobalNumberState GN; | |
| TestComparator Cmp(F1.F, F2.F, &GN); | |
| EXPECT_TRUE(Cmp.testFunctionAccess(F1.F, F2.F)); | |
| EXPECT_EQ(Cmp.testCompare(), -1); | |
| EXPECT_EQ(Cmp.testCompareSignature(), 0); | |
| EXPECT_EQ(Cmp.testCmpBasicBlocks(F1.BB, F2.BB), -1); | |
| EXPECT_EQ(Cmp.testCmpConstants(F1.C, F2.C), -1); | |
| EXPECT_EQ(Cmp.testCmpGlobalValues(F1.F, F2.F), -1); | |
| EXPECT_EQ(Cmp.testCmpValues(F1.I, F2.I), 0); | |
| bool needToCmpOperands = false; | |
| EXPECT_EQ(Cmp.testCmpOperations(F1.I, F2.I, needToCmpOperands), 0); | |
| EXPECT_TRUE(needToCmpOperands); | |
| EXPECT_EQ(Cmp.testCmpTypes(F1.T, F2.T), 0); | |
| EXPECT_EQ(Cmp.testCmpPrimitives(), -4); | |
| } |