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

//
// Misc optimizations that are useful for and/or are only valid for
// AssemblyScript output.
//

#include "ir/flat.h"
#include "ir/local-graph.h"
#include "pass.h"
#include "wasm-builder.h"
#include "wasm-traversal.h"
#include "wasm.h"
#include <unordered_map>
#include <unordered_set>
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
#include "wasm-printing.h"
#include <iostream>
#endif

namespace wasm {

namespace PostAssemblyScript {

static Name RETAIN = Name("~lib/rt/pure/__retain");
static Name RELEASE = Name("~lib/rt/pure/__release");
static Name ALLOC = Name("~lib/rt/tlsf/__alloc");
static Name ALLOCARRAY = Name("~lib/rt/__allocArray");

template<typename K, typename V> using Map = std::unordered_map<K, V>;
template<typename T> using Set = std::unordered_set<T>;

// A variant of LocalGraph that considers only assignments when computing
// influences.
//
// This allows us to find locals aliasing a retain, while ignoring other
// influences.
//
// For example, we are interested in
//
//   var a = __retain(X)
//   var b = a;
//   __release(b); // releases X
//
// but not in
//
//  var a = __retain(X);
//  var b = someFunction(a);
//  __release(b);
//  return a;
//
// since the latter releases not 'X' but the reference returned by the call,
// which is usually something else.
struct AliasGraph : LocalGraph {
  AliasGraph(Function* func) : LocalGraph(func) {}
  void computeInfluences() {
    for (auto& pair : locations) {
      auto* curr = pair.first;
      if (auto* set = curr->dynCast<LocalSet>()) {
        if (auto* get = set->value->dynCast<LocalGet>()) {
          getInfluences[get].insert(set);
        }
      } else {
        auto* get = curr->cast<LocalGet>();
        for (auto* set : getSetses[get]) {
          setInfluences[set].insert(get);
        }
      }
    }
  }
};

// Tests if the given call calls retain. Note that this differs from what we
// consider a full retain pattern, which must also set a local.
static bool isRetainCall(Call* expr) {
  // __retain(...)
  return expr->target == RETAIN && expr->type == Type::i32 &&
         expr->operands.size() == 1 && expr->operands[0]->type == Type::i32;
}

// Tests if a local.set is considered to be a full retain pattern.
static bool isRetain(LocalSet* expr) {
  // local.set(X, __retain(...))
  if (auto* call = expr->value->dynCast<Call>()) {
    return isRetainCall(call);
  }
  return false;
}

#ifndef NDEBUG
// Tests if the given location is that of a full retain pattern.
static bool isRetainLocation(Expression** expr) {
  if (expr != nullptr) {
    if (auto localSet = (*expr)->dynCast<LocalSet>()) {
      return isRetain(localSet);
    }
  }
  return false;
}
#endif

// Tests if the given call calls release. Note that this differs from what we
// consider a full release pattern, which must also get a local.
static bool isReleaseCall(Call* expr) {
  // __release(...)
  return expr->target == RELEASE && expr->type == Type::none &&
         expr->operands.size() == 1 && expr->operands[0]->type == Type::i32;
}

// Tests if the given location is that of a full release pattern. Note that
// the local.get is our key when checking for releases to align with
// AliasGraph, and not the outer call, which is also the reason why there is
// no `isRelease` as we can't tell from the local.get alone.
static bool isReleaseLocation(Expression** expr) {
  // __release(local.get(X, ...))
  if (expr != nullptr) {
    if (auto* call = (*expr)->dynCast<Call>()) {
      return isReleaseCall(call) && call->operands[0]->is<LocalGet>();
    }
  }
  return false;
}

// Tests if the given call calls any allocation function.
static bool isAllocCall(Call* expr) {
  return (expr->target == ALLOC || expr->target == ALLOCARRAY) &&
         expr->type == Type::i32;
}

// A pass that eliminates redundant retain and release calls.
//
// Does a cheap traversal first, remembering ARC-style patterns, and goes all-in
// only if it finds any.
//
// This is based on the assumption that the compiler is not allowed to emit
// unbalanced retains or releases, except if
//
// * a value is returned or otherwise escapes in one branch or
// * a branch is being internally unified by the compiler
//
// which we detect below. In turn, we do not have to deal with control
// structures but can instead look for escapes reached (by any alias) using
// AliasGraph.
//
// For example, in code like
//
//   var a = __retain(X);
//   if (cond) {
//     return a;
//   }
//   __release(a);
//  return null;
//
// we cannot eliminate the retain/release pair because the implementation
// dictates that returned references must remain retained for the caller since
// dropping to RC=0 on the boundary would prematurely free the object.
//
// Typical patterns this recognizes are simple pairs of the form
//
//   var a = __retain(X);
//   __release(a);
//
// retains with balanced releases of the form
//
//   var a = __retain(X);
//   if (cond) {
//     __release(a);
//   } else {
//     __release(a);
//   }
//
// releases with balanced retains of the form
//
//   var a;
//   if (cond) {
//     a = __retain(X);
//   } else {
//     a = __retain(Y);
//   }
//   __release(a);
//
// including technically invalid patterns assumed to be not present in compiler
// output, like:
//
//   var b = __retain(a);
//   if (cond) {
//     __release(b); // unbalanced release
//   }
//
// To detect the latter, we'd have to follow control structures around, which
// we don't do since it isn't neccessary / to keep the amount of work minimal.
struct OptimizeARC : public WalkerPass<PostWalker<OptimizeARC>> {

