// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import '../compiler.dart' show Compiler;
import '../constants/constant_system.dart';
import '../constants/values.dart';
import '../elements/elements.dart';
import '../js_backend/js_backend.dart';
import '../types/types.dart';
import '../universe/selector.dart';
import '../universe/call_structure.dart';
import '../world.dart' show ClassWorld, World;

import 'nodes.dart';
import 'types.dart';

/**
 * [InvokeDynamicSpecializer] and its subclasses are helpers to
 * optimize intercepted dynamic calls. It knows what input types
 * would be beneficial for performance, and how to change a invoke
 * dynamic to a builtin instruction (e.g. HIndex, HBitNot).
 */
class InvokeDynamicSpecializer {
  const InvokeDynamicSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    return TypeMaskFactory.inferredTypeForSelector(
        instruction.selector, instruction.mask, compiler);
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    return null;
  }

  Operation operation(ConstantSystem constantSystem) => null;

  static InvokeDynamicSpecializer lookupSpecializer(Selector selector) {
    if (selector.isIndex) {
      return const IndexSpecializer();
    } else if (selector.isIndexSet) {
      return const IndexAssignSpecializer();
    } else if (selector.isOperator) {
      if (selector.name == 'unary-') {
        return const UnaryNegateSpecializer();
      } else if (selector.name == '~') {
        return const BitNotSpecializer();
      } else if (selector.name == '+') {
        return const AddSpecializer();
      } else if (selector.name == '-') {
        return const SubtractSpecializer();
      } else if (selector.name == '*') {
        return const MultiplySpecializer();
      } else if (selector.name == '/') {
        return const DivideSpecializer();
      } else if (selector.name == '~/') {
        return const TruncatingDivideSpecializer();
      } else if (selector.name == '%') {
        return const ModuloSpecializer();
      } else if (selector.name == '>>') {
        return const ShiftRightSpecializer();
      } else if (selector.name == '<<') {
        return const ShiftLeftSpecializer();
      } else if (selector.name == '&') {
        return const BitAndSpecializer();
      } else if (selector.name == '|') {
        return const BitOrSpecializer();
      } else if (selector.name == '^') {
        return const BitXorSpecializer();
      } else if (selector.name == '==') {
        return const EqualsSpecializer();
      } else if (selector.name == '<') {
        return const LessSpecializer();
      } else if (selector.name == '<=') {
        return const LessEqualSpecializer();
      } else if (selector.name == '>') {
        return const GreaterSpecializer();
      } else if (selector.name == '>=') {
        return const GreaterEqualSpecializer();
      }
    } else if (selector.isCall) {
      if (selector.argumentCount == 1 && selector.namedArguments.length == 0) {
        if (selector.name == 'codeUnitAt') {
          return const CodeUnitAtSpecializer();
        }
      }
    }
    return const InvokeDynamicSpecializer();
  }
}

class IndexAssignSpecializer extends InvokeDynamicSpecializer {
  const IndexAssignSpecializer();

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    if (instruction.inputs[1].isMutableIndexable(compiler)) {
      if (!instruction.inputs[2].isInteger(compiler)
          && compiler.options.enableTypeAssertions) {
        // We want the right checked mode error.
        return null;
      }
      return new HIndexAssign(instruction.inputs[1],
                              instruction.inputs[2],
                              instruction.inputs[3],
                              instruction.selector);
    }
    return null;
  }
}

class IndexSpecializer extends InvokeDynamicSpecializer {
  const IndexSpecializer();

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    if (!instruction.inputs[1].isIndexablePrimitive(compiler)) return null;
    if (!instruction.inputs[2].isInteger(compiler)
        && compiler.options.enableTypeAssertions) {
      // We want the right checked mode error.
      return null;
    }
    TypeMask receiverType =
        instruction.getDartReceiver(compiler).instructionType;
    TypeMask type = TypeMaskFactory.inferredTypeForSelector(
        instruction.selector, receiverType, compiler);
    return new HIndex(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, type);
  }
}

