#ifndef wasm_analysis_monotone_analyzer_impl_h #define wasm_analysis_monotone_analyzer_impl_h #include #include #include "monotone-analyzer.h" #include "support/unique_deferring_queue.h" namespace wasm::analysis { template inline MonotoneCFGAnalyzer::MonotoneCFGAnalyzer(L& lattice, TxFn& txfn, CFG& cfg) : lattice(lattice), txfn(txfn), cfg(cfg), states(cfg.size(), lattice.getBottom()) {} template inline void MonotoneCFGAnalyzer::evaluateFunctionEntry(Function* func) { txfn.evaluateFunctionEntry(func, states[0]); } template inline void MonotoneCFGAnalyzer::evaluate() { UniqueDeferredQueue worklist; // Start with all blocks on the work list. TODO: optimize the iteration order // using e.g. strongly-connected components. for (Index i = 0; i < cfg.size(); ++i) { worklist.push(i); } while (!worklist.empty()) { // The index of the block we will analyze. Index i = worklist.pop(); // Apply the transfer function to the input state to compute the output // state, then propagate the output state to the dependent blocks. auto state = states[i]; for (const auto* dep : txfn.transfer(cfg[i], state)) { // If the input state for the dependent block changes, we need to // re-analyze it. if (lattice.join(states[dep->getIndex()], state)) { worklist.push(dep->getIndex()); } } } } template inline void MonotoneCFGAnalyzer::collectResults() { for (Index i = 0, size = cfg.size(); i < size; ++i) { // The transfer function generates the final set of states and uses it to // produce useful information. For example, in reaching definitions // analysis, these final states are used to populate a mapping of // local.get's to a set of local.set's that affect its value. txfn.collectResults(cfg[i], states[i]); } } // Currently prints both the basic information and intermediate states of each // BlockState. template inline void MonotoneCFGAnalyzer::print(std::ostream& os) { os << "CFG Analyzer" << std::endl; for (Index i = 0, size = cfg.size(); i < size; ++i) { os << "CFG Block: " << cfg[i].getIndex() << std::endl; os << "Input State: "; states[i].print(os); for (auto& pred : cfg[i].preds()) { os << " " << pred->getIndex(); } os << std::endl << "Successors:"; for (auto& succ : cfg[i].succs()) { os << " " << succ->getIndex(); } os << "\n"; txfn.print(os, cfg[i], states[i]); } os << "End\n"; } } // namespace wasm::analysis #endif // wasm_analysis_monotone_analyzer_impl_h