/*
 * 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->isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
  }
  if (auto* store = curr->dynCast<Store>()) {
    return store->isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
  }
  if (curr->is<AtomicRMW>() || 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);

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

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