1 /*
   2  * Copyright (c) 2009, 2015, 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  */
  23 package org.graalvm.compiler.lir;
  24 
  25 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
  26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
  27 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
  28 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
  29 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.OUTGOING;
  30 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
  31 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
  32 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
  33 import static org.graalvm.compiler.lir.LIRInstruction.OperandMode.ALIVE;
  34 import static org.graalvm.compiler.lir.LIRInstruction.OperandMode.DEF;
  35 import static org.graalvm.compiler.lir.LIRInstruction.OperandMode.TEMP;
  36 import static org.graalvm.compiler.lir.LIRValueUtil.isVirtualStackSlot;
  37 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
  38 
  39 import java.lang.annotation.ElementType;
  40 import java.lang.annotation.Retention;
  41 import java.lang.annotation.RetentionPolicy;
  42 import java.lang.annotation.Target;
  43 import java.util.Arrays;
  44 import java.util.EnumMap;
  45 import java.util.EnumSet;
  46 
  47 import org.graalvm.compiler.debug.Debug;
  48 import org.graalvm.compiler.debug.DebugCounter;
  49 import org.graalvm.compiler.graph.NodeSourcePosition;
  50 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
  51 import org.graalvm.compiler.lir.StandardOp.MoveOp;
  52 import org.graalvm.compiler.lir.StandardOp.ValueMoveOp;
  53 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
  54 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  55 
  56 import jdk.vm.ci.code.RegisterValue;
  57 import jdk.vm.ci.code.StackSlot;
  58 import jdk.vm.ci.meta.JavaConstant;
  59 import jdk.vm.ci.meta.Value;
  60 
  61 /**
  62  * The base class for an {@code LIRInstruction}.
  63  */
  64 public abstract class LIRInstruction {
  65     /**
  66      * Constants denoting how a LIR instruction uses an operand.
  67      */
  68     public enum OperandMode {
  69         /**
  70          * The value must have been defined before. It is alive before the instruction until the
  71          * beginning of the instruction, but not necessarily throughout the instruction. A register
  72          * assigned to it can also be assigned to a {@link #TEMP} or {@link #DEF} operand. The value
  73          * can be used again after the instruction, so the instruction must not modify the register.
  74          */
  75         USE,
  76 
  77         /**
  78          * The value must have been defined before. It is alive before the instruction and
  79          * throughout the instruction. A register assigned to it cannot be assigned to a
  80          * {@link #TEMP} or {@link #DEF} operand. The value can be used again after the instruction,
  81          * so the instruction must not modify the register.
  82          */
  83         ALIVE,
  84 
  85         /**
  86          * The value must not have been defined before, and must not be used after the instruction.
  87          * The instruction can do whatever it wants with the register assigned to it (or not use it
  88          * at all).
  89          */
  90         TEMP,
  91 
  92         /**
  93          * The value must not have been defined before. The instruction has to assign a value to the
  94          * register. The value can (and most likely will) be used after the instruction.
  95          */
  96         DEF,
  97     }
  98 
  99     @Retention(RetentionPolicy.RUNTIME)
 100     @Target(ElementType.FIELD)
 101     public static @interface Use {
 102 
 103         OperandFlag[] value() default OperandFlag.REG;
 104     }
 105 
 106     @Retention(RetentionPolicy.RUNTIME)
 107     @Target(ElementType.FIELD)
 108     public static @interface Alive {
 109 
 110         OperandFlag[] value() default OperandFlag.REG;
 111     }
 112 
 113     @Retention(RetentionPolicy.RUNTIME)
 114     @Target(ElementType.FIELD)
 115     public static @interface Temp {
 116 
 117         OperandFlag[] value() default OperandFlag.REG;
 118     }
 119 
 120     @Retention(RetentionPolicy.RUNTIME)
 121     @Target(ElementType.FIELD)
 122     public static @interface Def {
 123 
 124         OperandFlag[] value() default OperandFlag.REG;
 125     }
 126 
 127     @Retention(RetentionPolicy.RUNTIME)
 128     @Target(ElementType.FIELD)
 129     public static @interface State {
 130     }
 131 
 132     /**
 133      * Flags for an operand.
 134      */
 135     public enum OperandFlag {
 136         /**
 137          * The value can be a {@link RegisterValue}.
 138          */
 139         REG,
 140 
 141         /**
 142          * The value can be a {@link StackSlot}.
 143          */
 144         STACK,
 145 
 146         /**
 147          * The value can be a {@link CompositeValue}.
 148          */
 149         COMPOSITE,
 150 
 151         /**
 152          * The value can be a {@link JavaConstant}.
 153          */
 154         CONST,
 155 
 156         /**
 157          * The value can be {@link Value#ILLEGAL}.
 158          */
 159         ILLEGAL,
 160 
 161         /**
 162          * The register allocator should try to assign a certain register to improve code quality.
 163          * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints.
 164          */
 165         HINT,
 166 
 167         /**
 168          * The value can be uninitialized, e.g., a stack slot that has not written to before. This
 169          * is only used to avoid false positives in verification code.
 170          */
 171         UNINITIALIZED,
 172 
 173         /** Outgoing block value. */
 174         OUTGOING,
 175     }
 176 
 177     /**
 178      * For validity checking of the operand flags defined by instruction subclasses.
 179      */
 180     protected static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS;
 181 
 182     static {
 183         ALLOWED_FLAGS = new EnumMap<>(OperandMode.class);
 184         ALLOWED_FLAGS.put(OperandMode.USE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED));
 185         ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED, OUTGOING));
 186         ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, HINT));
 187         ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, HINT));
 188     }
 189 
 190     /**
 191      * The flags of the base and index value of an address.
 192      */
 193     protected static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(REG, ILLEGAL);
 194 
 195     private final LIRInstructionClass<?> instructionClass;
 196 
 197     /**
 198      * Instruction id for register allocation.
 199      */
 200     private int id;
 201 
 202     /**
 203      * The source position of the code that generated this instruction.
 204      */
 205     private NodeSourcePosition position;
 206 
 207     private static final DebugCounter LIR_NODE_COUNT = Debug.counter("LIRNodes");
 208 
 209     /**
 210      * Constructs a new LIR instruction.
 211      */
 212     public LIRInstruction(LIRInstructionClass<? extends LIRInstruction> c) {
 213         LIR_NODE_COUNT.increment();
 214         instructionClass = c;
 215         assert c.getClazz() == this.getClass();
 216         id = -1;
 217     }
 218 
 219     public abstract void emitCode(CompilationResultBuilder crb);
 220 
 221     public final int id() {
 222         return id;
 223     }
 224 
 225     public final void setId(int id) {
 226         this.id = id;
 227     }
 228 
 229     public final NodeSourcePosition getPosition() {
 230         return position;
 231     }
 232 
 233     public final void setPosition(NodeSourcePosition position) {
 234         this.position = position;
 235     }
 236 
 237     public final String name() {
 238         return instructionClass.getOpcode(this);
 239     }
 240 
 241     public final boolean hasOperands() {
 242         return instructionClass.hasOperands() || hasState() || destroysCallerSavedRegisters();
 243     }
 244 
 245     public final boolean hasState() {
 246         return instructionClass.hasState(this);
 247     }
 248 
 249     public boolean destroysCallerSavedRegisters() {
 250         return false;
 251     }
 252 
 253     // InstructionValueProcedures
 254     public final void forEachInput(InstructionValueProcedure proc) {
 255         instructionClass.forEachUse(this, proc);
 256     }
 257 
 258     public final void forEachAlive(InstructionValueProcedure proc) {
 259         instructionClass.forEachAlive(this, proc);
 260     }
 261 
 262     public final void forEachTemp(InstructionValueProcedure proc) {
 263         instructionClass.forEachTemp(this, proc);
 264     }
 265 
 266     public final void forEachOutput(InstructionValueProcedure proc) {
 267         instructionClass.forEachDef(this, proc);
 268     }
 269 
 270     public final void forEachState(InstructionValueProcedure proc) {
 271         instructionClass.forEachState(this, proc);
 272     }
 273 
 274     // ValueProcedures
 275     public final void forEachInput(ValueProcedure proc) {
 276         instructionClass.forEachUse(this, proc);
 277     }
 278 
 279     public final void forEachAlive(ValueProcedure proc) {
 280         instructionClass.forEachAlive(this, proc);
 281     }
 282 
 283     public final void forEachTemp(ValueProcedure proc) {
 284         instructionClass.forEachTemp(this, proc);
 285     }
 286 
 287     public final void forEachOutput(ValueProcedure proc) {
 288         instructionClass.forEachDef(this, proc);
 289     }
 290 
 291     public final void forEachState(ValueProcedure proc) {
 292         instructionClass.forEachState(this, proc);
 293     }
 294 
 295     // States
 296     public final void forEachState(InstructionStateProcedure proc) {
 297         instructionClass.forEachState(this, proc);
 298     }
 299 
 300     public final void forEachState(StateProcedure proc) {
 301         instructionClass.forEachState(this, proc);
 302     }
 303 
 304     // InstructionValueConsumers
 305     public final void visitEachInput(InstructionValueConsumer proc) {
 306         instructionClass.visitEachUse(this, proc);
 307     }
 308 
 309     public final void visitEachAlive(InstructionValueConsumer proc) {
 310         instructionClass.visitEachAlive(this, proc);
 311     }
 312 
 313     public final void visitEachTemp(InstructionValueConsumer proc) {
 314         instructionClass.visitEachTemp(this, proc);
 315     }
 316 
 317     public final void visitEachOutput(InstructionValueConsumer proc) {
 318         instructionClass.visitEachDef(this, proc);
 319     }
 320 
 321     public final void visitEachState(InstructionValueConsumer proc) {
 322         instructionClass.visitEachState(this, proc);
 323     }
 324 
 325     // ValueConsumers
 326     public final void visitEachInput(ValueConsumer proc) {
 327         instructionClass.visitEachUse(this, proc);
 328     }
 329 
 330     public final void visitEachAlive(ValueConsumer proc) {
 331         instructionClass.visitEachAlive(this, proc);
 332     }
 333 
 334     public final void visitEachTemp(ValueConsumer proc) {
 335         instructionClass.visitEachTemp(this, proc);
 336     }
 337 
 338     public final void visitEachOutput(ValueConsumer proc) {
 339         instructionClass.visitEachDef(this, proc);
 340     }
 341 
 342     public final void visitEachState(ValueConsumer proc) {
 343         instructionClass.visitEachState(this, proc);
 344     }
 345 
 346     @SuppressWarnings("unused")
 347     public final Value forEachRegisterHint(Value value, OperandMode mode, InstructionValueProcedure proc) {
 348         return instructionClass.forEachRegisterHint(this, mode, proc);
 349     }
 350 
 351     @SuppressWarnings("unused")
 352     public final Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) {
 353         return instructionClass.forEachRegisterHint(this, mode, proc);
 354     }
 355 
 356     // Checkstyle: stop
 357     /**
 358      * Returns {@code true} if the instruction is a {@link MoveOp}.
 359      *
 360      * This function is preferred to {@code instanceof MoveOp} since the type check is more
 361      * expensive than reading a field from {@link LIRInstructionClass}.
 362      */
 363     public final boolean isMoveOp() {
 364         return instructionClass.isMoveOp();
 365     }
 366 
 367     /**
 368      * Returns {@code true} if the instruction is a {@link ValueMoveOp}.
 369      *
 370      * This function is preferred to {@code instanceof ValueMoveOp} since the type check is more
 371      * expensive than reading a field from {@link LIRInstructionClass}.
 372      */
 373     public final boolean isValueMoveOp() {
 374         return instructionClass.isValueMoveOp();
 375     }
 376 
 377     /**
 378      * Returns {@code true} if the instruction is a {@link LoadConstantOp}.
 379      *
 380      * This function is preferred to {@code instanceof LoadConstantOp} since the type check is more
 381      * expensive than reading a field from {@link LIRInstructionClass}.
 382      */
 383     public final boolean isLoadConstantOp() {
 384         return instructionClass.isLoadConstantOp();
 385     }
 386     // Checkstyle: resume
 387 
 388     /**
 389      * Utility method to add stack arguments to a list of temporaries. Useful for modeling calling
 390      * conventions that kill outgoing argument space.
 391      *
 392      * @return additional temporaries
 393      */
 394     protected static Value[] addStackSlotsToTemporaries(Value[] parameters, Value[] temporaries) {
 395         int extraTemps = 0;
 396         for (Value p : parameters) {
 397             if (isStackSlot(p)) {
 398                 extraTemps++;
 399             }
 400             assert !isVirtualStackSlot(p) : "only real stack slots in calling convention";
 401         }
 402         if (extraTemps != 0) {
 403             int index = temporaries.length;
 404             Value[] newTemporaries = Arrays.copyOf(temporaries, temporaries.length + extraTemps);
 405             for (Value p : parameters) {
 406                 if (isStackSlot(p)) {
 407                     newTemporaries[index++] = p;
 408                 }
 409             }
 410             return newTemporaries;
 411         }
 412         return temporaries;
 413     }
 414 
 415     public void verify() {
 416     }
 417 
 418     /**
 419      * Adds a comment to this instruction.
 420      */
 421     public final void setComment(LIRGenerationResult res, String comment) {
 422         res.setComment(this, comment);
 423     }
 424 
 425     /**
 426      * Gets the comment attached to this instruction.
 427      */
 428     public final String getComment(LIRGenerationResult res) {
 429         return res.getComment(this);
 430     }
 431 
 432     public final String toStringWithIdPrefix() {
 433         if (id != -1) {
 434             return String.format("%4d %s", id, toString());
 435         }
 436         return "     " + toString();
 437     }
 438 
 439     @Override
 440     public String toString() {
 441         return instructionClass.toString(this);
 442     }
 443 
 444     public String toString(LIRGenerationResult res) {
 445         String toString = toString();
 446         if (res == null) {
 447             return toString;
 448         }
 449         String comment = getComment(res);
 450         if (comment == null) {
 451             return toString;
 452         }
 453         return String.format("%s // %s", toString, comment);
 454     }
 455 
 456     public LIRInstructionClass<?> getLIRInstructionClass() {
 457         return instructionClass;
 458     }
 459 
 460     @Override
 461     public int hashCode() {
 462         return id;
 463     }
 464 }