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

#ifndef wasm_ir_local_graph_h
#define wasm_ir_local_graph_h

#include "support/small_set.h"
#include "wasm.h"

namespace wasm {

//
// Finds the connections between local.gets and local.sets, creating
// a graph of those ties. This is useful for "ssa-style" optimization,
// in which you want to know exactly which sets are relevant for a
// a get, so it is as if each get has just one set, logically speaking
// (see the SSA pass for actually creating new local indexes based
// on this).
//
// Note that this is not guaranteed to be precise in unreachable code. That is,
// we do not make the effort to represent the exact sets for each get, and may
// overestimate them (specifically, we may mark the entry value as possible,
// even if unreachability prevents that; doing so helps simplify and optimize
// the code, which we think is worthwhile for the possible annoyance in
// debugging etc.; and it has no downside for optimization, since unreachable
// code will be removed anyhow).
//
// There are two options here, the normal LocalGraph which is eager and computes
// everything up front, which is faster if most things end up needed, and a lazy
// one which computes on demand, which can be much faster if we only need a
// small subset of queries.
//

// Base class for both LocalGraph and LazyLocalGraph (not meant for direct use).
struct LocalGraphBase {
protected:
  // If a module is passed in, it is used to find which features are needed in
  // the computation (for example, if exception handling is disabled, then we
  // can generate a simpler CFG, as calls cannot throw).
  LocalGraphBase(Function* func, Module* module = nullptr)
    : func(func), module(module) {}

public:
  // A set of sets, returned from the query about which sets can be read from a
  // get. Typically only one or two apply there, so this is a small set.
  using Sets = SmallSet<LocalSet*, 2>;

  // Where each get and set is.
  using Locations = std::map<Expression*, Expression**>;

  // A map of each get to the sets relevant to it (i.e., that it can read from).
  using GetSetsMap = std::unordered_map<LocalGet*, Sets>;

  // Sets of gets or sets, that are influenced, returned from get*Influences().
  using SetInfluences = std::unordered_set<LocalGet*>;
  using GetInfluences = std::unordered_set<LocalSet*>;

  using SetInfluencesMap = std::unordered_map<LocalSet*, SetInfluences>;
  using GetInfluencesMap = std::unordered_map<LocalGet*, GetInfluences>;

protected:
  Function* func;
  Module* module;

  std::set<Index> SSAIndexes;
};

struct LocalGraph : public LocalGraphBase {
  LocalGraph(Function* func, Module* module = nullptr);

  // Get the sets relevant for a local.get.
  //
  // A nullptr set means there is no local.set for that value, which means it is
  // the initial value from the function entry: 0 for a var, the received value
  // for a param.
  //
  // Often there is a single set, or a phi or two items, so we use a small set.
  const Sets& getSets(LocalGet* get) const {
    auto iter = getSetsMap.find(get);
    if (iter == getSetsMap.end()) {
      // A missing entry means there is nothing there (and we saved a little
      // space by not putting something there).
      //
      // Use a canonical constant empty set to avoid allocation.
      static const Sets empty;
      return empty;
    }
    return iter->second;
  }

  // We compute the locations of gets and sets while doing the main computation
  // and make it accessible for users, for easy replacing of things without
  // extra work.
  Locations locations;

  // Checks if two gets are equivalent, that is, definitely have the same
  // value.
  bool equivalent(LocalGet* a, LocalGet* b);

  // Optional: compute the influence graphs between sets and gets (useful for
  // algorithms that propagate changes). Set influences are the gets that can
  // read from it; get influences are the sets that can (directly) read from it.
  void computeSetInfluences();
  void computeGetInfluences();

  void computeInfluences() {
    computeSetInfluences();
    computeGetInfluences();
  }

  const SetInfluences& getSetInfluences(LocalSet* set) const {
    auto iter = setInfluences.find(set);
    if (iter == setInfluences.end()) {
      // Use a canonical constant empty set to avoid allocation.
      static const SetInfluences empty;
      return empty;
    }
    return iter->second;
  }
  const GetInfluences& getGetInfluences(LocalGet* get) const {
    auto iter = getInfluences.find(get);
    if (iter == getInfluences.end()) {
      // Use a canonical constant empty set to avoid allocation.
      static const GetInfluences empty;
      return empty;
    }
    return iter->second;
  }

  // Optional: Compute the local indexes that are SSA, in the sense of
  //  * a single set for all the gets for that local index
  //  * the set dominates all the gets (logically implied by the former
  //  property)
  //  * no other set (aside from the zero-init)
  // The third property is not exactly standard SSA, but is useful since we are
  // not in SSA form in our IR. To see why it matters, consider these:
  //
  // x = 0 // zero init
  // [..]
  // x = 10
  // y = x + 20
  // x = 30 // !!!
  // f(y)
  //
  // The !!! line violates that property - it is another set for x, and it may
  // interfere say with replacing f(y) with f(x + 20). Instead, if we know the
  // only other possible set for x is the zero init, then things like the !!!
  // line cannot exist, and it is valid to replace f(y) with f(x + 20). (This
  // could be simpler, but in wasm the zero init always exists.)

