//===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Defines a driver for translating Wasm bitcode into PNaCl bitcode.
///
/// The translator uses V8's WebAssembly decoder to handle the binary Wasm
/// format but replaces the usual TurboFan builder with a new PNaCl builder.
///
//===----------------------------------------------------------------------===//

#if ALLOW_WASM

#include "WasmTranslator.h"

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#endif // __clang__
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif // defined(__GNUC__) && !defined(__clang__)

#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/zone.h"

#include "src/bit-vector.h"

#include "src/wasm/ast-decoder-impl.h"

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif // defined(__GNUC__) && !defined(__clang__)

#include "IceCfgNode.h"
#include "IceGlobalInits.h"

using namespace std;
using namespace Ice;
using namespace v8::internal;
using namespace v8::internal::wasm;
using v8::internal::wasm::DecodeWasmModule;

#undef LOG
#define LOG(Expr) log([&](Ostream &out) { Expr; })

namespace {
// 64KB
const uint32_t WASM_PAGE_SIZE = 64 << 10;

std::string toStdString(WasmName Name) {
  return std::string(Name.name, Name.length);
}

Ice::Type toIceType(wasm::LocalType Type) {
  switch (Type) {
  case MachineRepresentation::kNone:
    llvm::report_fatal_error("kNone type not supported");
  case MachineRepresentation::kBit:
    return IceType_i1;
  case MachineRepresentation::kWord8:
    return IceType_i8;
  case MachineRepresentation::kWord16:
    return IceType_i16;
  case MachineRepresentation::kWord32:
    return IceType_i32;
  case MachineRepresentation::kWord64:
    return IceType_i64;
  case MachineRepresentation::kFloat32:
    return IceType_f32;
  case MachineRepresentation::kFloat64:
    return IceType_f64;
  case MachineRepresentation::kSimd128:
    llvm::report_fatal_error("ambiguous SIMD type");
  case MachineRepresentation::kTagged:
    llvm::report_fatal_error("kTagged type not supported");
  }
  llvm::report_fatal_error("unexpected type");
}

Ice::Type toIceType(v8::internal::MachineType Type) {
  // TODO (eholk): reorder these based on expected call frequency.
  if (Type == MachineType::Int32()) {
    return IceType_i32;
  }
  if (Type == MachineType::Uint32()) {
    return IceType_i32;
  }
  if (Type == MachineType::Int8()) {
    return IceType_i8;
  }
  if (Type == MachineType::Uint8()) {
    return IceType_i8;
  }
  if (Type == MachineType::Int16()) {
    return IceType_i16;
  }
  if (Type == MachineType::Uint16()) {
    return IceType_i16;
  }
  if (Type == MachineType::Int64()) {
    return IceType_i64;
  }
  if (Type == MachineType::Uint64()) {
    return IceType_i64;
  }
  if (Type == MachineType::Float32()) {
    return IceType_f32;
  }
  if (Type == MachineType::Float64()) {
    return IceType_f64;
  }
  llvm::report_fatal_error("Unsupported MachineType");
}

std::string fnNameFromId(uint32_t Id) {
  return std::string("fn") + to_string(Id);
}

std::string getFunctionName(const WasmModule *Module, uint32_t func_index) {
  // Try to find the function name in the export table
  for (const auto Export : Module->export_table) {
    if (Export.func_index == func_index) {
      return "__szwasm_" + toStdString(Module->GetName(Export.name_offset,
                                                       Export.name_length));
    }
  }
  return fnNameFromId(func_index);
}

} // end of anonymous namespace

/// This class wraps either an Operand or a CfgNode.
///
/// Turbofan's sea of nodes representation only has nodes for values, control
/// flow, etc. In Subzero these concepts are all separate. This class lets V8's
/// Wasm decoder treat Subzero objects as though they are all the same.
class OperandNode {
  static constexpr uintptr_t NODE_FLAG = 1;
  static constexpr uintptr_t UNDEF_PTR = (uintptr_t)-1;

  uintptr_t Data = UNDEF_PTR;

public:
  OperandNode() = default;
  explicit OperandNode(Operand *Operand)
      : Data(reinterpret_cast<uintptr_t>(Operand)) {}
  explicit OperandNode(CfgNode *Node)
      : Data(reinterpret_cast<uintptr_t>(Node) | NODE_FLAG) {}
  explicit OperandNode(nullptr_t) : Data(UNDEF_PTR) {}

  operator Operand *() const {
    if (UNDEF_PTR == Data) {
      return nullptr;
    }
    if (!isOperand()) {
      llvm::report_fatal_error("This OperandNode is not an Operand");
    }
    return reinterpret_cast<Operand *>(Data);
  }

  operator CfgNode *() const {
    if (UNDEF_PTR == Data) {
      return nullptr;
    }
    if (!isCfgNode()) {
      llvm::report_fatal_error("This OperandNode is not a CfgNode");
    }
    return reinterpret_cast<CfgNode *>(Data & ~NODE_FLAG);
  }

  explicit operator bool() const { return (Data != UNDEF_PTR) && Data; }
  bool operator==(const OperandNode &Rhs) const {
    return (Data == Rhs.Data) ||
           (UNDEF_PTR == Data && (Rhs.Data == 0 || Rhs.Data == NODE_FLAG)) ||
           (UNDEF_PTR == Rhs.Data && (Data == 0 || Data == NODE_FLAG));
  }
  bool operator!=(const OperandNode &Rhs) const { return !(*this == Rhs); }

  bool isOperand() const { return (Data != UNDEF_PTR) && !(Data & NODE_FLAG); }
  bool isCfgNode() const { return (Data != UNDEF_PTR) && (Data & NODE_FLAG); }

  Operand *toOperand() const { return static_cast<Operand *>(*this); }

  CfgNode *toCfgNode() const { return static_cast<CfgNode *>(*this); }
};

Ostream &operator<<(Ostream &Out, const OperandNode &Op) {
  if (Op.isOperand()) {
    const auto *Oper = Op.toOperand();
    Out << "(Operand*)" << Oper;
    if (Oper) {
      Out << "::" << Oper->getType();
    }
  } else if (Op.isCfgNode()) {
    Out << "(CfgNode*)" << Op.toCfgNode();
  } else {
    Out << "nullptr";
  }
  return Out;
}