class BitNotSpecializer extends InvokeDynamicSpecializer {
  const BitNotSpecializer();

  UnaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.bitNot;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    // All bitwise operations on primitive types either produce an
    // integer or throw an error.
    JavaScriptBackend backend = compiler.backend;
    if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
      return backend.uint32Type;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction input = instruction.inputs[1];
    if (input.isNumber(compiler)) {
      return new HBitNot(input, instruction.selector,
                         computeTypeFromInputTypes(instruction, compiler));
    }
    return null;
  }
}

class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
  const UnaryNegateSpecializer();

  UnaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.negate;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    TypeMask operandType = instruction.inputs[1].instructionType;
    if (instruction.inputs[1].isNumberOrNull(compiler)) return operandType;
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction input = instruction.inputs[1];
    if (input.isNumber(compiler)) {
      return new HNegate(input, instruction.selector, input.instructionType);
    }
    return null;
  }
}

abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
  const BinaryArithmeticSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    JavaScriptBackend backend = compiler.backend;
    if (left.isIntegerOrNull(compiler) && right.isIntegerOrNull(compiler)) {
      return backend.intType;
    }
    if (left.isNumberOrNull(compiler)) {
      if (left.isDoubleOrNull(compiler) || right.isDoubleOrNull(compiler)) {
        return backend.doubleType;
      }
      return backend.numType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  bool isBuiltin(HInvokeDynamic instruction, Compiler compiler) {
    return instruction.inputs[1].isNumber(compiler)
        && instruction.inputs[2].isNumber(compiler);
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    if (isBuiltin(instruction, compiler)) {
      HInstruction builtin = newBuiltinVariant(instruction, compiler);
      if (builtin != null) return builtin;
      // Even if there is no builtin equivalent instruction, we know
      // the instruction does not have any side effect, and that it
      // can be GVN'ed.
      clearAllSideEffects(instruction);
    }
    return null;
  }

  void clearAllSideEffects(HInstruction instruction) {
    instruction.sideEffects.clearAllSideEffects();
    instruction.sideEffects.clearAllDependencies();
    instruction.setUseGvn();
  }

  bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    return left.isPositiveIntegerOrNull(compiler)
        && right.isPositiveIntegerOrNull(compiler);
  }

  bool inputsAreUInt31(HInstruction instruction, Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    return left.isUInt31(compiler) && right.isUInt31(compiler);
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);

  Selector renameToOptimizedSelector(String name,
                                     Selector selector,
                                     Compiler compiler) {
    if (selector.name == name) return selector;
    JavaScriptBackend backend = compiler.backend;
    return new Selector.call(
        new Name(name, backend.helpers.interceptorsLibrary),
        new CallStructure(selector.argumentCount));
  }
}

