Mercurial > hg > graal-compiler
changeset 22978:64eb72b6165d
TraceRA: add TraceGlobalMoveResolutionMappingTest.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Thu, 12 Nov 2015 18:04:38 +0100 |
parents | 913b2001af72 |
children | 9ef376e2e6b6 |
files | graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/alloc/trace/TraceGlobalMoveResolutionMappingTest.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/ShadowedRegisterValue.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolver.java |
diffstat | 4 files changed, 336 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/alloc/trace/TraceGlobalMoveResolutionMappingTest.java Thu Nov 12 18:04:38 2015 +0100 @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.test.alloc.trace; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.HashSet; + +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.Register.RegisterCategory; +import jdk.vm.ci.code.RegisterValue; +import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.LIRKind; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.Value; + +import org.junit.Before; +import org.junit.Test; + +import com.oracle.graal.lir.alloc.trace.ShadowedRegisterValue; +import com.oracle.graal.lir.alloc.trace.TraceGlobalMoveResolutionPhase; + +/** + * Test global move resolver of the trace register allocator. + * + * Especially the mapping of LabelOp.incoming and BlockEndOp.outgoing. + */ +public class TraceGlobalMoveResolutionMappingTest { + + private static final class MoveResolverMock extends TraceGlobalMoveResolutionPhase.MoveResolver { + + private static final class Pair { + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((dst == null) ? 0 : dst.hashCode()); + result = prime * result + ((src == null) ? 0 : src.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Pair other = (Pair) obj; + if (dst == null) { + if (other.dst != null) { + return false; + } + } else if (!dst.equals(other.dst)) { + return false; + } + if (src == null) { + if (other.src != null) { + return false; + } + } else if (!src.equals(other.src)) { + return false; + } + return true; + } + + private final Value src; + private final AllocatableValue dst; + + Pair(Value src, AllocatableValue dst) { + this.src = src; + this.dst = dst; + } + + @Override + public String toString() { + return dst.toString() + " <- " + src; + } + } + + private final HashSet<Pair> mapping = new HashSet<>(); + + @Override + public void addMapping(Value src, AllocatableValue dst) { + mapping.add(new Pair(src, dst)); + } + + public int size() { + return mapping.size(); + } + + public boolean contains(Value src, AllocatableValue dst) { + return mapping.contains(new Pair(src, dst)); + } + + @Override + public String toString() { + return mapping.toString(); + } + + } + + private static final RegisterCategory CPU = new RegisterCategory("CPU"); + + private static final Register r0 = new Register(0, 0, "r0", CPU); + private static final Register r1 = new Register(1, 1, "r1", CPU); + + private static enum DummyPlatformKind implements PlatformKind { + Long; + + private EnumKey<DummyPlatformKind> key = new EnumKey<>(this); + + public Key getKey() { + return key; + } + + public int getSizeInBytes() { + return 8; + } + + public int getVectorLength() { + return 1; + } + + public char getTypeChar() { + return 'l'; + } + } + + private static final LIRKind kind = LIRKind.value(DummyPlatformKind.Long); + + private MoveResolverMock resolver; + + @Before + public void setUp() { + resolver = new MoveResolverMock(); + } + + private void addMapping(Value src, Value dst) { + TraceGlobalMoveResolutionPhase.addMapping(resolver, src, dst); + } + + /** Create RegisterValue. */ + private static RegisterValue v(Register r) { + return r.asValue(kind); + } + + /** Create StackSlot. */ + private static StackSlot s(int offset) { + return StackSlot.get(kind, -offset, true); + } + + /** Create ShadowedRegisterValue. */ + private static ShadowedRegisterValue sd(Register reg, int offset) { + return new ShadowedRegisterValue(v(reg), s(offset)); + } + + private void assertContains(Value src, AllocatableValue dst) { + assertTrue(String.format("Expected move from %s to %s. %s", src, dst, resolver), resolver.contains(src, dst)); + } + + private void assertSize(int expected) { + assertEquals(resolver.toString(), expected, resolver.size()); + } + + @Test + public void testReg2Reg0() { + addMapping(v(r0), v(r1)); + assertContains(v(r0), v(r1)); + } + + @Test + public void testReg2Reg1() { + addMapping(v(r0), v(r0)); + assertSize(0); + } + + @Test + public void testStack2Stack0() { + addMapping(s(1), s(2)); + assertContains(s(1), s(2)); + } + + @Test + public void testStack2Stack1() { + addMapping(s(1), s(1)); + assertSize(0); + } + + @Test + public void testStack2Reg() { + addMapping(s(1), v(r1)); + assertContains(s(1), v(r1)); + } + + @Test + public void testReg2Stack() { + addMapping(v(r0), s(1)); + assertContains(v(r0), s(1)); + } + + @Test + public void testShadowed2Reg() { + addMapping(sd(r0, 1), v(r1)); + assertContains(v(r0), v(r1)); + } + + @Test + public void testReg2Shadowed0() { + addMapping(v(r0), sd(r1, 1)); + assertSize(2); + assertContains(v(r0), v(r1)); + assertContains(v(r0), s(1)); + } + + @Test + public void testReg2Shadowed1() { + addMapping(v(r0), sd(r0, 1)); + assertSize(1); + assertContains(v(r0), s(1)); + } + + @Test + public void testStack2Shadowed0() { + addMapping(s(2), sd(r1, 1)); + assertSize(2); + assertContains(s(2), v(r1)); + assertContains(v(r1), s(1)); + } + + @Test + public void testStack2Shadowed1() { + addMapping(s(1), sd(r1, 1)); + assertSize(1); + assertContains(s(1), v(r1)); + } + + @Test + public void testShadowed2Shadowed0() { + addMapping(sd(r0, 1), sd(r1, 2)); + assertSize(2); + assertContains(v(r0), v(r1)); + assertContains(v(r0), s(2)); + } + + @Test + public void testShadowed2Shadowed1() { + addMapping(sd(r0, 1), sd(r1, 1)); + assertSize(1); + assertContains(v(r0), v(r1)); + } + + @Test + public void testShadowed2Shadowed2() { + addMapping(sd(r0, 1), sd(r0, 1)); + assertSize(0); + } +}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/ShadowedRegisterValue.java Wed Nov 11 17:09:42 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/ShadowedRegisterValue.java Thu Nov 12 18:04:38 2015 +0100 @@ -40,7 +40,7 @@ /** * Represents a {@link #register} which has a shadow copy on the {@link #stackslot stack}. */ -final class ShadowedRegisterValue extends CompositeValue { +public final class ShadowedRegisterValue extends CompositeValue { private static final EnumSet<OperandFlag> registerFlags = EnumSet.of(REG); private static final EnumSet<OperandFlag> stackslotFlags = EnumSet.of(STACK);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java Wed Nov 11 17:09:42 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java Thu Nov 12 18:04:38 2015 +0100 @@ -47,7 +47,14 @@ import com.oracle.graal.lir.ssa.SSAUtil.PhiValueVisitor; import com.oracle.graal.lir.ssi.SSIUtil; -final class TraceGlobalMoveResolutionPhase extends TraceAllocationPhase { +public final class TraceGlobalMoveResolutionPhase extends TraceAllocationPhase { + + /** + * Abstract move resolver interface for testing. + */ + public abstract static class MoveResolver { + public abstract void addMapping(Value src, AllocatableValue dst); + } private final TraceBuilderResult<?> resultTraces; @@ -68,41 +75,7 @@ TraceGlobalMoveResolver moveResolver = new TraceGlobalMoveResolver(lirGenRes, spillMoveFactory, arch); PhiValueVisitor visitor = (Value phiIn, Value phiOut) -> { if (!isIllegal(phiIn) && !TraceGlobalMoveResolver.isMoveToSelf(phiOut, phiIn)) { - // prepare input/output values. - final Value src; - final Value srcShadow; - if (isShadowedRegisterValue(phiOut)) { - ShadowedRegisterValue phiOutSh = asShadowedRegisterValue(phiOut); - src = phiOutSh.getRegister(); - srcShadow = phiOutSh.getStackSlot(); - } else { - src = phiOut; - srcShadow = null; - } - assert src != null; - assert srcShadow == null || isRegister(src) && isStackSlotValue(srcShadow) : "Unexpected shadowed value: " + phiOut; - - final Value dst; - final Value dstShadow; - if (isShadowedRegisterValue(phiIn)) { - ShadowedRegisterValue phiInSh = asShadowedRegisterValue(phiIn); - dst = phiInSh.getRegister(); - dstShadow = phiInSh.getStackSlot(); - } else { - dst = phiIn; - dstShadow = null; - } - assert dst != null; - assert dstShadow == null || isRegister(dst) && isStackSlotValue(dstShadow) : "Unexpected shadowed value: " + phiIn; - - // set dst - if (!dst.equals(src)) { - moveResolver.addMapping(src, (AllocatableValue) dst); - } - // set dst_shadow - if (dstShadow != null && !dstShadow.equals(src)) { - moveResolver.addMapping(src, (AllocatableValue) dstShadow); - } + addMapping(moveResolver, phiOut, phiIn); } }; @@ -135,4 +108,43 @@ } } } + + public static void addMapping(MoveResolver moveResolver, Value from, Value to) { + assert !isIllegal(to); + // prepare input/output values. + final Value src; + final Value srcShadow; + if (isShadowedRegisterValue(from)) { + ShadowedRegisterValue phiOutSh = asShadowedRegisterValue(from); + src = phiOutSh.getRegister(); + srcShadow = phiOutSh.getStackSlot(); + } else { + src = from; + srcShadow = null; + } + assert src != null; + assert srcShadow == null || isRegister(src) && isStackSlotValue(srcShadow) : "Unexpected shadowed value: " + from; + + final Value dst; + final Value dstShadow; + if (isShadowedRegisterValue(to)) { + ShadowedRegisterValue phiInSh = asShadowedRegisterValue(to); + dst = phiInSh.getRegister(); + dstShadow = phiInSh.getStackSlot(); + } else { + dst = to; + dstShadow = null; + } + assert dst != null; + assert dstShadow == null || isRegister(dst) && isStackSlotValue(dstShadow) : "Unexpected shadowed value: " + to; + + // set dst + if (!dst.equals(src)) { + moveResolver.addMapping(src, (AllocatableValue) dst); + } + // set dst_shadow + if (dstShadow != null && !dstShadow.equals(src)) { + moveResolver.addMapping(src, (AllocatableValue) dstShadow); + } + } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolver.java Wed Nov 11 17:09:42 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolver.java Thu Nov 12 18:04:38 2015 +0100 @@ -60,7 +60,7 @@ /** */ -final class TraceGlobalMoveResolver { +final class TraceGlobalMoveResolver extends TraceGlobalMoveResolutionPhase.MoveResolver { private int insertIdx; private LIRInsertionBuffer insertionBuffer; // buffer where moves are inserted @@ -416,6 +416,7 @@ this.insertIdx = insertIdx; } + @Override public void addMapping(Value from, AllocatableValue to) { if (Debug.isLogEnabled()) { Debug.log("add move mapping from %s to %s", from, to);