bool isComparison(wasm::WasmOpcode Opcode) {
  switch (Opcode) {
  case kExprI32Ne:
  case kExprI64Ne:
  case kExprI32Eq:
  case kExprI64Eq:
  case kExprI32LtS:
  case kExprI64LtS:
  case kExprI32LtU:
  case kExprI64LtU:
  case kExprI32GeS:
  case kExprI64GeS:
  case kExprI32GtS:
  case kExprI64GtS:
  case kExprI32GtU:
  case kExprI64GtU:
  case kExprF32Eq:
  case kExprF64Eq:
  case kExprF32Ne:
  case kExprF64Ne:
  case kExprF32Le:
  case kExprF64Le:
  case kExprF32Lt:
  case kExprF64Lt:
  case kExprF32Ge:
  case kExprF64Ge:
  case kExprF32Gt:
  case kExprF64Gt:
  case kExprI32LeS:
  case kExprI64LeS:
  case kExprI32GeU:
  case kExprI64GeU:
  case kExprI32LeU:
  case kExprI64LeU:
    return true;
  default:
    return false;
  }
}

class IceBuilder {
  using Node = OperandNode;
  using Variable = Ice::Variable;

  IceBuilder() = delete;
  IceBuilder(const IceBuilder &) = delete;
  IceBuilder &operator=(const IceBuilder &) = delete;

public:
  explicit IceBuilder(class Cfg *Func)
      : ControlPtr(nullptr), Func(Func), Ctx(Func->getContext()) {}

  /// Allocates a buffer of Nodes for use by V8.
  Node *Buffer(size_t Count) {
    LOG(out << "Buffer(" << Count << ")\n");
    return Func->allocateArrayOf<Node>(Count);
  }

  Node Error() { llvm::report_fatal_error("Error"); }
  Node Start(uint32_t Params) {
    LOG(out << "Start(" << Params << ") = ");
    auto *Entry = Func->getEntryNode();
    assert(Entry);
    LOG(out << Node(Entry) << "\n");

    // Load the WasmMemory address to make it available everywhere else in the
    // function.
    auto *WasmMemoryPtr =
        Ctx->getConstantExternSym(Ctx->getGlobalString("WASM_MEMORY"));
    assert(WasmMemory == nullptr);
    auto *WasmMemoryV = makeVariable(getPointerType());
    Entry->appendInst(InstLoad::create(Func, WasmMemoryV, WasmMemoryPtr));
    WasmMemory = WasmMemoryV;

    return OperandNode(Entry);
  }
  Node Param(uint32_t Index, wasm::LocalType Type) {
    LOG(out << "Param(" << Index << ") = ");
    auto *Arg = makeVariable(toIceType(Type));
    assert(Index == NextArg);
    Func->addArg(Arg);
    ++NextArg;
    LOG(out << Node(Arg) << "\n");
    return OperandNode(Arg);
  }
  Node Loop(CfgNode *Entry) {
    auto *Loop = Func->makeNode();
    LOG(out << "Loop(" << Entry << ") = " << Loop << "\n");
    Entry->appendInst(InstBr::create(Func, Loop));
    return OperandNode(Loop);
  }
  void Terminate(Node Effect, Node Control) {
    // TODO(eholk): this is almost certainly wrong
    LOG(out << "Terminate(" << Effect << ", " << Control << ")"
            << "\n");
  }
  Node Merge(uint32_t Count, Node *Controls) {
    LOG(out << "Merge(" << Count);
    for (uint32_t i = 0; i < Count; ++i) {
      LOG(out << ", " << Controls[i]);
    }
    LOG(out << ") = ");

    auto *MergedNode = Func->makeNode();

    for (uint32_t i = 0; i < Count; ++i) {
      CfgNode *Control = Controls[i];
      Control->appendInst(InstBr::create(Func, MergedNode));
    }
    LOG(out << (OperandNode)MergedNode << "\n");
    return OperandNode(MergedNode);
  }
  Node Phi(wasm::LocalType, uint32_t Count, Node *Vals, Node Control) {
    LOG(out << "Phi(" << Count << ", " << Control);
    for (uint32_t i = 0; i < Count; ++i) {
      LOG(out << ", " << Vals[i]);
    }
    LOG(out << ") = ");

    const auto &InEdges = Control.toCfgNode()->getInEdges();
    assert(Count == InEdges.size());

    assert(Count > 0);

    auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control);

    // Multiply by 200 in case more things get added later.

