001/* 002 * Copyright (c) 2009, 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; 024 025import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; 026import static com.oracle.graal.lir.LIRInstruction.OperandMode.*; 027 028import java.lang.annotation.*; 029import java.util.*; 030 031import jdk.internal.jvmci.code.*; 032import com.oracle.graal.debug.*; 033import jdk.internal.jvmci.meta.*; 034 035import com.oracle.graal.lir.asm.*; 036 037/** 038 * The base class for an {@code LIRInstruction}. 039 */ 040public abstract class LIRInstruction { 041 /** 042 * Constants denoting how a LIR instruction uses an operand. 043 */ 044 public enum OperandMode { 045 /** 046 * The value must have been defined before. It is alive before the instruction until the 047 * beginning of the instruction, but not necessarily throughout the instruction. A register 048 * assigned to it can also be assigned to a {@link #TEMP} or {@link #DEF} operand. The value 049 * can be used again after the instruction, so the instruction must not modify the register. 050 */ 051 USE, 052 053 /** 054 * The value must have been defined before. It is alive before the instruction and 055 * throughout the instruction. A register assigned to it cannot be assigned to a 056 * {@link #TEMP} or {@link #DEF} operand. The value can be used again after the instruction, 057 * so the instruction must not modify the register. 058 */ 059 ALIVE, 060 061 /** 062 * The value must not have been defined before, and must not be used after the instruction. 063 * The instruction can do whatever it wants with the register assigned to it (or not use it 064 * at all). 065 */ 066 TEMP, 067 068 /** 069 * The value must not have been defined before. The instruction has to assign a value to the 070 * register. The value can (and most likely will) be used after the instruction. 071 */ 072 DEF, 073 } 074 075 @Retention(RetentionPolicy.RUNTIME) 076 @Target(ElementType.FIELD) 077 public static @interface Use { 078 079 OperandFlag[] value() default OperandFlag.REG; 080 } 081 082 @Retention(RetentionPolicy.RUNTIME) 083 @Target(ElementType.FIELD) 084 public static @interface Alive { 085 086 OperandFlag[] value() default OperandFlag.REG; 087 } 088 089 @Retention(RetentionPolicy.RUNTIME) 090 @Target(ElementType.FIELD) 091 public static @interface Temp { 092 093 OperandFlag[] value() default OperandFlag.REG; 094 } 095 096 @Retention(RetentionPolicy.RUNTIME) 097 @Target(ElementType.FIELD) 098 public static @interface Def { 099 100 OperandFlag[] value() default OperandFlag.REG; 101 } 102 103 @Retention(RetentionPolicy.RUNTIME) 104 @Target(ElementType.FIELD) 105 public static @interface State { 106 } 107 108 /** 109 * Flags for an operand. 110 */ 111 public enum OperandFlag { 112 /** 113 * The value can be a {@link RegisterValue}. 114 */ 115 REG, 116 117 /** 118 * The value can be a {@link StackSlot}. 119 */ 120 STACK, 121 122 /** 123 * The value can be a {@link CompositeValue}. 124 */ 125 COMPOSITE, 126 127 /** 128 * The value can be a {@link JavaConstant}. 129 */ 130 CONST, 131 132 /** 133 * The value can be {@link Value#ILLEGAL}. 134 */ 135 ILLEGAL, 136 137 /** 138 * The register allocator should try to assign a certain register to improve code quality. 139 * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints. 140 */ 141 HINT, 142 143 /** 144 * The value can be uninitialized, e.g., a stack slot that has not written to before. This 145 * is only used to avoid false positives in verification code. 146 */ 147 UNINITIALIZED, 148 } 149 150 /** 151 * For validity checking of the operand flags defined by instruction subclasses. 152 */ 153 protected static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS; 154 155 static { 156 ALLOWED_FLAGS = new EnumMap<>(OperandMode.class); 157 ALLOWED_FLAGS.put(OperandMode.USE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); 158 ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); 159 ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, COMPOSITE, CONST, ILLEGAL, HINT)); 160 ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, HINT)); 161 } 162 163 /** 164 * The flags of the base and index value of an address. 165 */ 166 protected static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(REG, ILLEGAL); 167 168 private final LIRInstructionClass<?> instructionClass; 169 170 /** 171 * Instruction id for register allocation. 172 */ 173 private int id; 174 175 private static final DebugMetric LIR_NODE_COUNT = Debug.metric("LIRNodes"); 176 177 /** 178 * Constructs a new LIR instruction. 179 */ 180 public LIRInstruction(LIRInstructionClass<? extends LIRInstruction> c) { 181 LIR_NODE_COUNT.increment(); 182 instructionClass = c; 183 assert c.getClazz() == this.getClass(); 184 id = -1; 185 } 186 187 public abstract void emitCode(CompilationResultBuilder crb); 188 189 public final int id() { 190 return id; 191 } 192 193 public final void setId(int id) { 194 this.id = id; 195 } 196 197 public final String name() { 198 return instructionClass.getOpcode(this); 199 } 200 201 public final boolean hasOperands() { 202 return instructionClass.hasOperands() || hasState() || destroysCallerSavedRegisters(); 203 } 204 205 public final boolean hasState() { 206 return instructionClass.hasState(this); 207 } 208 209 public boolean destroysCallerSavedRegisters() { 210 return false; 211 } 212 213 // InstructionValueProcedures 214 public final void forEachInput(InstructionValueProcedure proc) { 215 instructionClass.forEachUse(this, proc); 216 } 217 218 public final void forEachAlive(InstructionValueProcedure proc) { 219 instructionClass.forEachAlive(this, proc); 220 } 221 222 public final void forEachTemp(InstructionValueProcedure proc) { 223 instructionClass.forEachTemp(this, proc); 224 } 225 226 public final void forEachOutput(InstructionValueProcedure proc) { 227 instructionClass.forEachDef(this, proc); 228 } 229 230 public final void forEachState(InstructionValueProcedure proc) { 231 instructionClass.forEachState(this, proc); 232 } 233 234 // ValueProcedures 235 public final void forEachInput(ValueProcedure proc) { 236 instructionClass.forEachUse(this, proc); 237 } 238 239 public final void forEachAlive(ValueProcedure proc) { 240 instructionClass.forEachAlive(this, proc); 241 } 242 243 public final void forEachTemp(ValueProcedure proc) { 244 instructionClass.forEachTemp(this, proc); 245 } 246 247 public final void forEachOutput(ValueProcedure proc) { 248 instructionClass.forEachDef(this, proc); 249 } 250 251 public final void forEachState(ValueProcedure proc) { 252 instructionClass.forEachState(this, proc); 253 } 254 255 // States 256 public final void forEachState(InstructionStateProcedure proc) { 257 instructionClass.forEachState(this, proc); 258 } 259 260 public final void forEachState(StateProcedure proc) { 261 instructionClass.forEachState(this, proc); 262 } 263 264 // InstructionValueConsumers 265 public final void visitEachInput(InstructionValueConsumer proc) { 266 instructionClass.forEachUse(this, proc); 267 } 268 269 public final void visitEachAlive(InstructionValueConsumer proc) { 270 instructionClass.forEachAlive(this, proc); 271 } 272 273 public final void visitEachTemp(InstructionValueConsumer proc) { 274 instructionClass.forEachTemp(this, proc); 275 } 276 277 public final void visitEachOutput(InstructionValueConsumer proc) { 278 instructionClass.forEachDef(this, proc); 279 } 280 281 public final void visitEachState(InstructionValueConsumer proc) { 282 instructionClass.forEachState(this, proc); 283 } 284 285 // ValueConsumers 286 public final void visitEachInput(ValueConsumer proc) { 287 instructionClass.forEachUse(this, proc); 288 } 289 290 public final void visitEachAlive(ValueConsumer proc) { 291 instructionClass.forEachAlive(this, proc); 292 } 293 294 public final void visitEachTemp(ValueConsumer proc) { 295 instructionClass.forEachTemp(this, proc); 296 } 297 298 public final void visitEachOutput(ValueConsumer proc) { 299 instructionClass.forEachDef(this, proc); 300 } 301 302 public final void visitEachState(ValueConsumer proc) { 303 instructionClass.forEachState(this, proc); 304 } 305 306 @SuppressWarnings("unused") 307 public final Value forEachRegisterHint(Value value, OperandMode mode, InstructionValueProcedure proc) { 308 return instructionClass.forEachRegisterHint(this, mode, proc); 309 } 310 311 @SuppressWarnings("unused") 312 public final Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) { 313 return instructionClass.forEachRegisterHint(this, mode, proc); 314 } 315 316 public void verify() { 317 } 318 319 public final String toStringWithIdPrefix() { 320 if (id != -1) { 321 return String.format("%4d %s", id, toString()); 322 } 323 return " " + toString(); 324 } 325 326 @Override 327 public String toString() { 328 return instructionClass.toString(this); 329 } 330 331 public LIRInstructionClass<?> getLIRInstructionClass() { 332 return instructionClass; 333 } 334}