/*
 * Copyright 2015 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.
 */

//
// Removes names from locations that are never branched to, and
// merge names when possible (by merging their blocks)
//

#include <ir/branch-utils.h>
#include <pass.h>
#include <shared-constants.h>
#include <wasm.h>

namespace wasm {

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

  Pass* create() override { return new RemoveUnusedNames; }

  // We maintain a list of branches that we saw in children, then when we reach
  // a parent block, we know if it was branched to
  std::map<Name, std::set<Expression*>> branchesSeen;

  void visitExpression(Expression* curr) {
    BranchUtils::operateOnScopeNameUses(curr, [&](Name& name) {
      if (name.is()) {
        branchesSeen[name].insert(curr);
      }
    });
  }

  void handleBreakTarget(Name& name) {
    if (name.is()) {
      if (branchesSeen.find(name) == branchesSeen.end()) {
        name = Name();
      } else {
        branchesSeen.erase(name);
      }
    }
  }

  void visitBlock(Block* curr) {
    if (curr->name.is() && curr->list.size() == 1) {
      auto* child = curr->list[0]->dynCast<Block>();
      if (child && child->name.is() && child->type == curr->type) {
        // we have just one child, this block, so breaking out of it goes to the
        // same place as breaking out of us, we just need one name (and block)
        auto& branches = branchesSeen[curr->name];
        for (auto* branch : branches) {
          BranchUtils::replacePossibleTarget(branch, curr->name, child->name);
        }
        child->finalize(child->type);
        replaceCurrent(child);
      }
    }
    handleBreakTarget(curr->name);
  }

  void visitLoop(Loop* curr) {
    handleBreakTarget(curr->name);
    if (!curr->name.is() && curr->body->type == curr->type) {
      replaceCurrent(curr->body);
    }
  }

  void visitTry(Try* curr) {
    handleBreakTarget(curr->name);
    // Try has not just a break target but also an optional delegate with a
    // target name, so call the generic visitor as well to handle that.
    visitExpression(curr);
  }

  void visitFunction(Function* curr) {
    // When we reach the function body we can erase delegations to the caller.
    branchesSeen.erase(DELEGATE_CALLER_TARGET);
    assert(branchesSeen.empty());
  }
};

Pass* createRemoveUnusedNamesPass() { return new RemoveUnusedNames(); }

} // namespace wasm