    // TODO(eholk): find a better way besides multiplying by some arbitrary
    // constant.
    auto *Phi = InstPhi::create(Func, Count * 200, Dest);
    for (uint32_t i = 0; i < Count; ++i) {
      auto *Op = Vals[i].toOperand();
      assert(Op);
      Phi->addArgument(Op, InEdges[i]);
    }
    setDefiningInst(Dest, Phi);
    Control.toCfgNode()->appendInst(Phi);
    LOG(out << Node(Dest) << "\n");
    return OperandNode(Dest);
  }
  Node EffectPhi(uint32_t Count, Node *Effects, Node Control) {
    // TODO(eholk): this function is almost certainly wrong.
    LOG(out << "EffectPhi(" << Count << ", " << Control << "):\n");
    for (uint32_t i = 0; i < Count; ++i) {
      LOG(out << "  " << Effects[i] << "\n");
    }
    return OperandNode(nullptr);
  }
  Node Int32Constant(int32_t Value) {
    LOG(out << "Int32Constant(" << Value << ") = ");
    auto *Const = Ctx->getConstantInt32(Value);
    assert(Const);
    assert(Control());
    LOG(out << Node(Const) << "\n");
    return OperandNode(Const);
  }
  Node Int64Constant(int64_t Value) {
    LOG(out << "Int64Constant(" << Value << ") = ");
    auto *Const = Ctx->getConstantInt64(Value);
    assert(Const);
    LOG(out << Node(Const) << "\n");
    return OperandNode(Const);
  }
  Node Float32Constant(float Value) {
    LOG(out << "Float32Constant(" << Value << ") = ");
    auto *Const = Ctx->getConstantFloat(Value);
    assert(Const);
    LOG(out << Node(Const) << "\n");
    return OperandNode(Const);
  }
  Node Float64Constant(double Value) {
    LOG(out << "Float64Constant(" << Value << ") = ");
    auto *Const = Ctx->getConstantDouble(Value);
    assert(Const);
    LOG(out << Node(Const) << "\n");
    return OperandNode(Const);
  }
  Node Binop(wasm::WasmOpcode Opcode, Node Left, Node Right) {
    LOG(out << "Binop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Left
            << ", " << Right << ") = ");
    BooleanVariable *BoolDest = nullptr;
    Variable *Dest = nullptr;
    if (isComparison(Opcode)) {
      BoolDest = makeVariable<BooleanVariable>(IceType_i32);
      Dest = BoolDest;
    } else {
      Dest = makeVariable(Left.toOperand()->getType());
    }
    switch (Opcode) {
    case kExprI32Add:
    case kExprI64Add:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Add, Dest, Left, Right));
      break;
    case kExprF32Add:
    case kExprF64Add:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fadd,
                                                   Dest, Left, Right));
      break;
    case kExprI32Sub:
    case kExprI64Sub:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Sub, Dest, Left, Right));
      break;
    case kExprF32Sub:
    case kExprF64Sub:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fsub,
                                                   Dest, Left, Right));
      break;
    case kExprI32Mul:
    case kExprI64Mul:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Mul, Dest, Left, Right));
      break;
    case kExprF32Mul:
    case kExprF64Mul:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fmul,
                                                   Dest, Left, Right));
      break;
    case kExprI32DivS:
    case kExprI64DivS:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Sdiv,
                                                   Dest, Left, Right));
      break;
    case kExprI32DivU:
    case kExprI64DivU:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Udiv,
                                                   Dest, Left, Right));
      break;
    case kExprF32Div:
    case kExprF64Div:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fdiv,
                                                   Dest, Left, Right));
      break;
    case kExprI32RemU:
    case kExprI64RemU:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Urem,
                                                   Dest, Left, Right));
      break;
    case kExprI32RemS:
    case kExprI64RemS:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Srem,
                                                   Dest, Left, Right));
      break;
    case kExprI32Ior:
    case kExprI64Ior:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Or, Dest, Left, Right));
      break;
    case kExprI32Xor:
    case kExprI64Xor:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Xor, Dest, Left, Right));
      break;
    case kExprI32Shl:
    case kExprI64Shl:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Shl, Dest, Left, Right));
      break;
    case kExprI32Rol:
    case kExprI64Rol: {
      // TODO(eholk): add rotate as an ICE instruction to make it easier to take
      // advantage of hardware support.

      const auto DestTy = Left.toOperand()->getType();
      const SizeT BitCount = typeWidthInBytes(DestTy) * CHAR_BIT;

      auto *Masked = makeVariable(DestTy);
      auto *Bottom = makeVariable(DestTy);
      auto *Top = makeVariable(DestTy);
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::And, Masked, Right,
                                 Ctx->getConstantInt(DestTy, BitCount - 1)));
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Shl, Top, Left, Masked));
      auto *RotShift = makeVariable(DestTy);
      Control()->appendInst(InstArithmetic::create(
          Func, InstArithmetic::Sub, RotShift,
          Ctx->getConstantInt(DestTy, BitCount), Masked));
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr,
                                                   Bottom, Left, RotShift));
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom));
      break;
    }
    case kExprI32Ror:
    case kExprI64Ror: {
      // TODO(eholk): add rotate as an ICE instruction to make it easier to take
      // advantage of hardware support.

      const auto DestTy = Left.toOperand()->getType();
      const SizeT BitCount = typeWidthInBytes(DestTy) * CHAR_BIT;

      auto *Masked = makeVariable(DestTy);
      auto *Bottom = makeVariable(DestTy);
      auto *Top = makeVariable(DestTy);
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::And, Masked, Right,
                                 Ctx->getConstantInt(DestTy, BitCount - 1)));
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr,
                                                   Top, Left, Masked));
      auto *RotShift = makeVariable(DestTy);
      Control()->appendInst(InstArithmetic::create(
          Func, InstArithmetic::Sub, RotShift,
          Ctx->getConstantInt(DestTy, BitCount), Masked));
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Shl,
                                                   Bottom, Left, RotShift));
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom));
      break;
    }
    case kExprI32ShrU:
    case kExprI64ShrU:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr,
                                                   Dest, Left, Right));
      break;
    case kExprI32ShrS:
    case kExprI64ShrS:
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Ashr,
                                                   Dest, Left, Right));
      break;
    case kExprI32And:
    case kExprI64And:
      Control()->appendInst(
          InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right));
      break;
    case kExprI32Ne:
    case kExprI64Ne: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Ne, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32Eq:
    case kExprI64Eq: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Eq, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32LtS:
    case kExprI64LtS: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Slt, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32LeS:
    case kExprI64LeS: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Sle, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32GeU:
    case kExprI64GeU: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Uge, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32LeU:
    case kExprI64LeU: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Ule, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32LtU:
    case kExprI64LtU: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Ult, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32GeS:
    case kExprI64GeS: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32GtS:
    case kExprI64GtS: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprI32GtU:
    case kExprI64GtU: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprF32Eq:
    case kExprF64Eq: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstFcmp::create(Func, InstFcmp::Ueq, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprF32Ne:
    case kExprF64Ne: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprF32Le:
    case kExprF64Le: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprF32Lt:
    case kExprF64Lt: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstFcmp::create(Func, InstFcmp::Ult, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprF32Ge:
    case kExprF64Ge: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstFcmp::create(Func, InstFcmp::Uge, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    case kExprF32Gt:
    case kExprF64Gt: {
      auto *TmpDest = makeVariable(IceType_i1);
      Control()->appendInst(
          InstFcmp::create(Func, InstFcmp::Ugt, TmpDest, Left, Right));
      BoolDest->setBoolSource(TmpDest);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
      break;
    }
    default:
      LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n");
      llvm::report_fatal_error("Uncovered or invalid binop.");
      return OperandNode(nullptr);
    }
    LOG(out << Dest << "\n");
    return OperandNode(Dest);
  }
  Node Unop(wasm::WasmOpcode Opcode, Node Input) {
    LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input
            << ") = ");
    Variable *Dest = nullptr;
    switch (Opcode) {
    // TODO (eholk): merge these next two cases using getConstantInteger
    case kExprI32Eqz: {
      auto *BoolDest = makeVariable<BooleanVariable>(IceType_i32);
      Dest = BoolDest;
      auto *Tmp = makeVariable(IceType_i1);
      Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input,
                                             Ctx->getConstantInt32(0)));
      BoolDest->setBoolSource(Tmp);
      Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp));
      break;
    }
    case kExprI64Eqz: {
      auto *BoolDest = makeVariable<BooleanVariable>(IceType_i32);
      Dest = BoolDest;
      auto *Tmp = makeVariable(IceType_i1);
      Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input,
                                             Ctx->getConstantInt64(0)));
      BoolDest->setBoolSource(Tmp);
      Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp));
      break;
    }
    case kExprI32Ctz: {
      Dest = makeVariable(IceType_i32);
      const auto FnName = Ctx->getGlobalString("llvm.cttz.i32");
      bool BadInstrinsic = false;
      const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
      assert(!BadInstrinsic);
      assert(Info);

      auto *Call = InstIntrinsicCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprF32Neg: {
      Dest = makeVariable(IceType_f32);
      Control()->appendInst(InstArithmetic::create(
          Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input));
      break;
    }
    case kExprF64Neg: {
      Dest = makeVariable(IceType_f64);
      Control()->appendInst(InstArithmetic::create(
          Func, InstArithmetic::Fsub, Dest, Ctx->getConstantDouble(0), Input));
      break;
    }
    case kExprF32Abs: {
      Dest = makeVariable(IceType_f32);
      const auto FnName = Ctx->getGlobalString("llvm.fabs.f32");
      bool BadInstrinsic = false;
      const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
      assert(!BadInstrinsic);
      assert(Info);

      auto *Call = InstIntrinsicCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprF64Abs: {
      Dest = makeVariable(IceType_f64);
      const auto FnName = Ctx->getGlobalString("llvm.fabs.f64");
      bool BadInstrinsic = false;
      const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
      assert(!BadInstrinsic);
      assert(Info);

      auto *Call = InstIntrinsicCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprF32Floor: {
      Dest = makeVariable(IceType_f64);
      const auto FnName = Ctx->getGlobalString("env$$floor_f");
      constexpr bool HasTailCall = false;

      auto *Call = InstCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprF64Floor: {
      Dest = makeVariable(IceType_f64);
      const auto FnName = Ctx->getGlobalString("env$$floor_d");
      constexpr bool HasTailCall = false;

      auto *Call = InstCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprF32Sqrt: {
      Dest = makeVariable(IceType_f32);
      const auto FnName = Ctx->getGlobalString("llvm.sqrt.f32");
      bool BadInstrinsic = false;
      const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
      assert(!BadInstrinsic);
      assert(Info);

      auto *Call = InstIntrinsicCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprF64Sqrt: {
      Dest = makeVariable(IceType_f64);
      const auto FnName = Ctx->getGlobalString("llvm.sqrt.f64");
      bool BadInstrinsic = false;
      const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic);
      assert(!BadInstrinsic);
      assert(Info);

      auto *Call = InstIntrinsicCall::create(
          Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info);
      Call->addArg(Input);
      Control()->appendInst(Call);
      break;
    }
    case kExprI64UConvertI32:
      Dest = makeVariable(IceType_i64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Zext, Dest, Input));
      break;
    case kExprI64SConvertI32:
      Dest = makeVariable(IceType_i64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Sext, Dest, Input));
      break;
    case kExprI32SConvertF32:
      Dest = makeVariable(IceType_i32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Fptosi, Dest, Input));
      break;
    case kExprI32UConvertF32:
      Dest = makeVariable(IceType_i32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Fptoui, Dest, Input));
      break;
    case kExprI32SConvertF64:
      Dest = makeVariable(IceType_i32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Fptosi, Dest, Input));
      break;
    case kExprI32UConvertF64:
      Dest = makeVariable(IceType_i32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Fptoui, Dest, Input));
      break;
    case kExprI32ReinterpretF32:
      Dest = makeVariable(IceType_i32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Bitcast, Dest, Input));
      break;
    case kExprI64ReinterpretF64:
      Dest = makeVariable(IceType_i64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Bitcast, Dest, Input));
      break;
    case kExprF64ReinterpretI64:
      Dest = makeVariable(IceType_f64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Bitcast, Dest, Input));
      break;
    case kExprI32ConvertI64:
      Dest = makeVariable(IceType_i32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Trunc, Dest, Input));
      break;
    case kExprF64SConvertI32:
      Dest = makeVariable(IceType_f64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Sitofp, Dest, Input));
      break;
    case kExprF64UConvertI32:
      Dest = makeVariable(IceType_f64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Uitofp, Dest, Input));
      break;
    case kExprF64ConvertF32:
      Dest = makeVariable(IceType_f64);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Fpext, Dest, Input));
      break;
    case kExprF32SConvertI32:
      Dest = makeVariable(IceType_f32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Sitofp, Dest, Input));
      break;
    case kExprF32UConvertI32:
      Dest = makeVariable(IceType_f32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Uitofp, Dest, Input));
      break;
    case kExprF32ReinterpretI32:
      Dest = makeVariable(IceType_f32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Bitcast, Dest, Input));
      break;
    case kExprF32ConvertF64:
      Dest = makeVariable(IceType_f32);
      Control()->appendInst(
          InstCast::create(Func, InstCast::Fptrunc, Dest, Input));
      break;
    default:
      LOG(out << "Unknown unop: " << WasmOpcodes::OpcodeName(Opcode) << "\n");
      llvm::report_fatal_error("Uncovered or invalid unop.");
      return OperandNode(nullptr);
    }
    LOG(out << Dest << "\n");
    return OperandNode(Dest);
  }
  uint32_t InputCount(CfgNode *Node) const { return Node->getInEdges().size(); }
  bool IsPhiWithMerge(Node Phi, Node Merge) const {
    LOG(out << "IsPhiWithMerge(" << Phi << ", " << Merge << ")"
            << "\n");
    if (Phi && Phi.isOperand()) {
      LOG(out << "  ...is operand"
              << "\n");
      if (getDefiningInst(Phi)) {
        LOG(out << "  ...has defining instruction"
                << "\n");
        LOG(out << getDefNode(Phi) << "\n");
        LOG(out << "  ..." << (getDefNode(Phi) == Merge) << "\n");
        return getDefNode(Phi) == Merge;
      }
    }
    return false;
  }
  void AppendToMerge(CfgNode *Merge, CfgNode *From) const {
    From->appendInst(InstBr::create(Func, Merge));
  }
  void AppendToPhi(Node Merge, Node Phi, Node From) {
    LOG(out << "AppendToPhi(" << Merge << ", " << Phi << ", " << From << ")"
            << "\n");
    auto *Inst = getDefiningInst(Phi);
    assert(Inst->getDest()->getType() == From.toOperand()->getType());
    Inst->addArgument(From, getDefNode(From));
  }

  //-----------------------------------------------------------------------
  // Operations that read and/or write {control} and {effect}.
  //-----------------------------------------------------------------------
  Node Branch(Node Cond, Node *TrueNode, Node *FalseNode) {
    // true_node and false_node appear to be out parameters.
    LOG(out << "Branch(" << Cond << ", ");

    // save control here because true_node appears to alias control.
    auto *Ctrl = Control();

    *TrueNode = OperandNode(Func->makeNode());
    *FalseNode = OperandNode(Func->makeNode());

    LOG(out << *TrueNode << ", " << *FalseNode << ")"
            << "\n");

    auto *CondBool = Cond.toOperand()->asBoolean();
    if (CondBool == nullptr) {
      CondBool = makeVariable(IceType_i1);
      Ctrl->appendInst(InstIcmp::create(Func, InstIcmp::Ne, CondBool, Cond,
                                        Ctx->getConstantInt32(0)));
    }

    Ctrl->appendInst(InstBr::create(Func, CondBool, *TrueNode, *FalseNode));
    return OperandNode(nullptr);
  }
  InstSwitch *CurrentSwitch = nullptr;
  CfgNode *SwitchNode = nullptr;
  SizeT SwitchIndex = 0;
  Node Switch(uint32_t Count, Node Key) {
    LOG(out << "Switch(" << Count << ", " << Key << ")\n");

    assert(!CurrentSwitch);

    auto *Default = Func->makeNode();
    // Count - 1 because the decoder counts the default label but Subzero does
    // not.
    CurrentSwitch = InstSwitch::create(Func, Count - 1, Key, Default);
    SwitchIndex = 0;
    SwitchNode = Control();
    // We don't actually append the switch to the CfgNode here because not all
    // the branches are ready.
    return Node(nullptr);
  }
  Node IfValue(int32_t Value, Node) {
    LOG(out << "IfValue(" << Value << ") [Index = " << SwitchIndex << "]\n");
    assert(CurrentSwitch);
    auto *Target = Func->makeNode();
    CurrentSwitch->addBranch(SwitchIndex++, Value, Target);
    return Node(Target);
  }
  Node IfDefault(Node) {
    LOG(out << "IfDefault(...) [Index = " << SwitchIndex << "]\n");
    assert(CurrentSwitch);
    assert(CurrentSwitch->getLabelDefault());
    // Now we append the switch, since this should be the last edge.
    assert(SwitchIndex == CurrentSwitch->getNumCases());
    SwitchNode->appendInst(CurrentSwitch);
    SwitchNode = nullptr;
    auto Default = Node(CurrentSwitch->getLabelDefault());
    CurrentSwitch = nullptr;
    return Default;
  }
  Node Return(uint32_t Count, Node *Vals) {
    assert(1 >= Count);
    LOG(out << "Return(");
    if (Count > 0)
      LOG(out << Vals[0]);
    LOG(out << ")"
            << "\n");
    auto *Instr =
        1 == Count ? InstRet::create(Func, Vals[0]) : InstRet::create(Func);
    Control()->appendInst(Instr);
    Control()->setHasReturn();
    LOG(out << Node(nullptr) << "\n");
    return OperandNode(nullptr);
  }
  Node ReturnVoid() {
    LOG(out << "ReturnVoid() = ");
    auto *Instr = InstRet::create(Func);
    Control()->appendInst(Instr);
    Control()->setHasReturn();
    LOG(out << Node(nullptr) << "\n");
    return OperandNode(nullptr);
  }
  Node Unreachable() {
    LOG(out << "Unreachable() = ");
    auto *Instr = InstUnreachable::create(Func);
    Control()->appendInst(Instr);
    LOG(out << Node(nullptr) << "\n");
    return OperandNode(nullptr);
  }

  Node CallDirect(uint32_t Index, Node *Args) {
    LOG(out << "CallDirect(" << Index << ")"
            << "\n");
    assert(Module->IsValidFunction(Index));
    const auto *Module = this->Module->module;
    assert(Module);
    const auto &Target = Module->functions[Index];
    const auto *Sig = Target.sig;
    assert(Sig);
    const auto NumArgs = Sig->parameter_count();
    LOG(out << "  number of args: " << NumArgs << "\n");

    const auto TargetName = getFunctionName(Module, Index);
    LOG(out << "  target name: " << TargetName << "\n");

    assert(Sig->return_count() <= 1);

    auto TargetOperand =
        Ctx->getConstantSym(0, Ctx->getGlobalString(TargetName));

    auto *Dest = Sig->return_count() > 0
                     ? makeVariable(toIceType(Sig->GetReturn()))
                     : nullptr;
    auto *Call = InstCall::create(Func, NumArgs, Dest, TargetOperand,
                                  false /* HasTailCall */);
    for (uint32_t i = 0; i < NumArgs; ++i) {
      // The builder reserves the first argument for the code object.
      LOG(out << "  args[" << i << "] = " << Args[i + 1] << "\n");
      Call->addArg(Args[i + 1]);
    }

    Control()->appendInst(Call);
    LOG(out << "Call Result = " << Node(Dest) << "\n");
    return OperandNode(Dest);
  }
  Node CallImport(uint32_t Index, Node *Args) {
    LOG(out << "CallImport(" << Index << ")"
            << "\n");
    const auto *Module = this->Module->module;
    assert(Module);
    const auto *Sig = this->Module->GetImportSignature(Index);
    assert(Sig);
    const auto NumArgs = Sig->parameter_count();
    LOG(out << "  number of args: " << NumArgs << "\n");

    const auto &Target = Module->import_table[Index];
    const auto ModuleName = toStdString(
        Module->GetName(Target.module_name_offset, Target.module_name_length));
    const auto FnName = toStdString(Module->GetName(
        Target.function_name_offset, Target.function_name_length));

    const auto TargetName = Ctx->getGlobalString(ModuleName + "$$" + FnName);
    LOG(out << "  target name: " << TargetName << "\n");

    assert(Sig->return_count() <= 1);

    auto TargetOperand = Ctx->getConstantExternSym(TargetName);

    auto *Dest = Sig->return_count() > 0
                     ? makeVariable(toIceType(Sig->GetReturn()))
                     : nullptr;
    constexpr bool NoTailCall = false;
    auto *Call =
        InstCall::create(Func, NumArgs, Dest, TargetOperand, NoTailCall);
    for (uint32_t i = 0; i < NumArgs; ++i) {
      // The builder reserves the first argument for the code object.
      LOG(out << "  args[" << i << "] = " << Args[i + 1] << "\n");
      assert(Args[i + 1].toOperand()->getType() == toIceType(Sig->GetParam(i)));
      Call->addArg(Args[i + 1]);
    }

    Control()->appendInst(Call);
    LOG(out << "Call Result = " << Node(Dest) << "\n");
    return OperandNode(Dest);
  }
  Node CallIndirect(uint32_t SigIndex, Node *Args) {
    LOG(out << "CallIndirect(" << SigIndex << ")\n");
    // TODO(eholk): Compile to something better than a switch.
    const auto *Module = this->Module->module;
    assert(Module);
    const auto &IndirectTable = Module->function_table;

    auto *Abort = getIndirectFailTarget();

    assert(Args[0].toOperand());

    auto *Switch = InstSwitch::create(Func, IndirectTable.size(),
                                      Args[0].toOperand(), Abort);
    assert(Abort);

    const bool HasReturn = Module->signatures[SigIndex]->return_count() != 0;
    const Ice::Type DestTy =
        HasReturn ? toIceType(Module->signatures[SigIndex]->GetReturn())
                  : IceType_void;

    auto *Dest = HasReturn ? makeVariable(DestTy) : nullptr;

    auto *ExitNode = Func->makeNode();
    auto *PhiInst =
        HasReturn ? InstPhi::create(Func, IndirectTable.size(), Dest) : nullptr;

    for (uint32_t Index = 0; Index < IndirectTable.size(); ++Index) {
      const auto &Target = Module->functions[IndirectTable[Index]];

      if (SigIndex == Target.sig_index) {
        auto *CallNode = Func->makeNode();
        auto *SavedControl = Control();
        *ControlPtr = OperandNode(CallNode);
        auto *Tmp = CallDirect(Target.func_index, Args).toOperand();
        *ControlPtr = OperandNode(SavedControl);
        if (PhiInst) {
          PhiInst->addArgument(Tmp, CallNode);
        }
        CallNode->appendInst(InstBr::create(Func, ExitNode));
        Switch->addBranch(Index, Index, CallNode);
      } else {
        Switch->addBranch(Index, Index, Abort);
      }
    }

    if (PhiInst) {
      ExitNode->appendInst(PhiInst);
    }

    Control()->appendInst(Switch);
    *ControlPtr = OperandNode(ExitNode);
    return OperandNode(Dest);
  }
  Node Invert(Node Node) {
    (void)Node;
    llvm::report_fatal_error("Invert");
  }

  //-----------------------------------------------------------------------
  // Operations that concern the linear memory.
  //-----------------------------------------------------------------------
  Node MemSize(uint32_t Offset) {
    (void)Offset;
    llvm::report_fatal_error("MemSize");
  }
  Node LoadGlobal(uint32_t Index) {
    (void)Index;
    llvm::report_fatal_error("LoadGlobal");
  }
  Node StoreGlobal(uint32_t Index, Node Val) {
    (void)Index;
    (void)Val;
    llvm::report_fatal_error("StoreGlobal");
  }

  Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index,
               uint32_t Offset) {
    LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset
            << "]) = ");

    auto *RealAddr = sanitizeAddress(Index, Offset);

    auto *LoadResult = makeVariable(toIceType(MemType));
    Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr));

    // and cast, if needed
    Variable *Result = nullptr;
    if (toIceType(Type) != toIceType(MemType)) {
      auto DestType = toIceType(Type);
      Result = makeVariable(DestType);
      // TODO(eholk): handle signs correctly.
      if (isScalarIntegerType(DestType)) {
        if (MemType.IsSigned()) {
          Control()->appendInst(
              InstCast::create(Func, InstCast::Sext, Result, LoadResult));
        } else {
          Control()->appendInst(
              InstCast::create(Func, InstCast::Zext, Result, LoadResult));
        }
      } else if (isScalarFloatingType(DestType)) {
        Control()->appendInst(
            InstCast::create(Func, InstCast::Sitofp, Result, LoadResult));
      } else {
        llvm::report_fatal_error("Unsupported type for memory load");
      }
    } else {
      Result = LoadResult;
    }

    LOG(out << Result << "\n");
    return OperandNode(Result);
  }
  void StoreMem(MachineType Type, Node Index, uint32_t Offset, Node Val) {
    LOG(out << "StoreMem." << toIceType(Type) << "(" << Index << "[" << Offset
            << "] = " << Val << ")"
            << "\n");

    auto *RealAddr = sanitizeAddress(Index, Offset);

    // cast the value to the right type, if needed
    Operand *StoreVal = nullptr;
    if (toIceType(Type) != Val.toOperand()->getType()) {
      auto *LocalStoreVal = makeVariable(toIceType(Type));
      Control()->appendInst(
          InstCast::create(Func, InstCast::Trunc, LocalStoreVal, Val));
      StoreVal = LocalStoreVal;
    } else {
      StoreVal = Val;
    }

    // then store the memory
    Control()->appendInst(InstStore::create(Func, StoreVal, RealAddr));
  }

  static void PrintDebugName(OperandNode Node) {
    (void)Node;
    llvm::report_fatal_error("PrintDebugName");
  }

  CfgNode *Control() {
    return ControlPtr ? ControlPtr->toCfgNode() : Func->getEntryNode();
  }
  Node Effect() { return *EffectPtr; }

  void set_module(wasm::ModuleEnv *Module) { this->Module = Module; }

  void set_control_ptr(Node *Control) { this->ControlPtr = Control; }

  void set_effect_ptr(Node *Effect) { this->EffectPtr = Effect; }

