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}