blob: 5746577bb46fb137c56f8a3e805b86da471e626f [file] [log] [blame] [edit]
#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<LivenessTransferFunction,
FiniteIntPowersetLattice,
AnalysisDirection::Backward> {
// 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