1// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4package com.android.tools.r8.ir.regalloc;
5
6import static junit.framework.TestCase.assertFalse;
7import static junit.framework.TestCase.assertTrue;
8
9import com.android.tools.r8.ir.code.Add;
10import com.android.tools.r8.ir.code.ConstNumber;
11import com.android.tools.r8.ir.code.ConstType;
12import com.android.tools.r8.ir.code.MoveType;
13import com.android.tools.r8.ir.code.NumericType;
14import com.android.tools.r8.ir.code.Value;
15import org.junit.Test;
16
17public class IdenticalAfterRegisterAllocationTest {
18
19  private static class MockRegisterAllocator implements RegisterAllocator {
20    @Override
21    public void allocateRegisters(boolean debug) {
22    }
23
24    @Override
25    public int registersUsed() {
26      return 0;
27    }
28
29    @Override
30    public int getRegisterForValue(Value value, int instructionNumber) {
31      // Use the value number as the register number.
32      return value.getNumber();
33    }
34
35    @Override
36    public boolean argumentValueUsesHighRegister(Value value, int instructionNumber) {
37      return false;
38    }
39
40    @Override
41    public int getArgumentOrAllocateRegisterForValue(Value value, int instructionNumber) {
42      return value.getNumber();
43    }
44  }
45
46  @Test
47  public void equalityOfConstantOperands() {
48    RegisterAllocator allocator = new MockRegisterAllocator();
49    Value value0 = new Value(0, MoveType.SINGLE, null);
50    ConstNumber const0 = new ConstNumber(ConstType.INT, value0, 0);
51    Value value1 = new Value(1, MoveType.SINGLE, null);
52    ConstNumber const1 = new ConstNumber(ConstType.INT, value1, 1);
53    Value value2 = new Value(2, MoveType.SINGLE, null);
54    ConstNumber const2 = new ConstNumber(ConstType.INT, value2, 2);
55    Value value3 = new Value(2, MoveType.SINGLE, null);
56    Add add0 = new Add(NumericType.INT, value3, value0, value1);
57    Add add1 = new Add(NumericType.INT, value3, value0, value2);
58    value0.computeNeedsRegister();
59    assertTrue(value0.needsRegister());
60    value1.computeNeedsRegister();
61    assertFalse(value1.needsRegister());
62    value2.computeNeedsRegister();
63    assertFalse(value2.needsRegister());
64    value3.computeNeedsRegister();
65    assertTrue(value3.needsRegister());
66    // value1 and value2 represent different constants and the additions are therefore
67    // not equivalent.
68    assertFalse(add0.identicalAfterRegisterAllocation(add1, allocator));
69  }
70}
71