// Copyright (c) 2018, 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.optimize;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.Div;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.IRMetadata;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Move;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
import com.android.tools.r8.ir.regalloc.LiveIntervals;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.utils.InternalOptions;
import java.util.LinkedList;
import org.junit.Test;

public class ConstantRemovalTest {

  private static class MockLinearScanRegisterAllocator extends LinearScanRegisterAllocator {
    MockLinearScanRegisterAllocator(AppView<?> appView, IRCode code) {
      super(appView, code);
    }

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

  private static class MockLiveIntervals extends LiveIntervals {
    MockLiveIntervals(Value value) {
      super(value);
    }

    @Override
    public LiveIntervals getSplitCovering(int i) {
      return this;
    }
  }

  @Test
  public void removeConstantsTest() {
    // Produce a basic block representing the code:
    //
    // ConstNumber          v3 <-  0 (LONG)
    // ConstNumber          v0(10) <-  10 (LONG)
    // Div                  v3 <- v3, v0(10)
    // ConstNumber          v2(10) <-  10 (INT)
    // Move                 v1 <- v2(10) (INT)
    // Div                  v1 <- v1, v1
    // ConstNumber          v0(10) <-  10 (LONG)
    // Div                  v3 <- v3, v0(10)
    // Return
    //
    // Use a register allocator that uses the value number as the register.
    //
    // Then test that peephole optimization realizes that the last const number
    // is needed and the value 10 is *not* still in register 0 at that point.
    final NumberGenerator basicBlockNumberGenerator = new NumberGenerator();
    BasicBlock block = new BasicBlock();
    block.setNumber(basicBlockNumberGenerator.next());

    IRMetadata metadata = IRMetadata.unknown();
    Position position = SyntheticPosition.builder().disableMethodCheck().setLine(0).build();

    Value v3 = new Value(3, TypeElement.getLong(), null);
    v3.setNeedsRegister(true);
    new MockLiveIntervals(v3);
    Instruction instruction = new ConstNumber(v3, 0);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    Value v0 = new Value(0, TypeElement.getLong(), null);
    v0.setNeedsRegister(true);
    new MockLiveIntervals(v0);
    instruction = new ConstNumber(v0, 10);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    instruction = new Div(NumericType.LONG, v3, v3, v0);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    Value v2 = new Value(2, TypeElement.getInt(), null);
    v2.setNeedsRegister(true);
    new MockLiveIntervals(v2);
    instruction = new ConstNumber(v2, 10);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    Value v1 = new Value(1, TypeElement.getInt(), null);
    v1.setNeedsRegister(true);
    new MockLiveIntervals(v1);
    instruction = new Move(v1 ,v2);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    instruction = new Div(NumericType.INT, v1, v1, v1);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    Value v0_2 = new Value(0, TypeElement.getLong(), null);
    v0_2.setNeedsRegister(true);
    new MockLiveIntervals(v0_2);
    instruction = new ConstNumber(v0_2, 10);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    instruction = new Div(NumericType.LONG, v3, v3, v0_2);
    instruction.setPosition(position);
    block.add(instruction, metadata);

    Instruction ret = new Return();
    ret.setPosition(position);
    block.add(ret, metadata);
    block.setFilledForTesting();

    LinkedList<BasicBlock> blocks = new LinkedList<>();
    blocks.add(block);

    InternalOptions options = new InternalOptions();
    options.debug = true;
    AppInfo appInfo =
        AppInfo.createInitialAppInfo(
            DexApplication.builder(options, null).build(),
            GlobalSyntheticsStrategy.forNonSynthesizing());
    AppView<?> appView = AppView.createForD8(appInfo);
    IRCode code =
        new IRCode(
            options,
            null,
            Position.none(),
            blocks,
            new NumberGenerator(),
            basicBlockNumberGenerator,
            IRMetadata.unknown(),
            Origin.unknown(),
            new MutableMethodConversionOptions(options));
    PeepholeOptimizer.optimize(appView, code, new MockLinearScanRegisterAllocator(appView, code));

    // Check that all four constant number instructions remain.
    assertEquals(
        4,
        code.entryBlock().getInstructions().stream().filter(Instruction::isConstNumber).count());
  }
}
