LIRGeneratorTool.java revision 12968:4d8a004e5c6d
1/* 2 * Copyright (c) 2011, 2016, 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.gen; 24 25import org.graalvm.compiler.core.common.LIRKind; 26import org.graalvm.compiler.core.common.calc.Condition; 27import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; 28import org.graalvm.compiler.core.common.spi.CodeGenProviders; 29import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; 30import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; 31import org.graalvm.compiler.core.common.type.Stamp; 32import org.graalvm.compiler.debug.GraalError; 33import org.graalvm.compiler.graph.NodeSourcePosition; 34import org.graalvm.compiler.lir.LIRFrameState; 35import org.graalvm.compiler.lir.LIRInstruction; 36import org.graalvm.compiler.lir.LabelRef; 37import org.graalvm.compiler.lir.SwitchStrategy; 38import org.graalvm.compiler.lir.Variable; 39 40import jdk.vm.ci.code.CodeCacheProvider; 41import jdk.vm.ci.code.Register; 42import jdk.vm.ci.code.RegisterAttributes; 43import jdk.vm.ci.code.TargetDescription; 44import jdk.vm.ci.code.ValueKindFactory; 45import jdk.vm.ci.meta.AllocatableValue; 46import jdk.vm.ci.meta.Constant; 47import jdk.vm.ci.meta.JavaConstant; 48import jdk.vm.ci.meta.JavaKind; 49import jdk.vm.ci.meta.MetaAccessProvider; 50import jdk.vm.ci.meta.PlatformKind; 51import jdk.vm.ci.meta.Value; 52import jdk.vm.ci.meta.ValueKind; 53 54public interface LIRGeneratorTool extends DiagnosticLIRGeneratorTool, ValueKindFactory<LIRKind> { 55 56 /** 57 * Factory for creating moves. 58 */ 59 public interface MoveFactory { 60 61 /** 62 * Checks whether the supplied constant can be used without loading it into a register for 63 * most operations, i.e., for commonly used arithmetic, logical, and comparison operations. 64 * 65 * @param c The constant to check. 66 * @return True if the constant can be used directly, false if the constant needs to be in a 67 * register. 68 */ 69 boolean canInlineConstant(Constant c); 70 71 /** 72 * @param constant The constant that might be moved to a stack slot. 73 * @return {@code true} if constant to stack moves are supported for this constant. 74 */ 75 boolean allowConstantToStackMove(Constant constant); 76 77 LIRInstruction createMove(AllocatableValue result, Value input); 78 79 LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input); 80 81 LIRInstruction createLoad(AllocatableValue result, Constant input); 82 } 83 84 abstract class BlockScope implements AutoCloseable { 85 86 public abstract AbstractBlockBase<?> getCurrentBlock(); 87 88 @Override 89 public abstract void close(); 90 91 } 92 93 ArithmeticLIRGeneratorTool getArithmetic(); 94 95 CodeGenProviders getProviders(); 96 97 TargetDescription target(); 98 99 MetaAccessProvider getMetaAccess(); 100 101 CodeCacheProvider getCodeCache(); 102 103 ForeignCallsProvider getForeignCalls(); 104 105 AbstractBlockBase<?> getCurrentBlock(); 106 107 LIRGenerationResult getResult(); 108 109 boolean hasBlockEnd(AbstractBlockBase<?> block); 110 111 MoveFactory getMoveFactory(); 112 113 /** 114 * Get a special {@link MoveFactory} for spill moves. 115 * 116 * The instructions returned by this factory must only depend on the input values. References to 117 * values that require interaction with register allocation are strictly forbidden. 118 */ 119 MoveFactory getSpillMoveFactory(); 120 121 BlockScope getBlockScope(AbstractBlockBase<?> block); 122 123 Value emitConstant(LIRKind kind, Constant constant); 124 125 Value emitJavaConstant(JavaConstant constant); 126 127 /** 128 * Some backends need to convert sub-word kinds to a larger kind in 129 * {@link ArithmeticLIRGeneratorTool#emitLoad} and {@link #emitLoadConstant} because sub-word 130 * registers can't be accessed. This method converts the {@link LIRKind} of a memory location or 131 * constant to the {@link LIRKind} that will be used when it is loaded into a register. 132 */ 133 <K extends ValueKind<K>> K toRegisterKind(K kind); 134 135 AllocatableValue emitLoadConstant(ValueKind<?> kind, Constant constant); 136 137 void emitNullCheck(Value address, LIRFrameState state); 138 139 Variable emitLogicCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue); 140 141 Value emitValueCompareAndSwap(Value address, Value expectedValue, Value newValue); 142 143 /** 144 * Emit an atomic read-and-add instruction. 145 * 146 * @param address address of the value to be read and written 147 * @param delta the value to be added 148 */ 149 default Value emitAtomicReadAndAdd(Value address, Value delta) { 150 throw GraalError.unimplemented(); 151 } 152 153 /** 154 * Emit an atomic read-and-write instruction. 155 * 156 * @param address address of the value to be read and written 157 * @param newValue the new value to be written 158 */ 159 default Value emitAtomicReadAndWrite(Value address, Value newValue) { 160 throw GraalError.unimplemented(); 161 } 162 163 void emitDeoptimize(Value actionAndReason, Value failedSpeculation, LIRFrameState state); 164 165 Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args); 166 167 RegisterAttributes attributes(Register register); 168 169 /** 170 * Create a new {@link Variable}. 171 * 172 * @param kind The type of the value that will be stored in this {@link Variable}. See 173 * {@link LIRKind} for documentation on what to pass here. Note that in most cases, 174 * simply passing {@link Value#getValueKind()} is wrong. 175 * @return A new {@link Variable}. 176 */ 177 Variable newVariable(ValueKind<?> kind); 178 179 Variable emitMove(Value input); 180 181 void emitMove(AllocatableValue dst, Value src); 182 183 void emitMoveConstant(AllocatableValue dst, Constant src); 184 185 Variable emitAddress(AllocatableValue stackslot); 186 187 void emitMembar(int barriers); 188 189 void emitUnwind(Value operand); 190 191 /** 192 * Called just before register allocation is performed on the LIR owned by this generator. 193 * Overriding implementations of this method must call the overridden method. 194 */ 195 void beforeRegisterAllocation(); 196 197 void emitIncomingValues(Value[] params); 198 199 /** 200 * Emits a return instruction. Implementations need to insert a move if the input is not in the 201 * correct location. 202 */ 203 void emitReturn(JavaKind javaKind, Value input); 204 205 AllocatableValue asAllocatable(Value value); 206 207 Variable load(Value value); 208 209 Value loadNonConst(Value value); 210 211 /** 212 * Determines if only oop maps are required for the code generated from the LIR. 213 */ 214 boolean needOnlyOopMaps(); 215 216 /** 217 * Gets the ABI specific operand used to return a value of a given kind from a method. 218 * 219 * @param javaKind the {@link JavaKind} of value being returned 220 * @param valueKind the backend type of the value being returned 221 * @return the operand representing the ABI defined location used return a value of kind 222 * {@code kind} 223 */ 224 AllocatableValue resultOperandFor(JavaKind javaKind, ValueKind<?> valueKind); 225 226 <I extends LIRInstruction> I append(I op); 227 228 void setSourcePosition(NodeSourcePosition position); 229 230 void emitJump(LabelRef label); 231 232 void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, 233 double trueDestinationProbability); 234 235 void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpKind, double overflowProbability); 236 237 void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability); 238 239 Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue); 240 241 Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue); 242 243 void emitStrategySwitch(JavaConstant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value); 244 245 void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget); 246 247 Variable emitByteSwap(Value operand); 248 249 Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length); 250 251 @SuppressWarnings("unused") 252 default Variable emitStringIndexOf(Value sourcePointer, Value sourceCount, Value targetPointer, Value targetCount, int constantTargetCount) { 253 throw GraalError.unimplemented(); 254 } 255 256 void emitBlackhole(Value operand); 257 258 LIRKind getLIRKind(Stamp stamp); 259 260 void emitPause(); 261 262 void emitPrefetchAllocate(Value address); 263} 264