/*
 * 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 <wasm.h>
#include <pass.h>

namespace wasm {

struct RemoveUnusedNames : public WalkerPass<PostWalker<RemoveUnusedNames, Visitor<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 visitBreak(Break *curr) {
    branchesSeen[curr->name].insert(curr);
  }

  void visitSwitch(Switch *curr) {
    for (auto name : curr->targets) {
      branchesSeen[name].insert(curr);
    }
    branchesSeen[curr->default_].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()) {
        // 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) {
          if (Break* br = branch->dynCast<Break>()) {
            if (br->name == curr->name) br->name = child->name;
          } else if (Switch* sw = branch->dynCast<Switch>()) {
            for (auto& target : sw->targets) {
              if (target == curr->name) target = child->name;
            }
            if (sw->default_ == curr->name) sw->default_ = child->name;
          } else {
            WASM_UNREACHABLE();
          }
        }
        replaceCurrent(child);
      }
    }
    handleBreakTarget(curr->name);
  }

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

  void visitFunction(Function *curr) {
    assert(branchesSeen.empty());
  }
};

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

} // namespace wasm
