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

#ifndef wasm_ir_properties_h
#define wasm_ir_properties_h

#include "ir/bits.h"
#include "ir/effects.h"
#include "ir/match.h"
#include "wasm.h"

namespace wasm::Properties {

inline bool isSymmetric(Binary* binary) {
  switch (binary->op) {
    case AddInt32:
    case MulInt32:
    case AndInt32:
    case OrInt32:
    case XorInt32:
    case EqInt32:
    case NeInt32:

    case AddInt64:
    case MulInt64:
    case AndInt64:
    case OrInt64:
    case XorInt64:
    case EqInt64:
    case NeInt64:

    case MinFloat32:
    case MaxFloat32:
    case EqFloat32:
    case NeFloat32:
    case MinFloat64:
    case MaxFloat64:
    case EqFloat64:
    case NeFloat64:
      return true;

    default:
      return false;
  }
}

inline bool isControlFlowStructure(Expression* curr) {
  return curr->is<Block>() || curr->is<If>() || curr->is<Loop>() ||
         curr->is<Try>() || curr->is<TryTable>();
}

// Check if an expression is a control flow construct with a name, which implies
// it may have breaks or delegates to it.
inline bool isNamedControlFlow(Expression* curr) {
  if (auto* block = curr->dynCast<Block>()) {
    return block->name.is();
  } else if (auto* loop = curr->dynCast<Loop>()) {
    return loop->name.is();
  } else if (auto* try_ = curr->dynCast<Try>()) {
    return try_->name.is();
  }
  return false;
}

// A constant expression is something like a Const: it has a fixed value known
// at compile time, and passes that propagate constants can try to propagate it.
// Constant expressions are also allowed in global initializers in wasm. Also
// when two constant expressions compare equal at compile time, their values at
// runtime will be equal as well. TODO: combine this with
// isValidInConstantExpression or find better names(#4845)
inline bool isSingleConstantExpression(const Expression* curr) {
  if (auto* refAs = curr->dynCast<RefAs>()) {
    if (refAs->op == ExternConvertAny || refAs->op == AnyConvertExtern) {
      return isSingleConstantExpression(refAs->value);
    }
  }
  return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>() ||
         curr->is<StringConst>();
}

inline bool isConstantExpression(const Expression* curr) {
  if (isSingleConstantExpression(curr)) {
    return true;
  }
  if (auto* tuple = curr->dynCast<TupleMake>()) {
    for (auto* op : tuple->operands) {
      if (!isSingleConstantExpression(op)) {
        return false;
      }
    }
    return true;
  }
  return false;
}

inline bool isBranch(const Expression* curr) {
  return curr->is<Break>() || curr->is<Switch>() || curr->is<BrOn>();
}

inline Literal getLiteral(const Expression* curr) {
  if (auto* c = curr->dynCast<Const>()) {
    return c->value;
  } else if (auto* n = curr->dynCast<RefNull>()) {
    return Literal(n->type);
  } else if (auto* r = curr->dynCast<RefFunc>()) {
    return Literal::makeFunc(r->func, r->type);
  } else if (auto* i = curr->dynCast<RefI31>()) {
    if (auto* c = i->value->dynCast<Const>()) {
      return Literal::makeI31(c->value.geti32(),
                              i->type.getHeapType().getShared());
    }
  } else if (auto* s = curr->dynCast<StringConst>()) {
    return Literal(s->string.toString());
  } else if (auto* r = curr->dynCast<RefAs>()) {
    if (r->op == ExternConvertAny) {
      return getLiteral(r->value).externalize();
    } else if (r->op == AnyConvertExtern) {
      return getLiteral(r->value).internalize();
    }
  }
  WASM_UNREACHABLE("non-constant expression");
}

inline Literals getLiterals(const Expression* curr) {
  if (isSingleConstantExpression(curr)) {
    return {getLiteral(curr)};
  } else if (auto* tuple = curr->dynCast<TupleMake>()) {
    Literals literals;
    for (auto* op : tuple->operands) {
      literals.push_back(getLiteral(op));
    }
    return literals;
  } else {
    WASM_UNREACHABLE("non-constant expression");
  }
}

// Check if an expression is a sign-extend, and if so, returns the value
// that is extended, otherwise nullptr
inline Expression* getSignExtValue(Expression* curr) {
  // We only care about i32s here, and ignore i64s, unreachables, etc.
  if (curr->type != Type::i32) {
    return nullptr;
  }
  if (auto* unary = curr->dynCast<Unary>()) {
    if (unary->op == ExtendS8Int32 || unary->op == ExtendS16Int32) {
      return unary->value;
    }
    return nullptr;
  }
  using namespace Match;
  int32_t leftShift = 0, rightShift = 0;
  Expression* extended = nullptr;
  if (matches(curr,
              binary(ShrSInt32,
                     binary(ShlInt32, any(&extended), i32(&leftShift)),
                     i32(&rightShift))) &&
      leftShift == rightShift && leftShift != 0) {
    return extended;
  }
  return nullptr;
}

// gets the size of the sign-extended value
inline Index getSignExtBits(Expression* curr) {
  assert(curr->type == Type::i32);
  if (auto* unary = curr->dynCast<Unary>()) {
    switch (unary->op) {
      case ExtendS8Int32:
        return 8;
      case ExtendS16Int32:
        return 16;
      default:
        WASM_UNREACHABLE("invalid unary operation");
    }
  } else {
    auto* rightShift = curr->cast<Binary>()->right;
    return 32 - Bits::getEffectiveShifts(rightShift);
  }
}

// Check if an expression is almost a sign-extend: perhaps the inner shift
// is too large. We can split the shifts in that case, which is sometimes
// useful (e.g. if we can remove the signext)
inline Expression* getAlmostSignExt(Expression* curr) {
  using namespace Match;
  int32_t leftShift = 0, rightShift = 0;
  Expression* extended = nullptr;
  if (matches(curr,
              binary(ShrSInt32,
                     binary(ShlInt32, any(&extended), i32(&leftShift)),
                     i32(&rightShift))) &&
      Bits::getEffectiveShifts(rightShift, Type::i32) <=
        Bits::getEffectiveShifts(leftShift, Type::i32) &&
      rightShift != 0) {
    return extended;
  }
  return nullptr;
}

// gets the size of the almost sign-extended value, as well as the
// extra shifts, if any
inline Index getAlmostSignExtBits(Expression* curr, Index& extraLeftShifts) {
  auto* leftShift = curr->cast<Binary>()->left->cast<Binary>()->right;
  auto* rightShift = curr->cast<Binary>()->right;
  extraLeftShifts =
    Bits::getEffectiveShifts(leftShift) - Bits::getEffectiveShifts(rightShift);
  return getSignExtBits(curr);
}

// Check if an expression is a zero-extend, and if so, returns the value
// that is extended, otherwise nullptr
inline Expression* getZeroExtValue(Expression* curr) {
  // We only care about i32s here, and ignore i64s, unreachables, etc.
  if (curr->type != Type::i32) {
    return nullptr;
  }
  using namespace Match;
  int32_t mask = 0;
  Expression* extended = nullptr;
  if (matches(curr, binary(AndInt32, any(&extended), i32(&mask))) &&
      Bits::getMaskedBits(mask) != 0) {
    return extended;
  }
  return nullptr;
}

// gets the size of the sign-extended value
inline Index getZeroExtBits(Expression* curr) {
  assert(curr->type == Type::i32);
  int32_t mask = curr->cast<Binary>()->right->cast<Const>()->value.geti32();
  return Bits::getMaskedBits(mask);
}

// Returns a falling-through value, that is, it looks through a local.tee
// and other operations that receive a value and let it flow through them. If
// there is no value falling through, returns the node itself (as that is the
// value that trivially falls through, with 0 steps in the middle).
//
// Note that this returns the value that would fall through if one does in fact
// do so. For example, the final element in a block may not fall through if we
// hit a return or a trap or an exception is thrown before we get there.
//
// This method returns the 'immediate' fallthrough, that is, the immediate
// child of this expression. See getFallthrough for a method that looks all the
// way to the final value falling through, potentially through multiple
// intermediate expressions.
//
// Behavior wrt tee/br_if is customizable, since in some cases we do not want to
// look through them (for example, the type of a tee is related to the local,
// not the value, so if we returned the fallthrough of the tee we'd have a
// possible difference between the type in the IR and the type of the value,
// which some cases care about; the same for a br_if, whose type is related to
// the branch target).
//
// TODO: Receive a Module instead of FeatureSet, to pass to EffectAnalyzer?

enum class FallthroughBehavior { AllowTeeBrIf, NoTeeBrIf };

inline Expression** getImmediateFallthroughPtr(
  Expression** currp,
  const PassOptions& passOptions,
  Module& module,
  FallthroughBehavior behavior = FallthroughBehavior::AllowTeeBrIf) {
  auto* curr = *currp;
  // If the current node is unreachable, there is no value
  // falling through.
  if (curr->type == Type::unreachable) {
    return currp;
  }
  if (auto* set = curr->dynCast<LocalSet>()) {
    if (set->isTee() && behavior == FallthroughBehavior::AllowTeeBrIf) {
      return &set->value;
    }
  } else if (auto* block = curr->dynCast<Block>()) {
    // if no name, we can't be broken to, and then can look at the fallthrough
    if (!block->name.is() && block->list.size() > 0) {
      return &block->list.back();
    }
  } else if (auto* loop = curr->dynCast<Loop>()) {
    return &loop->body;
  } else if (auto* iff = curr->dynCast<If>()) {
    if (iff->ifFalse) {
      // Perhaps just one of the two actually returns.
      if (iff->ifTrue->type == Type::unreachable) {
        return &iff->ifFalse;
      } else if (iff->ifFalse->type == Type::unreachable) {
        return &iff->ifTrue;
      }
    }
  } else if (auto* br = curr->dynCast<Break>()) {
    // Note that we must check for the ability to reorder the condition and the
    // value, as the value is first, which would be a problem here:
    //
    //  (br_if ..
    //    (local.get $x)    ;; value
    //    (tee_local $x ..) ;; condition
    //  )
    //
    // We must not say that the fallthrough value is $x, since it is the
    // *earlier* value of $x before the tee that is passed out. But, if we can
    // reorder then that means that the value could have been last and so we do
    // know the fallthrough in that case.
    if (br->condition && br->value &&
        behavior == FallthroughBehavior::AllowTeeBrIf &&
        EffectAnalyzer::canReorder(
          passOptions, module, br->condition, br->value)) {
      return &br->value;
    }
  } else if (auto* tryy = curr->dynCast<Try>()) {
    if (!EffectAnalyzer(passOptions, module, tryy->body).throws()) {
      return &tryy->body;
    }
  } else if (auto* as = curr->dynCast<RefCast>()) {
    return &as->ref;
  } else if (auto* as = curr->dynCast<RefAs>()) {
    // Extern conversions are not casts and actually produce new values.
    // Treating them as fallthroughs would lead to misoptimizations of
    // subsequent casts.
    if (as->op != AnyConvertExtern && as->op != ExternConvertAny) {
      return &as->value;
    }
  } else if (auto* br = curr->dynCast<BrOn>()) {
    return &br->ref;
  }
  return currp;
}

inline Expression* getImmediateFallthrough(
  Expression* curr,
  const PassOptions& passOptions,
  Module& module,
  FallthroughBehavior behavior = FallthroughBehavior::AllowTeeBrIf) {
  return *getImmediateFallthroughPtr(&curr, passOptions, module, behavior);
}

// Similar to getImmediateFallthrough, but looks through multiple children to
// find the final value that falls through.
inline Expression* getFallthrough(
  Expression* curr,
  const PassOptions& passOptions,
  Module& module,
  FallthroughBehavior behavior = FallthroughBehavior::AllowTeeBrIf) {
  while (1) {
    auto* next = getImmediateFallthrough(curr, passOptions, module, behavior);
    if (next == curr) {
      return curr;
    }
    curr = next;
  }
}

// Look at all the intermediate fallthrough expressions and return the most
// precise type we know this value will have.
inline Type getFallthroughType(Expression* curr,
                               const PassOptions& passOptions,
                               Module& module) {
  Type type = curr->type;
  if (!type.isRef()) {
    // Only reference types can be improved (excepting improvements to
    // unreachable, which we leave to refinalization).
    // TODO: Handle tuples if that ever becomes important.
    return type;
  }
  while (1) {
    auto* next = getImmediateFallthrough(curr, passOptions, module);
    if (next == curr) {
      return type;
    }
    type = Type::getGreatestLowerBound(type, next->type);
    if (type == Type::unreachable) {
      return type;
    }
    curr = next;
  }
}

// Find the best fallthrough value ordered by refinement of heaptype, refinement
// of nullability, and closeness to the current expression. The type of the
// expression this function returns may be nullable even if `getFallthroughType`
// is non-nullable, but the heap type will definitely match.
inline Expression** getMostRefinedFallthrough(Expression** currp,
                                              const PassOptions& passOptions,
                                              Module& module) {
  Expression* curr = *currp;
  if (!curr->type.isRef()) {
    return currp;
  }
  auto bestType = curr->type.getHeapType();
  auto bestExactness = curr->type.getExactness();
  auto bestNullability = curr->type.getNullability();
  auto** bestp = currp;
  while (1) {
    curr = *currp;
    auto** nextp =
      Properties::getImmediateFallthroughPtr(currp, passOptions, module);
    auto* next = *nextp;
    if (next == curr || next->type == Type::unreachable) {
      return bestp;
    }
    assert(next->type.isRef());
    auto nextType = next->type.getHeapType();
    auto nextExactness = next->type.getExactness();
    auto nextNullability = next->type.getNullability();
    if (nextType == bestType && nextExactness == bestExactness) {
      // Heap types match: refine nullability if possible.
      if (bestNullability == Nullable && nextNullability == NonNullable) {
        bestp = nextp;
        bestNullability = NonNullable;
      }
    } else if ((nextType != bestType &&
                HeapType::isSubType(nextType, bestType)) ||
               (nextType == bestType && nextExactness == Exact &&
                bestExactness == Inexact)) {
      // Refine heap, resetting nullability.
      bestp = nextp;
      bestType = nextType;
      bestExactness = nextExactness;
      bestNullability = nextNullability;
    }
    currp = nextp;
  }
}

inline Index getNumChildren(Expression* curr) {
  Index ret = 0;

#define DELEGATE_ID curr->_id

#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>();

#define DELEGATE_GET_FIELD(id, field) cast->field

#define DELEGATE_FIELD_CHILD(id, field) ret++;

#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)                               \
  if (cast->field) {                                                           \
    ret++;                                                                     \
  }

#define DELEGATE_FIELD_INT(id, field)
#define DELEGATE_FIELD_LITERAL(id, field)
#define DELEGATE_FIELD_NAME(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)

#include "wasm-delegations-fields.def"

  return ret;
}

// Returns whether the resulting value here must fall through without being
// modified. For example, a tee always does so. That is, this returns false if
// and only if the return value may have some computation performed on it to
// change it from the inputs the instruction receives.
// This differs from getFallthrough() which returns a single value that falls
// through - here if more than one value can fall through, like in if-else,
// we can return true. That is, there we care about a value falling through and
// for us to get that actual value to look at; here we just care whether the
// value falls through without being changed, even if it might be one of
// several options.
inline bool isResultFallthrough(Expression* curr) {
  // Note that we don't check if there is a return value here; the node may be
  // unreachable, for example, but then there is no meaningful answer to give
  // anyhow.
  return curr->is<LocalSet>() || curr->is<Block>() || curr->is<If>() ||
         curr->is<Loop>() || curr->is<Try>() || curr->is<TryTable>() ||
         curr->is<Select>() || curr->is<Break>();
}

inline bool canEmitSelectWithArms(Expression* ifTrue, Expression* ifFalse) {
  // A select only allows a single value in its arms in the spec:
  // https://webassembly.github.io/spec/core/valid/instructions.html#xref-syntax-instructions-syntax-instr-parametric-mathsf-select-t-ast
  return ifTrue->type.isSingle() && ifFalse->type.isSingle();
}

// If this instruction accesses memory or the heap, or otherwise participates in
// shared memory synchronization, return the memory order corresponding to the
// kind of synchronization it does. Return MemoryOrder::Unordered if there is no
// synchronization. Does not look at children.
inline MemoryOrder getMemoryOrder(Expression* curr) {
  if (auto* get = curr->dynCast<StructGet>()) {
    return get->order;
  }
  if (auto* set = curr->dynCast<StructSet>()) {
    return set->order;
  }
  if (auto* load = curr->dynCast<Load>()) {
    return load->order;
  }
  if (auto* store = curr->dynCast<Store>()) {
    return store->order;
  }
  if (auto* rmw = curr->dynCast<AtomicRMW>()) {
    return rmw->order;
  }
  if (auto* cmpxchg = curr->dynCast<AtomicCmpxchg>()) {
    return cmpxchg->order;
  }
  if (curr->is<AtomicWait>() || curr->is<AtomicNotify>() ||
      curr->is<AtomicFence>()) {
    return MemoryOrder::SeqCst;
  }
  return MemoryOrder::Unordered;
}

// Whether this instruction will be unwritable in the text and binary formats
// because it requires a type index immediate giving the type of a child that
// has unreachable or null type, and therefore does not have a type index.
inline bool hasUnwritableTypeImmediate(Expression* curr) {
#define DELEGATE_ID curr->_id

#define DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(id, field)                        \
  if (curr->cast<id>()->field) {                                               \
    auto type = curr->cast<id>()->field->type;                                 \
    if (type == Type::unreachable || type.isNull()) {                          \
      return true;                                                             \
    }                                                                          \
  }

#define DELEGATE_FIELD_CHILD(id, field)
#define DELEGATE_FIELD_CHILD_VECTOR(id, field)
#define DELEGATE_FIELD_INT(id, field)
#define DELEGATE_FIELD_INT_ARRAY(id, field)
#define DELEGATE_FIELD_INT_VECTOR(id, field)
#define DELEGATE_FIELD_LITERAL(id, field)
#define DELEGATE_FIELD_NAME(id, field)
#define DELEGATE_FIELD_NAME_VECTOR(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_TYPE_VECTOR(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)

#include "wasm-delegations-fields.def"

  return false;
}

// A "generative" expression is one that can generate different results for the
// same inputs, and that difference is *not* explained by other expressions that
// interact with this one. This is an intrinsic/internal property of the
// expression.
//
// To see the issue more concretely, consider these:
//
//    x = load(100);
//    ..
//    y = load(100);
//
//  versus
//
//    x = struct.new();
//    ..
//    y = struct.new();
//
// Are x and y identical in both cases? For loads, we can look at the code
// in ".." to see: if there are no possible stores to memory, then the
// result is identical (and we have EffectAnalyzer for that). For the GC
// allocations, though, it doesn't matter what is in "..": there is nothing
// in the wasm that we can check to find out if the results are the same or
// not. (In fact, in this case they are always not the same.) So the
// generativity is "intrinsic" to the expression and it is because each call to
// struct.new generates a new value.
//
// Thus, loads are nondeterministic but not generative, while GC allocations
// are in fact generative. Note that "generative" need not mean "allocation" as
// if wasm were to add "get current time" or "get a random number" instructions
// then those would also be generative - generating a new current time value or
// a new random number on each execution, respectively.
//
//  * Note that NaN nondeterminism is ignored here. It is a valid wasm
//    implementation to have deterministic NaN behavior, and we optimize under
//    that simplifying assumption.
//  * Note that calls are ignored here. In theory this concept could be defined
//    either way for them - that is, we could potentially define them as
//    generative, as they might contain such an instruction, or we could define
//    this property as only looking at code in the current function. We choose
//    the latter because calls are already handled best in other manners (using
//    EffectAnalyzer).
//
bool isGenerative(Expression* curr, Function* func, Module& wasm);

// As above, but only checks |curr| and not children.
bool isShallowlyGenerative(Expression* curr, Function* func, Module& wasm);

// Whether this expression is valid in a context where WebAssembly requires a
// constant expression, such as a global initializer.
bool isValidConstantExpression(Module& wasm, Expression* expr);

} // namespace wasm::Properties

#endif // wasm_ir_properties_h
