// Copyright 2014 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

#include <cstdint>
#include <cstdio>
#include <cmath>
#include <string>
#include <algorithm>
#include <map>

#include "simple_ast.h"
#include "optimizer.h"

using namespace cashew;

typedef std::vector<IString> StringVec;

//==================
// Globals
//==================

Ref extraInfo;

//==================
// Infrastructure
//==================

template<class T, class V>
int indexOf(T list, V value) {
  for (size_t i = 0; i < list.size(); i++) {
    if (list[i] == value) return i;
  }
  return -1;
}

int jsD2I(double x) {
  return (int)((int64_t)x);
}

char *strdupe(const char *str) {
  char *ret = (char *)malloc(strlen(str)+1); // leaked!
  strcpy(ret, str);
  return ret;
}

IString getHeapStr(int x, bool unsign) {
  switch (x) {
    case 8: return unsign ? HEAPU8 : HEAP8;
    case 16: return unsign ? HEAPU16 : HEAP16;
    case 32: return unsign ? HEAPU32 : HEAP32;
  }
  assert(0);
  return ":(";
}

Ref deStat(Ref node) {
  if (node[0] == STAT) return node[1];
  return node;
}

Ref getStatements(Ref node) {
  if (node[0] == DEFUN) {
    return node[3];
  } else if (node[0] == BLOCK) {
    return node->size() > 1 ? node[1] : nullptr;
  } else {
    return arena.alloc();
  }
}

// Types

AsmType intToAsmType(int type) {
  if (type >= 0 && type <= ASM_NONE) return (AsmType)type;
  else {
    assert(0);
    return ASM_NONE;
  }
}

// forward decls
Ref makeEmpty();
bool isEmpty(Ref node);
Ref makeAsmCoercedZero(AsmType type);
Ref makeArray(int size_hint);
Ref makeBool(bool b);
Ref makeNum(double x);
Ref makeName(IString str);
Ref makeAsmCoercion(Ref node, AsmType type);
Ref make1(IString type, Ref a);
Ref make3(IString type, Ref a, Ref b, Ref c);

AsmData::AsmData(Ref f) {
  func = f;

  // process initial params
  Ref stats = func[3];
  size_t i = 0;
  while (i < stats->size()) {
    Ref node = stats[i];
    if (node[0] != STAT || node[1][0] != ASSIGN || node[1][2][0] != NAME) break;
    node = node[1];
    Ref name = node[2][1];
    int index = func[2]->indexOf(name);
    if (index < 0) break; // not an assign into a parameter, but a global
    IString& str = name->getIString();
    if (locals.count(str) > 0) break; // already done that param, must be starting function body
    locals[str] = Local(detectType(node[3]), true);
    params.push_back(str);
    stats[i] = makeEmpty();
    i++;
  }
  // process initial variable definitions and remove '= 0' etc parts - these
  // are not actually assignments in asm.js
  while (i < stats->size()) {
    Ref node = stats[i];
    if (node[0] != VAR) break;
    for (size_t j = 0; j < node[1]->size(); j++) {
      Ref v = node[1][j];
      IString& name = v[0]->getIString();
      Ref value = v[1];
      if (locals.count(name) == 0) {
        locals[name] = Local(detectType(value, nullptr, true), false);
        vars.push_back(name);
        v->setSize(1); // make an un-assigning var
      } else {
        assert(j == 0); // cannot break in the middle
        goto outside;
      }
    }
    i++;
  }
  outside:
  // look for other var definitions and collect them
  while (i < stats->size()) {
    traversePre(stats[i], [&](Ref node) {
      Ref type = node[0];
      if (type == VAR) {
        dump("bad, seeing a var in need of fixing", func);
        abort(); //, 'should be no vars to fix! ' + func[1] + ' : ' + JSON.stringify(node));
      }
    });
    i++;
  }
  // look for final RETURN statement to get return type.
  Ref retStmt = stats->back();
  if (!!retStmt && retStmt[0] == RETURN && !!retStmt[1]) {
    ret = detectType(retStmt[1]);
  } else {
    ret = ASM_NONE;
  }
}

void AsmData::denormalize() {
  Ref stats = func[3];
  // Remove var definitions, if any
  for (size_t i = 0; i < stats->size(); i++) {
    if (stats[i][0] == VAR) {
      stats[i] = makeEmpty();
    } else {
      if (!isEmpty(stats[i])) break;
    }
  }
  // calculate variable definitions
  Ref varDefs = makeArray(vars.size());
  for (auto v : vars) {
    varDefs->push_back(make1(v, makeAsmCoercedZero(locals[v].type)));
  }
  // each param needs a line; reuse emptyNodes as much as we can
  size_t numParams = params.size();
  size_t emptyNodes = 0;
  while (emptyNodes < stats->size()) {
    if (!isEmpty(stats[emptyNodes])) break;
    emptyNodes++;
  }
  size_t neededEmptyNodes = numParams + (varDefs->size() ? 1 : 0); // params plus one big var if there are vars
  if (neededEmptyNodes > emptyNodes) {
    stats->insert(0, neededEmptyNodes - emptyNodes);
  } else if (neededEmptyNodes < emptyNodes) {
    stats->splice(0, emptyNodes - neededEmptyNodes);
  }
  // add param coercions
  int next = 0;
  for (auto param : func[2]->getArray()) {
    IString str = param->getIString();
    assert(locals.count(str) > 0);
    stats[next++] = make1(STAT, make3(ASSIGN, makeBool(true), makeName(str.c_str()), makeAsmCoercion(makeName(str.c_str()), locals[str].type)));
  }
  if (varDefs->size()) {
    stats[next] = make1(VAR, varDefs);
  }
  /*
  if (inlines->size() > 0) {
    var i = 0;
    traverse(func, function(node, type) {
      if (type == CALL && node[1][0] == NAME && node[1][1] == 'inlinejs') {
        node[1] = inlines[i++]; // swap back in the body
      }
    });
  }
  */
  // ensure that there's a final RETURN statement if needed.
  if (ret != ASM_NONE) {
    Ref retStmt = stats->back();
    if (!retStmt || retStmt[0] != RETURN) {
      stats->push_back(make1(RETURN, makeAsmCoercedZero(ret)));
    }
  }
  //printErr('denormalized \n\n' + astToSrc(func) + '\n\n');
}

// Constructions TODO: share common constructions, and assert they remain frozen

Ref makeArray(int size_hint=0) {
  return &arena.alloc()->setArray(size_hint);
}

Ref makeBool(bool b) {
  return &arena.alloc()->setBool(b);
}

Ref makeString(const IString& s) {
  return &arena.alloc()->setString(s);
}

Ref makeEmpty() {
  return ValueBuilder::makeToplevel();
}

Ref makeNum(double x) {
  return ValueBuilder::makeDouble(x);
}

Ref makeName(IString str) {
  return ValueBuilder::makeName(str);
}

Ref makeBlock() {
  return ValueBuilder::makeBlock();
}

Ref make1(IString s1, Ref a) {
  Ref ret(makeArray(2));
  ret->push_back(makeString(s1));
  ret->push_back(a);
  return ret;
}

Ref make2(IString s1, IString s2, Ref a) {
  Ref ret(makeArray(2));
  ret->push_back(makeString(s1));
  ret->push_back(makeString(s2));
  ret->push_back(a);
  return ret;
}

Ref make2(IString s1, Ref a, Ref b) {
  Ref ret(makeArray(3));
  ret->push_back(makeString(s1));
  ret->push_back(a);
  ret->push_back(b);
  return ret;
}

Ref make3(IString type, IString a, Ref b, Ref c) {
  Ref ret(makeArray(4));
  ret->push_back(makeString(type));
  ret->push_back(makeString(a));
  ret->push_back(b);
  ret->push_back(c);
  return ret;
}

Ref make3(IString type, Ref a, Ref b, Ref c) {
  Ref ret(makeArray(4));
  ret->push_back(makeString(type));
  ret->push_back(a);
  ret->push_back(b);
  ret->push_back(c);
  return ret;
}