  bool isFunctionParallel() override { return true; }

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

  // Sets that are retains, to location
  Map<LocalSet*, Expression**> retains;

  // Gets that are releases, to location
  Map<LocalGet*, Expression**> releases;

  // Gets that are escapes, i.e. being returned or thrown
  Set<LocalGet*> escapes;

  void visitLocalSet(LocalSet* curr) {
    if (isRetain(curr)) {
      retains[curr] = getCurrentPointer();
    }
  }

  void visitCall(Call* curr) {
    auto** currp = getCurrentPointer();
    if (isReleaseLocation(currp)) {
      releases[curr->operands[0]->cast<LocalGet>()] = currp;
    }
  }

  void visitReturn(Return* curr) {
    // return(local.get(X, ...)) ?
    // indicates that an object is returned from one function and given to
    // another, so releasing it would be invalid.
    auto* value = curr->value;
    if (value) {
      if (auto* localGet = value->dynCast<LocalGet>()) {
        escapes.insert(localGet);
      }
    }
  }

  void visitThrow(Throw* curr) {
    // throw(..., local.get(X, ...), ...) ?
    // indicates that an object is thrown in one function and can be caught
    // anywhere, like in another function, so releasing it would be invalid.
    for (auto* operand : curr->operands) {
      if (auto* localGet = operand->dynCast<LocalGet>()) {
        escapes.insert(localGet);
        break;
      }
    }
  }

  void eliminateRetain(Expression** location) {
    assert(isRetainLocation(location));
    auto* localSet = (*location)->cast<LocalSet>();
    localSet->value = localSet->value->cast<Call>()->operands[0];
  }

  void eliminateRelease(Expression** location) {
    assert(isReleaseLocation(location));
    Builder builder(*getModule());
    *location = builder.makeNop();
  }

  // Tests if a retain reaches an escape and thus is considered necessary.
  bool
  testReachesEscape(LocalSet* retain, AliasGraph& graph, Set<LocalSet*>& seen) {
    for (auto* localGet : graph.setInfluences[retain]) {
      if (releases.find(localGet) != releases.end()) {
        continue;
      }
      if (escapes.find(localGet) != escapes.end()) {
        return true;
      }
      for (auto* localSet : graph.getInfluences[localGet]) {
        if (seen.find(localSet) == seen.end()) {
          seen.insert(localSet);
          if (testReachesEscape(localSet, graph, seen)) {
            return true;
          }
        }
      }
    }
    return false;
  }

  bool testReachesEscape(LocalSet* retain, AliasGraph& graph) {
    Set<LocalSet*> seen;
    return testReachesEscape(retain, graph, seen);
  }

  // Collects all reachable releases of a retain.
  void collectReleases(LocalSet* retain,
                       AliasGraph& graph,
                       Set<Expression**>& found,
                       Set<LocalSet*>& seen) {
    for (auto* localGet : graph.setInfluences[retain]) {
      auto foundRelease = releases.find(localGet);
      if (foundRelease != releases.end()) {
        found.insert(foundRelease->second);
      } else {
        for (auto* localSet : graph.getInfluences[localGet]) {
          if (seen.find(localSet) == seen.end()) {
            seen.insert(localSet);
            collectReleases(localSet, graph, found, seen);
          }
        }
      }
    }
  }

  void collectReleases(LocalSet* retain,
                       AliasGraph& graph,
                       Set<Expression**>& found) {
    Set<LocalSet*> seen;
    collectReleases(retain, graph, found, seen);
  }

  // Given a retain, gets the retained expression
  static Expression* getRetainedExpression(LocalSet* retain) {
    assert(isRetain(retain));
    return retain->value->cast<Call>()->operands[0];
  }

