/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Sorts functions by their static use count. This helps reduce the size of wasm
// binaries because fewer bytes are needed to encode references to frequently
// used functions.
//
// This may incur a tradeoff, though, as while it reduces binary size, it may
// increase gzip size. This might be because the new order has the functions in
// a less beneficial position for compression, that is, mutually-compressible
// functions are no longer together (when they were before, in the original
// order, the has some natural tendency one way or the other). TODO: investigate
// similarity ordering here (see #4322)
//

#include <memory>

#include <ir/element-utils.h>
#include <pass.h>
#include <wasm.h>

namespace wasm {

using NameCountMap = std::unordered_map<Name, std::atomic<Index>>;

struct CallCountScanner : public WalkerPass<PostWalker<CallCountScanner>> {
  bool isFunctionParallel() override { return true; }

  bool modifiesBinaryenIR() override { return false; }

  CallCountScanner(NameCountMap* counts) : counts(counts) {}

  std::unique_ptr<Pass> create() override {
    return std::make_unique<CallCountScanner>(counts);
  }

  void visitCall(Call* curr) {
    // can't add a new element in parallel
    assert(counts->count(curr->target) > 0);
    (*counts)[curr->target]++;
  }

private:
  NameCountMap* counts;
};

struct ReorderFunctions : public Pass {
  // Only reorders functions, does not change their contents.
  bool requiresNonNullableLocalFixups() override { return false; }

  void run(Module* module) override {
    NameCountMap counts;
    // fill in info, as we operate on it in parallel (each function to its own
    // entry)
    for (auto& func : module->functions) {
      counts.try_emplace(func->name, 0);
    }
    // find counts on function calls
    CallCountScanner(&counts).run(getPassRunner(), module);
    // find counts on global usages
    if (module->start.is()) {
      counts[module->start]++;
    }
    for (auto& curr : module->exports) {
      if (curr->kind == ExternalKind::Function) {
        counts[*curr->getInternalName()]++;
      }
    }
    ElementUtils::iterAllElementFunctionNames(
      module, [&](Name name) { counts[name]++; });
    // TODO: count all RefFunc as well
    // TODO: count the declaration section as well, which adds another mention
    // sort
    std::sort(module->functions.begin(),
              module->functions.end(),
              [&counts](const std::unique_ptr<Function>& a,
                        const std::unique_ptr<Function>& b) -> bool {
                if (counts[a->name] == counts[b->name]) {
                  return a->name > b->name;
                }
                return counts[a->name] > counts[b->name];
              });
  }
};

Pass* createReorderFunctionsPass() { return new ReorderFunctions(); }

struct ReorderFunctionsByName : public Pass {
  // Only reorders functions, does not change their contents.
  bool requiresNonNullableLocalFixups() override { return false; }

  void run(Module* module) override {
    std::sort(module->functions.begin(),
              module->functions.end(),
              [](const std::unique_ptr<Function>& a,
                 const std::unique_ptr<Function>& b) -> bool {
                return a->name < b->name;
              });
  }
};

Pass* createReorderFunctionsByNamePass() {
  return new ReorderFunctionsByName();
}

} // namespace wasm
