1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.graalvm.compiler.lir.test.alloc.trace; 24 25import static org.junit.Assert.assertEquals; 26import static org.junit.Assert.assertTrue; 27 28import java.util.HashSet; 29 30import org.junit.Before; 31import org.junit.Ignore; 32import org.junit.Test; 33 34import org.graalvm.compiler.core.common.LIRKind; 35import org.graalvm.compiler.lir.alloc.trace.ShadowedRegisterValue; 36import org.graalvm.compiler.lir.alloc.trace.TraceGlobalMoveResolutionPhase; 37import org.graalvm.util.Pair; 38 39import jdk.vm.ci.code.Register; 40import jdk.vm.ci.code.Register.RegisterCategory; 41import jdk.vm.ci.code.RegisterValue; 42import jdk.vm.ci.code.StackSlot; 43import jdk.vm.ci.meta.AllocatableValue; 44import jdk.vm.ci.meta.PlatformKind; 45import jdk.vm.ci.meta.Value; 46 47/** 48 * Test global move resolver of the trace register allocator. 49 * 50 * Especially the mapping of LabelOp.incoming and BlockEndOp.outgoing. 51 */ 52public class TraceGlobalMoveResolutionMappingTest { 53 54 private static final class MoveResolverMock extends TraceGlobalMoveResolutionPhase.MoveResolver { 55 56 private final HashSet<Pair<Value, AllocatableValue>> mapping = new HashSet<>(); 57 58 @Override 59 public void addMapping(Value src, AllocatableValue dst, Value srcStack) { 60 mapping.add(Pair.create(src, dst)); 61 } 62 63 public int size() { 64 return mapping.size(); 65 } 66 67 public boolean contains(Value src, AllocatableValue dst) { 68 return mapping.contains(Pair.create(src, dst)); 69 } 70 71 @Override 72 public String toString() { 73 return mapping.toString(); 74 } 75 76 } 77 78 private static final RegisterCategory CPU = new RegisterCategory("CPU"); 79 80 private static final Register r0 = new Register(0, 0, "r0", CPU); 81 private static final Register r1 = new Register(1, 1, "r1", CPU); 82 83 private enum DummyPlatformKind implements PlatformKind { 84 Long; 85 86 private EnumKey<DummyPlatformKind> key = new EnumKey<>(this); 87 88 @Override 89 public Key getKey() { 90 return key; 91 } 92 93 @Override 94 public int getSizeInBytes() { 95 return 8; 96 } 97 98 @Override 99 public int getVectorLength() { 100 return 1; 101 } 102 103 @Override 104 public char getTypeChar() { 105 return 'l'; 106 } 107 } 108 109 private static final LIRKind kind = LIRKind.value(DummyPlatformKind.Long); 110 111 private MoveResolverMock resolver; 112 113 @Before 114 public void setUp() { 115 resolver = new MoveResolverMock(); 116 } 117 118 private void addMapping(Value src, Value dst) { 119 TraceGlobalMoveResolutionPhase.addMapping(resolver, src, dst); 120 } 121 122 /** Create RegisterValue. */ 123 private static RegisterValue v(Register r) { 124 return r.asValue(kind); 125 } 126 127 /** Create StackSlot. */ 128 private static StackSlot s(int offset) { 129 return StackSlot.get(kind, -offset, true); 130 } 131 132 /** Create ShadowedRegisterValue. */ 133 private static ShadowedRegisterValue sd(Register reg, int offset) { 134 return new ShadowedRegisterValue(v(reg), s(offset)); 135 } 136 137 private void assertContains(Value src, AllocatableValue dst) { 138 assertTrue(String.format("Expected move from %s to %s. %s", src, dst, resolver), resolver.contains(src, dst)); 139 } 140 141 private void assertSize(int expected) { 142 assertEquals(resolver.toString(), expected, resolver.size()); 143 } 144 145 @Test 146 public void testReg2Reg0() { 147 addMapping(v(r0), v(r1)); 148 assertContains(v(r0), v(r1)); 149 } 150 151 @Test 152 public void testReg2Reg1() { 153 addMapping(v(r0), v(r0)); 154 assertSize(0); 155 } 156 157 @Test 158 public void testStack2Stack0() { 159 addMapping(s(1), s(2)); 160 assertContains(s(1), s(2)); 161 } 162 163 @Test 164 public void testStack2Stack1() { 165 addMapping(s(1), s(1)); 166 assertSize(0); 167 } 168 169 @Test 170 public void testStack2Reg() { 171 addMapping(s(1), v(r1)); 172 assertContains(s(1), v(r1)); 173 } 174 175 @Test 176 public void testReg2Stack() { 177 addMapping(v(r0), s(1)); 178 assertContains(v(r0), s(1)); 179 } 180 181 @Test 182 public void testShadowed2Reg() { 183 addMapping(sd(r0, 1), v(r1)); 184 assertContains(v(r0), v(r1)); 185 } 186 187 @Test 188 public void testReg2Shadowed0() { 189 addMapping(v(r0), sd(r1, 1)); 190 assertSize(2); 191 assertContains(v(r0), v(r1)); 192 assertContains(v(r0), s(1)); 193 } 194 195 @Test 196 public void testReg2Shadowed1() { 197 addMapping(v(r0), sd(r0, 1)); 198 assertSize(1); 199 assertContains(v(r0), s(1)); 200 } 201 202 @Test 203 @Ignore("Cannot express mapping dependencies (yet)") 204 public void testStack2Shadowed0() { 205 addMapping(s(2), sd(r1, 1)); 206 assertSize(2); 207 assertContains(s(2), v(r1)); 208 assertContains(v(r1), s(1)); 209 } 210 211 @Test 212 public void testStack2Shadowed0WorkArount() { 213 addMapping(s(2), sd(r1, 1)); 214 assertSize(2); 215 assertContains(s(2), v(r1)); 216 assertContains(s(2), s(1)); 217 } 218 219 @Test 220 public void testStack2Shadowed1() { 221 addMapping(s(1), sd(r1, 1)); 222 assertSize(1); 223 assertContains(s(1), v(r1)); 224 } 225 226 @Test 227 public void testShadowed2Shadowed0() { 228 addMapping(sd(r0, 1), sd(r1, 2)); 229 assertSize(2); 230 assertContains(v(r0), v(r1)); 231 assertContains(v(r0), s(2)); 232 } 233 234 @Test 235 public void testShadowed2Shadowed1() { 236 addMapping(sd(r0, 1), sd(r1, 1)); 237 assertSize(1); 238 assertContains(v(r0), v(r1)); 239 } 240 241 @Test 242 public void testShadowed2Shadowed2() { 243 addMapping(sd(r0, 1), sd(r0, 1)); 244 assertSize(0); 245 } 246} 247