#ifndef wasm_analysis_cfg_h
#define wasm_analysis_cfg_h
#include <iostream>
#include <vector>
#include "wasm.h"
namespace wasm::analysis {
struct CFG;
struct BasicBlock {
using iterator = std::vector<Expression*>::const_iterator;
iterator begin() const { return insts.cbegin(); }
iterator end() const { return insts.cend(); }
size_t size() const { return insts.size(); }
using reverse_iterator = std::vector<Expression*>::const_reverse_iterator;
reverse_iterator rbegin() const { return insts.rbegin(); }
reverse_iterator rend() const { return insts.rend(); }
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;
Index getIndex() const { return index; }
bool isEntry() const { return entry; }
bool isExit() const { return exit; }
private:
Index index;
bool entry = false;
bool exit = false;
std::vector<Expression*> insts;
std::vector<const BasicBlock*> predecessors;
std::vector<const BasicBlock*> successors;
friend CFG;
};
struct CFG {
using iterator = std::vector<BasicBlock>::const_iterator;
iterator begin() const { return blocks.cbegin(); }
iterator end() const { return blocks.cend(); }
size_t size() const { return blocks.size(); }
using reverse_iterator = std::vector<BasicBlock>::const_reverse_iterator;
reverse_iterator rbegin() const { return blocks.rbegin(); }
reverse_iterator rend() const { return blocks.rend(); }
const BasicBlock& operator[](size_t i) const { return *(begin() + i); }
static CFG fromFunction(Function* func);
void print(std::ostream& os, Module* wasm = nullptr) const;
private:
std::vector<BasicBlock> blocks;
friend BasicBlock;
};
struct CFGBlockIndexes {
CFGBlockIndexes(const CFG& cfg);
Index get(Expression* expr) const {
auto iter = map.find(expr);
if (iter == map.end()) {
return InvalidBlock;
}
return iter->second;
}
enum { InvalidBlock = Index(-1) };
private:
std::unordered_map<Expression*, Index> map;
};
}
#endif