private:
  wasm::ModuleEnv *Module;
  Node *ControlPtr;
  Node *EffectPtr;

  class Cfg *Func;
  GlobalContext *Ctx;

  CfgNode *BoundsFailTarget = nullptr;
  CfgNode *IndirectFailTarget = nullptr;

  SizeT NextArg = 0;

  CfgUnorderedMap<Operand *, InstPhi *> PhiMap;
  CfgUnorderedMap<Operand *, CfgNode *> DefNodeMap;

  Operand *WasmMemory = nullptr;

  InstPhi *getDefiningInst(Operand *Op) const {
    const auto &Iter = PhiMap.find(Op);
    if (Iter == PhiMap.end()) {
      return nullptr;
    }
    return Iter->second;
  }

  void setDefiningInst(Operand *Op, InstPhi *Phi) {
    LOG(out << "\n== setDefiningInst(" << Op << ", " << Phi << ") ==\n");
    PhiMap.emplace(Op, Phi);
  }

  template <typename T = Variable> T *makeVariable(Ice::Type Type) {
    return makeVariable<T>(Type, Control());
  }

  template <typename T = Variable>
  T *makeVariable(Ice::Type Type, CfgNode *DefNode) {
    auto *Var = Func->makeVariable<T>(Type);
    DefNodeMap.emplace(Var, DefNode);
    return Var;
  }

  CfgNode *getDefNode(Operand *Op) const {
    const auto &Iter = DefNodeMap.find(Op);
    if (Iter == DefNodeMap.end()) {
      return nullptr;
    }
    return Iter->second;
  }

  CfgNode *getBoundsFailTarget() {
    if (!BoundsFailTarget) {
      // TODO (eholk): Move this node to the end of the CFG, or even better,
      // have only one abort block for the whole module.
      BoundsFailTarget = Func->makeNode();
      BoundsFailTarget->appendInst(InstCall::create(
          Func, 0, nullptr,
          Ctx->getConstantExternSym(Ctx->getGlobalString("__Sz_bounds_fail")),
          false));
      BoundsFailTarget->appendInst(InstUnreachable::create(Func));
    }

    return BoundsFailTarget;
  }
  CfgNode *getIndirectFailTarget() {
    if (!IndirectFailTarget) {
      // TODO (eholk): Move this node to the end of the CFG, or even better,
      // have only one abort block for the whole module.
      IndirectFailTarget = Func->makeNode();
      IndirectFailTarget->appendInst(InstCall::create(
          Func, 0, nullptr,
          Ctx->getConstantExternSym(Ctx->getGlobalString("__Sz_indirect_fail")),
          false));
      IndirectFailTarget->appendInst(InstUnreachable::create(Func));
    }

    return IndirectFailTarget;
  }

  Operand *getWasmMemory() {
    assert(WasmMemory != nullptr);
    return WasmMemory;
  }

  Operand *sanitizeAddress(Operand *Base, uint32_t Offset) {
    SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE;

    bool ConstZeroBase = false;

    // first, add the index and the offset together.
    if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) {
      uint32_t RealOffset = Offset + ConstBase->getValue();
      if (RealOffset >= MemSize) {
        // We've proven this will always be an out of bounds access, so insert
        // an unconditional trap.
        Control()->appendInst(InstUnreachable::create(Func));
        // It doesn't matter what we return here, so return something that will
        // allow the rest of code generation to happen.
        //
        // We might be tempted to just abort translation here, but out of bounds
        // memory access is a runtime trap, not a compile error.
        return Ctx->getConstantZero(getPointerType());
      }
      Base = Ctx->getConstantInt32(RealOffset);
      ConstZeroBase = (0 == RealOffset);
    } else if (0 != Offset) {
      auto *Addr = makeVariable(Ice::getPointerType());
      auto *OffsetConstant = Ctx->getConstantInt32(Offset);
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
                                                   Addr, Base, OffsetConstant));

      Base = Addr;
    }

    // Do the bounds check if enabled
    if (getFlags().getWasmBoundsCheck() &&
        !llvm::isa<ConstantInteger32>(Base)) {
      // TODO (eholk): creating a new basic block on every memory access is
      // terrible (see https://goo.gl/Zj7DTr). Try adding a new instruction that
      // encapsulates this "abort if false" pattern.
      auto *CheckPassed = Func->makeNode();
      auto *CheckFailed = getBoundsFailTarget();

      auto *Check = makeVariable(IceType_i1);
      Control()->appendInst(InstIcmp::create(Func, InstIcmp::Ult, Check, Base,
                                             Ctx->getConstantInt32(MemSize)));
      Control()->appendInst(
          InstBr::create(Func, Check, CheckPassed, CheckFailed));

      *ControlPtr = OperandNode(CheckPassed);
    }

    Ice::Operand *RealAddr = nullptr;
    auto MemBase = getWasmMemory();
    if (!ConstZeroBase) {
      auto RealAddrV = Func->makeVariable(Ice::getPointerType());
      Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
                                                   RealAddrV, Base, MemBase));

      RealAddr = RealAddrV;
    } else {
      RealAddr = MemBase;
    }
    return RealAddr;
  }

  template <typename F = std::function<void(Ostream &)>> void log(F Fn) const {
    if (BuildDefs::dump() && (getFlags().getVerbose() & IceV_Wasm)) {
      Fn(Ctx->getStrDump());
      Ctx->getStrDump().flush();
    }
  }
};

