// Copyright (c) 2017, the R8 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.
package com.android.tools.r8.ir.regalloc;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Add;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
import com.android.tools.r8.utils.InternalOptions;
import java.util.List;
import org.junit.Test;

public class IdenticalAfterRegisterAllocationTest {

  private static class MockRegisterAllocator implements RegisterAllocator {
    private final ProgramMethod mockMethod;

    MockRegisterAllocator() {
      DexItemFactory dexItemFactory = new DexItemFactory();
      DexProgramClass clazz = DexProgramClass.createMockClassForTesting(new DexItemFactory());
      DexMethod signature =
          dexItemFactory.createMethod(
              clazz.type,
              dexItemFactory.createProto(dexItemFactory.voidType),
              dexItemFactory.createString("mock"));
      mockMethod =
          new ProgramMethod(
              clazz,
              DexEncodedMethod.builder()
                  .setMethod(signature)
                  .setAccessFlags(MethodAccessFlags.fromDexAccessFlags(0))
                  .disableAndroidApiLevelCheck()
                  .build());
    }

    @Override
    public ProgramMethod getProgramMethod() {
      return mockMethod;
    }

    @Override
    public void allocateRegisters() {
    }

    @Override
    public int registersUsed() {
      return 0;
    }

    @Override
    public int getRegisterForValue(Value value, int instructionNumber) {
      // Use the value number as the register number.
      return value.getNumber();
    }

    @Override
    public int getArgumentOrAllocateRegisterForValue(Value value, int instructionNumber) {
      return value.getNumber();
    }

    @Override
    public InternalOptions options() {
      return new InternalOptions();
    }

    @Override
    public AppView<?> getAppView() {
      return null;
    }

    @Override
    public void mergeBlocks(BasicBlock kept, BasicBlock removed) {
      // Intentionally empty, we don't need to track merging in this allocator.
    }

    @Override
    public boolean hasEqualTypesAtEntry(BasicBlock first, BasicBlock second) {
      return false;
    }

    @Override
    public void addNewBlockToShareIdenticalSuffix(
        BasicBlock block, int suffixSize, List<BasicBlock> predsBeforeSplit) {
      // Intentionally empty, we don't need to track suffix sharing in this allocator.
    }
  }

  @Test
  public void equalityOfConstantOperands() {
    RegisterAllocator allocator = new MockRegisterAllocator();
    Value value0 = new Value(0, TypeElement.getInt(), null);
    ConstNumber const0 = new ConstNumber(value0, 0);
    Value value1 = new Value(1, TypeElement.getInt(), null);
    ConstNumber const1 = new ConstNumber(value1, 1);
    Value value2 = new Value(2, TypeElement.getInt(), null);
    ConstNumber const2 = new ConstNumber(value2, 2);
    Value value3 = new Value(2, TypeElement.getInt(), null);
    Add add0 = new Add(NumericType.INT, value3, value0, value1);
    add0.setPosition(Position.none());
    Add add1 = new Add(NumericType.INT, value3, value0, value2);
    add1.setPosition(Position.none());
    value0.computeNeedsRegister();
    assertTrue(value0.needsRegister());
    value1.computeNeedsRegister();
    assertFalse(value1.needsRegister());
    value2.computeNeedsRegister();
    assertFalse(value2.needsRegister());
    value3.computeNeedsRegister();
    assertTrue(value3.needsRegister());
    // value1 and value2 represent different constants and the additions are therefore
    // not equivalent.
    assertFalse(
        add0.identicalAfterRegisterAllocation(
            add1, allocator, new MutableMethodConversionOptions(allocator.options())));
  }
}
