From bcc76146fed433cbc8ba01a9f568d979c145110b Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 30 Dec 2019 17:55:20 -0800 Subject: Add support for reference types proposal (#2451) This adds support for the reference type proposal. This includes support for all reference types (`anyref`, `funcref`(=`anyfunc`), and `nullref`) and four new instructions: `ref.null`, `ref.is_null`, `ref.func`, and new typed `select`. This also adds subtype relationship support between reference types. This does not include table instructions yet. This also does not include wasm2js support. Fixes #2444 and fixes #2447. --- src/passes/Inlining.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/passes/Inlining.cpp') diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index db1db5971..c43d41e7f 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -46,13 +46,13 @@ namespace wasm { // Useful into on a function, helping us decide if we can inline it struct FunctionInfo { - std::atomic calls; + std::atomic refs; Index size; std::atomic lightweight; bool usedGlobally; // in a table or export FunctionInfo() { - calls = 0; + refs = 0; size = 0; lightweight = true; usedGlobally = false; @@ -75,7 +75,7 @@ struct FunctionInfo { // FIXME: move this check to be first in this function, since we should // return true if oneCallerInlineMaxSize is bigger than // flexibleInlineMaxSize (which it typically should be). - if (calls == 1 && !usedGlobally && + if (refs == 1 && !usedGlobally && size <= options.inlining.oneCallerInlineMaxSize) { return true; } @@ -108,11 +108,16 @@ struct FunctionInfoScanner void visitCall(Call* curr) { // can't add a new element in parallel assert(infos->count(curr->target) > 0); - (*infos)[curr->target].calls++; + (*infos)[curr->target].refs++; // having a call is not lightweight (*infos)[getFunction()->name].lightweight = false; } + void visitRefFunc(RefFunc* curr) { + assert(infos->count(curr->func) > 0); + (*infos)[curr->func].refs++; + } + void visitFunction(Function* curr) { (*infos)[curr->name].size = Measurer::measure(curr->body); } @@ -374,7 +379,7 @@ struct Inlining : public Pass { doInlining(module, func.get(), action); inlinedUses[inlinedName]++; inlinedInto.insert(func.get()); - assert(inlinedUses[inlinedName] <= infos[inlinedName].calls); + assert(inlinedUses[inlinedName] <= infos[inlinedName].refs); } } // anything we inlined into may now have non-unique label names, fix it up @@ -388,7 +393,7 @@ struct Inlining : public Pass { module->removeFunctions([&](Function* func) { auto name = func->name; auto& info = infos[name]; - return inlinedUses.count(name) && inlinedUses[name] == info.calls && + return inlinedUses.count(name) && inlinedUses[name] == info.refs && !info.usedGlobally; }); // return whether we did any work -- cgit v1.2.3