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. 4 package com.android.tools.r8.ir.regalloc; 5 6 import com.android.tools.r8.ir.code.Instruction; 7 import com.android.tools.r8.ir.code.MoveType; 8 import java.util.Map; 9 import java.util.Set; 10 11 // Register moves used by the spilling register allocator. These are used both for spill and 12 // for phi moves and they are moves between actual registers represented by their register number. 13 public class RegisterMove { 14 MoveType type; 15 int dst; 16 int src; 17 Instruction definition; 18 RegisterMove(int dst, int src, MoveType type)19 public RegisterMove(int dst, int src, MoveType type) { 20 this.dst = dst; 21 this.src = src; 22 this.type = type; 23 } 24 RegisterMove(int dst, MoveType type, Instruction definition)25 public RegisterMove(int dst, MoveType type, Instruction definition) { 26 this.dst = dst; 27 this.src = LinearScanRegisterAllocator.NO_REGISTER; 28 this.type = type; 29 assert definition.isConstInstruction(); 30 this.definition = definition; 31 } 32 33 writes(int register)34 private boolean writes(int register) { 35 if (type == MoveType.WIDE && (dst + 1) == register) { 36 return true; 37 } 38 return dst == register; 39 } 40 isBlocked(Set<RegisterMove> moveSet, Map<Integer, Integer> valueMap)41 public boolean isBlocked(Set<RegisterMove> moveSet, Map<Integer, Integer> valueMap) { 42 for (RegisterMove move : moveSet) { 43 if (move.src == LinearScanRegisterAllocator.NO_REGISTER) { 44 continue; 45 } 46 if (move != this) { 47 if (writes(valueMap.get(move.src))) { 48 return true; 49 } 50 if (move.type == MoveType.WIDE) { 51 if (writes(valueMap.get(move.src) + 1)) { 52 return true; 53 } 54 } 55 } 56 } 57 return false; 58 } 59 60 @Override hashCode()61 public int hashCode() { 62 return src + dst * 3 + type.hashCode() * 5 + (definition == null ? 0 : definition.hashCode()); 63 } 64 65 @Override equals(Object other)66 public boolean equals(Object other) { 67 if (!(other instanceof RegisterMove)) { 68 return false; 69 } 70 RegisterMove o = (RegisterMove) other; 71 return o.src == src && o.dst == dst && o.type == type && o.definition == definition; 72 } 73 } 74