mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
5f7a67c8af
We introduce the `CycleEquivalence` analysis.
This is an analysis which implements the _Cycle Equivalence_ computation
algorithm, and provides as result the _cycle equivalence classes_
Specifically, we introduce:
- The `CycleEquivalenceClass`, which is the unitary element computed by
the analysis.
- The `CycleEquivalenceAnalysis`, which contains the algorithm to
compute the cycle equivalence.
- The `CycleEquivalencePass`, a `FunctionPass` that can be used to
perform the analysis on a `llvm::Function`.
The algorithm is composed by various stages:
- We construct a new `GenericGraph` object, replicating the input CFG,
with the addition of the `exit`->`entry` edge.
- Taking advantage of `llvm::GraphTraits<Undirected<>>`, we can now
implement the algorithm working on an undirected version of the input.
- We perform the `CycleEquivalence` computation, returning a
`llvm::SmallVector` of `CycleEquivalenceClass` objects.
In addition to using the `llvm::GraphTraits<Undirected<>>` traits to
walk on the equivalent undirected graph, we also need to:
- Perform a preliminary DFS, in order to:
- Assign the DFS number to each node in the graph.
- Compute the spanning tree, and use this information to distinguish
tree edges and back edges when running the algorithm.
The internal graph used by the analysis also normalizes the graph in
order to have a sinle exit node (called sink), which is a requirement
for the `CycleEquivalence` algorithm.
We also implement the `llvm::DOTGraphTraits` for the
`CycleEquivalenceAnalysis<llvm::Function *>` specialization. In this
way, we can have a graphical representation of the undirected graph used
internally in the `CycleEquivalenceAnalysis` core implementation.
We add some `FileCheck` tests on some well-known graph topologies.
35 lines
1019 B
C++
35 lines
1019 B
C++
//
|
|
// Copyright rev.ng Labs Srl. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "revng-c/RestructureCFG/CycleEquivalencePass.h"
|
|
#include "revng-c/RestructureCFG/CycleEquivalenceResult.h"
|
|
|
|
using namespace llvm;
|
|
|
|
char CycleEquivalencePass::ID = 0;
|
|
|
|
static constexpr const char *Flag = "cycle-equivalence";
|
|
using Reg = llvm::RegisterPass<CycleEquivalencePass>;
|
|
static Reg X(Flag, "Cycle Equivalence Pass");
|
|
|
|
bool CycleEquivalencePass::runOnFunction(llvm::Function &F) {
|
|
|
|
EdgeToCycleEquivalenceClassIDMap = getEdgeToCycleEquivalenceClassIDMap(&F);
|
|
|
|
// The goal of `CycleEquivalencePass` is to just perform an analysis
|
|
// computation, this operation should not perform a change of the IR
|
|
return false;
|
|
}
|
|
|
|
void CycleEquivalencePass::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
|
|
|
|
// This is a read only analysis, that does not touch the IR
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
const CycleEquivalenceAnalysis<Function *>::CycleEquivalenceResult &
|
|
CycleEquivalencePass::getResult() {
|
|
return EdgeToCycleEquivalenceClassIDMap;
|
|
}
|