Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 0 additions & 149 deletions src/analysis/cfg-impl.h

This file was deleted.

12 changes: 6 additions & 6 deletions src/analysis/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,19 @@ void CFG::print(std::ostream& os, Module* wasm) const {

void BasicBlock::print(std::ostream& os, Module* wasm, size_t start) const {
os << ";; preds: [";
for (auto& pred : preds()) {
if (&pred != &*preds().begin()) {
for (const auto* pred : preds()) {
if (pred != *preds().begin()) {
os << ", ";
}
os << pred.index;
os << pred->index;
}
os << "], succs: [";

for (auto& succ : succs()) {
if (&succ != &*succs().begin()) {
for (const auto* succ : succs()) {
if (succ != *succs().begin()) {
os << ", ";
}
os << succ.index;
os << succ->index;
}
os << "]\n";

Expand Down
12 changes: 4 additions & 8 deletions src/analysis/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ struct BasicBlock {
reverse_iterator rbegin() const { return insts.rbegin(); }
reverse_iterator rend() const { return insts.rend(); }

// Iterables for predecessor and successor blocks.
struct BasicBlockIterable;
BasicBlockIterable preds() const;
BasicBlockIterable succs() const;
const std::vector<const BasicBlock*>& preds() const { return predecessors; }
const std::vector<const BasicBlock*>& succs() const { return successors; }

void print(std::ostream& os, Module* wasm = nullptr, size_t start = 0) const;

Expand All @@ -56,8 +54,8 @@ struct BasicBlock {
private:
Index index;
std::vector<Expression*> insts;
std::vector<BasicBlock*> predecessors;
std::vector<BasicBlock*> successors;
std::vector<const BasicBlock*> predecessors;
std::vector<const BasicBlock*> successors;

friend CFG;
};
Expand Down Expand Up @@ -109,6 +107,4 @@ struct CFGBlockIndexes {

} // namespace wasm::analysis

#include "cfg-impl.h"

#endif // wasm_analysis_cfg_h
15 changes: 6 additions & 9 deletions src/analysis/monotone-analyzer-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,13 @@ inline void MonotoneCFGAnalyzer<L, TxFn>::evaluate() {
Index i = worklist.pop();

// Apply the transfer function to the input state to compute the output
// state for the block.
// state, then propagate the output state to the dependent blocks.
auto state = states[i];
txfn.transfer(cfg[i], state);

// Propagate state to the dependent blocks.
for (auto& dep : txfn.getDependents(cfg[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());
if (lattice.join(states[dep->getIndex()], state)) {
worklist.push(dep->getIndex());
}
}
}
Expand All @@ -73,11 +70,11 @@ inline void MonotoneCFGAnalyzer<L, TxFn>::print(std::ostream& os) {
os << "Input State: ";
states[i].print(os);
for (auto& pred : cfg[i].preds()) {
os << " " << pred.getIndex();
os << " " << pred->getIndex();
}
os << std::endl << "Successors:";
for (auto& succ : cfg[i].succs()) {
os << " " << succ.getIndex();
os << " " << succ->getIndex();
}
os << "\n";
txfn.print(os, cfg[i], states[i]);
Expand Down
9 changes: 4 additions & 5 deletions src/analysis/transfer-function.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ namespace wasm::analysis {
template<typename T>
concept BasicBlockInputRange =
std::ranges::input_range<T> &&
std::is_same<std::ranges::range_value_t<T>, BasicBlock>::value;
std::is_same<std::ranges::range_value_t<T>, const BasicBlock*>::value;

template<typename TxFn, typename L>
concept TransferFunctionImpl = requires(
TxFn& txfn, const CFG& cfg, const BasicBlock& bb, typename L::Element& elem) {
// Apply the transfer function to update a lattice element with information
// from a basic block.
{ txfn.transfer(bb, elem) } noexcept -> std::same_as<void>;
// Get a range over the basic blocks that depend on the given block.
{ txfn.getDependents(bb) } noexcept -> BasicBlockInputRange;
// from a basic block. Return an object that can be iterated over to get the
// basic blocks that may need to be re-analyzed.
{ txfn.transfer(bb, elem) } noexcept -> BasicBlockInputRange;
};

#define TransferFunction TransferFunctionImpl<L>
Expand Down
21 changes: 8 additions & 13 deletions src/analysis/visitor-transfer-function.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,11 @@ struct VisitorTransferFunc : public Visitor<SubType> {
bool collectingResults = false;

public:
// Returns an iterable to all the BasicBlocks which depend on currBlock for
// information.
BasicBlock::BasicBlockIterable
getDependents(const BasicBlock& currBlock) noexcept {
if constexpr (Direction == AnalysisDirection::Backward) {
return currBlock.preds();
} else {
return currBlock.succs();
}
}

// Executes the transfer function on all the expressions of the corresponding
// CFG node, starting with the node's input state, and changes the input state
// to the final output state of the node in place.
void transfer(const BasicBlock& bb,
typename L::Element& inputState) noexcept {
const std::vector<const BasicBlock*>&
transfer(const BasicBlock& bb, typename L::Element& inputState) noexcept {
// If the block is empty, we propagate the state by inputState =
// outputState.

Expand All @@ -64,6 +53,12 @@ struct VisitorTransferFunc : public Visitor<SubType> {
}
}
currState = nullptr;

if constexpr (Direction == AnalysisDirection::Backward) {
return bb.preds();
} else {
return bb.succs();
}
}

// This is for collecting results after solving an analysis. Implemented in
Expand Down