  void computeSSAIndexes();

  bool isSSA(Index x);

private:
  GetSetsMap getSetsMap;

  SetInfluencesMap setInfluences;
  GetInfluencesMap getInfluences;
};

// The internal implementation of the flow analysis used to compute things. This
// must be declared in the header so that LazyLocalGraph can declare a unique
// ptr to it, below.
struct LocalGraphFlower;

struct LazyLocalGraph : public LocalGraphBase {
  // We optionally receive an expression class to consider relevant for queries,
  // see below. (Only expressions of this class can be queried later.)
  LazyLocalGraph(Function* func,
                 Module* module = nullptr,
                 std::optional<Expression::Id> queryClass = std::nullopt);
  ~LazyLocalGraph();

  // Similar APIs as in LocalGraph, but lazy versions. Each of them does a
  // lookup, and if there is a missing entry then we did not do the computation
  // yet, and then we do it and memoize it.
  const Sets& getSets(LocalGet* get) const {
    auto iter = getSetsMap.find(get);
    if (iter == getSetsMap.end()) {
      computeGetSets(get);
      iter = getSetsMap.find(get);
      assert(iter != getSetsMap.end());
    }
    return iter->second;
  }
  const SetInfluences& getSetInfluences(LocalSet* set) const {
    auto iter = setInfluences.find(set);
    if (iter == setInfluences.end()) {
      computeSetInfluences(set);
      iter = setInfluences.find(set);
      assert(iter != setInfluences.end());
    }
    return iter->second;
  }
  const GetInfluences& getGetInfluences(LocalGet* get) const {
    if (!getInfluences) {
      computeGetInfluences();
      assert(getInfluences);
    }
    return (*getInfluences)[get];
  }
  bool isSSA(Index index) const {
    auto iter = SSAIndexes.find(index);
    if (iter == SSAIndexes.end()) {
      auto ret = computeSSA(index);
      // The result must have been memoized.
      assert(SSAIndexes.contains(index));
      return ret;
    }
    return iter->second;
  }

  const Locations& getLocations() const {
    if (!locations) {
      computeLocations();
      assert(locations);
    }
    return *locations;
  }

  // Query whether it is valid to move a LocalSet to a new position, that is,
  // that moving it will not alter observable behavior. That means that no
  // Localget is able to observe a different value than before. This returns the
  // set of LocalGets that may do so, that is, the gets for which we detected a
  // problem, hence if the set is empty, the set is valid to move.
  //
  // For example:
  //
  //  1. set
  //  2. get
  //  3. call
  //  4. get
  //
  // If we move the set to the call, then the get on line 2 could observe a
  // different value (the pre-existing value in that local, before line 1), and
  // we'd return that get here.
  //
  // |to| must be of the class |queryClass| that is defined during construction.
  // That is, we must decide ahead of time which places we want to query about
  // moving LocalSets to, and can then issue queries on any of those, in an
  // efficient manner.
  //
  // This assumes that |to| is in a position dominated by |set|, that is we are
  // moving the set "forward". (In particular, that implies that the new
  // position will have monotonically *less* influence than before - we don't
  // need to scan all possible gets of that index in the entire function, we can
  // look only on the gets influenced by the set, and see how the new position
  // behaves regarding them.)
  SetInfluences canMoveSet(LocalSet* set, Expression* to);

private:
  std::optional<Expression::Id> queryClass;

  // These data structures are mutable so that we can memoize.
  mutable GetSetsMap getSetsMap;

  mutable SetInfluencesMap setInfluences;
  // The entire |getInfluences| is computed once the first request for one
  // arrives, so the entire thing is either present or not, unlike setInfluences
  // which is fine-grained. The difference is that the influences of a get may
  // include sets of other indexes, so there is no simple way to lazify that
  // computation.
  mutable std::optional<GetInfluencesMap> getInfluences;
  // A map if indexes to a bool indicating if the index is SSA. If there is no
  // entry, it has not yet been computed.
  mutable std::unordered_map<Index, bool> SSAIndexes;
  mutable std::optional<Locations> locations;

  // Compute the sets for a get and store them on getSetsMap.
  void computeGetSets(LocalGet* get) const;
  // Compute influences for a set and store them on setInfluences.
  void computeSetInfluences(LocalSet* set) const;
  // Compute influences for all gets and store them on getInfluences.
  void computeGetInfluences() const;
  // Compute whether an index is SSA and store that on SSAIndexes.
  bool computeSSA(Index index) const;
  // Compute locations and store them on getInfluences.
  void computeLocations() const;

  // This remains alive as long as we are, so that we can compute things lazily.
  // It is mutable as when we construct this is an internal detail, that does
  // not cause observable differences in API calls.
  mutable std::unique_ptr<LocalGraphFlower> flower;

  // We create |flower| lazily.
  void makeFlower() const;
};

} // namespace wasm

#endif // wasm_ir_local_graph_h
