// 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.optimize;

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

import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.Goto;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.If.Type;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Throw;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
import java.util.LinkedList;
import org.junit.Test;

public class TrivialGotoEliminationTest {
  @Test
  public void trivialGotoInEntryBlock() {
    // Setup silly block structure:
    //
    // block0:
    //   goto block2
    // block1:
    //   v0 = const-number 0
    //   throw v0
    // block2:
    //   return
    Position position = Position.testingPosition();
    BasicBlock block2 = new BasicBlock();
    block2.setNumber(2);
    BasicBlock block0 = BasicBlock.createGotoBlock(0, position, block2);
    block0.setFilledForTesting();
    block2.getPredecessors().add(block0);
    Instruction ret = new Return();
    ret.setPosition(position);
    block2.add(ret);
    block2.setFilledForTesting();
    BasicBlock block1 = new BasicBlock();
    block1.setNumber(1);
    Value value = new Value(0, ValueType.INT, null);
    Instruction number = new ConstNumber(value, 0);
    number.setPosition(position);
    block1.add(number);
    Instruction throwing = new Throw(value);
    throwing.setPosition(position);
    block1.add(throwing);
    block1.setFilledForTesting();
    LinkedList<BasicBlock> blocks = new LinkedList<>();
    blocks.add(block0);
    blocks.add(block1);
    blocks.add(block2);
    // Check that the goto in block0 remains. There was a bug in the trivial goto elimination
    // that ended up removing that goto changing the code to start with the unreachable
    // throw.
    IRCode code =
        new IRCode(new InternalOptions(), null, blocks, new ValueNumberGenerator(), false, false);
    CodeRewriter.collapsTrivialGotos(null, code);
    assertTrue(code.blocks.get(0).isTrivialGoto());
    assertTrue(blocks.contains(block0));
    assertTrue(blocks.contains(block1));
    assertTrue(blocks.contains(block2));
  }

  @Test
  public void trivialGotoLoopAsFallthrough() {
    // Setup block structure:
    // block0:
    //   v0 <- argument
    //   if ne v0 block2
    //
    // block1:
    //   goto block3
    //
    // block2:
    //   return
    //
    // block3:
    //   goto block3
    Position position = Position.testingPosition();
    BasicBlock block2 = new BasicBlock();
    block2.setNumber(2);
    Instruction ret = new Return();
    ret.setPosition(position);
    block2.add(ret);
    block2.setFilledForTesting();

    BasicBlock block3 = new BasicBlock();
    block3.setNumber(3);
    Instruction instruction = new Goto();
    instruction.setPosition(position);
    block3.add(instruction);
    block3.setFilledForTesting();
    block3.getSuccessors().add(block3);

    BasicBlock block1 = BasicBlock.createGotoBlock(1, position);
    block1.getSuccessors().add(block3);
    block1.setFilledForTesting();

    BasicBlock block0 = new BasicBlock();
    block0.setNumber(0);
    Value value = new Value(0, ValueType.OBJECT, null);
    instruction = new Argument(value);
    instruction.setPosition(position);
    block0.add(instruction);
    instruction = new If(Type.EQ, value);
    instruction.setPosition(position);
    block0.add(instruction);
    block0.getSuccessors().add(block2);
    block0.getSuccessors().add(block1);
    block0.setFilledForTesting();

    block1.getPredecessors().add(block0);
    block2.getPredecessors().add(block0);
    block3.getPredecessors().add(block1);
    block3.getPredecessors().add(block3);

    LinkedList<BasicBlock> blocks = new LinkedList<>();
    blocks.add(block0);
    blocks.add(block1);
    blocks.add(block2);
    blocks.add(block3);
    // Check that the goto in block0 remains. There was a bug in the trivial goto elimination
    // that ended up removing that goto changing the code to start with the unreachable
    // throw.
    IRCode code =
        new IRCode(new InternalOptions(), null, blocks, new ValueNumberGenerator(), false, false);
    CodeRewriter.collapsTrivialGotos(null, code);
    assertTrue(block0.getInstructions().get(1).isIf());
    assertEquals(block1, block0.getInstructions().get(1).asIf().fallthroughBlock());
    assertTrue(blocks.containsAll(ImmutableList.of(block0, block1, block2, block3)));
  }
}
