#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Support/GenericDomTree.h" #include "revng/ADT/ConstantRangeSet.h" #include "revng/MFP/MFP.h" #include "revng/Support/Statistics.h" #include "revng/ValueMaterializer/AdvancedValueInfo.h" #include "revng/ValueMaterializer/ControlFlowEdgesGraph.h" #include "revng/ValueMaterializer/DataFlowGraph.h" #include "revng/ValueMaterializer/MemoryOracle.h" namespace llvm { class LazyValueInfo; class DominatorTree; } // namespace llvm namespace Oracle { enum Values { None, LazyValueInfo, AdvancedValueInfo, Count }; } // namespace Oracle inline RunningStatistics DFGSizeStatitistics("vm-dfg-size"); class ValueMaterializer { private: using ConstraintsMap = std::map; private: // // Inputs // llvm::Instruction *Context; llvm::Value *V; MemoryOracle &MO; llvm::LazyValueInfo &LVI; const llvm::DominatorTree &DT; DataFlowGraph::Limits TheLimits; Oracle::Values Oracle; // // Outputs // DataFlowGraph DataFlowGraph; ConstraintsMap OracleConstraints; map *, MFP::MFPResult>> MFIResults; std::optional Values; ControlFlowEdgesGraph CFEG; private: ValueMaterializer(llvm::Instruction *Context, llvm::Value *V, MemoryOracle &MO, llvm::LazyValueInfo &LVI, const llvm::DominatorTree &DT, DataFlowGraph::Limits TheLimits, Oracle::Values Oracle) : Context(Context), V(V), MO(MO), LVI(LVI), DT(DT), TheLimits(TheLimits), Oracle(Oracle) {} public: static ValueMaterializer getValuesFor(llvm::Instruction *Context, llvm::Value *V, MemoryOracle &MO, llvm::LazyValueInfo &LVI, const llvm::DominatorTree &DT, DataFlowGraph::Limits TheLimits, Oracle::Values Oracle) { ValueMaterializer Result(Context, V, MO, LVI, DT, TheLimits, Oracle); Result.run(); return Result; } public: const auto &dataFlowGraph() const { return DataFlowGraph; } const auto &oracleConstraints() const { return OracleConstraints; } const auto &mfiResult() const { return MFIResults; } const auto &values() const { return Values; } const auto &cfeg() const { return CFEG; } private: void run(); void computeOracleConstraints(); void applyOracleResultsToDataFlowGraph(); void computeSizeLowerBound(); void electMaterializationStartingPoints(); };