diff --git a/src/cfg/domtree.h b/src/cfg/domtree.h index 5753a311402..a718d4036a4 100644 --- a/src/cfg/domtree.h +++ b/src/cfg/domtree.h @@ -43,7 +43,8 @@ namespace wasm { // etc. // // The BasicBlock type is assumed to have a ".in" property which declares a -// vector of pointers to the incoming blocks, that is, the predecessors. +// vector of pointers to the incoming blocks, that is, the predecessors, and a +// ".contents.index" property to hold each block's index in `blocks`. template struct DomTree { std::vector iDoms; @@ -83,9 +84,8 @@ DomTree::DomTree(std::vector>& blocks) { } // Map basic blocks to their indices. - std::unordered_map blockIndices; for (Index i = 0; i < numBlocks; i++) { - blockIndices[blocks[i].get()] = i; + blocks[i]->contents.index = i; } // Initialize the iDoms array. The entry starts with its own index, which is @@ -107,14 +107,14 @@ DomTree::DomTree(std::vector>& blocks) { auto& preds = blocks[index]->in; Index newParent = nonsense; for (auto* pred : preds) { - auto predIndex = blockIndices[pred]; + Index predIndex = pred->contents.index; // In a reducible graph, we only need to care about the predecessors - // that appear before us in the reverse postorder numbering. The only - // predecessor that can appear *after* us is a loop backedge, but that + // that appear before us in the reverse postorder numbering. Any + // predecessor that appears at or after us is a loop backedge, which // will never dominate the loop - the loop is dominated by its single // entry (since it is reducible, it has just one entry). - if (predIndex > index) { + if (predIndex >= index) { continue; } diff --git a/src/cfg/wto.h b/src/cfg/wto.h index b12a57ff74e..95b8101fe4d 100644 --- a/src/cfg/wto.h +++ b/src/cfg/wto.h @@ -115,12 +115,6 @@ WeakTopologicalOrdering::WeakTopologicalOrdering( return; } - for (Index i = 0; i < numBlocks; ++i) { - blocks[i]->contents.index = i; - } - - // TODO: Avoid building an unordered_map of block indices in DomTree when - // BasicBlock already stores its RPO index on `contents`. DomTree domTree(blocks); auto isReachable = [&](Index i) { @@ -253,8 +247,8 @@ WeakTopologicalOrdering::WeakTopologicalOrdering( // fixed-point analysis over its basic blocks using a Weak Topological Ordering. // // Usage: -// 1. Construct `WTOWorklist work(cfg);` (which initializes `inQueue` and -// `index` on each block's `contents`). +// 1. Construct `WTOWorklist work(cfg);` (which initializes `inQueue` on each +// block's `contents`). // 2. Seed the initial block(s) to evaluate via `work.push(cfg.entry);`. // 3. Call `work.run([&](BasicBlock* block) { ... });`. Inside the visitor // callback, evaluate the transfer function for `block` and call @@ -272,11 +266,8 @@ template struct WTOWorklist { CFG& cfg; WTOWorklist(CFG& cfg) : cfg(cfg) { - auto& basicBlocks = cfg.basicBlocks; - for (Index i = 0; i < basicBlocks.size(); ++i) { - auto& contents = basicBlocks[i]->contents; - contents.inQueue = false; - contents.index = i; + for (auto& block : cfg.basicBlocks) { + block->contents.inQueue = false; } } diff --git a/src/passes/OnceReduction.cpp b/src/passes/OnceReduction.cpp index 814483d51e0..0075c020c79 100644 --- a/src/passes/OnceReduction.cpp +++ b/src/passes/OnceReduction.cpp @@ -217,6 +217,9 @@ struct Scanner : public WalkerPass> { // Information in a basic block. struct BlockInfo { + // For DomTree. + Index index; + // We track relevant expressions, which are call to "once" functions, and // writes to "once" globals. std::vector exprs; diff --git a/test/example/domtree.cpp b/test/example/domtree.cpp index e1b93ccc437..b7ce78d18de 100644 --- a/test/example/domtree.cpp +++ b/test/example/domtree.cpp @@ -7,6 +7,9 @@ using namespace wasm; struct BasicBlock { + struct { + Index index; + } contents; std::vector in; void addPred(BasicBlock* pred) { in.push_back(pred); }