#ifndef ABSTRACHTCACHESTATE_H #define ABSTRACHTCACHESTATE_H #include #include #include #include #include #include #include #include #include #include "AbstractState.h" #include "Address.h" #include "ConcreteState.h" // Forward declarations namespace cacheAnaPass { class AbstractCache; } // namespace cacheAnaPass class AbstractCache { public: // everything is public, because IDGAF // map keys are instruction Addresses. std::map> Edges; std::map Nodes; AbstractCache() {} /** * @brief Add an Edge to the Abstract Cache * * @param Pre Predecessor Address * @param Suc Successor Address */ void addEdge(unsigned int Pre, unsigned int Suc) { Edges[Pre].push_back(Suc); Nodes[Pre].Successors.push_back(Suc); Nodes[Suc].Predecessors.push_back(Pre); } void addEmptyNode(unsigned int NodeAddr) { Nodes[NodeAddr] = AbstractState(NodeAddr); } void fillAbstractCache(unsigned int NodeNr) { Nodes[NodeNr].Computed = true; for (unsigned int SuccNr : Nodes[NodeNr].Successors) { Nodes[SuccNr]; if (Nodes[SuccNr].Computed) { // Join don't call Nodes[SuccNr].mustJoin(Nodes[NodeNr]); Nodes[SuccNr].mustJoin(AbstractState(NodeNr)); } else { // Update and fill Succ Nodes[SuccNr].fill(Nodes[NodeNr], NodeNr); fillAbstractCache(SuccNr); } } return; } unsigned int collectHits() { unsigned int Hits = 0; for (auto const &E : Edges) { auto Predecessor = Nodes[E.first]; for (unsigned int SuccessorAddr : E.second) { // When successors Address is in predecessor, we have a Hit. Hits += Predecessor.isHit(Address(SuccessorAddr)) ? 1 : 0; } } return Hits; } unsigned int collectMisses() { unsigned int Misses = 0; for (auto const &E : Edges) { auto Predecessor = Nodes[E.first]; for (unsigned int SuccessorAddr : E.second) { // When successors Address is in predecessor, we have a Hit. Misses += Predecessor.isHit(Address(SuccessorAddr)) ? 0 : 1; } } return Misses; } void dumpEdges() { llvm::outs() << "Dumping Edges:\n"; for (auto const &E : Edges) { llvm::outs() << E.first; bool FirstPrint = true; for (unsigned int To : E.second) { if (FirstPrint) { llvm::outs() << " -> " << To; FirstPrint = false; } else { llvm::outs() << ", " << To; } } llvm::outs() << "\n"; } } void dumpDotFile() { std::ofstream DotFile; DotFile.open("out.dot"); DotFile << "digraph g {" << "\n"; for (auto const &E : Edges) { for (unsigned int To : E.second) { DotFile << E.first << " -> " << To << "\n"; } } DotFile << "}\n"; DotFile.close(); } void dumpNodes() { for (auto const &E : Edges) { Nodes[E.first].dump(); } } }; // namespace #endif // ABSTRACHTCACHESTATE_H