#ifndef wasm_analysis_monotone_analyzer_impl_h
#define wasm_analysis_monotone_analyzer_impl_h
#include <iostream>
#include <unordered_map>
#include "monotone-analyzer.h"
namespace wasm::analysis {
template<typename Lattice>
inline BlockState<Lattice>::BlockState(const BasicBlock* underlyingBlock,
Lattice& lattice)
: cfgBlock(underlyingBlock), inputState(lattice.getBottom()) {}
template<typename Lattice>
inline void BlockState<Lattice>::print(std::ostream& os) {
os << "CFG Block: " << cfgBlock->getIndex() << std::endl;
os << "Input State: ";
inputState.print(os);
os << std::endl << "Predecessors:";
for (auto pred : cfgBlock->preds()) {
os << " " << pred.getIndex();
}
os << std::endl << "Successors:";
for (auto succ : cfgBlock->succs()) {
os << " " << succ.getIndex();
}
os << std::endl;
}
template<typename Lattice, typename TransferFunction>
inline MonotoneCFGAnalyzer<Lattice, TransferFunction>::MonotoneCFGAnalyzer(
Lattice& lattice, TransferFunction& transferFunction, CFG& cfg)
: lattice(lattice), transferFunction(transferFunction), cfg(cfg) {
for (auto it = cfg.begin(); it != cfg.end(); it++) {
stateBlocks.emplace_back(&(*it), lattice);
}
}
template<typename Lattice, typename TransferFunction>
inline void
MonotoneCFGAnalyzer<Lattice, TransferFunction>::evaluateFunctionEntry(
Function* func) {
transferFunction.evaluateFunctionEntry(func, stateBlocks[0].inputState);
}
template<typename Lattice, typename TransferFunction>
inline void MonotoneCFGAnalyzer<Lattice, TransferFunction>::evaluate() {
std::queue<const BasicBlock*> worklist;
transferFunction.enqueueWorklist(cfg, worklist);
while (!worklist.empty()) {
BlockState<Lattice>& currBlockState =
stateBlocks[worklist.front()->getIndex()];
worklist.pop();
typename Lattice::Element outputState = currBlockState.inputState;
transferFunction.transfer(currBlockState.cfgBlock, outputState);
for (auto& dep : transferFunction.getDependents(currBlockState.cfgBlock)) {
if (stateBlocks[dep.getIndex()].inputState.makeLeastUpperBound(
outputState)) {
worklist.push(&dep);
}
}
}
}
template<typename Lattice, typename TransferFunction>
inline void MonotoneCFGAnalyzer<Lattice, TransferFunction>::collectResults() {
for (BlockState currBlockState : stateBlocks) {
typename Lattice::Element inputStateCopy = currBlockState.inputState;
transferFunction.collectResults(currBlockState.cfgBlock, inputStateCopy);
}
}
template<typename Lattice, typename TransferFunction>
inline void
MonotoneCFGAnalyzer<Lattice, TransferFunction>::print(std::ostream& os) {
os << "CFG Analyzer" << std::endl;
for (auto state : stateBlocks) {
state.print(os);
typename Lattice::Element temp = state.inputState;
transferFunction.print(os, state.cfgBlock, temp);
}
os << "End" << std::endl;
}
}
#endif