  // Tests if a retained value originates at an allocation and thus is
  // considered necessary.
  bool testRetainsAllocation(Expression* retained,
                             AliasGraph& graph,
                             Set<LocalSet*>& seen) {
    if (auto* call = retained->dynCast<Call>()) {
      if (call->target == ALLOC || call->target == ALLOCARRAY) {
        return true;
      }
    } else {
      if (auto* localGet = retained->dynCast<LocalGet>()) {
        for (auto* localSet : graph.getSetses[localGet]) {
          if (localSet != nullptr) {
            if (seen.find(localSet) == seen.end()) {
              seen.insert(localSet);
              if (testRetainsAllocation(localSet->value, graph, seen)) {
                return true;
              }
            }
          }
        }
      }
    }
    return false;
  }

  bool testRetainsAllocation(Expression* retained, AliasGraph& graph) {
    Set<LocalSet*> seen;
    return testRetainsAllocation(retained, graph, seen);
  }

  // Given a release location, gets the local.get that is our release indicator
  static LocalGet* getReleaseByLocation(Expression** releaseLocation) {
    assert(isReleaseLocation(releaseLocation));
    return (*releaseLocation)->cast<Call>()->operands[0]->cast<LocalGet>();
  }

  // Tests if a release has balanced retains, that is it is being retained in
  // any path leading to the release. For example
  //
  //   var c = somethingElse() || a;
  //   ...
  //
  // which compiles to
  //
  //   if (!(b = somethingElse())) {
  //     b = __retain(a);
  //   }
  //   var c = b;
  //   ...
  //   __release(c);
  //
  // is unbalanced since it reaches a retain and something else. Here, the
  // compiler inserts the retain call because it must unify the two branches
  // since the result of `somethingElse()` is known to be retained for the
  // caller and the other branch must yield a retained value as well.
  bool testBalancedRetains(LocalGet* release,
                           AliasGraph& graph,
                           Map<LocalGet*, bool>& cache,
                           Set<LocalGet*>& seen) {
    auto cached = cache.find(release);
    if (cached != cache.end()) {
      return cached->second;
    }
    for (auto* localSet : graph.getSetses[release]) {
      if (localSet == nullptr) {
        return cache[release] = false;
      }
      if (retains.find(localSet) == retains.end()) {
        if (auto* localGet = localSet->value->dynCast<LocalGet>()) {
          if (seen.find(localGet) == seen.end()) {
            seen.insert(localGet);
            if (!testBalancedRetains(localGet, graph, cache, seen)) {
              return cache[release] = false;
            }
          } else {
            return cache[release] = false;
          }
        } else {
          return cache[release] = false;
        }
      }
    }
    return cache[release] = true;
  }

  bool testBalancedRetains(LocalGet* release,
                           AliasGraph& graph,
                           Map<LocalGet*, bool>& cache) {
    Set<LocalGet*> seen;
    return testBalancedRetains(release, graph, cache, seen);
  }

  void doWalkFunction(Function* func) {
    Flat::verifyFlatness(func);
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
    std::cerr << "[PostAssemblyScript::OptimizeARC] walking " << func->name
              << "\n";
#endif
    super::doWalkFunction(func);
    if (retains.empty()) {
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
      std::cerr << "  no ARC code\n";
#endif
      return;
    }

    AliasGraph graph(func);
    graph.computeInfluences();

    Set<Expression**> redundantRetains;
    Set<Expression**> redundantReleases;
    Map<LocalGet*, bool> balancedRetainsCache;

    // For each retain, check that it
    //
    // * doesn't reach an escape
    // * doesn't retain an allocation
    // * reaches at least one release
    // * reaches only releases with balanced retains
    //
    for (auto& pair : retains) {
      auto* retain = pair.first;
      auto** retainLocation = pair.second;
      if (!testReachesEscape(retain, graph)) {
        if (!testRetainsAllocation(getRetainedExpression(retain), graph)) {
          Set<Expression**> releaseLocations;
          collectReleases(retain, graph, releaseLocations);
          if (!releaseLocations.empty()) {
            bool allBalanced = true;
            for (auto** releaseLocation : releaseLocations) {
              if (!testBalancedRetains(getReleaseByLocation(releaseLocation),
                                       graph,
                                       balancedRetainsCache)) {
                allBalanced = false;
                break;
              }
            }
            if (allBalanced) {
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
              std::cerr << "  eliminating ";
              WasmPrinter::printExpression(retain, std::cerr, true);
              std::cerr << " reaching\n";
#endif
              redundantRetains.insert(retainLocation);
              for (auto** getLocation : releaseLocations) {
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
                std::cerr << "    ";
                WasmPrinter::printExpression(*getLocation, std::cerr, true);
                std::cerr << "\n";
#endif
                redundantReleases.insert(getLocation);
              }
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
            } else {
              std::cerr << "  cannot eliminate ";
              WasmPrinter::printExpression(retain, std::cerr, true);
              std::cerr << " - unbalanced\n";
#endif
            }
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
          } else {
            std::cerr << "  cannot eliminate ";
            WasmPrinter::printExpression(retain, std::cerr, true);
            std::cerr << " - zero releases\n";
#endif
          }
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
        } else {
          std::cerr << "  cannot eliminate ";
          WasmPrinter::printExpression(retain, std::cerr, true);
          std::cerr << " - retains allocation\n";
#endif
        }
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
      } else {
        std::cerr << "  cannot eliminate ";
        WasmPrinter::printExpression(retain, std::cerr, true);
        std::cerr << " - reaches return\n";
#endif
      }
    }
    for (auto** location : redundantRetains) {
      eliminateRetain(location);
    }
    for (auto** location : redundantReleases) {
      eliminateRelease(location);
    }
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
    std::cerr << "  eliminated " << redundantRetains.size() << "/"
              << retains.size() << " retains and " << redundantReleases.size()
              << "/" << releases.size() << " releases\n";
#endif
  }
};

// Eliminating retains and releases makes it more likely that other passes lead
// to collapsed release/retain pairs that are not full retain or release
// patterns, and this pass finalizes such pairs. Typical patterns are entire
// unnecessary allocations of the form
//
//   __release(__retain(__alloc(...));
//
// otherwise unnecessary pairs of the form
//
//   __release(__retain(...));
//
// or retains/releases of constants which indicate data in static memory which
// are unnecessary to refcount:
//
//  __retain("staticString");
//
//  __release("staticString");
//
struct FinalizeARC : public WalkerPass<PostWalker<FinalizeARC>> {

