Files
revng-revng/lib/DataLayoutAnalysis/DLAPass.cpp
T
Alvise de Faveri 4c8215fc47 DLA: Add pointers
* Changes to the `LayoutTypeSystem` graph

Pointers are identified in the TypeSystem graph as leaf nodes which
have a new type of edge (PointerEdge) that connects them to another
node of the graph. The destination of the edge represents the layout of
the pointed type.

* Changes to the Front-end

Pointer edges, and their destination nodes, are created by the DLA
front-end (`DLACreateIntraProceduralTypes`) whenever an access node has
a size that is compatible with the size of a pointer in the current
Architecture.
Successors might then be added to the newly generated node, if any,
by looking up the llvm::Value it is attached to.

* Changes to the Middle-end

Most of the DLA passes should ignore Pointer Edges, so they are modified
accordingly. Most notably, nodes that represent pointed layouts should
never be merged/pruned-off.

* Changes to the Back-end

The `TypeDeclCreationAction` of the decompiler and the `DLAMakeLayouts`
step of the DLA back-end are modified to take into account the new
information about pointers.

⚠️ There is a known issue with this version of the decompiler,
namely the fact that type loops are not detected and can cause the
emitter to enter an infinite loop.
2021-11-16 17:00:34 +01:00

81 lines
2.9 KiB
C++

//
// Copyright (c) rev.ng Srls. See LICENSE.md for details.
//
#include "revng/Model/LoadModelPass.h"
#include "revng-c/DataLayoutAnalysis/DLALayouts.h"
#include "revng-c/DataLayoutAnalysis/DLAPass.h"
#include "revng-c/Utils/Utils.h"
#include "Backend/DLAMakeLayouts.h"
#include "Frontend/DLATypeSystemBuilder.h"
#include "Middleend/DLAStep.h"
namespace {
llvm::cl::opt<std::string> DLADir("dla-flatc-dir",
llvm::cl::desc("Path to serialize flatc"),
llvm::cl::value_desc("Path"),
llvm::cl::cat(MainCategory),
llvm::cl::NumOccurrencesFlag::Optional);
} // end of unnamed namespace
char DLAPass::ID = 0;
static Logger<> BuilderLog("dla-builder-log");
using Register = llvm::RegisterPass<DLAPass>;
static Register X("dla", "Data Layout Analysis Pass", false, false);
void DLAPass::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
AU.addRequired<LoadModelWrapperPass>();
AU.addRequired<llvm::LoopInfoWrapperPass>();
AU.addRequired<llvm::ScalarEvolutionWrapperPass>();
AU.setPreservesAll();
}
bool DLAPass::runOnModule(llvm::Module &M) {
auto &ModelWrapper = getAnalysis<LoadModelWrapperPass>().get();
// Front-end: Create the LayoutTypeSystem graph from an LLVM module
dla::LayoutTypeSystem TS;
dla::DLATypeSystemLLVMBuilder Builder{ TS };
Builder.buildFromLLVMModule(M, this, ModelWrapper.getReadOnlyModel());
if (BuilderLog.isEnabled())
Builder.dumpValuesMapping("DLA-values-initial.csv");
// Middle-end Steps: manipulate nodes and edges of the DLATypeSystem graph
dla::StepManager SM;
revng_check(SM.addStep<dla::CollapseIdentityAndInheritanceCC>());
revng_check(SM.addStep<dla::PropagateInheritanceToAccessors>());
revng_check(SM.addStep<dla::RemoveTransitiveInheritanceEdges>());
revng_check(SM.addStep<dla::MakeInheritanceTree>());
revng_check(SM.addStep<dla::PruneLayoutNodesWithoutLayout>());
revng_check(SM.addStep<dla::RemoveConflictingEdges>());
revng_check(SM.addStep<dla::CollapseSingleChild>());
revng_check(SM.addStep<dla::ComputeUpperMemberAccesses>());
revng_check(SM.addStep<dla::CollapseCompatibleArrays>());
revng_check(SM.addStep<dla::ComputeNonInterferingComponents>());
revng_check(SM.addStep<dla::DeduplicateUnionFields>());
revng_check(SM.addStep<dla::ComputeNonInterferingComponents>());
SM.run(TS);
if (BuilderLog.isEnabled())
Builder.dumpValuesMapping("DLA-values-after-ME.csv");
// Compress the equivalence classes obtained after graph manipulation
dla::VectEqClasses &EqClasses = TS.getEqClasses();
EqClasses.compress();
// Create Layouts from the final nodes of the graph
dla::LayoutPtrVector OrderedLayouts = makeLayouts(TS, this->Layouts);
// Map Layouts back to their corresponding LayoutTypePtr
dla::LayoutTypePtrVect Values = Builder.getValues();
this->ValueLayoutsMap = makeLayoutMap(Values, OrderedLayouts, EqClasses);
return true;
}