mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
43ae7a91cb
Add a step that recognizes if two subtrees of a union node are topologically equivalent and merges them. This corresponds to removing duplicate fields in unions. This deduplication was prevously done while emitting layouts. A check is inserted into DLAMakeLayouts to assert that, after constructing unions, no union has only one child, which could be the case if we didn't deduplicate union fields in the graph.
80 lines
2.8 KiB
C++
80 lines
2.8 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) {
|
|
dla::LayoutTypeSystem TS;
|
|
|
|
// Front-end: Create the LayoutTypeSystem graph from an LLVM module
|
|
dla::DLATypeSystemLLVMBuilder Builder{ TS };
|
|
Builder.buildFromLLVMModule(M, this);
|
|
|
|
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;
|
|
}
|