summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cfg/cfg-traversal.h38
-rw-r--r--src/passes/CoalesceLocals.cpp2
2 files changed, 36 insertions, 4 deletions
diff --git a/src/cfg/cfg-traversal.h b/src/cfg/cfg-traversal.h
index b862c9403..74afc7525 100644
--- a/src/cfg/cfg-traversal.h
+++ b/src/cfg/cfg-traversal.h
@@ -289,15 +289,20 @@ struct CFGWalker : public PostWalker<SubType, VisitorType> {
std::map<BasicBlock*, size_t> debugIds;
- void dumpCFG(std::string message, Function* func) {
- std::cout << "<==\nCFG [" << message << "]:\n";
+ void generateDebugIds() {
+ if (debugIds.size() > 0) return;
for (auto& block : basicBlocks) {
debugIds[block.get()] = debugIds.size();
}
+ }
+
+ void dumpCFG(std::string message) {
+ std::cout << "<==\nCFG [" << message << "]:\n";
+ generateDebugIds();
for (auto& block : basicBlocks) {
assert(debugIds.count(block.get()) > 0);
std::cout << " block " << debugIds[block.get()] << ":\n";
- block->contents.dump(func);
+ block->contents.dump(static_cast<SubType*>(this)->getFunction());
for (auto& in : block->in) {
assert(debugIds.count(in) > 0);
assert(std::find(in->out.begin(), in->out.end(), block.get()) != in->out.end()); // must be a parallel link back
@@ -307,9 +312,36 @@ struct CFGWalker : public PostWalker<SubType, VisitorType> {
std::cout << " out: " << debugIds[out] << "\n";
assert(std::find(out->in.begin(), out->in.end(), block.get()) != out->in.end()); // must be a parallel link back
}
+ checkDuplicates(block->in);
+ checkDuplicates(block->out);
}
std::cout << "==>\n";
}
+
+private:
+ // links in out and in must be unique
+ void checkDuplicates(std::vector<BasicBlock*>& list) {
+ std::unordered_set<BasicBlock*> seen;
+ for (auto* curr : list) {
+ assert(seen.count(curr) == 0);
+ seen.insert(curr);
+ }
+ }
+
+ void removeLink(std::vector<BasicBlock*>& list, BasicBlock* toRemove) {
+ if (list.size() == 1) {
+ list.clear();
+ return;
+ }
+ for (size_t i = 0; i < list.size(); i++) {
+ if (list[i] == toRemove) {
+ list[i] = list.back();
+ list.pop_back();
+ return;
+ }
+ }
+ WASM_UNREACHABLE();
+ }
};
} // namespace wasm
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index 91f5df1e1..1b5755939 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -183,7 +183,7 @@ struct CoalesceLocals : public WalkerPass<CFGWalker<CoalesceLocals, Visitor<Coal
liveBlocks = findLiveBlocks();
unlinkDeadBlocks(liveBlocks);
#ifdef CFG_DEBUG
- dumpCFG("the cfg", getFunction());
+ dumpCFG("the cfg");
#endif
// flow liveness across blocks
#ifdef CFG_PROFILE