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