#ifndef wasm_analysis_liveness_transfer_function_h #define wasm_analysis_liveness_transfer_function_h #include "lattice.h" #include "lattices/powerset.h" #include "visitor-transfer-function.h" namespace wasm::analysis { struct LivenessTransferFunction : public VisitorTransferFunc { // Transfer function implementation. A local becomes live before a get // and becomes dead before a set. void visitLocalSet(LocalSet* curr) { assert(currState); currState->set(curr->index, false); } void visitLocalGet(LocalGet* curr) { assert(currState); currState->set(curr->index, true); } // Prints the intermediate states of each basic block cfgBlock by applying // the transfer function on each expression of the CFG block. This data is // not stored. Requires the cfgBlock, and a temp copy of the input state // to be passed in, where the temp copy is modified in place to produce the // intermediate states. void print(std::ostream& os, const BasicBlock& bb, FiniteIntPowersetLattice::Element& inputState) { os << "Intermediate States (reverse order): " << std::endl; currState = &inputState; currState->print(os); os << std::endl; // Since we don't store the intermediate states, we need to re-run the // transfer function on all the CFG node expressions to reconstruct // the intermediate states here. for (auto it = bb.rbegin(); it != bb.rend(); ++it) { os << ShallowExpression{*it} << "\n"; visit(*it); currState->print(os); os << "\n"; } currState = nullptr; } }; } // namespace wasm::analysis #endif // wasm_analysis_liveness_transfer_function_h