  bool isFunctionParallel() override { return true; }

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

  uint32_t eliminatedAllocations = 0;
  uint32_t eliminatedRetains = 0;
  uint32_t eliminatedReleases = 0;

  void visitCall(Call* curr) {
    if (isReleaseCall(curr)) {
      if (auto* releasedCall = curr->operands[0]->dynCast<Call>()) {
        if (isRetainCall(releasedCall)) {
          if (auto* retainedCall = releasedCall->operands[0]->dynCast<Call>()) {
            if (isAllocCall(retainedCall)) {
              // __release(__retain(__alloc(...))) - unnecessary allocation
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
              std::cerr << "  finalizing ";
              WasmPrinter::printExpression(curr, std::cerr, true);
              std::cerr << " - unnecessary allocation\n";
#endif
              Builder builder(*getModule());
              replaceCurrent(builder.makeNop());
              ++eliminatedAllocations;
              ++eliminatedRetains;
              ++eliminatedReleases;
              return;
            }
          }
          // __release(__retain(...)) - unnecessary pair
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
          std::cerr << "  finalizing ";
          WasmPrinter::printExpression(curr, std::cerr, true);
          std::cerr << " - unnecessary pair\n";
#endif
          Builder builder(*getModule());
          replaceCurrent(builder.makeDrop(releasedCall->operands[0]));
          ++eliminatedRetains;
          ++eliminatedReleases;
        }
      } else if (curr->operands[0]->is<Const>()) {
        // __release(42) - unnecessary static release
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
        std::cerr << "  finalizing ";
        WasmPrinter::printExpression(curr, std::cerr, true);
        std::cerr << " - static release\n";
#endif
        Builder builder(*getModule());
        replaceCurrent(builder.makeNop());
        ++eliminatedReleases;
      }
    } else if (isRetainCall(curr)) {
      if (auto* retainedConst = curr->operands[0]->dynCast<Const>()) {
        // __retain(42) - unnecessary static retain
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
        std::cerr << "  finalizing ";
        WasmPrinter::printExpression(curr, std::cerr, true);
        std::cerr << " - static retain\n";
#endif
        replaceCurrent(retainedConst);
        ++eliminatedRetains;
      }
    }
  }

  void doWalkFunction(Function* func) {
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
    std::cerr << "[PostAssemblyScript::FinalizeARC] walking " << func->name
              << "\n";
#endif
    super::doWalkFunction(func);
#ifdef POST_ASSEMBLYSCRIPT_DEBUG
    if (eliminatedAllocations > 0 || eliminatedRetains > 0 ||
        eliminatedReleases > 0) {
      std::cerr << "  finalized " << eliminatedAllocations << " allocations, "
                << eliminatedRetains << " retains and" << eliminatedReleases
                << " releases\n";
    } else {
      std::cerr << "  nothing to do\n";
    }
#endif
  }
};

} // namespace PostAssemblyScript

// declare passes

Pass* createPostAssemblyScriptPass() {
  return new PostAssemblyScript::OptimizeARC();
}

Pass* createPostAssemblyScriptFinalizePass() {
  return new PostAssemblyScript::FinalizeARC();
}

} // namespace wasm