std::unique_ptr<Cfg> WasmTranslator::translateFunction(Zone *Zone,
                                                       FunctionBody &Body) {
  OstreamLocker L1(Ctx);
  auto Func = Cfg::create(Ctx, getNextSequenceNumber());
  TimerMarker T(TimerStack::TT_wasmGenIce, Func.get());
  Ice::CfgLocalAllocatorScope L2(Func.get());

  // TODO(eholk): parse the function signature...

  Func->setEntryNode(Func->makeNode());

  IceBuilder Builder(Func.get());
  SR_WasmDecoder<OperandNode, IceBuilder> Decoder(Zone, &Builder, Body);

  LOG(out << getFlags().getDefaultGlobalPrefix() << "\n");
  Decoder.Decode();

  // We don't always know where the incoming branches are in phi nodes, so this
  // function finds them.
  Func->fixPhiNodes();

  Func->computeInOutEdges();

  return Func;
}

constexpr SizeT InitialBufferSize = 16 << 10; // 16KB

WasmTranslator::WasmTranslator(GlobalContext *Ctx)
    : Translator(Ctx), Buffer(InitialBufferSize) {}

void WasmTranslator::translate(
    const std::string &IRFilename,
    std::unique_ptr<llvm::DataStreamer> InputStream) {
  TimerMarker T(TimerStack::TT_wasm, Ctx);

  LOG(out << "Initializing v8/wasm stuff..."
          << "\n");
  Zone Zone;
  ZoneScope _(&Zone);

  SizeT BytesRead = 0;
  while (true) {
    BytesRead +=
        InputStream->GetBytes(&Buffer[BytesRead], Buffer.size() - BytesRead);
    LOG(out << "Read " << BytesRead << " bytes"
            << "\n");
    if (BytesRead < Buffer.size())
      break;
    Buffer.resize(Buffer.size() * 2);
  }

  LOG(out << "Decoding module " << IRFilename << "\n");

  constexpr v8::internal::Isolate *NoIsolate = nullptr;
  auto Result = DecodeWasmModule(NoIsolate, &Zone, Buffer.data(),
                                 Buffer.data() + BytesRead, false, kWasmOrigin);

  auto Module = Result.val;

  LOG(out << "Module info:"
          << "\n");
  LOG(out << "  min_mem_pages:           " << Module->min_mem_pages << "\n");
  LOG(out << "  max_mem_pages:           " << Module->max_mem_pages << "\n");
  LOG(out << "  number of globals:       " << Module->globals.size() << "\n");
  LOG(out << "  number of signatures:    " << Module->signatures.size()
          << "\n");
  LOG(out << "  number of functions:     " << Module->functions.size() << "\n");
  LOG(out << "  number of data_segments: " << Module->data_segments.size()
          << "\n");
  LOG(out << "  function table size:     " << Module->function_table.size()
          << "\n");
  LOG(out << "  import table size:       " << Module->import_table.size()
          << "\n");
  LOG(out << "  export table size:       " << Module->export_table.size()
          << "\n");

  LOG(out << "\n"
          << "Data segment information:"
          << "\n");
  uint32_t Id = 0;
  for (const auto Seg : Module->data_segments) {
    LOG(out << Id << ":  (" << Seg.source_offset << ", " << Seg.source_size
            << ") => " << Seg.dest_addr);
    if (Seg.init) {
      LOG(out << " init\n");
    } else {
      LOG(out << "\n");
    }
    Id++;
  }

  LOG(out << "\n"
          << "Import information:"
          << "\n");
  for (const auto Import : Module->import_table) {
    auto ModuleName = toStdString(
        Module->GetName(Import.module_name_offset, Import.module_name_length));
    auto FnName = toStdString(Module->GetName(Import.function_name_offset,
                                              Import.function_name_length));
    LOG(out << "  " << Import.sig_index << ": " << ModuleName << "::" << FnName
            << "\n");
  }

  LOG(out << "\n"
          << "Export information:"
          << "\n");
  for (const auto Export : Module->export_table) {
    LOG(out << "  " << Export.func_index << ": "
            << toStdString(
                   Module->GetName(Export.name_offset, Export.name_length))
            << " (" << Export.name_offset << ", " << Export.name_length << ")");
    LOG(out << "\n");
  }

  LOG(out << "\n"
          << "Function information:"
          << "\n");
  for (const auto F : Module->functions) {
    LOG(out << "  " << F.func_index << ": "
            << toStdString(Module->GetName(F.name_offset, F.name_length))
            << " (" << F.name_offset << ", " << F.name_length << ")");
    if (F.exported)
      LOG(out << " export");
    if (F.external)
      LOG(out << " extern");
    LOG(out << "\n");
  }

  LOG(out << "\n"
          << "Indirect table:"
          << "\n");
  for (uint32_t F : Module->function_table) {
    LOG(out << "  " << F << ": " << getFunctionName(Module, F) << "\n");
  }

  ModuleEnv ModuleEnv;
  ModuleEnv.module = Module;

  FunctionBody Body;
  Body.module = &ModuleEnv;

  LOG(out << "Translating " << IRFilename << "\n");

  {
    unique_ptr<VariableDeclarationList> Globals =
        makeUnique<VariableDeclarationList>();

    // Global variables, etc go here.
    auto *WasmMemory = VariableDeclaration::createExternal(Globals.get());
    WasmMemory->setName(Ctx->getGlobalString("WASM_DATA_INIT"));

    // Fill in the segments
    SizeT WritePtr = 0;
    for (const auto Seg : Module->data_segments) {
      // fill in gaps with zero.
      if (Seg.dest_addr > WritePtr) {
        WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create(
            Globals.get(), Seg.dest_addr - WritePtr));
        WritePtr = Seg.dest_addr;
      }

      // Add the data
      WasmMemory->addInitializer(VariableDeclaration::DataInitializer::create(
          Globals.get(),
          reinterpret_cast<const char *>(Module->module_start) +
              Seg.source_offset,
          Seg.source_size));

      WritePtr += Seg.source_size;
    }

    // Save the size of the initialized data in a global variable so the runtime
    // can use it to determine the initial heap break.
    auto *GlobalDataSize = VariableDeclaration::createExternal(Globals.get());
    GlobalDataSize->setName(Ctx->getGlobalString("WASM_DATA_SIZE"));
    GlobalDataSize->addInitializer(VariableDeclaration::DataInitializer::create(
        Globals.get(), reinterpret_cast<const char *>(&WritePtr),
        sizeof(WritePtr)));

    // Save the number of pages for the runtime
    auto *GlobalNumPages = VariableDeclaration::createExternal(Globals.get());
    GlobalNumPages->setName(Ctx->getGlobalString("WASM_NUM_PAGES"));
    GlobalNumPages->addInitializer(VariableDeclaration::DataInitializer::create(
        Globals.get(), reinterpret_cast<const char *>(&Module->min_mem_pages),
        sizeof(Module->min_mem_pages)));

    Globals->push_back(WasmMemory);
    Globals->push_back(GlobalDataSize);
    Globals->push_back(GlobalNumPages);

    lowerGlobals(std::move(Globals));
  }

  // Translate each function.
  for (const auto Fn : Module->functions) {
    const auto FnName = getFunctionName(Module, Fn.func_index);

    LOG(out << "  " << Fn.func_index << ": " << FnName << "...");

    Body.sig = Fn.sig;
    Body.base = Buffer.data();
    Body.start = Buffer.data() + Fn.code_start_offset;
    Body.end = Buffer.data() + Fn.code_end_offset;

    std::unique_ptr<Cfg> Func = nullptr;
    {
      TimerMarker T_func(getContext(), FnName);
      Func = translateFunction(&Zone, Body);
      Func->setFunctionName(Ctx->getGlobalString(FnName));
    }
    Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func)));
    LOG(out << "done.\n");
  }

  return;
}

#endif // ALLOW_WASM
