Files
revng-revng/tests/Unit/IRHelpers.cpp
T
Alessandro Di Federico bd09716534 FCI: provide a custom CFG
The `FunctionCallIdentification` analysis now provides a custom view on
the CFG where 1) dispatcher-related basic blocks are absent, 2) nodes
performing functions calls have an edge to their return address and 3)
nodes ending with a return instruction have no successor.

This CFG is now employed by the reaching definitions analysis and OSRA.

Additionally, the implementation of the `visitSuccessors` and
`visitPredecessors` method has been reviewed. It now consists in a class
that needs to be inherited and for which two methods should be
implemented, one to perform the visit of a block and another one to
enumerate the successors.

In addition, all the users of `visitSuccessors`/`visitPredecessors` have
been updated, a simple set of tests has been introduced and
`GeneratedCodeBasicInfo::visitPredecessors` has been dropped.
2019-01-18 15:18:46 +01:00

100 lines
2.2 KiB
C++

/// \file IRHelpers.cpp
/// \brief Tests for IRHelpers
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
// Boost includes
#define BOOST_TEST_MODULE IRHelpers
bool init_unit_test();
#include <boost/test/unit_test.hpp>
// Local libraries includes
#include "revng/Support/IRHelpers.h"
// Local includes
#include "LLVMTestHelpers.h"
using namespace llvm;
const char *VisitorTestBody = R"LLVM(
%a = add i64 0, 0
br i1 true, label %first_if_true, label %first_if_false
first_if_true:
%b = add i64 0, 0
br label %center
first_if_false:
%c = add i64 0, 0
br label %center
center:
%d = add i64 0, 0
%target = add i64 0, 0
br i1 true, label %second_if_true, label %second_if_false
second_if_true:
%e = add i64 0, 0
br label %end
second_if_false:
%f = add i64 0, 0
br label %end
end:
%g = add i64 0, 0
ret void
)LLVM";
BOOST_AUTO_TEST_CASE(TestBackwardBFSVisitor) {
struct Visitor : public BackwardBFSVisitor<Visitor> {
std::vector<std::string> VisitLog;
VisitAction visit(instruction_range Range) {
for (Instruction &I : Range)
VisitLog.push_back(getName(&I));
return Continue;
}
};
LLVMContext TestContext;
std::unique_ptr<Module> M = loadModule(TestContext, VisitorTestBody);
Function *F = M->getFunction("main");
Visitor V;
V.run(instructionByName(F, "target"));
const std::vector<std::string> GroundTruth = {
"d", "first_if_false:2", "c", "first_if_true:2", "b", "initial_block:2", "a"
};
revng_assert(V.VisitLog == GroundTruth);
}
BOOST_AUTO_TEST_CASE(TestForwardBFSVisitor) {
struct Visitor : public ForwardBFSVisitor<Visitor> {
std::vector<std::string> VisitLog;
VisitAction visit(instruction_range Range) {
for (Instruction &I : Range)
VisitLog.push_back(getName(&I));
return Continue;
}
};
LLVMContext TestContext;
std::unique_ptr<Module> M = loadModule(TestContext, VisitorTestBody);
Function *F = M->getFunction("main");
Visitor V;
V.run(instructionByName(F, "target"));
const std::vector<std::string> GroundTruth = {
"center:3", "e", "second_if_true:2", "f", "second_if_false:2", "g", "end:2"
};
revng_assert(V.VisitLog == GroundTruth);
}