Ref makeAsmCoercedZero(AsmType type) {
  switch (type) {
    case ASM_INT: return makeNum(0); break;
    case ASM_DOUBLE: return make2(UNARY_PREFIX, PLUS, makeNum(0)); break;
    case ASM_FLOAT: {
      if (!ASM_FLOAT_ZERO.isNull()) {
        return makeName(ASM_FLOAT_ZERO);
      } else {
        return make2(CALL, makeName(MATH_FROUND), &(makeArray(1))->push_back(makeNum(0)));
      }
      break;
    }
    case ASM_FLOAT32X4: {
      return make2(CALL, makeName(SIMD_FLOAT32X4), &(makeArray(4))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_FLOAT64X2: {
      return make2(CALL, makeName(SIMD_FLOAT64X2), &(makeArray(2))->push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_INT8X16: {
      return make2(CALL, makeName(SIMD_INT8X16), &(makeArray(16))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_INT16X8: {
      return make2(CALL, makeName(SIMD_INT16X8), &(makeArray(8))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_INT32X4: {
      return make2(CALL, makeName(SIMD_INT32X4), &(makeArray(4))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_BOOL8X16: {
      return make2(CALL, makeName(SIMD_BOOL8X16), &(makeArray(16))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_BOOL16X8: {
      return make2(CALL, makeName(SIMD_BOOL16X8), &(makeArray(8))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_BOOL32X4: {
      return make2(CALL, makeName(SIMD_BOOL32X4), &(makeArray(4))->push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    case ASM_BOOL64X2: {
      return make2(CALL, makeName(SIMD_BOOL64X2), &(makeArray(2))->push_back(makeNum(0)).push_back(makeNum(0)));
      break;
    }
    default: assert(0);
  }
  abort();
}

Ref makeAsmCoercion(Ref node, AsmType type) {
  switch (type) {
    case ASM_INT: return make3(BINARY, OR, node, makeNum(0));
    case ASM_DOUBLE: return make2(UNARY_PREFIX, PLUS, node);
    case ASM_FLOAT: return make2(CALL, makeName(MATH_FROUND), &(makeArray(1))->push_back(node));
    case ASM_FLOAT32X4: return make2(CALL, makeName(SIMD_FLOAT32X4_CHECK), &(makeArray(1))->push_back(node));
    case ASM_FLOAT64X2: return make2(CALL, makeName(SIMD_FLOAT64X2_CHECK), &(makeArray(1))->push_back(node));
    case ASM_INT8X16: return make2(CALL, makeName(SIMD_INT8X16_CHECK), &(makeArray(1))->push_back(node));
    case ASM_INT16X8: return make2(CALL, makeName(SIMD_INT16X8_CHECK), &(makeArray(1))->push_back(node));
    case ASM_INT32X4: return make2(CALL, makeName(SIMD_INT32X4_CHECK), &(makeArray(1))->push_back(node));
    case ASM_NONE:
    default: return node; // non-validating code, emit nothing XXX this is dangerous, we should only allow this when we know we are not validating
  }
}

// Checks

bool isEmpty(Ref node) {
  return (node->size() == 2 && node[0] == TOPLEVEL && node[1]->size() == 0) ||
          (node->size() > 0 && node[0] == BLOCK && (!node[1] || node[1]->size() == 0));
}

bool commable(Ref node) { // TODO: hashing
  IString type = node[0]->getIString();
  if (type == ASSIGN || type == BINARY || type == UNARY_PREFIX || type == NAME || type == NUM || type == CALL || type == SEQ || type == CONDITIONAL || type == SUB) return true;
  return false;
}

bool isMathFunc(const char *name) {
  static const char *Math_ = "Math_";
  static unsigned size = strlen(Math_);
  return strncmp(name, Math_, size) == 0;
}

bool isMathFunc(Ref value) {
  return value->isString() && isMathFunc(value->getCString());
}

bool callHasSideEffects(Ref node) { // checks if the call itself (not the args) has side effects (or is not statically known)
  return !(node[1][0] == NAME && isMathFunc(node[1][1]));
}

bool hasSideEffects(Ref node) { // this is 99% incomplete!
  IString type = node[0]->getIString();
  switch (type[0]) {
    case 'n':
      if (type == NUM || type == NAME) return false;
      break;
    case 's':
      if (type == STRING) return false;
      if (type == SUB) return hasSideEffects(node[1]) || hasSideEffects(node[2]);
      break;
    case 'u':
      if (type == UNARY_PREFIX) return hasSideEffects(node[2]);
      break;
    case 'b':
      if (type == BINARY) return hasSideEffects(node[2]) || hasSideEffects(node[3]);
      break;
    case 'c':
      if (type == CALL) {
        if (callHasSideEffects(node)) return true;
        // This is a statically known call, with no side effects. only args can side effect us
        for (auto arg : node[2]->getArray()) {
          if (hasSideEffects(arg)) return true;
        }
        return false;
      } else if (type == CONDITIONAL) return hasSideEffects(node[1]) || hasSideEffects(node[2]) || hasSideEffects(node[3]); 
      break;
  }
  return true;
}

// checks if a node has just basic operations, nothing with side effects nor that can notice side effects, which
// implies we can move it around in the code
bool triviallySafeToMove(Ref node, AsmData& asmData) {
  bool ok = true;
  traversePre(node, [&](Ref node) {
    Ref type = node[0];
    if (type == STAT || type == BINARY || type == UNARY_PREFIX || type == ASSIGN || type == NUM) return;
    else if (type == NAME) {
      if (!asmData.isLocal(node[1]->getIString())) ok = false;
    } else if (type == CALL) {
      if (callHasSideEffects(node)) ok = false;
    } else {
      ok = false;
    }  
  });
  return ok;
}

// Transforms

// We often have branchings that are simplified so one end vanishes, and
// we then get
//   if (!(x < 5))
// or such. Simplifying these saves space and time.
Ref simplifyNotCompsDirect(Ref node) {
  if (node[0] == UNARY_PREFIX && node[1] == L_NOT) {
    // de-morgan's laws do not work on floats, due to nans >:(
    if (node[2][0] == BINARY && (detectType(node[2][2]) == ASM_INT && detectType(node[2][3]) == ASM_INT)) {
      Ref op = node[2][1];
      switch(op->getCString()[0]) {
        case '<': {
          if (op == LT)  { op->setString(GE); break; }
          if (op == LE) { op->setString(GT); break; }
          return node;
        }
        case '>': {
          if (op == GT)  { op->setString(LE); break; }
          if (op == GE) { op->setString(LT); break; }
          return node;
        }
        case '=': {
          if (op == EQ) { op->setString(NE); break; }
          return node;
        }
        case '!': {
          if (op == NE) { op->setString(EQ); break; }
          return node;
        }
        default: return node;
      }
      return make3(BINARY, op, node[2][2], node[2][3]);
    } else if (node[2][0] == UNARY_PREFIX && node[2][1] == L_NOT) {
      return node[2][2];
    }
  }
  return node;
}

Ref flipCondition(Ref cond) {
  return simplifyNotCompsDirect(make2(UNARY_PREFIX, L_NOT, cond));
}

void safeCopy(Ref target, Ref source) { // safely copy source onto target, even if source is a subnode of target
  Ref temp = source; // hold on to source
  *target = *temp;
}

void clearEmptyNodes(Ref arr) {
  int skip = 0;
  for (size_t i = 0; i < arr->size(); i++) {
    if (skip) {
      arr[i-skip] = arr[i];
    }
    if (isEmpty(deStat(arr[i]))) {
      skip++;
    }
  }
  if (skip) arr->setSize(arr->size() - skip);
}
void clearUselessNodes(Ref arr) {
  int skip = 0;
  for (size_t i = 0; i < arr->size(); i++) {
    Ref curr = arr[i];
    if (skip) {
      arr[i-skip] = curr;
    }
    if (isEmpty(deStat(curr)) || (curr[0] == STAT && !hasSideEffects(curr[1]))) {
      skip++;
    }
  }
  if (skip) arr->setSize(arr->size() - skip);
}

void removeAllEmptySubNodes(Ref ast) {
  traversePre(ast, [](Ref node) {
    if (node[0] == DEFUN) {
      clearEmptyNodes(node[3]);
    } else if (node[0] == BLOCK && node->size() > 1 && !!node[1]) {
      clearEmptyNodes(node[1]);
    } else if (node[0] == SEQ && isEmpty(node[1])) {
      safeCopy(node, node[2]);
    }
  });
}
void removeAllUselessSubNodes(Ref ast) {
  traversePrePost(ast, [](Ref node) {
    Ref type = node[0];
    if (type == DEFUN) {
      clearUselessNodes(node[3]);
    } else if (type == BLOCK && node->size() > 1 && !!node[1]) {
      clearUselessNodes(node[1]);
    } else if (type == SEQ && isEmpty(node[1])) {
      safeCopy(node, node[2]);
    }
  }, [](Ref node) {
    Ref type = node[0];
    if (type == IF) {
      bool empty2 = isEmpty(node[2]), has3 = node->size() == 4 && !!node[3], empty3 = !has3 || isEmpty(node[3]);
      if (!empty2 && empty3 && has3) { // empty else clauses
        node->setSize(3);
      } else if (empty2 && !empty3) { // empty if blocks
        safeCopy(node, make2(IF, make2(UNARY_PREFIX, L_NOT, node[1]), node[3]));
      } else if (empty2 && empty3) {
        if (hasSideEffects(node[1])) {
          safeCopy(node, make1(STAT, node[1]));
        } else {
          safeCopy(node, makeEmpty());
        }
      }
    }
  });
}

Ref unVarify(Ref vars) { // transform var x=1, y=2 etc. into (x=1, y=2), i.e., the same assigns, but without a var definition
  Ref ret = makeArray(1);
  ret->push_back(makeString(STAT));
  if (vars->size() == 1) {
    ret->push_back(make3(ASSIGN, makeBool(true), makeName(vars[0][0]->getIString()), vars[0][1]));
  } else {
    ret->push_back(makeArray(vars->size()-1));
    Ref curr = ret[1];
    for (size_t i = 0; i+1 < vars->size(); i++) {
      curr->push_back(makeString(SEQ));
      curr->push_back(make3(ASSIGN, makeBool(true), makeName(vars[i][0]->getIString()), vars[i][1]));
      if (i != vars->size()-2) {
        curr->push_back(makeArray());
        curr = curr[2];
      }
    }
    curr->push_back(make3(ASSIGN, makeBool(true), makeName(vars->back()[0]->getIString()), vars->back()[1]));
  }
  return ret;
}

// Calculations

int measureCost(Ref ast) {
  int size = 0;
  traversePre(ast, [&size](Ref node) {
    Ref type = node[0];
    if (type == NUM || type == UNARY_PREFIX) size--;
    else if (type == BINARY) {
      if (node[3][0] == NUM && node[3][1]->getNumber() == 0) size--;
      else if (node[1] == DIV || node[1] == MOD) size += 2;
    }
    else if (type == CALL && !callHasSideEffects(node)) size -= 2;
    else if (type == SUB) size++;
    size++;
  });
  return size;
}

//==================
// Params
//==================

bool preciseF32 = false,
     receiveJSON = false,
     emitJSON = false,
     minifyWhitespace = false,
     last = false;

//=====================
// Optimization passes
//=====================

#define HASES \
  bool has(const IString& str) { \
    return count(str) > 0; \
  } \
  bool has(Ref node) { \
    return node->isString() && count(node->getIString()) > 0; \
  }

class StringSet : public cashew::IStringSet {
public:
  StringSet() {}
  StringSet(const char *str) : IStringSet(str) {}

  HASES

  void dump() {
    err("===");
    for (auto str : *this) {
      errv("%s", str.c_str());
    }
    err("===");
  }
};

StringSet USEFUL_BINARY_OPS("<< >> | & ^"),
          COMPARE_OPS("< <= > >= == == != !=="),
          BITWISE("| & ^"),
          SAFE_BINARY_OPS("+ -"), // division is unsafe as it creates non-ints in JS; mod is unsafe as signs matter so we can't remove |0's; mul does not nest with +,- in asm
          COERCION_REQUIRING_OPS("sub unary-prefix"), // ops that in asm must be coerced right away
          COERCION_REQUIRING_BINARIES("* / %"); // binary ops that in asm must be coerced

StringSet ASSOCIATIVE_BINARIES("+ * | & ^"),
          CONTROL_FLOW("do while for if switch"),
          LOOP("do while for"),
          NAME_OR_NUM("name num"),
          CONDITION_CHECKERS("if do while switch"),
          BOOLEAN_RECEIVERS("if do while conditional"),
          SAFE_TO_DROP_COERCION("unary-prefix name num");

StringSet BREAK_CAPTURERS("do while for switch"),
          CONTINUE_CAPTURERS("do while for"),
          FUNCTIONS_THAT_ALWAYS_THROW("abort ___resumeException ___cxa_throw ___cxa_rethrow");

IString DCEABLE_TYPE_DECLS("__emscripten_dceable_type_decls");


bool isFunctionTable(const char *name) {
  static const char *functionTable = "FUNCTION_TABLE";
  static unsigned size = strlen(functionTable);
  return strncmp(name, functionTable, size) == 0;
}

bool isFunctionTable(Ref value) {
  return value->isString() && isFunctionTable(value->getCString());
}

// Internal utilities

bool canDropCoercion(Ref node) {
  if (SAFE_TO_DROP_COERCION.has(node[0])) return true;
  if (node[0] == BINARY) {
    switch (node[1]->getCString()[0]) {
      case '>': return node[1] == RSHIFT || node[1] == TRSHIFT;
      case '<': return node[1] == LSHIFT;
      case '|': case '^': case '&': return true;
    }
  }
  return false;
}

Ref simplifyCondition(Ref node) {
  node = simplifyNotCompsDirect(node);
  // on integers, if (x == 0) is the same as if (x), and if (x != 0) as if (!x)
  if (node[0] == BINARY && (node[1] == EQ || node[1] == NE)) {
    Ref target;
    if (detectType(node[2]) == ASM_INT && node[3][0] == NUM && node[3][1]->getNumber() == 0) {
      target = node[2];
    } else if (detectType(node[3]) == ASM_INT && node[2][0] == NUM && node[2][1]->getNumber() == 0) {
      target = node[3];
    }
    if (!!target) {
      if (target[0] == BINARY && (target[1] == OR || target[1] == TRSHIFT) && target[3][0] == NUM && target[3][1]->getNumber() == 0 &&
          canDropCoercion(target[2])) {
        target = target[2]; // drop the coercion, in a condition it is ok to do if (x)
      }
      if (node[1] == EQ) {
        return make2(UNARY_PREFIX, L_NOT, target);
      } else {
        return target;
      }
    }
  }
  return node;
}

// Passes

// Eliminator aka Expressionizer
//
// The goal of this pass is to eliminate unneeded variables (which represent one of the infinite registers in the LLVM
// model) and thus to generate complex expressions where possible, for example
//
//  var x = a(10);
//  var y = HEAP[20];
//  print(x+y);
//
// can be transformed into
//
//  print(a(10)+HEAP[20]);
//
// The basic principle is to scan along the code in the order of parsing/execution, and keep a list of tracked
// variables that are current contenders for elimination. We must untrack when we see something that we cannot
// cross, for example, a write to memory means we must invalidate variables that depend on reading from
// memory, since if we change the order then we do not preserve the computation.
//
// We rely on some assumptions about emscripten-generated code here, which means we can do a lot more than
// a general JS optimization can. For example, we assume that SUB nodes (indexing like HEAP[..]) are
// memory accesses or FUNCTION_TABLE accesses, and in both cases that the symbol cannot be replaced although
// the contents can. So we assume FUNCTION_TABLE might have its contents changed but not be pointed to
// a different object, which allows
//
//  var x = f();
//  FUNCTION_TABLE[x]();
//
// to be optimized (f could replace FUNCTION_TABLE, so in general JS eliminating x is not valid).
//
// In memSafe mode, we are more careful and assume functions can replace HEAP and FUNCTION_TABLE, which
// can happen in ALLOW_MEMORY_GROWTH mode

StringSet ELIMINATION_SAFE_NODES("assign call if toplevel do return label switch binary unary-prefix"); // do is checked carefully, however
StringSet IGNORABLE_ELIMINATOR_SCAN_NODES("num toplevel string break continue dot"); // dot can only be STRING_TABLE.*
StringSet ABORTING_ELIMINATOR_SCAN_NODES("new object function defun for while array throw"); // we could handle some of these, TODO, but nontrivial (e.g. for while, the condition is hit multiple times after the body)
StringSet HEAP_NAMES("HEAP8 HEAP16 HEAP32 HEAPU8 HEAPU16 HEAPU32 HEAPF32 HEAPF64");

bool isTempDoublePtrAccess(Ref node) { // these are used in bitcasts; they are not really affecting memory, and should cause no invalidation
  assert(node[0] == SUB);
  return (node[2][0] == NAME && node[2][1] == TEMP_DOUBLE_PTR) ||
         (node[2][0] == BINARY && ((node[2][2][0] == NAME && node[2][2][1] == TEMP_DOUBLE_PTR) ||
                                     (node[2][3][0] == NAME && node[2][3][1] == TEMP_DOUBLE_PTR)));
}

class StringIntMap : public std::unordered_map<IString, int> {
public:
  HASES
};

class StringStringMap : public std::unordered_map<IString, IString> {
public:
  HASES
};

class StringRefMap : public std::unordered_map<IString, Ref> {
public:
  HASES
};

class StringTypeMap : public std::unordered_map<IString, AsmType> {
public:
  HASES
};

void eliminate(Ref ast, bool memSafe) {
#ifdef PROFILING
  clock_t tasmdata = 0;
  clock_t tfnexamine = 0;
  clock_t tvarcheck = 0;
  clock_t tstmtelim = 0;
  clock_t tstmtscan = 0;
  clock_t tcleanvars = 0;
  clock_t treconstruct = 0;
#endif

  // Find variables that have a single use, and if they can be eliminated, do so
  traverseFunctions(ast, [&](Ref func) {

#ifdef PROFILING
    clock_t start = clock();
#endif

    AsmData asmData(func);

#ifdef PROFILING
    tasmdata += clock() - start;
    start = clock();
#endif

    // First, find the potentially eliminatable functions: that have one definition and one use

    StringIntMap definitions;
    StringIntMap uses;
    StringIntMap namings;
    StringRefMap values;
    StringIntMap varsToRemove; // variables being removed, that we can eliminate all 'var x;' of (this refers to VAR nodes we should remove)
                            // 1 means we should remove it, 2 means we successfully removed it
    StringSet varsToTryToRemove; // variables that have 0 uses, but have side effects - when we scan we can try to remove them

    // examine body and note locals
    traversePre(func, [&](Ref node) {
      Ref type = node[0];
      if (type == NAME) {
        IString& name = node[1]->getIString();
        uses[name]++;
        namings[name]++;
      } else if (type == ASSIGN) {
        Ref target = node[2];
        if (target[0] == NAME) {
          IString& name = target[1]->getIString();
          // values is only used if definitions is 1
          if (definitions[name]++ == 0) {
            values[name] = node[3];
          }
          assert(node[1]->isBool(true)); // not +=, -= etc., just =
          uses[name]--; // because the name node will show up by itself in the previous case
        }
      }
    });

#ifdef PROFILING
    tfnexamine += clock() - start;
    start = clock();
#endif

    StringSet potentials; // local variables with 1 definition and 1 use
    StringSet sideEffectFree; // whether a local variable has no side effects in its definition. Only relevant when there are no uses

    auto unprocessVariable = [&](IString name) {
      potentials.erase(name);
      varsToRemove.erase(name);
      sideEffectFree.erase(name);
      varsToTryToRemove.erase(name);
    };
    std::function<void (IString)> processVariable = [&](IString name) {
      if (definitions[name] == 1 && uses[name] == 1) {
        potentials.insert(name);
      } else if (uses[name] == 0 && definitions[name] <= 1) { // no uses, no def or 1 def (cannot operate on phis, and the llvm optimizer will remove unneeded phis anyhow) (no definition means it is a function parameter, or a local with just |var x;| but no defining assignment)
        bool sideEffects = false;
        auto val = values.find(name);
        Ref value;
        if (val != values.end()) {
          value = val->second;
          // TODO: merge with other side effect code
          // First, pattern-match
          //  (HEAP32[((tempDoublePtr)>>2)]=((HEAP32[(($_sroa_0_0__idx1)>>2)])|0),HEAP32[(((tempDoublePtr)+(4))>>2)]=((HEAP32[((($_sroa_0_0__idx1)+(4))>>2)])|0),(+(HEAPF64[(tempDoublePtr)>>3])))
          // which has no side effects and is the special form of converting double to i64.
          if (!(value[0] == SEQ && value[1][0] == ASSIGN && value[1][2][0] == SUB && value[1][2][2][0] == BINARY && value[1][2][2][1] == RSHIFT &&
                value[1][2][2][2][0] == NAME && value[1][2][2][2][1] == TEMP_DOUBLE_PTR)) {
            // If not that, then traverse and scan normally.
            sideEffects = hasSideEffects(value);
          }
        }
        if (!sideEffects) {
          varsToRemove[name] = !definitions[name] ? 2 : 1; // remove it normally
          sideEffectFree.insert(name);
          // Each time we remove a variable with 0 uses, if its value has no
          // side effects and vanishes too, then we can remove a use from variables
          // appearing in it, and possibly eliminate again
          if (!!value) {
            traversePre(value, [&](Ref node) {
              if (node[0] == NAME) {
                IString name = node[1]->getIString();
                node[1]->setString(EMPTY); // we can remove this - it will never be shown, and should not be left to confuse us as we traverse
                if (asmData.isLocal(name)) {
                  uses[name]--; // cannot be infinite recursion since we descend an energy function
                  assert(uses[name] >= 0);
                  unprocessVariable(name);
                  processVariable(name);
                }
              } else if (node[0] == CALL) {
                // no side effects, so this must be a Math.* call or such. We can just ignore it and all children
                node[0]->setString(NAME);
                node[1]->setString(EMPTY);
              }
            });
          }
        } else {
          varsToTryToRemove.insert(name); // try to remove it later during scanning
        }
      }
    };
    for (auto name : asmData.locals) {
      processVariable(name.first);
    }

#ifdef PROFILING
    tvarcheck += clock() - start;
    start = clock();
#endif

    //printErr('defs: ' + JSON.stringify(definitions));
    //printErr('uses: ' + JSON.stringify(uses));
    //printErr('values: ' + JSON.stringify(values));
    //printErr('locals: ' + JSON.stringify(locals));
    //printErr('varsToRemove: ' + JSON.stringify(varsToRemove));
    //printErr('varsToTryToRemove: ' + JSON.stringify(varsToTryToRemove));
    values.clear();
    //printErr('potentials: ' + JSON.stringify(potentials));
    // We can now proceed through the function. In each list of statements, we try to eliminate
    struct Tracking {
      bool usesGlobals, usesMemory, hasDeps;
      Ref defNode;
      bool doesCall;
    };
    class Tracked : public std::unordered_map<IString, Tracking> {
    public:
      HASES
    };
    Tracked tracked;
    #define dumpTracked() { errv("tracking %d", tracked.size()); for (auto t : tracked) errv("... %s", t.first.c_str()); }
    // Although a set would be more appropriate, it would also be slower
    std::unordered_map<IString, StringVec> depMap;

    bool globalsInvalidated = false; // do not repeat invalidations, until we track something new
    bool memoryInvalidated = false;
    bool callsInvalidated = false;
    auto track = [&](IString name, Ref value, Ref defNode) { // add a potential that has just been defined to the tracked list, we hope to eliminate it
      Tracking& track = tracked[name];
      track.usesGlobals = false;
      track.usesMemory = false;
      track.hasDeps = false;
      track.defNode = defNode;
      track.doesCall = false;
      bool ignoreName = false; // one-time ignorings of names, as first op in sub and call
      traversePre(value, [&](Ref node) {
        Ref type = node[0];
        if (type == NAME) {
          if (!ignoreName) {
            IString depName = node[1]->getIString();
            if (!asmData.isLocal(depName)) {
              track.usesGlobals = true;
            }
            if (!potentials.has(depName)) { // deps do not matter for potentials - they are defined once, so no complexity
              depMap[depName].push_back(name);
              track.hasDeps = true;
            }
          } else {
            ignoreName = false;
          }
        } else if (type == SUB) {
          track.usesMemory = true;
          ignoreName = true;
        } else if (type == CALL) {
          track.usesGlobals = true;
          track.usesMemory = true;
          track.doesCall = true;
          ignoreName = true;
        } else {
          ignoreName = false;
        }
      });
      if (track.usesGlobals) globalsInvalidated = false;
      if (track.usesMemory) memoryInvalidated = false;
      if (track.doesCall) callsInvalidated = false;
    };

    // TODO: invalidate using a sequence number for each type (if you were tracked before the last invalidation, you are cancelled). remove for.in loops
    #define INVALIDATE(what, check) \
    auto invalidate##what = [&]() { \
      std::vector<IString> temp; \
      for (auto t : tracked) { \
        IString name = t.first; \
        Tracking& info = tracked[name]; \
        if (check) { \
          temp.push_back(name); \
        } \
      } \
      for (size_t i = 0; i < temp.size(); i++) { \
        tracked.erase(temp[i]); \
      } \
    };
    INVALIDATE(Globals, info.usesGlobals);
    INVALIDATE(Memory, info.usesMemory);
    INVALIDATE(Calls, info.doesCall);

    auto invalidateByDep = [&](IString dep) {
      for (auto name : depMap[dep]) {
        tracked.erase(name);
      }
      depMap.erase(dep);
    };

    std::function<void (IString name, Ref node)> doEliminate;

    // Generate the sequence of execution. This determines what is executed before what, so we know what can be reordered. Using
    // that, performs invalidations and eliminations
    auto scan = [&](Ref node) {
      bool abort = false;
      bool allowTracking = true; // false inside an if; also prevents recursing in an if
      std::function<void (Ref, bool)> traverseInOrder = [&](Ref node, bool ignoreSub) {
        if (abort) return;
        Ref type = node[0];
        if (type == ASSIGN) {
          Ref target = node[2];
          Ref value = node[3];
          bool nameTarget = target[0] == NAME;
          // If this is an assign to a name, handle it below rather than
          // traversing and treating as a read
          if (!nameTarget) {
            traverseInOrder(target, true); // evaluate left
          }
          traverseInOrder(value,  false); // evaluate right
          // do the actual assignment
          if (nameTarget) {
            IString name = target[1]->getIString();
            if (potentials.has(name) && allowTracking) {
              track(name, node[3], node);
            } else if (varsToTryToRemove.has(name)) {
              // replace it in-place
              safeCopy(node, value);
              varsToRemove[name] = 2;
            } else {
              // expensive check for invalidating specific tracked vars. This list is generally quite short though, because of
              // how we just eliminate in short spans and abort when control flow happens TODO: history numbers instead
              invalidateByDep(name); // can happen more than once per dep..
              if (!asmData.isLocal(name) && !globalsInvalidated) {
                invalidateGlobals();
                globalsInvalidated = true;
              }
              // if we can track this name (that we assign into), and it has 0 uses and we want to remove its VAR
              // definition - then remove it right now, there is no later chance
              if (allowTracking && varsToRemove.has(name) && uses[name] == 0) {
                track(name, node[3], node);
                doEliminate(name, node);
              }
            }
          } else if (target[0] == SUB) {
            if (isTempDoublePtrAccess(target)) {
              if (!globalsInvalidated) {
                invalidateGlobals();
                globalsInvalidated = true;
              }
            } else if (!memoryInvalidated) {
              invalidateMemory();
              memoryInvalidated = true;
            }
          }
        } else if (type == SUB) {
          // Only keep track of the global array names in memsafe mode i.e.
          // when they may change underneath us due to resizing
          if (node[1][0] != NAME || memSafe) {
            traverseInOrder(node[1], false); // evaluate inner
          }
          traverseInOrder(node[2], false); // evaluate outer
          // ignoreSub means we are a write (happening later), not a read
          if (!ignoreSub && !isTempDoublePtrAccess(node)) {
            // do the memory access
            if (!callsInvalidated) {
              invalidateCalls();
              callsInvalidated = true;
            }
          }
        } else if (type == BINARY) {
          bool flipped = false;
          if (ASSOCIATIVE_BINARIES.has(node[1]) && !NAME_OR_NUM.has(node[2][0]) && NAME_OR_NUM.has(node[3][0])) { // TODO recurse here?
            // associatives like + and * can be reordered in the simple case of one of the sides being a name, since we assume they are all just numbers
            Ref temp = node[2];
            node[2] = node[3];
            node[3] = temp;
            flipped = true;
          }
          traverseInOrder(node[2], false);
          traverseInOrder(node[3], false);
          if (flipped && NAME_OR_NUM.has(node[2][0])) { // dunno if we optimized, but safe to flip back - and keeps the code closer to the original and more readable
            Ref temp = node[2];
            node[2] = node[3];
            node[3] = temp;
          }
        } else if (type == NAME) {
          IString name = node[1]->getIString();
          if (tracked.has(name)) {
            doEliminate(name, node);
          } else if (!asmData.isLocal(name) && !callsInvalidated && (memSafe || !HEAP_NAMES.has(name))) { // ignore HEAP8 etc when not memory safe, these are ok to
                                                                                                          // access, e.g. SIMD_Int32x4_load(HEAP8, ...)
            invalidateCalls();
            callsInvalidated = true;
          }
        } else if (type == UNARY_PREFIX) {
          traverseInOrder(node[2], false);
        } else if (IGNORABLE_ELIMINATOR_SCAN_NODES.has(type)) {
        } else if (type == CALL) {
          // Named functions never change and are therefore safe to not track
          if (node[1][0] != NAME) {
            traverseInOrder(node[1], false);
          }
          Ref args = node[2];
          for (size_t i = 0; i < args->size(); i++) {
            traverseInOrder(args[i], false);
          }
          if (callHasSideEffects(node)) {
            // these two invalidations will also invalidate calls
            if (!globalsInvalidated) {
              invalidateGlobals();
              globalsInvalidated = true;
            }
            if (!memoryInvalidated) {
              invalidateMemory();
              memoryInvalidated = true;
            }
          }
        } else if (type == IF) {
          if (allowTracking) {
            traverseInOrder(node[1], false); // can eliminate into condition, but nowhere else
            if (!callsInvalidated) { // invalidate calls, since we cannot eliminate them into an if that may not execute!
              invalidateCalls();
              callsInvalidated = true;
            }
            allowTracking = false;
            traverseInOrder(node[2], false); // 2 and 3 could be 'parallel', really..
            if (!!node[3]) traverseInOrder(node[3], false);
            allowTracking = true;
          } else {
            tracked.clear();
          }
        } else if (type == BLOCK) {
          Ref stats = getStatements(node);
          if (!!stats) {
            for (size_t i = 0; i < stats->size(); i++) {
              traverseInOrder(stats[i], false);
            }
          }
        } else if (type == STAT) {
          traverseInOrder(node[1], false);
        } else if (type == LABEL) {
          traverseInOrder(node[2], false);
        } else if (type == SEQ) {
          traverseInOrder(node[1], false);
          traverseInOrder(node[2], false);
        } else if (type == DO) {
          if (node[1][0] == NUM && node[1][1]->getNumber() == 0) { // one-time loop
            traverseInOrder(node[2], false);
          } else {
            tracked.clear();
          }
        } else if (type == RETURN) {
          if (!!node[1]) traverseInOrder(node[1], false);
        } else if (type == CONDITIONAL) {
          if (!callsInvalidated) { // invalidate calls, since we cannot eliminate them into a branch of an LLVM select/JS conditional that does not execute
            invalidateCalls();
            callsInvalidated = true;
          }
          traverseInOrder(node[1], false);
          traverseInOrder(node[2], false);
          traverseInOrder(node[3], false);
        } else if (type == SWITCH) {
          traverseInOrder(node[1], false);
          Tracked originalTracked = tracked;
          Ref cases = node[2];
          for (size_t i = 0; i < cases->size(); i++) {
            Ref c = cases[i];
            assert(c[0]->isNull() || c[0][0] == NUM || (c[0][0] == UNARY_PREFIX && c[0][2][0] == NUM));
            Ref stats = c[1];
            for (size_t j = 0; j < stats->size(); j++) {
              traverseInOrder(stats[j], false);
            }
            // We cannot track from one switch case into another if there are external dependencies, undo all new trackings
            // Otherwise we can track, e.g. a var used in a case before assignment in another case is UB in asm.js, so no need for the assignment
            // TODO: general framework here, use in if-else as well
            std::vector<IString> toDelete;
            for (auto t : tracked) {
              if (!originalTracked.has(t.first)) {
                Tracking& info = tracked[t.first];
                if (info.usesGlobals || info.usesMemory || info.hasDeps) {
                  toDelete.push_back(t.first);
                }
              }
            }
            for (auto t : toDelete) {
              tracked.erase(t);
            }
          }
          tracked.clear(); // do not track from inside the switch to outside
        } else {
          assert(ABORTING_ELIMINATOR_SCAN_NODES.has(type));
          tracked.clear();
          abort = true;
        }
      };
      traverseInOrder(node, false);
    };
    //var eliminationLimit = 0; // used to debugging purposes
    doEliminate = [&](IString name, Ref node) {
      //if (eliminationLimit == 0) return;
      //eliminationLimit--;
      //printErr('elim!!!!! ' + name);
      // yes, eliminate!
      varsToRemove[name] = 2; // both assign and var definitions can have other vars we must clean up
      assert(tracked.has(name));
      Tracking& info = tracked[name];
      Ref defNode = info.defNode;
      assert(!!defNode);
      if (!sideEffectFree.has(name)) {
        assert(defNode[0] != VAR);
        // assign
        Ref value = defNode[3];
        // wipe out the assign
        safeCopy(defNode, makeEmpty());
        // replace this node in-place
        safeCopy(node, value);
      } else {
        // This has no side effects and no uses, empty it out in-place
        safeCopy(node, makeEmpty());
      }
      tracked.erase(name);
    };
    traversePre(func, [&](Ref block) {
      // Look for statements, including while-switch pattern
      Ref stats = getStatements(block);
      if (!stats && (block[0] == WHILE && block[2][0] == SWITCH)) {
        stats = &(makeArray(1)->push_back(block[2]));
      }
      if (!stats) return;
      tracked.clear();
      for (size_t i = 0; i < stats->size(); i++) {
        Ref node = deStat(stats[i]);
        Ref type = node[0];
        if (type == RETURN && i+1 < stats->size()) {
          stats->setSize(i+1); // remove any code after a return
        }
        // Check for things that affect elimination
        if (ELIMINATION_SAFE_NODES.has(type)) {
#ifdef PROFILING
          tstmtelim += clock() - start;
          start = clock();
#endif
          scan(node);
#ifdef PROFILING
          tstmtscan += clock() - start;
          start = clock();
#endif
        } else if (type == VAR) {
          continue; // asm normalisation has reduced 'var' to just the names
        } else {
          tracked.clear(); // not a var or assign, break all potential elimination so far
        }
      }
    });

#ifdef PROFILING
    tstmtelim += clock() - start;
    start = clock();
#endif

    StringIntMap seenUses;
    StringStringMap helperReplacements; // for looper-helper optimization

    // clean up vars, and loop variable elimination
    traversePrePost(func, [&](Ref node) {
      // pre
      Ref type = node[0];
      /*if (type == VAR) {
        node[1] = node[1].filter(function(pair) { return !varsToRemove[pair[0]] });
        if (node[1]->size() == 0) {
          // wipe out an empty |var;|
          node[0] = TOPLEVEL;
          node[1] = [];
        }
      } else */
      if (type == ASSIGN && node[1]->isBool(true) && node[2][0] == NAME && node[3][0] == NAME && node[2][1] == node[3][1]) {
        // elimination led to X = X, which we can just remove
        safeCopy(node, makeEmpty());
      }
    }, [&](Ref node) {
      // post
      Ref type = node[0];
      if (type == NAME) {
        IString name = node[1]->getIString();
        if (helperReplacements.has(name)) {
          node[1]->setString(helperReplacements[name]);
          return; // no need to track this anymore, we can't loop-optimize more than once
        }
        // track how many uses we saw. we need to know when a variable is no longer used (hence we run this in the post)
        seenUses[name]++;
      } else if (type == WHILE) {
        // try to remove loop helper variables specifically
        Ref stats = node[2][1];
        Ref last = stats->back();
        if (!!last && last[0] == IF && last[2][0] == BLOCK && !!last[3] && last[3][0] == BLOCK) {
          Ref ifTrue = last[2];
          Ref ifFalse = last[3];
          clearEmptyNodes(ifTrue[1]);
          clearEmptyNodes(ifFalse[1]);
          bool flip = false;
          if (ifFalse[1]->size() > 0 && !!ifFalse[1][0] && !!ifFalse[1]->back() && ifFalse[1]->back()[0] == BREAK) { // canonicalize break in the if-true
            Ref temp = ifFalse;
            ifFalse = ifTrue;
            ifTrue = temp;
            flip = true;
          }
          if (ifTrue[1]->size() > 0 && !!ifTrue[1][0] && !!ifTrue[1]->back() && ifTrue[1]->back()[0] == BREAK) {
            Ref assigns = ifFalse[1];
            clearEmptyNodes(assigns);
            std::vector<IString> loopers, helpers;
            for (size_t i = 0; i < assigns->size(); i++) {
              if (assigns[i][0] == STAT && assigns[i][1][0] == ASSIGN) {
                Ref assign = assigns[i][1];
                if (assign[1]->isBool(true) && assign[2][0] == NAME && assign[3][0] == NAME) {
                  IString looper = assign[2][1]->getIString();
                  IString helper = assign[3][1]->getIString();
                  if (definitions[helper] == 1 && seenUses[looper] == namings[looper] &&
                      !helperReplacements.has(helper) && !helperReplacements.has(looper)) {
                    loopers.push_back(looper);
                    helpers.push_back(helper);
                  }
                }
              }
            }
            // remove loop vars that are used in the rest of the else
            for (size_t i = 0; i < assigns->size(); i++) {
              if (assigns[i][0] == STAT && assigns[i][1][0] == ASSIGN) {
                Ref assign = assigns[i][1];
                if (!(assign[1]->isBool(true) && assign[2][0] == NAME && assign[3][0] == NAME) || indexOf(loopers, assign[2][1]->getIString()) < 0) {
                  // this is not one of the loop assigns
                  traversePre(assign, [&](Ref node) {
                    if (node[0] == NAME) {
                      int index = indexOf(loopers, node[1]->getIString());
                      if (index < 0) index = indexOf(helpers, node[1]->getIString());
                      if (index >= 0) {
                        loopers.erase(loopers.begin() + index);
                        helpers.erase(helpers.begin() + index);
                      }
                    }
                  });
                }
              }
            }
            // remove loop vars that are used in the if
            traversePre(ifTrue, [&](Ref node) {
              if (node[0] == NAME) {
                int index = indexOf(loopers, node[1]->getIString());
                if (index < 0) index = indexOf(helpers, node[1]->getIString());
                if (index >= 0) {
                  loopers.erase(loopers.begin() + index);
                  helpers.erase(helpers.begin() + index);
                }
              }
            });
            if (loopers.size() == 0) return;
            for (size_t l = 0; l < loopers.size(); l++) {
              IString looper = loopers[l];
              IString helper = helpers[l];
              // the remaining issue is whether loopers are used after the assignment to helper and before the last line (where we assign to it)
              int found = -1;
              for (int i = (int)stats->size()-2; i >= 0; i--) {
                Ref curr = stats[i];
                if (curr[0] == STAT && curr[1][0] == ASSIGN) {
                  Ref currAssign = curr[1];
                  if (currAssign[1]->isBool(true) && currAssign[2][0] == NAME) {
                    IString to = currAssign[2][1]->getIString();
                    if (to == helper) {
                      found = i;
                      break;
                    }
                  }
                }
              }
              if (found < 0) return;
              // if a loop variable is used after we assigned to the helper, we must save its value and use that.
              // (note that this can happen due to elimination, if we eliminate an expression containing the
              // loop var far down, past the assignment!)
              // first, see if the looper and helpers overlap. Note that we check for this looper, compared to
              // *ALL* the helpers. Helpers will be replaced by loopers as we eliminate them, potentially
              // causing conflicts, so any helper is a concern.
              int firstLooperUsage = -1;
              int lastLooperUsage = -1;
              int firstHelperUsage = -1;
              for (int i = found+1; i < (int)stats->size(); i++) {
                Ref curr = i < (int)stats->size()-1 ? stats[i] : last[1]; // on the last line, just look in the condition
                traversePre(curr, [&](Ref node) {
                  if (node[0] == NAME) {
                    if (node[1] == looper) {
                      if (firstLooperUsage < 0) firstLooperUsage = i;
                      lastLooperUsage = i;
                    } else if (indexOf(helpers, node[1]->getIString()) >= 0) {
                      if (firstHelperUsage < 0) firstHelperUsage = i;
                    }
                  }
                });
              }
              if (firstLooperUsage >= 0) {
                // the looper is used, we cannot simply merge the two variables
                if ((firstHelperUsage < 0 || firstHelperUsage > lastLooperUsage) && lastLooperUsage+1 < (int)stats->size() && triviallySafeToMove(stats[found], asmData) &&
                    seenUses[helper] == namings[helper]) {
                  // the helper is not used, or it is used after the last use of the looper, so they do not overlap,
                  // and the last looper usage is not on the last line (where we could not append after it), and the
                  // helper is not used outside of the loop.
                  // just move the looper definition to after the looper's last use
                  stats->insert(lastLooperUsage+1, stats[found]);
                  stats->splice(found, 1);
                } else {
                  // they overlap, we can still proceed with the loop optimization, but we must introduce a
                  // loop temp helper variable
                  IString temp(strdupe((std::string(looper.c_str()) + "$looptemp").c_str()));
                  assert(!asmData.isLocal(temp));
                  for (int i = firstLooperUsage; i <= lastLooperUsage; i++) {
                    Ref curr = i < (int)stats->size()-1 ? stats[i] : last[1]; // on the last line, just look in the condition

                    std::function<bool (Ref)> looperToLooptemp = [&](Ref node) {
                      if (node[0] == NAME) {
                        if (node[1] == looper) {
                          node[1]->setString(temp);
                        }
                      } else if (node[0] == ASSIGN && node[2][0] == NAME) {
                        // do not traverse the assignment target, phi assignments to the loop variable must remain
                        traversePrePostConditional(node[3], looperToLooptemp, [](Ref node){});
                        return false;
                      }
                      return true;
                    };
                    traversePrePostConditional(curr, looperToLooptemp, [](Ref node){});
                  }
                  asmData.addVar(temp, asmData.getType(looper));
                  stats->insert(found, make1(STAT, make3(ASSIGN, makeBool(true), makeName(temp), makeName(looper))));
                }
              }
            }
            for (size_t l = 0; l < helpers.size(); l++) {
              for (size_t k = 0; k < helpers.size(); k++) {
                if (l != k && helpers[l] == helpers[k]) return; // it is complicated to handle a shared helper, abort
              }
            }
            // hurrah! this is safe to do
            for (size_t l = 0; l < loopers.size(); l++) {
              IString looper = loopers[l];
              IString helper = helpers[l];
              varsToRemove[helper] = 2;
              traversePre(node, [&](Ref node) { // replace all appearances of helper with looper
                if (node[0] == NAME && node[1] == helper) node[1]->setString(looper);
              });
              helperReplacements[helper] = looper; // replace all future appearances of helper with looper
              helperReplacements[looper] = looper; // avoid any further attempts to optimize looper in this manner (seenUses is wrong anyhow, too)
            }
            // simplify the if. we remove the if branch, leaving only the else
            if (flip) {
              last[1] = simplifyNotCompsDirect(make2(UNARY_PREFIX, L_NOT, last[1]));
              Ref temp = last[2];
              last[2] = last[3];
              last[3] = temp;
            }
            if (loopers.size() == assigns->size()) {
              last->pop_back();
            } else {
              Ref elseStats = getStatements(last[3]);
              for (size_t i = 0; i < elseStats->size(); i++) {
                Ref stat = deStat(elseStats[i]);
                if (stat[0] == ASSIGN && stat[2][0] == NAME) {
                  if (indexOf(loopers, stat[2][1]->getIString()) >= 0) {
                    elseStats[i] = makeEmpty();
                  }
                }
              }
            }
          }
        }
      }
    });

#ifdef PROFILING
    tcleanvars += clock() - start;
    start = clock();
#endif

    for (auto v : varsToRemove) {
      if (v.second == 2 && asmData.isVar(v.first)) asmData.deleteVar(v.first);
    }

    asmData.denormalize();

#ifdef PROFILING
    treconstruct += clock() - start;
    start = clock();
#endif

  });

  removeAllEmptySubNodes(ast);

#ifdef PROFILING
  errv("    EL stages: a:%li fe:%li vc:%li se:%li (ss:%li) cv:%li r:%li",
    tasmdata, tfnexamine, tvarcheck, tstmtelim, tstmtscan, tcleanvars, treconstruct);
#endif
}

void eliminateMemSafe(Ref ast) {
  eliminate(ast, true);
}

void simplifyExpressions(Ref ast) {
  // Simplify common expressions used to perform integer conversion operations
  // in cases where no conversion is needed.
  auto simplifyIntegerConversions = [](Ref ast) {
    traversePre(ast, [](Ref node) {
      Ref type = node[0];
      if (type == BINARY       && node[1]    == RSHIFT && node[3][0] == NUM &&
          node[2][0] == BINARY && node[2][1] == LSHIFT && node[2][3][0] == NUM && node[3][1]->getNumber() == node[2][3][1]->getNumber()) {
        // Transform (x&A)<<B>>B to X&A.
        Ref innerNode = node[2][2];
        double shifts = node[3][1]->getNumber();
        if (innerNode[0] == BINARY && innerNode[1] == AND && innerNode[3][0] == NUM) {
          double mask = innerNode[3][1]->getNumber();
          if (isInteger32(mask) && isInteger32(shifts) && ((jsD2I(mask) << jsD2I(shifts)) >> jsD2I(shifts)) == jsD2I(mask)) {
            safeCopy(node, innerNode);
            return;
          }
        }
      } else if (type == BINARY && BITWISE.has(node[1])) {
        for (int i = 2; i <= 3; i++) {
          Ref subNode = node[i];
          if (subNode[0] == BINARY && subNode[1] == AND && subNode[3][0] == NUM && subNode[3][1]->getNumber() == 1) {
            // Rewrite (X < Y) & 1 to X < Y , when it is going into a bitwise operator. We could
            // remove even more (just replace &1 with |0, then subsequent passes could remove the |0)
            // but v8 issue #2513 means the code would then run very slowly in chrome.
            Ref input = subNode[2];
            if (input[0] == BINARY && COMPARE_OPS.has(input[1])) {
              safeCopy(node[i], input);
            }
          }
        }
      }
    });
  };

  // When there is a bunch of math like (((8+5)|0)+12)|0, only the external |0 is needed, one correction is enough.
  // At each node, ((X|0)+Y)|0 can be transformed into (X+Y): The inner corrections are not needed
  // TODO: Is the same is true for 0xff, 0xffff?
  // Likewise, if we have |0 inside a block that will be >>'d, then the |0 is unnecessary because some
  // 'useful' mathops already |0 anyhow.

  auto simplifyOps = [](Ref ast) {
    auto removeMultipleOrZero = [&ast] {
      bool rerun = true;
      while (rerun) {
        rerun = false;
        std::vector<int> stack;
        std::function<void (Ref)> process = [&stack, &rerun, &process, &ast](Ref node) {
          Ref type = node[0];
          if (type == BINARY && node[1] == OR) {
            if (node[2][0] == NUM && node[3][0] == NUM) {
              node[2][1]->setNumber(jsD2I(node[2][1]->getNumber()) | jsD2I(node[3][1]->getNumber()));
              stack.push_back(0);
              safeCopy(node, node[2]);
              return;
            }
            bool go = false;
            if (node[2][0] == NUM && node[2][1]->getNumber() == 0) {
              // canonicalize order
              Ref temp = node[3];
              node[3] = node[2];
              node[2] = temp;
              go = true;
            } else if (node[3][0] == NUM && node[3][1]->getNumber() == 0) {
              go = true;
            }
            if (!go) {
              stack.push_back(1);
              return;
            }
            // We might be able to remove this correction
            for (int i = stack.size()-1; i >= 0; i--) {
              if (stack[i] >= 1) {
                if (stack.back() < 2 && node[2][0] == CALL) break; // we can only remove multiple |0s on these
                if (stack.back() < 1 && (COERCION_REQUIRING_OPS.has(node[2][0]) ||
                                                 (node[2][0] == BINARY && COERCION_REQUIRING_BINARIES.has(node[2][1])))) break; // we can remove |0 or >>2
                // we will replace ourselves with the non-zero side. Recursively process that node.
                Ref result = node[2][0] == NUM && node[2][1]->getNumber() == 0 ? node[3] : node[2], other;
                // replace node in-place
                safeCopy(node, result);
                rerun = true;
                process(result);
                return;
              } else if (stack[i] == -1) {
                break; // Too bad, we can't
              }
            }
            stack.push_back(2); // From here on up, no need for this kind of correction, it's done at the top
                           // (Add this at the end, so it is only added if we did not remove it)
          } else if (type == BINARY && USEFUL_BINARY_OPS.has(node[1])) {
            stack.push_back(1);
          } else if ((type == BINARY && SAFE_BINARY_OPS.has(node[1])) || type == NUM || type == NAME) {
            stack.push_back(0); // This node is safe in that it does not interfere with this optimization
          } else if (type == UNARY_PREFIX && node[1] == B_NOT) {
            stack.push_back(1);
          } else {
            stack.push_back(-1); // This node is dangerous! Give up if you see this before you see '1'
          }
        };

        traversePrePost(ast, process, [&stack](Ref node) {
          assert(!stack.empty());
          stack.pop_back();
        });
      }
    };

    removeMultipleOrZero();

    // & and heap-related optimizations

    bool hasTempDoublePtr = false, rerunOrZeroPass = false;

    traversePrePostConditional(ast, [](Ref node) {
      // Detect trees which should not
      // be simplified.
      if (node[0] == SUB && node[1][0] == NAME && isFunctionTable(node[1][1])) {
        return false; // do not traverse subchildren here, we should not collapse 55 & 126.
      }
      return true;
    }, [&hasTempDoublePtr, &rerunOrZeroPass](Ref node) {
      // Simplifications are done now so
      // that we simplify a node's operands before the node itself. This allows
      // optimizations to cascade.
      Ref type = node[0];
      if (type == NAME) {
        if (node[1] == TEMP_DOUBLE_PTR) hasTempDoublePtr = true;
      } else if (type == BINARY && node[1] == AND && node[3][0] == NUM) {
        if (node[2][0] == NUM) {
          safeCopy(node, makeNum(jsD2I(node[2][1]->getNumber()) & jsD2I(node[3][1]->getNumber())));
          return;
        }
        Ref input = node[2];
        double amount = node[3][1]->getNumber();
        if (input[0] == BINARY && input[1] == AND && input[3][0] == NUM) {
          // Collapse X & 255 & 1
          node[3][1]->setNumber(jsD2I(amount) & jsD2I(input[3][1]->getNumber()));
          node[2] = input[2];
        } else if (input[0] == SUB && input[1][0] == NAME) {
          // HEAP8[..] & 255 => HEAPU8[..]
          HeapInfo hi = parseHeap(input[1][1]->getCString());
          if (hi.valid) {
            if (isInteger32(amount) && amount == powl(2, hi.bits)-1) {
              if (!hi.unsign) {
                input[1][1]->setString(getHeapStr(hi.bits, true)); // make unsigned
              }
              // we cannot return HEAPU8 without a coercion, but at least we do HEAP8 & 255 => HEAPU8 | 0
              node[1]->setString(OR);
              node[3][1]->setNumber(0);
              return;
            }
          }
        } else if (input[0] == BINARY && input[1] == RSHIFT &&
                   input[2][0] == BINARY && input[2][1] == LSHIFT &&
                   input[2][3][0] == NUM && input[3][0] == NUM &&
                   input[2][3][1]->getInteger() == input[3][1]->getInteger() &&
                   (~(0xFFFFFFFFu >> input[3][1]->getInteger()) & jsD2I(amount)) == 0) {
            // x << 24 >> 24 & 255 => x & 255
            return safeCopy(node, make3(BINARY, AND, input[2][2], node[3]));
        }
      } else if (type == BINARY && node[1] == XOR) {
        // LLVM represents bitwise not as xor with -1. Translate it back to an actual bitwise not.
        if (node[3][0] == UNARY_PREFIX && node[3][1] == MINUS && node[3][2][0] == NUM &&
            node[3][2][1]->getNumber() == 1 &&
            !(node[2][0] == UNARY_PREFIX && node[2][1] == B_NOT)) { // avoid creating ~~~ which is confusing for asm given the role of ~~
          safeCopy(node, make2(UNARY_PREFIX, B_NOT, node[2]));
          return;
        }
      } else if (type       == BINARY && node[1]    == RSHIFT && node[3][0]    == NUM &&
                 node[2][0] == BINARY && node[2][1] == LSHIFT && node[2][3][0] == NUM &&
                 node[2][2][0] == SUB && node[2][2][1][0] == NAME) {
        // collapse HEAPU?8[..] << 24 >> 24 etc. into HEAP8[..] | 0
        double amount = node[3][1]->getNumber();
        if (amount == node[2][3][1]->getNumber()) {
          HeapInfo hi = parseHeap(node[2][2][1][1]->getCString());
          if (hi.valid && hi.bits == 32 - amount) {
            node[2][2][1][1]->setString(getHeapStr(hi.bits, false));
            node[1]->setString(OR);
            node[2] = node[2][2];
            node[3][1]->setNumber(0);
            rerunOrZeroPass = true;
            return;
          }
        }
      } else if (type == ASSIGN) {
        // optimizations for assigning into HEAP32 specifically
        if (node[1]->isBool(true) && node[2][0] == SUB && node[2][1][0] == NAME) {
          if (node[2][1][1] == HEAP32) {
            // HEAP32[..] = x | 0 does not need the | 0 (unless it is a mandatory |0 of a call)
            if (node[3][0] == BINARY && node[3][1] == OR) {
              if (node[3][2][0] == NUM && node[3][2][1]->getNumber() == 0 && node[3][3][0] != CALL) {
                node[3] = node[3][3];
              } else if (node[3][3][0] == NUM && node[3][3][1]->getNumber() == 0 && node[3][2][0] != CALL) {
                node[3] = node[3][2];
              }
            }
          } else if (node[2][1][1] == HEAP8) {
            // HEAP8[..] = x & 0xff does not need the & 0xff
            if (node[3][0] == BINARY && node[3][1] == AND && node[3][3][0] == NUM && node[3][3][1]->getNumber() == 0xff) {
              node[3] = node[3][2];
            }
          } else if (node[2][1][1] == HEAP16) {
            // HEAP16[..] = x & 0xffff does not need the & 0xffff
            if (node[3][0] == BINARY && node[3][1] == AND && node[3][3][0] == NUM && node[3][3][1]->getNumber() == 0xffff) {
              node[3] = node[3][2];
            }
          }
        }
        Ref value = node[3];
        if (value[0] == BINARY && value[1] == OR) {
          // canonicalize order of |0 to end
          if (value[2][0] == NUM && value[2][1]->getNumber() == 0) {
            Ref temp = value[2];
            value[2] = value[3];
            value[3] = temp;
          }
          // if a seq ends in an |0, remove an external |0
          // note that it is only safe to do this in assigns, like we are doing here (return (x, y|0); is not valid)
          if (value[2][0] == SEQ && value[2][2][0] == BINARY && USEFUL_BINARY_OPS.has(value[2][2][1])) {
            node[3] = value[2];
          }
        }
      } else if (type == BINARY && node[1] == RSHIFT && node[2][0] == NUM && node[3][0] == NUM) {
        // optimize num >> num, in asm we need this since we do not optimize shifts in asm.js
        node[0]->setString(NUM);
        node[1]->setNumber(jsD2I(node[2][1]->getNumber()) >> jsD2I(node[3][1]->getNumber()));
        node->setSize(2);
        return;
      } else if (type == BINARY && node[1] == PLUS) {
        // The most common mathop is addition, e.g. in getelementptr done repeatedly. We can join all of those,
        // by doing (num+num) ==> newnum.
        if (node[2][0] == NUM && node[3][0] == NUM) {
          node[2][1]->setNumber(jsD2I(node[2][1]->getNumber()) + jsD2I(node[3][1]->getNumber()));
          safeCopy(node, node[2]);
          return;
        }
      }
    });

    if (rerunOrZeroPass) removeMultipleOrZero();

    if (hasTempDoublePtr) {
      AsmData asmData(ast);
      traversePre(ast, [](Ref node) {
        Ref type = node[0];
        if (type == ASSIGN) {
          if (node[1]->isBool(true) && node[2][0] == SUB && node[2][1][0] == NAME && node[2][1][1] == HEAP32) {
            // remove bitcasts that are now obviously pointless, e.g.
            // HEAP32[$45 >> 2] = HEAPF32[tempDoublePtr >> 2] = ($14 < $28 ? $14 : $28) - $42, HEAP32[tempDoublePtr >> 2] | 0;
            Ref value = node[3];
            if (value[0] == SEQ && value[1][0] == ASSIGN && value[1][2][0] == SUB && value[1][2][1][0] == NAME && value[1][2][1][1] == HEAPF32 &&
                value[1][2][2][0] == BINARY && value[1][2][2][2][0] == NAME && value[1][2][2][2][1] == TEMP_DOUBLE_PTR) {
              // transform to HEAPF32[$45 >> 2] = ($14 < $28 ? $14 : $28) - $42;
              node[2][1][1]->setString(HEAPF32);
              node[3] = value[1][3];
            }
          }
        } else if (type == SEQ) {
          // (HEAP32[tempDoublePtr >> 2] = HEAP32[$37 >> 2], +HEAPF32[tempDoublePtr >> 2])
          //   ==>
          // +HEAPF32[$37 >> 2]
          if (node[0] == SEQ && node[1][0] == ASSIGN && node[1][2][0] == SUB && node[1][2][1][0] == NAME &&
              (node[1][2][1][1] == HEAP32 || node[1][2][1][1] == HEAPF32) &&
              node[1][2][2][0] == BINARY && node[1][2][2][2][0] == NAME && node[1][2][2][2][1] == TEMP_DOUBLE_PTR &&
              node[1][3][0] == SUB && node[1][3][1][0] == NAME && (node[1][3][1][1] == HEAP32 || node[1][3][1][1] == HEAPF32) &&
              node[2][0] != SEQ) { // avoid (x, y, z) which can be used for tempDoublePtr on doubles for alignment fixes
            if (node[1][2][1][1] == HEAP32) {
              node[1][3][1][1]->setString(HEAPF32);
              safeCopy(node, makeAsmCoercion(node[1][3], detectType(node[2])));
              return;
            } else {
              node[1][3][1][1]->setString(HEAP32);
              safeCopy(node, make3(BINARY, OR, node[1][3], makeNum(0)));
              return;
            }
          }
        }
      });

      // finally, wipe out remaining ones by finding cases where all assignments to X are bitcasts, and all uses are writes to
      // the other heap type, then eliminate the bitcast
      struct BitcastData {
        int define_HEAP32, define_HEAPF32, use_HEAP32, use_HEAPF32, namings;
        bool ok;
        std::vector<Ref> defines, uses;

        BitcastData() : define_HEAP32(0), define_HEAPF32(0), use_HEAP32(0), use_HEAPF32(0), namings(0), ok(false) {}
      };
      std::unordered_map<IString, BitcastData> bitcastVars;
      traversePre(ast, [&bitcastVars](Ref node) {
        if (node[0] == ASSIGN && node[1]->isBool(true) && node[2][0] == NAME) {
          Ref value = node[3];
          if (value[0] == SEQ && value[1][0] == ASSIGN && value[1][2][0] == SUB && value[1][2][1][0] == NAME &&
              (value[1][2][1][1] == HEAP32 || value[1][2][1][1] == HEAPF32) &&
              value[1][2][2][0] == BINARY && value[1][2][2][2][0] == NAME && value[1][2][2][2][1] == TEMP_DOUBLE_PTR) {
            IString name = node[2][1]->getIString();
            IString heap = value[1][2][1][1]->getIString();
            if (heap == HEAP32) {
              bitcastVars[name].define_HEAP32++;
            } else {
              assert(heap == HEAPF32);
              bitcastVars[name].define_HEAPF32++;
            }
            bitcastVars[name].defines.push_back(node);
            bitcastVars[name].ok = true;
          }
        }
      });
      traversePre(ast, [&bitcastVars](Ref node) {
        Ref type = node[0];
        if (type == NAME && bitcastVars[node[1]->getCString()].ok) {
          bitcastVars[node[1]->getCString()].namings++;
        } else if (type == ASSIGN && node[1]->isBool(true)) {
          Ref value = node[3];
          if (value[0] == NAME) {
            IString name = value[1]->getIString();
            if (bitcastVars[name].ok) {
              Ref target = node[2];
              if (target[0] == SUB && target[1][0] == NAME && (target[1][1] == HEAP32 || target[1][1] == HEAPF32)) {
                if (target[1][1] == HEAP32) {
                  bitcastVars[name].use_HEAP32++;
                } else {
                  bitcastVars[name].use_HEAPF32++;
                }
                bitcastVars[name].uses.push_back(node);
              }
            }
          }
        }
      });
      for (auto iter : bitcastVars) {
        const IString& v = iter.first;
        BitcastData& info = iter.second;
        // good variables define only one type, use only one type, have definitions and uses, and define as a different type than they use
        if (info.define_HEAP32*info.define_HEAPF32 == 0 && info.use_HEAP32*info.use_HEAPF32 == 0 &&
            info.define_HEAP32+info.define_HEAPF32 > 0  && info.use_HEAP32+info.use_HEAPF32 > 0 &&
            info.define_HEAP32*info.use_HEAP32 == 0 && info.define_HEAPF32*info.use_HEAPF32 == 0 &&
            asmData.isLocal(v.c_str()) && info.namings == info.define_HEAP32+info.define_HEAPF32+info.use_HEAP32+info.use_HEAPF32) {
          IString& correct = info.use_HEAP32 ? HEAPF32 : HEAP32;
          for (auto define : info.defines) {
            define[3] = define[3][1][3];
            if (correct == HEAP32) {
              define[3] = make3(BINARY, OR, define[3], makeNum(0));
            } else {
              assert(correct == HEAPF32);
              define[3] = makeAsmCoercion(define[3], preciseF32 ? ASM_FLOAT : ASM_DOUBLE);
            }
            // do we want a simplifybitops on the new values here?
          }
          for (auto use : info.uses) {
            use[2][1][1]->setString(correct.c_str());
          }
          AsmType correctType;
          switch(asmData.getType(v.c_str())) {
            case ASM_INT: correctType = preciseF32 ? ASM_FLOAT : ASM_DOUBLE; break;
            case ASM_FLOAT: case ASM_DOUBLE: correctType = ASM_INT; break;
            default: assert(0);
          }
          asmData.setType(v.c_str(), correctType);
        }
      }
      asmData.denormalize();
    }
  };

  std::function<bool (Ref)> emitsBoolean = [&emitsBoolean](Ref node) {
    Ref type = node[0];
    if (type == NUM) {
      return node[1]->getNumber() == 0 || node[1]->getNumber() == 1;
    }
    if (type == BINARY) return COMPARE_OPS.has(node[1]);
    if (type == UNARY_PREFIX) return node[1] == L_NOT;
    if (type == CONDITIONAL) return emitsBoolean(node[2]) && emitsBoolean(node[3]);
    return false;
  };

  //   expensive | expensive can be turned into expensive ? 1 : expensive, and
  //   expensive | cheap     can be turned into cheap     ? 1 : expensive,
  // so that we can avoid the expensive computation, if it has no side effects.
  auto conditionalize = [&emitsBoolean](Ref ast) {
    traversePre(ast, [&emitsBoolean](Ref node) {
        const int MIN_COST = 7;
        if (node[0] == BINARY && (node[1] == OR || node[1] == AND) && node[3][0] != NUM && node[2][0] != NUM) {
        // logical operator on two non-numerical values
        Ref left = node[2];
        Ref right = node[3];
        if (!emitsBoolean(left) || !emitsBoolean(right)) return;
        bool leftEffects = hasSideEffects(left);
        bool rightEffects = hasSideEffects(right);
        if (leftEffects && rightEffects) return; // both must execute
        // canonicalize with side effects, if any, happening on the left
        if (rightEffects) {
          if (measureCost(left) < MIN_COST) return; // avoidable code is too cheap
          Ref temp = left;
          left = right;
          right = temp;
        } else if (leftEffects) {
          if (measureCost(right) < MIN_COST) return; // avoidable code is too cheap
        } else {
          // no side effects, reorder based on cost estimation
          int leftCost = measureCost(left);
          int rightCost = measureCost(right);
          if (std::max(leftCost, rightCost) < MIN_COST) return; // avoidable code is too cheap
          // canonicalize with expensive code on the right
          if (leftCost > rightCost) {
            Ref temp = left;
            left = right;
            right = temp;
          }
        }
        // worth it, perform conditionalization
        Ref ret;
        if (node[1] == OR) {
          ret = make3(CONDITIONAL, left, makeNum(1), right);
        } else { // &
          ret = make3(CONDITIONAL, left, right, makeNum(0));
        }
        if (left[0] == UNARY_PREFIX && left[1] == L_NOT) {
          ret[1] = flipCondition(left);
          Ref temp = ret[2];
          ret[2] = ret[3];
          ret[3] = temp;
        }
        safeCopy(node, ret);
        return;
      }
    });
  };

  auto simplifyNotZero = [](Ref ast) {
    traversePre(ast, [](Ref node) {
      if (BOOLEAN_RECEIVERS.has(node[0])) {
        auto boolean = node[1];
        if (boolean[0] == BINARY && boolean[1] == NE && boolean[3][0] == NUM && boolean[3][1]->getNumber() == 0) {
          node[1] = boolean[2];
        }
      }
    });
  };

  traverseFunctions(ast, [&](Ref func) {
    simplifyIntegerConversions(func);
    simplifyOps(func);
    traversePre(func, [](Ref node) {
      Ref ret = simplifyNotCompsDirect(node);
      if (ret.get() != node.get()) { // if we received a different pointer in return, then we need to copy the new value
        safeCopy(node, ret);
      }
    });
    conditionalize(func);
    simplifyNotZero(func);
  });
}

void simplifyIfs(Ref ast) {
  traverseFunctions(ast, [](Ref func) {
    bool simplifiedAnElse = false;

    traversePre(func, [&simplifiedAnElse](Ref node) {
      // simplify   if (x) { if (y) { .. } }   to   if (x ? y : 0) { .. }
      if (node[0] == IF) {
        Ref body = node[2];
        // recurse to handle chains
        while (body[0] == BLOCK) {
          Ref stats = body[1];
          if (stats->size() == 0) break;
          Ref other = stats->back();
          if (other[0] != IF) {
            // our if block does not end with an if. perhaps if have an else we can flip
            if (node->size() > 3 && !!node[3] && node[3][0] == BLOCK) {
              stats = node[3][1];
              if (stats->size() == 0) break;
              other = stats->back();
              if (other[0] == IF) {
                // flip node
                node[1] = flipCondition(node[1]);
                node[2] = node[3];
                node[3] = body;
                body = node[2];
              } else break;
            } else break;
          }
          // we can handle elses, but must be fully identical
          if (!!node[3] || !!other[3]) {
            if (!node[3]) break;
            if (!node[3]->deepCompare(other[3])) {
              // the elses are different, but perhaps if we flipped a condition we can do better
              if (node[3]->deepCompare(other[2])) {
                // flip other. note that other may not have had an else! add one if so; we will eliminate such things later
                if (!other[3]) other[3] = makeBlock();
                other[1] = flipCondition(other[1]);
                Ref temp = other[2];
                other[2] = other[3];
                other[3] = temp;
              } else break;
            }
          }
          if (stats->size() > 1) {
            // try to commaify - turn everything between the ifs into a comma operator inside the second if
            bool ok = true;
            for (size_t i = 0; i+1 < stats->size(); i++) {
              Ref curr = deStat(stats[i]);
              if (!commable(curr)) ok = false;
            }
            if (!ok) break;
            for (int i = stats->size()-2; i >= 0; i--) {
              Ref curr = deStat(stats[i]);
              other[1] = make2(SEQ, curr, other[1]);
            }
            Ref temp = makeArray(1);
            temp->push_back(other);
            stats = body[1] = temp;
          }
          if (stats->size() != 1) break;
          if (!!node[3]) simplifiedAnElse = true;
          node[1] = make3(CONDITIONAL, node[1], other[1], makeNum(0));
          body = node[2] = other[2];
        }
      }
    });

    if (simplifiedAnElse) {
      // there may be fusing opportunities

      // we can only fuse if we remove all uses of the label. if there are
      // other ones - if the label check can be reached from elsewhere -
      // we must leave it
      bool abort = false;

      std::unordered_map<int, int> labelAssigns;

      traversePre(func, [&labelAssigns, &abort](Ref node) {
        if (node[0] == ASSIGN && node[2][0] == NAME && node[2][1] == LABEL) {
          if (node[3][0] == NUM) {
            int value = node[3][1]->getInteger();
            labelAssigns[value] = labelAssigns[value] + 1;
          } else {
            // label is assigned a dynamic value (like from indirectbr), we cannot do anything
            abort = true;
          }
        }
      });
      if (abort) return;

      std::unordered_map<int, int> labelChecks;

      traversePre(func, [&labelChecks, &abort](Ref node) {
        if (node[0] == BINARY && node[1] == EQ && node[2][0] == BINARY && node[2][1] == OR &&
            node[2][2][0] == NAME && node[2][2][1] == LABEL) {
          if (node[3][0] == NUM) {
            int value = node[3][1]->getInteger();
            labelChecks[value] = labelChecks[value] + 1;
          } else {
            // label is checked vs a dynamic value (like from indirectbr), we cannot do anything
            abort = true;
          }
        }
      });
      if (abort) return;

      int inLoop = 0; // when in a loop, we do not emit   label = 0;   in the relooper as there is no need
      traversePrePost(func, [&inLoop, &labelAssigns, &labelChecks](Ref node) {
        if (node[0] == WHILE) inLoop++;
        Ref stats = getStatements(node);
        if (!!stats && stats->size() > 0) {
          for (int i = 0; i < (int)stats->size()-1; i++) {
            Ref pre = stats[i];
            Ref post = stats[i+1];
            if (pre[0] == IF && pre->size() > 3 && !!pre[3] && post[0] == IF && (post->size() <= 3 || !post[3])) {
              Ref postCond = post[1];
              if (postCond[0] == BINARY && postCond[1] == EQ &&
                  postCond[2][0] == BINARY && postCond[2][1] == OR &&
                  postCond[2][2][0] == NAME && postCond[2][2][1] == LABEL &&
                  postCond[2][3][0] == NUM && postCond[2][3][1]->getNumber() == 0 &&
                  postCond[3][0] == NUM) {
                int postValue = postCond[3][1]->getInteger();
                Ref preElse = pre[3];
                if (labelAssigns[postValue] == 1 && labelChecks[postValue] == 1 && preElse[0] == BLOCK && preElse->size() >= 2 && preElse[1]->size() == 1) {
                  Ref preStat = preElse[1][0];
                  if (preStat[0] == STAT && preStat[1][0] == ASSIGN &&
                      preStat[1][1]->isBool(true) && preStat[1][2][0] == NAME && preStat[1][2][1] == LABEL &&
                      preStat[1][3][0] == NUM && preStat[1][3][1]->getNumber() == postValue) {
                    // Conditions match, just need to make sure the post clears label
                    if (post[2][0] == BLOCK && post[2]->size() >= 2 && post[2][1]->size() > 0) {
                      Ref postStat = post[2][1][0];
                      bool haveClear =
                        postStat[0] == STAT && postStat[1][0] == ASSIGN &&
                        postStat[1][1]->isBool(true) && postStat[1][2][0] == NAME && postStat[1][2][1] == LABEL &&
                        postStat[1][3][0] == NUM && postStat[1][3][1]->getNumber() == 0;
                      if (!inLoop || haveClear) {
                        // Everything lines up, do it
                        pre[3] = post[2];
                        if (haveClear) pre[3][1]->splice(0, 1); // remove the label clearing
                        stats->splice(i+1, 1); // remove the post entirely
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }, [&inLoop](Ref node) {
        if (node[0] == WHILE) inLoop--;
      });
      assert(inLoop == 0);
    }
  });
}

void optimizeFrounds(Ref ast) {
  // collapse fround(fround(..)), which can happen due to elimination
  // also emit f0 instead of fround(0) (except in returns)
  int inReturn = 0;
  traversePrePost(ast, [&](Ref node) {
    if (node[0] == RETURN) {
      inReturn++;
    }
  }, [&](Ref node) {
    if (node[0] == RETURN) {
      inReturn--;
    }
    if (node[0] == CALL && node[1][0] == NAME && node[1][1] == MATH_FROUND) {
      Ref arg = node[2][0];
      if (arg[0] == NUM) {
        if (!inReturn && arg[1]->getInteger() == 0) {
          safeCopy(node, makeName(F0));
        }
      } else if (arg[0] == CALL && arg[1][0] == NAME && arg[1][1] == MATH_FROUND) {
        safeCopy(node, arg);
      }
    }
  });
}

// Very simple 'registerization', coalescing of variables into a smaller number.

const char* getRegPrefix(AsmType type) {
  switch (type) {
    case ASM_INT:       return "i"; break;
    case ASM_DOUBLE:    return "d"; break;
    case ASM_FLOAT:     return "f"; break;
    case ASM_FLOAT32X4: return "F4"; break;
    case ASM_FLOAT64X2: return "F2"; break;
    case ASM_INT8X16:   return "I16"; break;
    case ASM_INT16X8:   return "I8"; break;
    case ASM_INT32X4:   return "I4"; break;
    case ASM_BOOL8X16:  return "B16"; break;
    case ASM_BOOL16X8:  return "B8"; break;
    case ASM_BOOL32X4:  return "B4"; break;
    case ASM_BOOL64X2:  return "B2"; break;
    case ASM_NONE:      return "Z"; break;
    default: assert(0); // type doesn't have a name yet
  }
  return nullptr;
}

IString getRegName(AsmType type, int num) {
  const char* str = getRegPrefix(type);
  const int size = 256;
  char temp[size];
  int written = sprintf(temp, "%s%d", str, num);
  assert(written < size);
  temp[written] = 0;
  IString ret;
  ret.set(temp, false);
  return ret;
}

void registerize(Ref ast) {
  traverseFunctions(ast, [](Ref fun) {
    AsmData asmData(fun);
    // Add parameters as a first (fake) var (with assignment), so they get taken into consideration
    // note: params are special, they can never share a register between them (see later)
    Ref fake;
    if (!!fun[2] && fun[2]->size()) {
      Ref assign = makeNum(0);
      // TODO: will be an isEmpty here, can reuse it.
      fun[3]->insert(0, make1(VAR, fun[2]->map([&assign](Ref param) {
        return &(makeArray(2)->push_back(param).push_back(assign));
      })));
    }
    // Replace all var definitions with assignments; we will add var definitions at the top after we registerize
    StringSet allVars;
    traversePre(fun, [&](Ref node) {
      Ref type = node[0];
      if (type == VAR) {
        Ref vars = node[1]->filter([](Ref varr) { return varr->size() > 1; });
        if (vars->size() >= 1) {
          safeCopy(node, unVarify(vars));
        } else {
          safeCopy(node, makeEmpty());
        }
      } else if (type == NAME) {
        allVars.insert(node[1]->getIString());
      }
    });
    removeAllUselessSubNodes(fun); // vacuum?
    StringTypeMap regTypes; // reg name -> type
    auto getNewRegName = [&](int num, IString name) {
      AsmType type = asmData.getType(name);
      IString ret = getRegName(type, num);
      assert(!allVars.has(ret) || asmData.isLocal(ret)); // register must not shadow non-local name
      regTypes[ret] = type;
      return ret;
    };
    // Find the # of uses of each variable.
    // While doing so, check if all a variable's uses are dominated in a simple
    // way by a simple assign, if so, then we can assign its register to it
    // just for its definition to its last use, and not to the entire toplevel loop,
    // we call such variables "optimizable"
    StringIntMap varUses;
    int level = 1;
    std::unordered_map<int, StringSet> levelDominations; // level => set of dominated variables XXX vector?
    StringIntMap varLevels;
    StringSet possibles;
    StringSet unoptimizables;
    auto purgeLevel = [&]() {
      // Invalidate all dominating on this level, further users make it unoptimizable
      for (auto name : levelDominations[level]) {
        varLevels[name] = 0;
      }
      levelDominations[level].clear();
      level--;
    };
    std::function<bool (Ref node)> possibilifier = [&](Ref node) {
      Ref type = node[0];
      if (type == NAME) {
        IString name = node[1]->getIString();
        if (asmData.isLocal(name)) {
          varUses[name]++;
          if (possibles.has(name) && !varLevels[name]) unoptimizables.insert(name); // used outside of simple domination
        }
      } else if (type == ASSIGN && node[1]->isBool(true)) {
        if (!!node[2] && node[2][0] == NAME) {
          IString name = node[2][1]->getIString();
          // if local and not yet used, this might be optimizable if we dominate
          // all other uses
          if (asmData.isLocal(name) && !varUses[name] && !varLevels[name]) {
            possibles.insert(name);
            varLevels[name] = level;
            levelDominations[level].insert(name);
          }
        }
      } else if (CONTROL_FLOW.has(type)) {
        // recurse children, in the context of a loop
        if (type == WHILE || type == DO) {
          traversePrePostConditional(node[1], possibilifier, [](Ref node){});
          level++;
          traversePrePostConditional(node[2], possibilifier, [](Ref node){});
          purgeLevel();
        } else if (type == FOR) {
          traversePrePostConditional(node[1], possibilifier, [](Ref node){});
          for (int i = 2; i <= 4; i++) {
            level++;
            traversePrePostConditional(node[i], possibilifier, [](Ref node){});
            purgeLevel();
          }
        } else if (type == IF) {
          traversePrePostConditional(node[1], possibilifier, [](Ref node){});
          level++;
          traversePrePostConditional(node[2], possibilifier, [](Ref node){});
          purgeLevel();
          if (node->size() > 3 && !!node[3]) {
            level++;
            traversePrePostConditional(node[3], possibilifier, [](Ref node){});
            purgeLevel();
          }
        } else if (type == SWITCH) {
          traversePrePostConditional(node[1], possibilifier, [](Ref node){});
          Ref cases = node[2];
          for (size_t i = 0; i < cases->size(); i++) {
            level++;
            traversePrePostConditional(cases[i][1], possibilifier, [](Ref node){});
            purgeLevel();
          }
        } else assert(0);;
        return false; // prevent recursion into children, which we already did
      }
      return true;
    };
    traversePrePostConditional(fun, possibilifier, [](Ref node){});

    StringSet optimizables;
    for (auto possible : possibles) {
      if (!unoptimizables.has(possible)) optimizables.insert(possible);
    }

    // Go through the function's code, assigning 'registers'.
    // The only tricky bit is to keep variables locked on a register through loops,
    // since they can potentially be returned to. Optimizable variables lock onto
    // loops that they enter, unoptimizable variables lock in a conservative way
    // into the topmost loop.
    // Note that we cannot lock onto a variable in a loop if it was used and free'd
    // before! (then they could overwrite us in the early part of the loop). For now
    // we just use a fresh register to make sure we avoid this, but it could be
    // optimized to check for safe registers (free, and not used in this loop level).
    StringStringMap varRegs; // maps variables to the register they will use all their life
    std::vector<StringVec> freeRegsClasses;
    freeRegsClasses.resize(ASM_NONE);
    int nextReg = 1;
    StringVec fullNames;
    fullNames.push_back(EMPTY); // names start at 1
    std::vector<StringVec> loopRegs; // for each loop nesting level, the list of bound variables
    int loops = 0; // 0 is toplevel, 1 is first loop, etc
    StringSet activeOptimizables;
    StringIntMap optimizableLoops;
    StringSet paramRegs; // true if the register is used by a parameter (and so needs no def at start of function; also cannot
                         // be shared with another param, each needs its own)
    auto decUse = [&](IString name) {
      if (!varUses[name]) return false; // no uses left, or not a relevant variable
      if (optimizables.has(name)) activeOptimizables.insert(name);
      IString reg = varRegs[name];
      assert(asmData.isLocal(name));
      StringVec& freeRegs = freeRegsClasses[asmData.getType(name)];
      if (!reg) {
        // acquire register
        if (optimizables.has(name) && freeRegs.size() > 0 &&
            !(asmData.isParam(name) && paramRegs.has(freeRegs.back()))) { // do not share registers between parameters
          reg = freeRegs.back();
          freeRegs.pop_back();
        } else {
          assert(fullNames.size() == nextReg);
          reg = getNewRegName(nextReg++, name);
          fullNames.push_back(reg);
          if (asmData.isParam(name)) paramRegs.insert(reg);
        }
        varRegs[name] = reg;
      }
      varUses[name]--;
      assert(varUses[name] >= 0);
      if (varUses[name] == 0) {
        if (optimizables.has(name)) activeOptimizables.erase(name);
        // If we are not in a loop, or we are optimizable and not bound to a loop
        // (we might have been in one but left it), we can free the register now.
        if (loops == 0 || (optimizables.has(name) && !optimizableLoops.has(name))) {
          // free register
          freeRegs.push_back(reg);
        } else {
          // when the relevant loop is exited, we will free the register
          int relevantLoop = optimizables.has(name) ? (optimizableLoops[name] ? optimizableLoops[name] : 1) : 1;
          if ((int)loopRegs.size() <= relevantLoop+1) loopRegs.resize(relevantLoop+1);
          loopRegs[relevantLoop].push_back(reg);
        }
      }
      return true;
    };
    traversePrePost(fun, [&](Ref node) { // XXX we rely on traversal order being the same as execution order here
      Ref type = node[0];
      if (type == NAME) {
        IString name = node[1]->getIString();
        if (decUse(name)) {
          node[1]->setString(varRegs[name]);
        }
      } else if (LOOP.has(type)) {
        loops++;
        // Active optimizables lock onto this loop, if not locked onto one that encloses this one
        for (auto name : activeOptimizables) {
          if (!optimizableLoops[name]) {
            optimizableLoops[name] = loops;
          }
        }
      }
    }, [&](Ref node) {
      Ref type = node[0];
      if (LOOP.has(type)) {
        // Free registers that were locked to this loop
        if ((int)loopRegs.size() > loops && loopRegs[loops].size() > 0) {
          for (auto loopReg : loopRegs[loops]) {
            freeRegsClasses[regTypes[loopReg]].push_back(loopReg);
          }
          loopRegs[loops].clear();
        }
        loops--;
      }
    });
    if (!!fun[2] && fun[2]->size()) {
      fun[2]->setSize(0); // clear params, we will fill with registers
      fun[3]->splice(0, 1); // remove fake initial var
    }

    asmData.locals.clear();
    asmData.params.clear();
    asmData.vars.clear();
    for (int i = 1; i < nextReg; i++) {
      IString reg = fullNames[i];
      AsmType type = regTypes[reg];
      if (!paramRegs.has(reg)) {
        asmData.addVar(reg, type);
      } else {
        asmData.addParam(reg, type);
        fun[2]->push_back(makeString(reg));
      }
    }
    asmData.denormalize();
  });
}

// Assign variables to 'registers', coalescing them onto a smaller number of shared
// variables.
//
// This does the same job as 'registerize' above, but burns a lot more cycles trying
// to reduce the total number of register variables.  Key points about the operation:
//
//   * we decompose the AST into a flow graph and perform a full liveness
//     analysis, to determine which variables are live at each point.
//
//   * variables that are live concurrently are assigned to different registers.
//
//   * variables that are linked via 'x=y' style statements are assigned the same
//     register if possible, so that the redundant assignment can be removed.
//     (e.g. assignments used to pass state around through loops).
//
//   * any code that cannot be reached through the flow-graph is removed.
//     (e.g. redundant break statements like 'break L123; break;').
//
//   * any assignments that we can prove are not subsequently used are removed.
//     (e.g. unnecessary assignments to the 'label' variable).
//
void registerizeHarder(Ref ast) {
#ifdef PROFILING
  clock_t tasmdata = 0;
  clock_t tflowgraph = 0;
  clock_t tlabelfix = 0;
  clock_t tbackflow = 0;
  clock_t tjuncvaruniqassign = 0;
  clock_t tjuncvarsort = 0;
  clock_t tregassign = 0;
  clock_t tblockproc = 0;
  clock_t treconstruct = 0;
#endif

  traverseFunctions(ast, [&](Ref fun) {

#ifdef PROFILING
    clock_t start = clock();
#endif

    // Do not try to process non-validating methods, like the heap replacer
    bool abort = false;
    traversePre(fun, [&abort](Ref node) {
      if (node[0] == NEW) abort = true;
    });
    if (abort) return;

    // Do not process the dceable helper function for wasm, which declares
    // types, we need to alive for asm2wasm
    if (fun[1] == DCEABLE_TYPE_DECLS) return;

    AsmData asmData(fun);

#ifdef PROFILING
    tasmdata += clock() - start;
    start = clock();
#endif

    // Utilities for allocating register variables.
    // We need distinct register pools for each type of variable.

    typedef std::map<int, IString> IntStringMap;
    std::vector<IntStringMap> allRegsByType;
    allRegsByType.resize(ASM_NONE+1);
    int nextReg = 1;

    auto createReg = [&](IString forName) {
      // Create a new register of type suitable for the given variable name.
      AsmType type = asmData.getType(forName);
      IntStringMap& allRegs = allRegsByType[type];
      int reg = nextReg++;
      allRegs[reg] = getRegName(type, reg);
      return reg;
    };

    // Traverse the tree in execution order and synthesize a basic flow-graph.
    // It's convenient to build a kind of "dual" graph where the nodes identify
    // the junctions between blocks at which control-flow may branch, and each
    // basic block is an edge connecting two such junctions.
    // For each junction we store:
    //    * set of blocks that originate at the junction
    //    * set of blocks that terminate at the junction
    // For each block we store:
    //    * a single entry junction
    //    * a single exit junction
    //    * a 'use' and 'kill' set of names for the block
    //    * full sequence of NAME and ASSIGN nodes in the block
    //    * whether each such node appears as part of a larger expression
    //      (and therefore cannot be safely eliminated)
    //    * set of labels that can be used to jump to this block

    struct Junction {
      int id;
      std::set<int> inblocks, outblocks;
      IOrderedStringSet live;
      Junction(int id_) : id(id_) {}
    };
    struct Node {
    };
    struct Block {
      int id, entry, exit;
      std::set<int> labels;
      std::vector<Ref> nodes;
      std::vector<bool> isexpr;
      StringIntMap use;
      StringSet kill;
      StringStringMap link;
      StringIntMap lastUseLoc;
      StringIntMap firstDeadLoc;
      StringIntMap firstKillLoc;
      StringIntMap lastKillLoc;

      Block() : id(-1), entry(-1), exit(-1) {}
    };
    struct ContinueBreak {
      int co, br;
      ContinueBreak() : co(-1), br(-1) {}
      ContinueBreak(int co_, int br_) : co(co_), br(br_) {}
    };
    typedef std::unordered_map<IString, ContinueBreak> LabelState;

    std::vector<Junction> junctions;
    std::vector<Block*> blocks;
    int currEntryJunction = -1;
    Block* nextBasicBlock = nullptr;
    int isInExpr = 0;
    std::vector<LabelState> activeLabels;
    activeLabels.resize(1);
    IString nextLoopLabel;

    const int ENTRY_JUNCTION = 0;
    const int EXIT_JUNCTION = 1;
    const int ENTRY_BLOCK = 0;

    auto addJunction = [&]() {
      // Create a new junction, without inserting it into the graph.
      // This is useful for e.g. pre-allocating an exit node.
      int id = junctions.size();
      junctions.push_back(Junction(id));
      return id;
    };

    std::function<int (int, bool)> joinJunction;

    auto markJunction = [&](int id) {
      // Mark current traversal location as a junction.
      // This makes a new basic block exiting at this position.
      if (id < 0) {
        id = addJunction();
      }
      joinJunction(id, true);
      return id;
    };

    auto setJunction = [&](int id, bool force) {
      // Set the next entry junction to the given id.
      // This can be used to enter at a previously-declared point.
      // You can't return to a junction with no incoming blocks
      // unless the 'force' parameter is specified.
      assert(nextBasicBlock->nodes.size() == 0); // refusing to abandon an in-progress basic block
      if (force || junctions[id].inblocks.size() > 0) {
        currEntryJunction = id;
      } else {
        currEntryJunction = -1;
      }
    };

    joinJunction = [&](int id, bool force) {
      // Complete the pending basic block by exiting at this position.
      // This can be used to exit at a previously-declared point.
      if (currEntryJunction >= 0) {
        assert(nextBasicBlock);
        nextBasicBlock->id = blocks.size();
        nextBasicBlock->entry = currEntryJunction;
        nextBasicBlock->exit = id;
        junctions[currEntryJunction].outblocks.insert(nextBasicBlock->id);
        junctions[id].inblocks.insert(nextBasicBlock->id);
        blocks.push_back(nextBasicBlock);
      } 
      nextBasicBlock = new Block();
      setJunction(id, force);
      return id;
    };

    auto pushActiveLabels = [&](int onContinue, int onBreak) {
      // Push the target junctions for continuing/breaking a loop.
      // This should be called before traversing into a loop.
      assert(activeLabels.size() > 0);
      LabelState& prevLabels = activeLabels.back();
      LabelState newLabels = prevLabels;
      newLabels[EMPTY] = ContinueBreak(onContinue, onBreak);
      if (!!nextLoopLabel) {
        newLabels[nextLoopLabel] = ContinueBreak(onContinue, onBreak);
        nextLoopLabel = EMPTY;
      }
      // An unlabelled CONTINUE should jump to innermost loop,
      // ignoring any nested SWITCH statements.
      if (onContinue < 0 && prevLabels.count(EMPTY) > 0) {
        newLabels[EMPTY].co = prevLabels[EMPTY].co;
      }
      activeLabels.push_back(newLabels);
    };

    auto popActiveLabels = [&]() {
      // Pop the target junctions for continuing/breaking a loop.
      // This should be called after traversing into a loop.
      activeLabels.pop_back();
    };

    auto markNonLocalJump = [&](IString type, IString label) {
      // Complete a block via RETURN, BREAK or CONTINUE.
      // This joins the targetted junction and then sets the current junction to null.
      // Any code traversed before we get back to an existing junction is dead code.
      if (type == RETURN) {
        joinJunction(EXIT_JUNCTION, false);
      } else {
        assert(activeLabels.size() > 0);
        assert(activeLabels.back().count(label) > 0); // 'jump to unknown label');
        auto targets = activeLabels.back()[label];
        if (type == CONTINUE) {
          joinJunction(targets.co, false);
        } else if (type == BREAK) {
          joinJunction(targets.br, false);
        } else {
          assert(0); // 'unknown jump node type');
        }
      }
      currEntryJunction = -1;
    };

    auto addUseNode = [&](Ref node) {
      // Mark a use of the given name node in the current basic block.
      assert(node[0] == NAME); // 'not a use node');
      IString name = node[1]->getIString();
      if (asmData.isLocal(name)) {
        nextBasicBlock->nodes.push_back(node);
        nextBasicBlock->isexpr.push_back(isInExpr != 0);
        if (nextBasicBlock->kill.count(name) == 0) {
          nextBasicBlock->use[name] = 1;
        }
      }
    };

    auto addKillNode = [&](Ref node) {
      // Mark an assignment to the given name node in the current basic block.
      assert(node[0] == ASSIGN); //, 'not a kill node');
      assert(node[1]->isBool(true)); // 'not a kill node');
      assert(node[2][0] == NAME); //, 'not a kill node');
      IString name = node[2][1]->getIString();
      if (asmData.isLocal(name)) {
        nextBasicBlock->nodes.push_back(node);
        nextBasicBlock->isexpr.push_back(isInExpr != 0);
        nextBasicBlock->kill.insert(name);
      }
    };

    std::function<Ref (Ref)> lookThroughCasts = [&](Ref node) {
      // Look through value-preserving casts, like "x | 0" => "x"
      if (node[0] == BINARY && node[1] == OR) {
        if (node[3][0] == NUM && node[3][1]->getNumber() == 0) {
          return lookThroughCasts(node[2]);
        }
      }
      return node;
    };

    auto addBlockLabel = [&](Ref node) {
      assert(nextBasicBlock->nodes.size() == 0); // 'cant add label to an in-progress basic block')
      if (node[0] == NUM) {
        nextBasicBlock->labels.insert(node[1]->getInteger());
      }
    };

    auto isTrueNode = [&](Ref node) {
      // Check if the given node is statically truthy.
      return (node[0] == NUM && node[1]->getNumber() != 0);
    };

    auto isFalseNode = [&](Ref node) {
      // Check if the given node is statically falsy.
      return (node[0] == NUM && node[1]->getNumber() == 0);
    };

    std::function<void (Ref)> buildFlowGraph = [&](Ref node) {
      // Recursive function to build up the flow-graph.
      // It walks the tree in execution order, calling the above state-management
      // functions at appropriate points in the traversal.
      Ref type = node[0];
  
      // Any code traversed without an active entry junction must be dead,
      // as the resulting block could never be entered. Let's remove it.
      if (currEntryJunction < 0 && junctions.size() > 0) {
        safeCopy(node, makeEmpty());
        return;
      }
 
      // Traverse each node type according to its particular control-flow semantics.
      // TODO: switchify this
      if (type == DEFUN) {
        int jEntry = markJunction(-1);
        assert(jEntry == ENTRY_JUNCTION);
        int jExit = addJunction();
        assert(jExit == EXIT_JUNCTION);
        for (size_t i = 0; i < node[3]->size(); i++) {
          buildFlowGraph(node[3][i]);
        }
        joinJunction(jExit, false);
      } else if (type == IF) {
        isInExpr++;
        buildFlowGraph(node[1]);
        isInExpr--;
        int jEnter = markJunction(-1);
        int jExit = addJunction();
        if (!!node[2]) {
          // Detect and mark "if (label == N) { <labelled block> }".
          if (node[1][0] == BINARY && node[1][1] == EQ) {
            Ref lhs = lookThroughCasts(node[1][2]);
            if (lhs[0] == NAME && lhs[1] == LABEL) {
              addBlockLabel(lookThroughCasts(node[1][3]));
            }
          }
          buildFlowGraph(node[2]);
        }
        joinJunction(jExit, false);
        setJunction(jEnter, false);
        if (node->size() > 3 && !!node[3]) {
          buildFlowGraph(node[3]);
        }
        joinJunction(jExit, false);
      } else if (type == CONDITIONAL) {
        isInExpr++;
        // If the conditional has no side-effects, we can treat it as a single
        // block, which might open up opportunities to remove it entirely.
        if (!hasSideEffects(node)) {
          buildFlowGraph(node[1]);
          if (!!node[2]) {
            buildFlowGraph(node[2]);
          }
          if (!!node[3]) {
            buildFlowGraph(node[3]);
          }
        } else {
          buildFlowGraph(node[1]);
          int jEnter = markJunction(-1);
          int jExit = addJunction();
          if (!!node[2]) {
            buildFlowGraph(node[2]);
          }
          joinJunction(jExit, false);
          setJunction(jEnter, false);
          if (!!node[3]) {
            buildFlowGraph(node[3]);
          }
          joinJunction(jExit, false);
        }
        isInExpr--;
      } else if (type == WHILE) {
        // Special-case "while (1) {}" to use fewer junctions,
        // since emscripten generates a lot of these.
        if (isTrueNode(node[1])) {
          int jLoop = markJunction(-1);
          int jExit = addJunction();
          pushActiveLabels(jLoop, jExit);
          buildFlowGraph(node[2]);
          popActiveLabels();
          joinJunction(jLoop, false);
          setJunction(jExit, false);
        } else {
          int jCond = markJunction(-1);
          int jLoop = addJunction();
          int jExit = addJunction();
          isInExpr++;
          buildFlowGraph(node[1]);
          isInExpr--;
          joinJunction(jLoop, false);
          pushActiveLabels(jCond, jExit);
          buildFlowGraph(node[2]);
          popActiveLabels();
          joinJunction(jCond, false);
          // An empty basic-block linking condition exit to loop exit.
          setJunction(jLoop, false);
          joinJunction(jExit, false);
        }
      } else if (type == DO) {
        // Special-case "do {} while (1)" and "do {} while (0)" to use
        // fewer junctions, since emscripten generates a lot of these.
        if (isFalseNode(node[1])) {
          int jExit = addJunction();
          pushActiveLabels(jExit, jExit);
          buildFlowGraph(node[2]);
          popActiveLabels();
          joinJunction(jExit, false);
        } else if (isTrueNode(node[1])) {
          int jLoop = markJunction(-1);
          int jExit = addJunction();
          pushActiveLabels(jLoop, jExit);
          buildFlowGraph(node[2]);
          popActiveLabels();
          joinJunction(jLoop, false);
          setJunction(jExit, false);
        } else {
          int jLoop = markJunction(-1);
          int jCond = addJunction();
          int jCondExit = addJunction();
          int jExit = addJunction();
          pushActiveLabels(jCond, jExit);
          buildFlowGraph(node[2]);
          popActiveLabels();
          joinJunction(jCond, false);
          isInExpr++;
          buildFlowGraph(node[1]);
          isInExpr--;
          joinJunction(jCondExit, false);
          joinJunction(jLoop, false);
          setJunction(jCondExit, false);
          joinJunction(jExit, false);
        }
      } else if (type == FOR) {
        int jTest = addJunction();
        int jBody = addJunction();
        int jStep = addJunction();
        int jExit = addJunction();
        buildFlowGraph(node[1]);
        joinJunction(jTest, false);
        isInExpr++;
        buildFlowGraph(node[2]);
        isInExpr--;
        joinJunction(jBody, false);
        pushActiveLabels(jStep, jExit);
        buildFlowGraph(node[4]);
        popActiveLabels();
        joinJunction(jStep, false);
        buildFlowGraph(node[3]);
        joinJunction(jTest, false);
        setJunction(jBody, false);
        joinJunction(jExit, false);
      } else if (type == LABEL) {
        assert(BREAK_CAPTURERS.has(node[2][0])); // 'label on non-loop, non-switch statement')
        nextLoopLabel = node[1]->getIString();
        buildFlowGraph(node[2]);
      } else if (type == SWITCH) {
        // Emscripten generates switch statements of a very limited
        // form: all case clauses are numeric literals, and all
        // case bodies end with a (maybe implicit) break.  So it's
        // basically equivalent to a multi-way IF statement.
        isInExpr++;
        buildFlowGraph(node[1]);
        isInExpr--;
        Ref condition = lookThroughCasts(node[1]);
        int jCheckExit = markJunction(-1);
        int jExit = addJunction();
        pushActiveLabels(-1, jExit);
        bool hasDefault = false;
        for (size_t i = 0; i < node[2]->size(); i++) {
          setJunction(jCheckExit, false);
          // All case clauses are either 'default' or a numeric literal.
          if (!node[2][i][0]) {
            hasDefault = true;
          } else {
            // Detect switches dispatching to labelled blocks.
            if (condition[0] == NAME && condition[1] == LABEL) {
              addBlockLabel(lookThroughCasts(node[2][i][0]));
            }
          }
          for (size_t j = 0; j < node[2][i][1]->size(); j++) {
            buildFlowGraph(node[2][i][1][j]);
          }
          // Control flow will never actually reach the end of the case body.
          // If there's live code here, assume it jumps to case exit.
          if (currEntryJunction >= 0 && nextBasicBlock->nodes.size() > 0) {
            if (!!node[2][i][0]) {
              markNonLocalJump(RETURN, EMPTY);
            } else {
              joinJunction(jExit, false);
            }
          }
        }
        // If there was no default case, we also need an empty block
        // linking straight from the test evaluation to the exit.
        if (!hasDefault) {
          setJunction(jCheckExit, false);
        }
        joinJunction(jExit, false);
        popActiveLabels();
      } else if (type == RETURN) {
        if (!!node[1]) {
          isInExpr++;
          buildFlowGraph(node[1]);
          isInExpr--;
        }
        markNonLocalJump(type->getIString(), EMPTY);
      } else if (type == BREAK || type == CONTINUE) {
        markNonLocalJump(type->getIString(), !!node[1] ? node[1]->getIString() : EMPTY);
      } else if (type == ASSIGN) {
        isInExpr++;
        buildFlowGraph(node[3]);
        isInExpr--;
        if (node[1]->isBool(true) && node[2][0] == NAME) {
          addKillNode(node);
        } else {
          buildFlowGraph(node[2]);
        }
      } else if (type == NAME) {
        addUseNode(node);
      } else if (type == BLOCK || type == TOPLEVEL) {
        if (!!node[1]) {
          for (size_t i = 0; i < node[1]->size(); i++) {
            buildFlowGraph(node[1][i]);
          }
        }
      } else if (type == STAT) {
        buildFlowGraph(node[1]);
      } else if (type == UNARY_PREFIX) {
        isInExpr++;
        buildFlowGraph(node[2]);
        isInExpr--;
      } else if (type == BINARY) {
        isInExpr++;
        buildFlowGraph(node[2]);
        buildFlowGraph(node[3]);
        isInExpr--;
      } else if (type == CALL) {
        isInExpr++;
        buildFlowGraph(node[1]);
        if (!!node[2]) {
          for (size_t i = 0; i < node[2]->size(); i++) {
            buildFlowGraph(node[2][i]);
          }
        }
        isInExpr--;
        // If the call is statically known to throw,
        // treat it as a jump to function exit.
        if (!isInExpr && node[1][0] == NAME) {
          if (FUNCTIONS_THAT_ALWAYS_THROW.has(node[1][1])) {
            markNonLocalJump(RETURN, EMPTY);
          }
        }
      } else if (type == SEQ || type == SUB) {
        isInExpr++;
        buildFlowGraph(node[1]);
        buildFlowGraph(node[2]);
        isInExpr--;
      } else if (type == DOT || type == THROW) {
        isInExpr++;
        buildFlowGraph(node[1]);
        isInExpr--;
      } else if (type == NUM || type == STRING || type == VAR) {
        // nada
      } else {
        assert(0); // 'unsupported node type: ' + type);
      }
    };

    buildFlowGraph(fun);

#ifdef PROFILING
    tflowgraph += clock() - start;
    start = clock();
#endif

    assert(junctions[ENTRY_JUNCTION].inblocks.size() == 0); // 'function entry must have no incoming blocks');
    assert(junctions[EXIT_JUNCTION].outblocks.size() == 0); // 'function exit must have no outgoing blocks');
    assert(blocks[ENTRY_BLOCK]->entry == ENTRY_JUNCTION); //, 'block zero must be the initial block');

    // Fix up implicit jumps done by assigning to the LABEL variable.
    // If a block ends with an assignment to LABEL and there's another block
    // with that value of LABEL as precondition, we tweak the flow graph so
    // that the former jumps straight to the later.

    std::map<int, Block*> labelledBlocks;
    typedef std::pair<Ref, Block*> Jump;
    std::vector<Jump> labelledJumps;

    for (size_t i = 0; i < blocks.size(); i++) {
      Block* block = blocks[i];
      // Does it have any labels as preconditions to its entry?
      for (auto labelVal : block->labels) {
        // If there are multiple blocks with the same label, all bets are off.
        // This seems to happen sometimes for short blocks that end with a return.
        // TODO: it should be safe to merge the duplicates if they're identical.
        if (labelledBlocks.count(labelVal) > 0) {
          labelledBlocks.clear();
          labelledJumps.clear();
          goto AFTER_FINDLABELLEDBLOCKS;
        }
        labelledBlocks[labelVal] = block;
      }
      // Does it assign a specific label value at exit?
      if (block->kill.has(LABEL)) {
        Ref finalNode = block->nodes.back();
        if (finalNode[0] == ASSIGN && finalNode[2][1] == LABEL) {
          // If labels are computed dynamically then all bets are off.
          // This can happen due to indirect branching in llvm output.
          if (finalNode[3][0] != NUM) {
            labelledBlocks.clear();
            labelledJumps.clear();
            goto AFTER_FINDLABELLEDBLOCKS;
          }
          labelledJumps.push_back(Jump(finalNode[3][1], block));
        } else { 
          // If label is assigned a non-zero value elsewhere in the block
          // then all bets are off.  This can happen e.g. due to outlining
          // saving/restoring label to the stack.
          for (size_t j = 0; j < block->nodes.size() - 1; j++) {
            if (block->nodes[j][0] == ASSIGN && block->nodes[j][2][1] == LABEL) {
              if (block->nodes[j][3][0] != NUM || block->nodes[j][3][1]->getNumber() != 0) {
                labelledBlocks.clear();
                labelledJumps.clear();
                goto AFTER_FINDLABELLEDBLOCKS;
              }
            }
          }
        }
      }
    }

    AFTER_FINDLABELLEDBLOCKS:

    for (auto labelVal : labelledBlocks) {
      Block* block = labelVal.second;
      // Disconnect it from the graph, and create a
      // new junction for jumps targetting this label.
      junctions[block->entry].outblocks.erase(block->id);
      block->entry = addJunction();
      junctions[block->entry].outblocks.insert(block->id);
      // Add a fake use of LABEL to keep it alive in predecessor.
      block->use[LABEL] = 1;
      block->nodes.insert(block->nodes.begin(), makeName(LABEL));
      block->isexpr.insert(block->isexpr.begin(), 1);
    }
    for (size_t i = 0; i < labelledJumps.size(); i++) {
      auto labelVal = labelledJumps[i].first;
      auto block = labelledJumps[i].second;
      Block* targetBlock = labelledBlocks[labelVal->getInteger()];
      if (targetBlock) {
        // Redirect its exit to entry of the target block.
        junctions[block->exit].inblocks.erase(block->id);
        block->exit = targetBlock->entry;
        junctions[block->exit].inblocks.insert(block->id);
      }
    }

#ifdef PROFILING
    tlabelfix += clock() - start;
    start = clock();
#endif

    // Do a backwards data-flow analysis to determine the set of live
    // variables at each junction, and to use this information to eliminate
    // any unused assignments.
    // We run two nested phases.  The inner phase builds the live set for each
    // junction.  The outer phase uses this to try to eliminate redundant
    // stores in each basic block, which might in turn affect liveness info.

    auto analyzeJunction = [&](Junction& junc) {
      // Update the live set for this junction.
      IOrderedStringSet live;
      for (auto b : junc.outblocks) {
        Block* block = blocks[b];
        IOrderedStringSet& liveSucc = junctions[block->exit].live;
        for (auto name : liveSucc) {
          if (!block->kill.has(name)) {
            live.insert(name);
          }
        }
        for (auto name : block->use) {
          live.insert(name.first);
        }
      }
      junc.live = live;
    };

    auto analyzeBlock = [&](Block* block) {
      // Update information about the behaviour of the block.
      // This includes the standard 'use' and 'kill' information,
      // plus a 'link' set naming values that flow through from entry
      // to exit, possibly changing names via simple 'x=y' assignments.
      // As we go, we eliminate assignments if the variable is not
      // subsequently used.
      auto live = junctions[block->exit].live;
      StringIntMap use;
      StringSet kill;
      StringStringMap link;
      StringIntMap lastUseLoc;
      StringIntMap firstDeadLoc;
      StringIntMap firstKillLoc;
      StringIntMap lastKillLoc;
      for (auto name : live) {
        link[name] = name;
        lastUseLoc[name] = block->nodes.size();
        firstDeadLoc[name] = block->nodes.size();
      }
      for (int j = block->nodes.size() - 1; j >= 0 ; j--) {
        Ref node = block->nodes[j];
        if (node[0] == NAME) {
          IString name = node[1]->getIString();
          live.insert(name);
          use[name] = j;
          if (lastUseLoc.count(name) == 0) {
            lastUseLoc[name] = j;
            firstDeadLoc[name] = j;
          }
        } else {
          IString name = node[2][1]->getIString();
          // We only keep assignments if they will be subsequently used.
          if (live.has(name)) {
            kill.insert(name);
            use.erase(name);
            live.erase(name);
            firstDeadLoc[name] = j;
            firstKillLoc[name] = j;
            if (lastUseLoc.count(name) == 0) {
              lastUseLoc[name] = j;
            }
            if (lastKillLoc.count(name) == 0) {
              lastKillLoc[name] = j;
            }
            // If it's an "x=y" and "y" is not live, then we can create a
            // flow-through link from "y" to "x".  If not then there's no
            // flow-through link for "x".
            if (link.has(name)) {
              IString oldLink = link[name];
              link.erase(name);
              if (node[3][0] == NAME) {
                if (asmData.isLocal(node[3][1]->getIString())) {
                  link[node[3][1]->getIString()] = oldLink;
                }
              }
            }
          } else {
            // The result of this assignment is never used, so delete it.
            // We may need to keep the RHS for its value or its side-effects.
            auto removeUnusedNodes = [&](int j, int n) {
              for (auto pair : lastUseLoc) {
                pair.second -= n;
              }
              for (auto pair : firstKillLoc) {
                pair.second -= n;
              }
              for (auto pair : lastKillLoc) {
                pair.second -= n;
              }
              for (auto pair : firstDeadLoc) {
                pair.second -= n;
              }
              block->nodes.erase(block->nodes.begin() + j, block->nodes.begin() + j + n);
              block->isexpr.erase(block->isexpr.begin() + j, block->isexpr.begin() + j + n);
            };
            if (block->isexpr[j] || hasSideEffects(node[3])) {
              safeCopy(node, node[3]);
              removeUnusedNodes(j, 1);
            } else {
              int numUsesInExpr = 0;
              traversePre(node[3], [&](Ref node) {
                if (node[0] == NAME && asmData.isLocal(node[1]->getIString())) {
                  numUsesInExpr++;
                }
              });
              safeCopy(node, makeEmpty());
              j = j - numUsesInExpr;
              removeUnusedNodes(j, 1 + numUsesInExpr);
            }
          }
        }
      }
      // XXX efficiency
      block->use = use;
      block->kill = kill;
      block->link = link;
      block->lastUseLoc = lastUseLoc;
      block->firstDeadLoc = firstDeadLoc;
      block->firstKillLoc = firstKillLoc;
      block->lastKillLoc = lastKillLoc;
    };

    // Ordered map to work in approximate reverse order of junction appearance
    std::set<int> jWorkSet;
    std::set<int> bWorkSet;

    // Be sure to visit every junction at least once.
    // This avoids missing some vars because we disconnected them
    // when processing the labelled jumps.
    for (size_t i = EXIT_JUNCTION; i < junctions.size(); i++) {
      jWorkSet.insert(i);
      for (auto b : junctions[i].inblocks) {
        bWorkSet.insert(b);
      }
    }
    // Exit junction never has any live variable changes to propagate
    jWorkSet.erase(EXIT_JUNCTION);

    do {
      // Iterate on just the junctions until we get stable live sets.
      // The first run of this loop will grow the live sets to their maximal size.
      // Subsequent runs will shrink them based on eliminated in-block uses.
      while (jWorkSet.size() > 0) {
        auto last = jWorkSet.end();
        --last;
        Junction& junc = junctions[*last];
        jWorkSet.erase(last);
        IOrderedStringSet oldLive = junc.live; // copy it here, to check for changes later
        analyzeJunction(junc);
        if (oldLive != junc.live) {
          // Live set changed, updated predecessor blocks and junctions.
          for (auto b : junc.inblocks) {
            bWorkSet.insert(b);
            jWorkSet.insert(blocks[b]->entry);
          }
        }
      }
      // Now update the blocks based on the calculated live sets.
      while (bWorkSet.size() > 0) {
        auto last = bWorkSet.end();
        --last;
        Block* block = blocks[*last];
        bWorkSet.erase(last);
        auto oldUse = block->use;
        analyzeBlock(block);
        if (oldUse != block->use) {
          // The use set changed, re-process the entry junction.
          jWorkSet.insert(block->entry);
        }
      }
    } while (jWorkSet.size() > 0);

#ifdef PROFILING
    tbackflow += clock() - start;
    start = clock();
#endif

    // Insist that all function parameters are alive at function entry.
    // This ensures they will be assigned independent registers, even
    // if they happen to be unused.

    for (auto name : asmData.params) {
      junctions[ENTRY_JUNCTION].live.insert(name);
    }

    // For variables that are live at one or more junctions, we assign them
    // a consistent register for the entire scope of the function.  Find pairs
    // of variable that cannot use the same register (the "conflicts") as well
    // as pairs of variables that we'd like to have share the same register
    // (the "links").

    struct JuncVar {
      std::vector<bool> conf;
      IOrderedStringSet link;
      std::unordered_set<int> excl;
      int reg;
      bool used;
      JuncVar() : reg(-1), used(false) {}
    };
    size_t numLocals = asmData.locals.size();
    std::unordered_map<IString, size_t> nameToNum;
    std::vector<IString> numToName;
    nameToNum.reserve(numLocals);
    numToName.reserve(numLocals);
    for (auto kv : asmData.locals) {
      nameToNum[kv.first] = numToName.size();
      numToName.push_back(kv.first);
    }

    std::vector<JuncVar> juncVars(numLocals);
    for (Junction& junc : junctions) {
      for (IString name : junc.live) {
        JuncVar& jVar = juncVars[nameToNum[name]];
        jVar.used = true;
        jVar.conf.assign(numLocals, false);
      }
    }
    std::map<IString, std::vector<Block*>> possibleBlockConflictsMap;
    std::vector<std::pair<size_t, std::vector<Block*>>> possibleBlockConflicts;
    std::unordered_map<IString, std::vector<Block*>> possibleBlockLinks;
    possibleBlockConflicts.reserve(numLocals);
    possibleBlockLinks.reserve(numLocals);

    for (Junction& junc : junctions) {
      // Pre-compute the possible conflicts and links for each block rather
      // than checking potentially impossible options for each var
      possibleBlockConflictsMap.clear();
      possibleBlockConflicts.clear();
      possibleBlockLinks.clear();
      for (auto b : junc.outblocks) {
        Block* block = blocks[b];
        Junction& jSucc = junctions[block->exit];
        for (auto name : jSucc.live) {
          possibleBlockConflictsMap[name].push_back(block);
        }
        for (auto name_linkname : block->link) {
          if (name_linkname.first != name_linkname.second) {
            possibleBlockLinks[name_linkname.first].push_back(block);
          }
        }
      }
      // Find the live variables in this block, mark them as unnecessary to
      // check for conflicts (we mark all live vars as conflicting later)
      std::vector<size_t> liveJVarNums;
      liveJVarNums.reserve(junc.live.size());
      for (auto name : junc.live) {
        size_t jVarNum = nameToNum[name];
        liveJVarNums.push_back(jVarNum);
        possibleBlockConflictsMap.erase(name);
      }
      // Extract just the variables we might want to check for conflicts
      for (auto kv : possibleBlockConflictsMap) {
        possibleBlockConflicts.push_back(std::make_pair(nameToNum[kv.first], kv.second));
      }

      for (size_t jVarNum : liveJVarNums) {
        JuncVar& jvar = juncVars[jVarNum];
        IString name = numToName[jVarNum];
        // It conflicts with all other names live at this junction.
        for (size_t liveJVarNum : liveJVarNums) {
          jvar.conf[liveJVarNum] = true;
        }
        jvar.conf[jVarNum] = false; // except for itself, of course

        // It conflicts with any output vars of successor blocks,
        // if they're assigned before it goes dead in that block.
        for (auto jvarnum_blocks : possibleBlockConflicts) {
          size_t otherJVarNum = jvarnum_blocks.first;
          IString otherName = numToName[otherJVarNum];
          for (auto block : jvarnum_blocks.second) {
            if (block->lastKillLoc[otherName] < block->firstDeadLoc[name]) {
              jvar.conf[otherJVarNum] = true;
              juncVars[otherJVarNum].conf[jVarNum] = true;
              break;
            }
          }
        }

        // It links with any linkages in the outgoing blocks.
        for (auto block: possibleBlockLinks[name]) {
          IString linkName = block->link[name];
          jvar.link.insert(linkName);
          juncVars[nameToNum[linkName]].link.insert(name);
        }
      }
    }

#ifdef PROFILING
    tjuncvaruniqassign += clock() - start;
    start = clock();
#endif

    // Attempt to sort the junction variables to heuristically reduce conflicts.
    // Simple starting point: handle the most-conflicted variables first.
    // This seems to work pretty well.

    std::vector<size_t> sortedJVarNums;
    sortedJVarNums.reserve(juncVars.size());
    std::vector<size_t> jVarConfCounts(numLocals);
    for (size_t jVarNum = 0; jVarNum < juncVars.size(); jVarNum++) {
      JuncVar& jVar = juncVars[jVarNum];
      if (!jVar.used) continue;
      jVarConfCounts[jVarNum] = std::count(jVar.conf.begin(), jVar.conf.end(), true);
      sortedJVarNums.push_back(jVarNum);
    }
    std::sort(sortedJVarNums.begin(), sortedJVarNums.end(), [&](const size_t vi1, const size_t vi2) {
      // sort by # of conflicts
      if (jVarConfCounts[vi1] < jVarConfCounts[vi2]) return true;
      if (jVarConfCounts[vi1] == jVarConfCounts[vi2]) return numToName[vi1] < numToName[vi2];
      return false;
    });

#ifdef PROFILING
    tjuncvarsort += clock() - start;
    start = clock();
#endif

    // We can now assign a register to each junction variable.
    // Process them in order, trying available registers until we find
    // one that works, and propagating the choice to linked/conflicted
    // variables as we go.

    std::function<bool (IString, int)> tryAssignRegister = [&](IString name, int reg) {
      // Try to assign the given register to the given variable,
      // and propagate that choice throughout the graph.
      // Returns true if successful, false if there was a conflict.
      JuncVar& jv = juncVars[nameToNum[name]];
      if (jv.reg > 0) {
        return jv.reg == reg;
      }
      if (jv.excl.count(reg) > 0) {
        return false;
      }
      jv.reg = reg;
      // Exclude use of this register at all conflicting variables.
      for (size_t confNameNum = 0; confNameNum < jv.conf.size(); confNameNum++) {
        if (jv.conf[confNameNum]) {
          juncVars[confNameNum].excl.insert(reg);
        }
      }
      // Try to propagate it into linked variables.
      // It's not an error if we can't.
      for (auto linkName : jv.link) {
        tryAssignRegister(linkName, reg);
      }
      return true;
    };
    for (size_t jVarNum : sortedJVarNums) {
      // It may already be assigned due to linked-variable propagation.
      if (juncVars[jVarNum].reg > 0) {
        continue;
      }
      IString name = numToName[jVarNum];
      // Try to use existing registers first.
      auto& allRegs = allRegsByType[asmData.getType(name)];
      bool moar = false;
      for (auto reg : allRegs) {
        if (tryAssignRegister(name, reg.first)) {
          moar = true;
          break;
        }
      }
      if (moar) continue;
      // They're all taken, create a new one.
      tryAssignRegister(name, createReg(name));
    }

#ifdef PROFILING
    tregassign += clock() - start;
    start = clock();
#endif

    // Each basic block can now be processed in turn.
    // There may be internal-use-only variables that still need a register
    // assigned, but they can be treated just for this block.  We know
    // that all inter-block variables are in a good state thanks to
    // junction variable consistency.

    for (size_t i = 0; i < blocks.size(); i++) {
      Block* block = blocks[i];
      if (block->nodes.size() == 0) continue;
      Junction& jEnter = junctions[block->entry];
      Junction& jExit = junctions[block->exit];
      // Mark the point at which each input reg becomes dead.
      // Variables alive before this point must not be assigned
      // to that register.
      StringSet inputVars;
      std::unordered_map<int, int> inputDeadLoc;
      std::unordered_map<int, IString> inputVarsByReg;
      for (auto name : jExit.live) {
        if (!block->kill.has(name)) {
          inputVars.insert(name);
          int reg = juncVars[nameToNum[name]].reg;
          assert(reg > 0); // 'input variable doesnt have a register');
          inputDeadLoc[reg] = block->firstDeadLoc[name];
          inputVarsByReg[reg] = name;
        }
      }
      for (auto pair : block->use) {
        IString name = pair.first;
        if (!inputVars.has(name)) {
          inputVars.insert(name);
          int reg = juncVars[nameToNum[name]].reg;
          assert(reg > 0); // 'input variable doesnt have a register');
          inputDeadLoc[reg] = block->firstDeadLoc[name];
          inputVarsByReg[reg] = name;
        }
      }
      // TODO assert(setSize(setSub(inputVars, jEnter.live)) == 0);
      // Scan through backwards, allocating registers on demand.
      // Be careful to avoid conflicts with the input registers.
      // We consume free registers in last-used order, which helps to
      // eliminate "x=y" assignments that are the last use of "y".
      StringIntMap assignedRegs;
      auto freeRegsByTypePre = allRegsByType; // XXX copy
      // Begin with all live vars assigned per the exit junction.
      for (auto name : jExit.live) {
        int reg = juncVars[nameToNum[name]].reg;
        assert(reg > 0); // 'output variable doesnt have a register');
        assignedRegs[name] = reg;
        freeRegsByTypePre[asmData.getType(name)].erase(reg); // XXX assert?
      }
      std::vector<std::vector<int>> freeRegsByType;
      freeRegsByType.resize(freeRegsByTypePre.size());
      for (size_t j = 0; j < freeRegsByTypePre.size(); j++) {
        for (auto pair : freeRegsByTypePre[j]) {
          freeRegsByType[j].push_back(pair.first);
        }
      }
      // Scan through the nodes in sequence, modifying each node in-place
      // and grabbing/freeing registers as needed.
      std::vector<std::pair<int, Ref>> maybeRemoveNodes;
      for (int j = block->nodes.size() - 1; j >= 0; j--) {
        Ref node = block->nodes[j];
        IString name = (node[0] == ASSIGN ? node[2][1] : node[1])->getIString();
        IntStringMap& allRegs = allRegsByType[asmData.getType(name)];
        std::vector<int>& freeRegs = freeRegsByType[asmData.getType(name)];
        int reg = assignedRegs[name]; // XXX may insert a zero
        if (node[0] == NAME) {
          // A use.  Grab a register if it doesn't have one.
          if (reg <= 0) {
            if (inputVars.has(name) && j <= block->firstDeadLoc[name]) {
              // Assignment to an input variable, must use pre-assigned reg.
              reg = juncVars[nameToNum[name]].reg;
              assignedRegs[name] = reg;
              for (int k = freeRegs.size() - 1; k >= 0; k--) {
                if (freeRegs[k] == reg) {
                  freeRegs.erase(freeRegs.begin() + k);
                  break;
                }
              }
            } else {
              // Try to use one of the existing free registers.
              // It must not conflict with an input register.
              for (int k = freeRegs.size() - 1; k >= 0; k--) {
                reg = freeRegs[k];
                // Check for conflict with input registers.
                if (inputDeadLoc.count(reg) > 0) {
                  if (block->firstKillLoc[name] <= inputDeadLoc[reg]) {
                    if (name != inputVarsByReg[reg]) {
                      continue;
                    }
                  }
                }
                // Found one!
                assignedRegs[name] = reg;
                assert(reg > 0);
                freeRegs.erase(freeRegs.begin() + k);
                break;
              }
              // If we didn't find a suitable register, create a new one.
              if (assignedRegs[name] <= 0) {
                reg = createReg(name);
                assignedRegs[name] = reg;
              }
            }
          }
          node[1]->setString(allRegs[reg]);
        } else {
          // A kill. This frees the assigned register.
          assert(reg > 0); //, 'live variable doesnt have a reg?')
          node[2][1]->setString(allRegs[reg]);
          freeRegs.push_back(reg);
          assignedRegs.erase(name);
          if (node[3][0] == NAME && asmData.isLocal(node[3][1]->getIString())) {
            maybeRemoveNodes.push_back(std::pair<int, Ref>(j, node));
          }
        }
      }
      // If we managed to create any "x=x" assignments, remove them.
      for (size_t j = 0; j < maybeRemoveNodes.size(); j++) {
        Ref node = maybeRemoveNodes[j].second;
        if (node[2][1] == node[3][1]) {
          if (block->isexpr[maybeRemoveNodes[j].first]) {
            safeCopy(node, node[2]);
          } else {
            safeCopy(node, makeEmpty());
          }
        }
      }
    }

#ifdef PROFILING
    tblockproc += clock() - start;
    start = clock();
#endif

    // Assign registers to function params based on entry junction

    StringSet paramRegs;
    if (!!fun[2]) {
      for (size_t i = 0; i < fun[2]->size(); i++) {
        auto& allRegs = allRegsByType[asmData.getType(fun[2][i]->getIString())];
        fun[2][i]->setString(allRegs[juncVars[nameToNum[fun[2][i]->getIString()]].reg]);
        paramRegs.insert(fun[2][i]->getIString());
      }
    }

    // That's it!
    // Re-construct the function with appropriate variable definitions.

    asmData.locals.clear();
    asmData.params.clear();
    asmData.vars.clear();
    for (int i = 1; i < nextReg; i++) {
      for (size_t type = 0; type < allRegsByType.size(); type++) {
        if (allRegsByType[type].count(i) > 0) {
          IString reg = allRegsByType[type][i];
          if (!paramRegs.has(reg)) {
            asmData.addVar(reg, intToAsmType(type));
          } else {
            asmData.addParam(reg, intToAsmType(type));
          }
          break;
        }
      }
    }
    asmData.denormalize();

    removeAllUselessSubNodes(fun); // XXX vacuum?    vacuum(fun);

#ifdef PROFILING
    treconstruct += clock() - start;
    start = clock();
#endif

  });
#ifdef PROFILING
  errv("    RH stages: a:%li fl:%li lf:%li bf:%li jvua:%li jvs:%li jra:%li bp:%li r:%li",
    tasmdata, tflowgraph, tlabelfix, tbackflow, tjuncvaruniqassign, tjuncvarsort, tregassign, tblockproc, treconstruct);
#endif
}
// end registerizeHarder

// minified names generation
StringSet RESERVED("do if in for new try var env let case else enum this void with");
const char *VALID_MIN_INITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
const char *VALID_MIN_LATERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789";

StringVec minifiedNames;
std::vector<int> minifiedState;

void ensureMinifiedNames(int n) { // make sure the nth index in minifiedNames exists. done 100% deterministically
  static int VALID_MIN_INITS_LEN = strlen(VALID_MIN_INITS);
  static int VALID_MIN_LATERS_LEN = strlen(VALID_MIN_LATERS);

  while ((int)minifiedNames.size() < n+1) {
    // generate the current name
    std::string name;
    name += VALID_MIN_INITS[minifiedState[0]];
    for (size_t i = 1; i < minifiedState.size(); i++) {
      name += VALID_MIN_LATERS[minifiedState[i]];
    }
    IString str(strdupe(name.c_str())); // leaked!
    if (!RESERVED.has(str)) minifiedNames.push_back(str);
    // increment the state
    size_t i = 0;
    while (1) {
      minifiedState[i]++;
      if (minifiedState[i] < (i == 0 ? VALID_MIN_INITS_LEN : VALID_MIN_LATERS_LEN)) break;
      // overflow
      minifiedState[i] = 0;
      i++;
      if (i == minifiedState.size()) minifiedState.push_back(-1); // will become 0 after increment in next loop head
    }
  }
}

void minifyLocals(Ref ast) {
  assert(!!extraInfo);
  IString GLOBALS("globals");
  assert(extraInfo->has(GLOBALS));
  Ref globals = extraInfo[GLOBALS];

  if (minifiedState.size() == 0) minifiedState.push_back(0);

  traverseFunctions(ast, [&globals](Ref fun) {
    // Analyse the asmjs to figure out local variable names,
    // but operate on the original source tree so that we don't
    // miss any global names in e.g. variable initializers.
    AsmData asmData(fun);
    asmData.denormalize(); // TODO: we can avoid modifying at all here - we just need a list of local vars+params

    StringStringMap newNames;
    StringSet usedNames;

    // Find all the globals that we need to minify using
    // pre-assigned names.  Don't actually minify them yet
    // as that might interfere with local variable names.
    traversePre(fun, [&](Ref node) {
      if (node[0] == NAME) {
        IString name = node[1]->getIString();
        if (!asmData.isLocal(name)) {
          if (globals->has(name)) {
            IString minified = globals[name]->getIString();
            assert(!!minified);
            newNames[name] = minified;
            usedNames.insert(minified);
          }
        }
      }
    });

    // The first time we encounter a local name, we assign it a
    // minified name that's not currently in use.  Allocating on
    // demand means they're processed in a predictable order,
    // which is very handy for testing/debugging purposes.
    int nextMinifiedName = 0;
    auto getNextMinifiedName = [&]() {
      IString minified;
      while (1) {
        ensureMinifiedNames(nextMinifiedName);
        minified = minifiedNames[nextMinifiedName++];
        // TODO: we can probably remove !isLocalName here
        if (!usedNames.has(minified) && !asmData.isLocal(minified)) {
          return minified;
        }
      }
    };

    // We can also minify loop labels, using a separate namespace
    // to the variable declarations.
    StringStringMap newLabels;
    int nextMinifiedLabel = 0;
    auto getNextMinifiedLabel = [&]() {
      ensureMinifiedNames(nextMinifiedLabel);
      return minifiedNames[nextMinifiedLabel++];
    };

    // Traverse and minify all names.
    if (globals->has(fun[1]->getIString())) {
      fun[1]->setString(globals[fun[1]->getIString()]->getIString());
      assert(!!fun[1]);
    }
    if (!!fun[2]) {
      for (size_t i = 0; i < fun[2]->size(); i++) {
        IString minified = getNextMinifiedName();
        newNames[fun[2][i]->getIString()] = minified;
        fun[2][i]->setString(minified);
      }
    }
    traversePre(fun[3], [&](Ref node) {
      Ref type = node[0];
      if (type == NAME) {
        IString name = node[1]->getIString();
        IString minified = newNames[name];
        if (!!minified) {
          node[1]->setString(minified);
        } else if (asmData.isLocal(name)) {
          minified = getNextMinifiedName();
          newNames[name] = minified;
          node[1]->setString(minified);
        }
      } else if (type == VAR) {
        for (size_t i = 0; i < node[1]->size(); i++) {
          Ref defn = node[1][i];
          IString name = defn[0]->getIString();
          if (!(newNames.has(name))) {
            newNames[name] = getNextMinifiedName();
          }
          defn[0]->setString(newNames[name]);
        }
      } else if (type == LABEL) {
        IString name = node[1]->getIString();
        if (!newLabels.has(name)) {
          newLabels[name] = getNextMinifiedLabel();
        }
        node[1]->setString(newLabels[name]);
      } else if (type == BREAK || type == CONTINUE) {
        if (node->size() > 1 && !!node[1]) {
          node[1]->setString(newLabels[node[1]->getIString()]);
        }
      }
    });
  });
}

void asmLastOpts(Ref ast) {
  std::vector<Ref> statsStack;
  traverseFunctions(ast, [&](Ref fun) {
    traversePrePost(fun, [&](Ref node) {
      Ref type = node[0];
      Ref stats = getStatements(node);
      if (!!stats) statsStack.push_back(stats);
      if (CONDITION_CHECKERS.has(type)) {
        node[1] = simplifyCondition(node[1]);
      }
      if (type == WHILE && node[1][0] == NUM && node[1][1]->getNumber() == 1 && node[2][0] == BLOCK && node[2]->size() == 2) {
        // This is at the end of the pipeline, we can assume all other optimizations are done, and we modify loops
        // into shapes that might confuse other passes

        // while (1) { .. if (..) { break } } ==> do { .. } while(..)
        Ref stats = node[2][1];
        Ref last = stats->back();
        if (!!last && last[0] == IF && (last->size() < 4 || !last[3]) && last[2][0] == BLOCK && !!last[2][1][0]) {
          Ref lastStats = last[2][1];
          int lastNum = lastStats->size();
          Ref lastLast = lastStats[lastNum-1];
          if (!(lastLast[0] == BREAK && !lastLast[1])) return;// if not a simple break, dangerous
          for (int i = 0; i < lastNum; i++) {
            if (lastStats[i][0] != STAT && lastStats[i][0] != BREAK) return; // something dangerous
          }
          // ok, a bunch of statements ending in a break
          bool abort = false;
          int stack = 0;
          int breaks = 0;
          traversePrePost(stats, [&](Ref node) {
            Ref type = node[0];
            if (type == CONTINUE) {
              if (stack == 0 || !!node[1]) { // abort if labeled (we do not analyze labels here yet), or a continue directly on us
                abort = true;
              }
            } else if (type == BREAK) {
              if (stack == 0 || !!node[1]) { // relevant if labeled (we do not analyze labels here yet), or a break directly on us
                breaks++;
              }
            } else if (LOOP.has(type)) {
              stack++;
            }
          }, [&](Ref node) {
            if (LOOP.has(node[0])) {
              stack--;
            }
          });
          if (abort) return;
          assert(breaks > 0);
          if (lastStats->size() > 1 && breaks != 1) return; // if we have code aside from the break, we can only move it out if there is just one break
          if (statsStack.size() < 1) return; // no chance we have this stats on hand
          // start to optimize
          if (lastStats->size() > 1) {
            Ref parent = statsStack.back();
            int me = parent->indexOf(node);
            if (me < 0) return; // not always directly on a stats, could be in a label for example
            parent->insert(me+1, lastStats->size()-1);
            for (size_t i = 0; i+1 < lastStats->size(); i++) {
              parent[me+1+i] = lastStats[i];
            }
          }
          Ref conditionToBreak = last[1];
          stats->pop_back();
          node[0]->setString(DO);
          node[1] = simplifyNotCompsDirect(make2(UNARY_PREFIX, L_NOT, conditionToBreak));
        }
      } else if (type == BINARY) {
        if (node[1] == AND) {
          if (node[3][0] == UNARY_PREFIX && node[3][1] == MINUS && node[3][2][0] == NUM && node[3][2][1]->getNumber() == 1) {
            // Change &-1 into |0, at this point the hint is no longer needed
            node[1]->setString(OR);
            node[3] = node[3][2];
            node[3][1]->setNumber(0);
          }
        } else if (node[1] == MINUS && node[3][0] == UNARY_PREFIX) {
          // avoid X - (-Y) because some minifiers buggily emit X--Y which is invalid as -- can be a unary. Transform to
          //        X + Y
          if (node[3][1] == MINUS) { // integer
            node[1]->setString(PLUS);
            node[3] = node[3][2];
          } else if (node[3][1] == PLUS) { // float
            if (node[3][2][0] == UNARY_PREFIX && node[3][2][1] == MINUS) {
              node[1]->setString(PLUS);
              node[3][2] = node[3][2][2];
            }
          }
        }
      }
    }, [&](Ref node) {
      if (statsStack.size() > 0) {
        Ref stats = getStatements(node);
        if (!!stats) statsStack.pop_back();
      }
    });
    // convert  { singleton }  into  singleton
    traversePre(fun, [](Ref node) {
      if (node[0] == BLOCK && !!getStatements(node) && node[1]->size() == 1) {
        safeCopy(node, node[1][0]);
      }
    });
    // convert L: do { .. } while(0) into L: { .. }
    traversePre(fun, [](Ref node) {
      if (node[0] == LABEL && node[1]->isString() /* careful of var label = 5 */ &&
          node[2][0] == DO && node[2][1][0] == NUM && node[2][1][1]->getNumber() == 0 && node[2][2][0] == BLOCK) {
        // there shouldn't be any continues on this, not direct break or continue
        IString label = node[1]->getIString();
        bool abort = false;
        int breakCaptured = 0, continueCaptured = 0;
        traversePrePost(node[2][2], [&](Ref node) {
          if (node[0] == CONTINUE) {
            if (!node[1] && !continueCaptured) {
              abort = true;
            } else if (node[1]->isString() && node[1]->getIString() == label) {
              abort = true;
            }
          }
          if (node[0] == BREAK && !node[1] && !breakCaptured) {
            abort = true;
          }
          if (BREAK_CAPTURERS.has(node[0])) {
            breakCaptured++;
          }
          if (CONTINUE_CAPTURERS.has(node[0])) {
            continueCaptured++;
          }
        }, [&](Ref node) {
          if (BREAK_CAPTURERS.has(node[0])) {
            breakCaptured--;
          }
          if (CONTINUE_CAPTURERS.has(node[0])) {
            continueCaptured--;
          }
        });
        if (abort) return;
        safeCopy(node[2], node[2][2]);
      }
    });
  });
}

// Contrary to the name this does not eliminate actual dead functions, only
// those marked as such with DEAD_FUNCTIONS
void eliminateDeadFuncs(Ref ast) {
  assert(!!extraInfo);
  IString DEAD_FUNCTIONS("dead_functions");
  IString ABORT("abort");
  assert(extraInfo->has(DEAD_FUNCTIONS));
  StringSet deadFunctions;
  for (size_t i = 0; i < extraInfo[DEAD_FUNCTIONS]->size(); i++) {
    deadFunctions.insert(extraInfo[DEAD_FUNCTIONS][i]->getIString());
  }
  traverseFunctions(ast, [&](Ref fun) {
    if (!deadFunctions.has(fun[1].get()->getIString())) {
      return;
    }
    AsmData asmData(fun);
    fun[3]->setSize(1);
    fun[3][0] = make1(STAT, make2(CALL, makeName(ABORT), &(makeArray(1))->push_back(makeNum(-1))));
    asmData.vars.clear();
    asmData.denormalize();
  });
}

