# HG changeset patch # User Doug Simon # Date 1379707118 -7200 # Node ID b8695542d41bfd1d058a2cd362fa9b506fe28c32 # Parent aa10794f15746dc546f229c352d8c2df56a23574 added HSAIL register configuration The main change was to override Backend.newFrameMap() in HSAILBackend to use the HSAIL register configuration. Contributed-by: Vasanth Venkatachalam diff -r aa10794f1574 -r b8695542d41b graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java Fri Sep 20 21:14:24 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java Fri Sep 20 21:58:38 2013 +0200 @@ -59,9 +59,12 @@ paramTypeMap.put("HotSpotResolvedPrimitiveType", "s64"); } + /** + * Use the HSAIL register set when the compilation target is HSAIL. + */ @Override public FrameMap newFrameMap() { - return new HSAILFrameMap(runtime(), target, runtime().lookupRegisterConfig()); + return new HSAILFrameMap(runtime(), target, new HSAILRegisterConfig()); } @Override diff -r aa10794f1574 -r b8695542d41b graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Fri Sep 20 21:14:24 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Fri Sep 20 21:58:38 2013 +0200 @@ -23,33 +23,25 @@ package com.oracle.graal.compiler.hsail; -import static com.oracle.graal.api.code.CodeUtil.*; - +import java.lang.reflect.*; import java.util.logging.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CallingConvention.*; -import com.oracle.graal.api.runtime.Graal; -import com.oracle.graal.compiler.GraalCompiler; -import com.oracle.graal.java.GraphBuilderConfiguration; -import com.oracle.graal.java.GraphBuilderPhase; -import com.oracle.graal.nodes.StructuredGraph; -import com.oracle.graal.nodes.spi.GraalCodeCacheProvider; -import com.oracle.graal.phases.OptimisticOptimizations; -import com.oracle.graal.phases.PhasePlan; -import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.graph.GraalInternalError; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hsail.*; +import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.nodes.spi.Replacements; -import com.oracle.graal.compiler.target.Backend; -import com.oracle.graal.hsail.*; - -import java.lang.reflect.Method; /** * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code. @@ -96,6 +88,33 @@ return getHSAILCompilationResult(graph); } + /** + * HSAIL doesn't have a calling convention as such. Function arguments are actually passed in + * memory but then loaded into registers in the function body. This routine makes sure that + * arguments to a kernel or function are loaded (by the kernel or function body) into registers + * of the appropriate sizes. For example, int and float parameters should appear in S registers, + * whereas double and long parameters should appear in d registers. + */ + public static CallingConvention getHSAILCallingConvention(CallingConvention.Type type, TargetDescription target, ResolvedJavaMethod method, boolean stackOnly) { + Signature sig = method.getSignature(); + JavaType retType = sig.getReturnType(null); + int sigCount = sig.getParameterCount(false); + JavaType[] argTypes; + int argIndex = 0; + if (!Modifier.isStatic(method.getModifiers())) { + argTypes = new JavaType[sigCount + 1]; + argTypes[argIndex++] = method.getDeclaringClass(); + } else { + argTypes = new JavaType[sigCount]; + } + for (int i = 0; i < sigCount; i++) { + argTypes[argIndex++] = sig.getParameterType(i, null); + } + + RegisterConfig registerConfig = new HSAILRegisterConfig(); + return registerConfig.getCallingConvention(type, retType, argTypes, target, stackOnly); + } + public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) { Debug.dump(graph, "Graph"); TargetDescription target = new TargetDescription(new HSAIL(), true, 8, 0, true); @@ -105,7 +124,7 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.AFTER_PARSING, new HSAILPhase()); new HSAILPhase().apply(graph); - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false); try { CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult()); diff -r aa10794f1574 -r b8695542d41b graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Fri Sep 20 21:58:38 2013 +0200 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2009, 2012, 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.hsail; + +import com.oracle.graal.api.code.*; + +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; + +import static com.oracle.graal.hsail.HSAIL.*; + +/** + * This class defines a higher level interface for the register allocator to be able to access info + * about the {@link HSAIL} register set. + * + * Note: In HSAIL, the number of registers of each type is actually a variable number that must + * satisfy the equation: Total num of registers = No. of S registers + 2 * (No. of D registers) + 4 + * * (No. of Q registers) = 128 In other words we can have up to 128S or 64 D or 32Q or a blend. + * + * For now we haven't implemented support for a variable sized register file. Instead we've fixed + * the number of registers of each type so that they satisfy the above equation. See {@link HSAIL} + * for more details. + */ +public class HSAILRegisterConfig implements RegisterConfig { + + private final Register[] allocatable = {s0, s1, s2, s3, s4, s5, s6, /* s7, */s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, + d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15}; + + private final Register[] regBitness32 = {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31}; + private final Register[] regBitness64 = {d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15}; + private final RegisterAttributes[] attributesMap = RegisterAttributes.createMap(this, HSAIL.allRegisters); + + @Override + public Register getReturnRegister(Kind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + return s0; + case Float: + case Double: + return d0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getFrameRegister() { + // TODO Auto-generated method stub + return null; + } + + @Override + public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { + return callingConvention(regBitness32, regBitness64, returnType, parameterTypes, type, target, stackOnly); + } + + private CallingConvention callingConvention(Register[] generalParameterRegisters, Register[] longParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, + TargetDescription target, boolean stackOnly) { + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; + + int currentRegs32 = 0; + int currentRegs64 = 0; + int currentStackOffset = 0; + + for (int i = 0; i < parameterTypes.length; i++) { + final Kind kind = parameterTypes[i].getKind(); + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Float: + + if (!stackOnly && currentRegs32 < generalParameterRegisters.length) { + Register register = generalParameterRegisters[currentRegs32++]; + locations[i] = register.asValue(kind); + } + break; + case Long: + case Object: + case Double: + if (!stackOnly && currentRegs64 < longParameterRegisters.length) { + Register register = longParameterRegisters[currentRegs64++]; + locations[i] = register.asValue(kind); + } + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + + if (locations[i] == null) { + locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); + currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); + } + } + + Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); + AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + @Override + public Register[] getCallingConventionRegisters(Type type, Kind kind) { + throw new GraalInternalError("getCallingConventinoRegisters unimplemented"); + } + + @Override + public Register[] getAllocatableRegisters() { + return allocatable.clone(); + } + + @Override + public Register[] getAllocatableRegisters(PlatformKind kind) { + Kind k = (Kind) kind; + switch (k) { + case Int: + case Short: + case Byte: + case Float: + return regBitness32.clone(); + case Long: + case Double: + case Object: + return regBitness64.clone(); + + default: + throw new GraalInternalError("unknown register allocation"); + } + } + + @Override + public Register[] getCallerSaveRegisters() { + // TODO Auto-generated method stub + return new Register[0]; + } + + @Override + public CalleeSaveLayout getCalleeSaveLayout() { + return null; + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap.clone(); + } + + @Override + public Register getRegisterForRole(int id) { + throw new UnsupportedOperationException(); + } + + public HSAILRegisterConfig() { + + } +}