diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2022-01-13 15:23:15 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-13 23:23:15 +0000 |
commit | a971566d37ae44ff50eeec8ba4a2384d80684571 (patch) | |
tree | e6737758eb2d8d781fb399f8f93225928d5a1748 /src/ir/module-utils.h | |
parent | 6d92ba9ceb14563fb4d1e573f8644eb06a8cea2a (diff) | |
download | binaryen-a971566d37ae44ff50eeec8ba4a2384d80684571.tar.gz binaryen-a971566d37ae44ff50eeec8ba4a2384d80684571.tar.bz2 binaryen-a971566d37ae44ff50eeec8ba4a2384d80684571.zip |
[NFC] Move ModuleUtils::collectHeapTypes to a .cpp file (#4458)
In preparation for the refactoring in #4455.
Diffstat (limited to 'src/ir/module-utils.h')
-rw-r--r-- | src/ir/module-utils.h | 155 |
1 files changed, 3 insertions, 152 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 1d56c1a3e..d645ae5f7 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -22,7 +22,6 @@ #include "ir/manipulation.h" #include "ir/properties.h" #include "pass.h" -#include "support/insert_ordered.h" #include "support/unique_deferring_queue.h" #include "wasm.h" @@ -464,157 +463,9 @@ template<typename T> struct CallGraphPropertyAnalysis { // indices. HeapTypes are sorted in order of decreasing frequency to minize the // size of their collective encoding. Both a vector mapping indices to // HeapTypes and a map mapping HeapTypes to indices are produced. -inline void collectHeapTypes(Module& wasm, - std::vector<HeapType>& types, - std::unordered_map<HeapType, Index>& typeIndices) { - struct Counts : public InsertOrderedMap<HeapType, size_t> { - void note(HeapType type) { - if (!type.isBasic()) { - (*this)[type]++; - } - } - void note(Type type) { - for (HeapType ht : type.getHeapTypeChildren()) { - note(ht); - } - } - }; - - struct CodeScanner - : PostWalker<CodeScanner, UnifiedExpressionVisitor<CodeScanner>> { - Counts& counts; - - CodeScanner(Module& wasm, Counts& counts) : counts(counts) { - setModule(&wasm); - } - - void visitExpression(Expression* curr) { - if (auto* call = curr->dynCast<CallIndirect>()) { - counts.note(call->heapType); - } else if (curr->is<RefNull>()) { - counts.note(curr->type); - } else if (curr->is<RttCanon>() || curr->is<RttSub>()) { - counts.note(curr->type.getRtt().heapType); - } else if (auto* make = curr->dynCast<StructNew>()) { - // Some operations emit a HeapType in the binary format, if they are - // static and not dynamic (if dynamic, the RTT provides the heap type). - if (!make->rtt && make->type != Type::unreachable) { - counts.note(make->type.getHeapType()); - } - } else if (auto* make = curr->dynCast<ArrayNew>()) { - if (!make->rtt && make->type != Type::unreachable) { - counts.note(make->type.getHeapType()); - } - } else if (auto* make = curr->dynCast<ArrayInit>()) { - if (!make->rtt && make->type != Type::unreachable) { - counts.note(make->type.getHeapType()); - } - } else if (auto* cast = curr->dynCast<RefCast>()) { - if (!cast->rtt && cast->type != Type::unreachable) { - counts.note(cast->getIntendedType()); - } - } else if (auto* cast = curr->dynCast<RefTest>()) { - if (!cast->rtt && cast->type != Type::unreachable) { - counts.note(cast->getIntendedType()); - } - } else if (auto* cast = curr->dynCast<BrOn>()) { - if (cast->op == BrOnCast || cast->op == BrOnCastFail) { - if (!cast->rtt && cast->type != Type::unreachable) { - counts.note(cast->getIntendedType()); - } - } - } else if (auto* get = curr->dynCast<StructGet>()) { - counts.note(get->ref->type); - } else if (auto* set = curr->dynCast<StructSet>()) { - counts.note(set->ref->type); - } else if (Properties::isControlFlowStructure(curr)) { - if (curr->type.isTuple()) { - // TODO: Allow control flow to have input types as well - counts.note(Signature(Type::none, curr->type)); - } else { - counts.note(curr->type); - } - } - } - }; - - // Collect module-level info. - Counts counts; - CodeScanner(wasm, counts).walkModuleCode(&wasm); - for (auto& curr : wasm.tags) { - counts.note(curr->sig); - } - for (auto& curr : wasm.tables) { - counts.note(curr->type); - } - for (auto& curr : wasm.elementSegments) { - counts.note(curr->type); - } - - // Collect info from functions in parallel. - ModuleUtils::ParallelFunctionAnalysis<Counts, InsertOrderedMap> analysis( - wasm, [&](Function* func, Counts& counts) { - counts.note(func->type); - for (auto type : func->vars) { - counts.note(type); - } - if (!func->imported()) { - CodeScanner(wasm, counts).walk(func->body); - } - }); - - // Combine the function info with the module info. - for (auto& [_, functionCounts] : analysis.map) { - for (auto& [sig, count] : functionCounts) { - counts[sig] += count; - } - } - - // Recursively traverse each reference type, which may have a child type that - // is itself a reference type. This reflects an appearance in the binary - // format that is in the type section itself. - // As we do this we may find more and more types, as nested children of - // previous ones. Each such type will appear in the type section once, so - // we just need to visit it once. - InsertOrderedSet<HeapType> newTypes; - for (auto& [type, _] : counts) { - newTypes.insert(type); - } - while (!newTypes.empty()) { - auto iter = newTypes.begin(); - auto ht = *iter; - newTypes.erase(iter); - for (HeapType child : ht.getHeapTypeChildren()) { - if (!child.isBasic()) { - if (!counts.count(child)) { - newTypes.insert(child); - } - counts.note(child); - } - } - - if (auto super = ht.getSuperType()) { - if (!counts.count(*super)) { - newTypes.insert(*super); - // We should unconditionally count supertypes, but while the type system - // is in flux, skip counting them to keep the type orderings in nominal - // test outputs more similar to the orderings in the equirecursive - // outputs. FIXME - counts.note(*super); - } - } - } - - // Sort by frequency and then original insertion order. - std::vector<std::pair<HeapType, size_t>> sorted(counts.begin(), counts.end()); - std::stable_sort(sorted.begin(), sorted.end(), [&](auto a, auto b) { - return a.second > b.second; - }); - for (Index i = 0; i < sorted.size(); ++i) { - typeIndices[sorted[i].first] = i; - types.push_back(sorted[i].first); - } -} +void collectHeapTypes(Module& wasm, + std::vector<HeapType>& types, + std::unordered_map<HeapType, Index>& typeIndices); } // namespace wasm::ModuleUtils |