class AddSpecializer extends BinaryArithmeticSpecializer {
  const AddSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    if (inputsAreUInt31(instruction, compiler)) {
      JavaScriptBackend backend = compiler.backend;
      return backend.uint32Type;
    }
    if (inputsArePositiveIntegers(instruction, compiler)) {
      JavaScriptBackend backend = compiler.backend;
      return backend.positiveIntType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.add;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HAdd(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

class DivideSpecializer extends BinaryArithmeticSpecializer {
  const DivideSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.divide;
  }

  TypeMask computeTypeFromInputTypes(HInstruction instruction,
                                     Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    JavaScriptBackend backend = compiler.backend;
    if (left.isNumberOrNull(compiler)) {
      return backend.doubleType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return new HDivide(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, backend.doubleType);
  }
}

class ModuloSpecializer extends BinaryArithmeticSpecializer {
  const ModuloSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    if (inputsArePositiveIntegers(instruction, compiler)) {
      JavaScriptBackend backend = compiler.backend;
      return backend.positiveIntType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.modulo;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    // Modulo cannot be mapped to the native operator (different semantics).
    // TODO(sra): For non-negative values we can use JavaScript's %.
    return null;
  }
}

class MultiplySpecializer extends BinaryArithmeticSpecializer {
  const MultiplySpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.multiply;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    if (inputsArePositiveIntegers(instruction, compiler)) {
      JavaScriptBackend backend = compiler.backend;
      return backend.positiveIntType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HMultiply(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

class SubtractSpecializer extends BinaryArithmeticSpecializer {
  const SubtractSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.subtract;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HSubtract(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
  const TruncatingDivideSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.truncatingDivide;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    if (hasUint31Result(instruction, compiler)) {
      return backend.uint31Type;
    }
    if (inputsArePositiveIntegers(instruction, compiler)) {
      return backend.positiveIntType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  bool isNotZero(HInstruction instruction, Compiler compiler) {
    if (!instruction.isConstantInteger()) return false;
    HConstant rightConstant = instruction;
    IntConstantValue intConstant = rightConstant.constant;
    int count = intConstant.primitiveValue;
    return count != 0;
  }

  bool isTwoOrGreater(HInstruction instruction, Compiler compiler) {
    if (!instruction.isConstantInteger()) return false;
    HConstant rightConstant = instruction;
    IntConstantValue intConstant = rightConstant.constant;
    int count = intConstant.primitiveValue;
    return count >= 2;
  }

  bool hasUint31Result(HInstruction instruction, Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    if (right.isPositiveInteger(compiler)) {
      if (left.isUInt31(compiler) && isNotZero(right, compiler)) {
        return true;
      }
      if (left.isUInt32(compiler) && isTwoOrGreater(right, compiler)) {
        return true;
      }
    }
    return false;
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction right = instruction.inputs[2];
    if (isBuiltin(instruction, compiler)) {
      if (right.isPositiveInteger(compiler) && isNotZero(right, compiler)) {
        if (hasUint31Result(instruction, compiler)) {
          return newBuiltinVariant(instruction, compiler);
        }
        // We can call _tdivFast because the rhs is a 32bit integer
        // and not 0, nor -1.
        instruction.selector = renameToOptimizedSelector(
            '_tdivFast', instruction.selector, compiler);
      }
      clearAllSideEffects(instruction);
    }
    return null;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HTruncatingDivide(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
  const BinaryBitOpSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    // All bitwise operations on primitive types either produce an
    // integer or throw an error.
    HInstruction left = instruction.inputs[1];
    JavaScriptBackend backend = compiler.backend;
    if (left.isPrimitiveOrNull(compiler)) {
      return backend.uint32Type;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  bool argumentLessThan32(HInstruction instruction) {
    if (!instruction.isConstantInteger()) return false;
    HConstant rightConstant = instruction;
    IntConstantValue intConstant = rightConstant.constant;
    int count = intConstant.primitiveValue;
    return count >= 0 && count <= 31;
  }

  bool isPositive(HInstruction instruction, Compiler compiler) {
    // TODO: We should use the value range analysis. Currently, ranges
    // are discarded just after the analysis.
    return instruction.isPositiveInteger(compiler);
  }
}

class ShiftLeftSpecializer extends BinaryBitOpSpecializer {
  const ShiftLeftSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.shiftLeft;
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    if (left.isNumber(compiler)) {
      if (argumentLessThan32(right)) {
        return newBuiltinVariant(instruction, compiler);
      }
      // Even if there is no builtin equivalent instruction, we know
      // the instruction does not have any side effect, and that it
      // can be GVN'ed.
      clearAllSideEffects(instruction);
      if (isPositive(right, compiler)) {
        instruction.selector = renameToOptimizedSelector(
            '_shlPositive', instruction.selector, compiler);
      }
    }
    return null;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HShiftLeft(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

class ShiftRightSpecializer extends BinaryBitOpSpecializer {
  const ShiftRightSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    if (left.isUInt32(compiler)) return left.instructionType;
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    if (left.isNumber(compiler)) {
      if (argumentLessThan32(right) && isPositive(left, compiler)) {
        return newBuiltinVariant(instruction, compiler);
      }
      // Even if there is no builtin equivalent instruction, we know
      // the instruction does not have any side effect, and that it
      // can be GVN'ed.
      clearAllSideEffects(instruction);
      if (isPositive(right, compiler) && isPositive(left, compiler)) {
        instruction.selector = renameToOptimizedSelector(
            '_shrBothPositive', instruction.selector, compiler);
      } else if (isPositive(left, compiler) && right.isNumber(compiler)) {
        instruction.selector = renameToOptimizedSelector(
            '_shrReceiverPositive', instruction.selector, compiler);
      } else if (isPositive(right, compiler)) {
        instruction.selector = renameToOptimizedSelector(
            '_shrOtherPositive', instruction.selector, compiler);
      }
    }
    return null;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HShiftRight(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.shiftRight;
  }
}

class BitOrSpecializer extends BinaryBitOpSpecializer {
  const BitOrSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.bitOr;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    JavaScriptBackend backend = compiler.backend;
    if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
      return backend.uint31Type;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HBitOr(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

class BitAndSpecializer extends BinaryBitOpSpecializer {
  const BitAndSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.bitAnd;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    JavaScriptBackend backend = compiler.backend;
    if (left.isPrimitiveOrNull(compiler) &&
        (left.isUInt31(compiler) || right.isUInt31(compiler))) {
      return backend.uint31Type;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HBitAnd(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

class BitXorSpecializer extends BinaryBitOpSpecializer {
  const BitXorSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.bitXor;
  }

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    JavaScriptBackend backend = compiler.backend;
    if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
      return backend.uint31Type;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    return new HBitXor(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
  }
}

abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
  const RelationalSpecializer();

  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                     Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
      return backend.boolType;
    }
    return super.computeTypeFromInputTypes(instruction, compiler);
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    if (left.isNumber(compiler) && right.isNumber(compiler)) {
      return newBuiltinVariant(instruction, compiler);
    }
    return null;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
}

class EqualsSpecializer extends RelationalSpecializer {
  const EqualsSpecializer();

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    HInstruction left = instruction.inputs[1];
    HInstruction right = instruction.inputs[2];
    TypeMask instructionType = left.instructionType;
    if (right.isConstantNull() || left.isPrimitiveOrNull(compiler)) {
      return newBuiltinVariant(instruction, compiler);
    }
    World world = compiler.world;
    JavaScriptBackend backend = compiler.backend;
    Iterable<Element> matches = world.allFunctions.filter(
        instruction.selector, instructionType);
    // This test relies the on `Object.==` and `Interceptor.==` always being
    // implemented because if the selector matches by subtype, it still will be
    // a regular object or an interceptor.
    if (matches.every(backend.isDefaultEqualityImplementation)) {
      return newBuiltinVariant(instruction, compiler);
    }
    return null;
  }

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.equal;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return new HIdentity(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, backend.boolType);
  }
}

class LessSpecializer extends RelationalSpecializer {
  const LessSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.less;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return new HLess(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, backend.boolType);
  }
}

class GreaterSpecializer extends RelationalSpecializer {
  const GreaterSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.greater;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return new HGreater(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, backend.boolType);
  }
}

class GreaterEqualSpecializer extends RelationalSpecializer {
  const GreaterEqualSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.greaterEqual;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return new HGreaterEqual(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, backend.boolType);
  }
}

class LessEqualSpecializer extends RelationalSpecializer {
  const LessEqualSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.lessEqual;
  }

  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                 Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return new HLessEqual(
        instruction.inputs[1], instruction.inputs[2],
        instruction.selector, backend.boolType);
  }
}

class CodeUnitAtSpecializer extends InvokeDynamicSpecializer {
  const CodeUnitAtSpecializer();

  BinaryOperation operation(ConstantSystem constantSystem) {
    return constantSystem.codeUnitAt;
  }

  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                   Compiler compiler) {
    // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index
    // bounds checking optimizations as for HIndex.
    return null;
  }
}
