001/* 002 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.lir.gen; 024 025import jdk.internal.jvmci.code.*; 026import jdk.internal.jvmci.common.*; 027import jdk.internal.jvmci.meta.*; 028 029import com.oracle.graal.compiler.common.calc.*; 030import com.oracle.graal.compiler.common.cfg.*; 031import com.oracle.graal.compiler.common.spi.*; 032import com.oracle.graal.lir.*; 033 034public interface LIRGeneratorTool extends ArithmeticLIRGenerator, BenchmarkCounterFactory { 035 036 /** 037 * Factory for creating spill moves. 038 * 039 * The instructions returned by the methods must only depend on the input values. References to 040 * values that require interaction with register allocation are strictly forbidden. 041 */ 042 public interface SpillMoveFactory { 043 044 LIRInstruction createMove(AllocatableValue result, Value input); 045 046 LIRInstruction createStackMove(AllocatableValue result, Value input); 047 } 048 049 public abstract class BlockScope implements AutoCloseable { 050 051 public abstract AbstractBlockBase<?> getCurrentBlock(); 052 053 public abstract void close(); 054 055 } 056 057 CodeGenProviders getProviders(); 058 059 TargetDescription target(); 060 061 MetaAccessProvider getMetaAccess(); 062 063 CodeCacheProvider getCodeCache(); 064 065 ForeignCallsProvider getForeignCalls(); 066 067 AbstractBlockBase<?> getCurrentBlock(); 068 069 LIRGenerationResult getResult(); 070 071 boolean hasBlockEnd(AbstractBlockBase<?> block); 072 073 SpillMoveFactory getSpillMoveFactory(); 074 075 BlockScope getBlockScope(AbstractBlockBase<?> block); 076 077 Value emitLoadConstant(LIRKind kind, Constant constant); 078 079 Variable emitLoad(LIRKind kind, Value address, LIRFrameState state); 080 081 void emitStore(LIRKind kind, Value address, Value input, LIRFrameState state); 082 083 void emitNullCheck(Value address, LIRFrameState state); 084 085 Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue); 086 087 /** 088 * Emit an atomic read-and-add instruction. 089 * 090 * @param address address of the value to be read and written 091 * @param delta the value to be added 092 */ 093 default Value emitAtomicReadAndAdd(Value address, Value delta) { 094 throw JVMCIError.unimplemented(); 095 } 096 097 /** 098 * Emit an atomic read-and-write instruction. 099 * 100 * @param address address of the value to be read and written 101 * @param newValue the new value to be written 102 */ 103 default Value emitAtomicReadAndWrite(Value address, Value newValue) { 104 throw JVMCIError.unimplemented(); 105 } 106 107 void emitDeoptimize(Value actionAndReason, Value failedSpeculation, LIRFrameState state); 108 109 Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args); 110 111 RegisterAttributes attributes(Register register); 112 113 /** 114 * Create a new {@link Variable}. 115 * 116 * @param kind The type of the value that will be stored in this {@link Variable}. See 117 * {@link LIRKind} for documentation on what to pass here. Note that in most cases, 118 * simply passing {@link Value#getLIRKind()} is wrong. 119 * @return A new {@link Variable}. 120 */ 121 Variable newVariable(LIRKind kind); 122 123 Variable emitMove(Value input); 124 125 void emitMove(AllocatableValue dst, Value src); 126 127 /** 128 * Emits an op that loads the address of some raw data. 129 * 130 * @param dst the variable into which the address is loaded 131 * @param data the data to be installed with the generated code 132 */ 133 void emitData(AllocatableValue dst, byte[] data); 134 135 Variable emitAddress(StackSlotValue slot); 136 137 void emitMembar(int barriers); 138 139 void emitUnwind(Value operand); 140 141 /** 142 * Called just before register allocation is performed on the LIR owned by this generator. 143 * Overriding implementations of this method must call the overridden method. 144 */ 145 void beforeRegisterAllocation(); 146 147 void emitIncomingValues(Value[] params); 148 149 /** 150 * Emits a return instruction. Implementations need to insert a move if the input is not in the 151 * correct location. 152 */ 153 void emitReturn(Value input); 154 155 AllocatableValue asAllocatable(Value value); 156 157 Variable load(Value value); 158 159 Value loadNonConst(Value value); 160 161 /** 162 * Determines if only oop maps are required for the code generated from the LIR. 163 */ 164 boolean needOnlyOopMaps(); 165 166 /** 167 * Gets the ABI specific operand used to return a value of a given kind from a method. 168 * 169 * @param kind the kind of value being returned 170 * @return the operand representing the ABI defined location used return a value of kind 171 * {@code kind} 172 */ 173 AllocatableValue resultOperandFor(LIRKind kind); 174 175 <I extends LIRInstruction> I append(I op); 176 177 void emitJump(LabelRef label); 178 179 void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, 180 double trueDestinationProbability); 181 182 void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpKind, double overflowProbability); 183 184 void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability); 185 186 Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue); 187 188 Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue); 189 190 void emitStrategySwitch(JavaConstant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value); 191 192 void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget); 193 194 CallingConvention getCallingConvention(); 195 196 Variable emitBitCount(Value operand); 197 198 Variable emitBitScanForward(Value operand); 199 200 Variable emitBitScanReverse(Value operand); 201 202 Variable emitByteSwap(Value operand); 203 204 Variable emitArrayEquals(Kind kind, Value array1, Value array2, Value length); 205 206 void emitBlackhole(Value operand); 207 208 @SuppressWarnings("unused") 209 default Value emitCountLeadingZeros(Value value) { 210 throw JVMCIError.unimplemented(); 211 } 212 213 @SuppressWarnings("unused") 214 default Value emitCountTrailingZeros(Value value) { 215 throw JVMCIError.unimplemented(); 216 } 217 218}