comparison graal/GraalCompiler/src/com/sun/c1x/gen/LIRItem.java @ 2509:16b9a8b5ad39

Renamings Runtime=>GraalRuntime and Compiler=>GraalCompiler
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 11:50:44 +0200
parents graal/Compiler/src/com/sun/c1x/gen/LIRItem.java@9ec15d6914ca
children 4a016ff4d2df
comparison
equal deleted inserted replaced
2508:fea94949e0a2 2509:16b9a8b5ad39
1 /*
2 * Copyright (c) 2009, 2011, 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 com.sun.c1x.gen;
24
25 import com.sun.c1x.alloc.OperandPool.*;
26 import com.sun.c1x.ir.*;
27 import com.sun.c1x.util.*;
28 import com.sun.cri.ci.*;
29
30 /**
31 * A helper utility for loading the {@linkplain Value#operand() result}
32 * of an instruction for use by another instruction. This helper takes
33 * into account the specifics of the consuming instruction such as whether
34 * it requires the input operand to be in memory or a register, any
35 * register size requirements of the input operand, and whether the
36 * usage has the side-effect of overwriting the input operand. To satisfy
37 * these constraints, an intermediate operand may be created and move
38 * instruction inserted to copy the output of the producer instruction
39 * into the intermediate operand.
40 *
41 * @author Marcelo Cintra
42 * @author Thomas Wuerthinger
43 * @author Doug Simon
44 */
45 public class LIRItem {
46
47 /**
48 * The instruction whose usage by another instruction is being modeled by this object.
49 * An instruction {@code x} uses instruction {@code y} if the {@linkplain Value#operand() result}
50 * of {@code y} is an input operand of {@code x}.
51 */
52 public Value instruction;
53
54 /**
55 * The LIR context of this helper object.
56 */
57 private final LIRGenerator gen;
58
59 /**
60 * The operand holding the result of this item's {@linkplain #instruction}.
61 */
62 private CiValue resultOperand;
63
64 /**
65 * Denotes if the use of the instruction's {@linkplain #resultOperand result operand}
66 * overwrites the value in the operand. That is, the use both uses and defines the
67 * operand. In this case, an {@linkplain #intermediateOperand intermediate operand}
68 * is created for the use so that other consumers of this item's {@linkplain #instruction}
69 * are not impacted.
70 */
71 private boolean destructive;
72
73 /**
74 * @see #destructive
75 */
76 private CiValue intermediateOperand;
77
78 public LIRItem(Value value, LIRGenerator gen) {
79 this.gen = gen;
80 setInstruction(value);
81 }
82
83 public void setInstruction(Value instruction) {
84 this.instruction = instruction;
85 if (instruction != null) {
86 resultOperand = gen.makeOperand(instruction);
87 } else {
88 resultOperand = CiValue.IllegalValue;
89 }
90 intermediateOperand = CiValue.IllegalValue;
91 }
92
93 public LIRItem(LIRGenerator gen) {
94 this.gen = gen;
95 setInstruction(null);
96 }
97
98 public void loadItem(CiKind kind) {
99 if (kind == CiKind.Byte || kind == CiKind.Boolean) {
100 loadByteItem();
101 } else {
102 loadItem();
103 }
104 }
105
106 public void loadForStore(CiKind kind) {
107 if (gen.canStoreAsConstant(instruction, kind)) {
108 resultOperand = instruction.operand();
109 if (!resultOperand.isConstant()) {
110 resultOperand = instruction.asConstant();
111 }
112 } else if (kind == CiKind.Byte || kind == CiKind.Boolean) {
113 loadByteItem();
114 } else {
115 loadItem();
116 }
117 }
118
119 public CiValue result() {
120 assert !destructive || !resultOperand.isRegister() : "shouldn't use setDestroysRegister with physical registers";
121 if (destructive && (resultOperand.isVariable() || resultOperand.isConstant())) {
122 if (intermediateOperand.isIllegal()) {
123 intermediateOperand = gen.newVariable(instruction.kind);
124 gen.lir.move(resultOperand, intermediateOperand);
125 }
126 return intermediateOperand;
127 } else {
128 return resultOperand;
129 }
130 }
131
132 public void setDestroysRegister() {
133 destructive = true;
134 }
135
136 /**
137 * Determines if the operand is in a stack slot.
138 */
139 public boolean isStack() {
140 return resultOperand.isAddress() || resultOperand.isStackSlot();
141 }
142
143 /**
144 * Determines if the operand is in a register or may be
145 * resolved to a register by the register allocator.
146 */
147 public boolean isRegisterOrVariable() {
148 return resultOperand.isVariableOrRegister();
149 }
150
151 public void loadByteItem() {
152 if (gen.compilation.target.arch.isX86()) {
153 loadItem();
154 CiValue res = result();
155
156 if (!res.isVariable() || !gen.operands.mustBeByteRegister(res)) {
157 // make sure that it is a byte register
158 assert !instruction.kind.isFloat() && !instruction.kind.isDouble() : "can't load floats in byte register";
159 CiValue reg = gen.operands.newVariable(CiKind.Byte, VariableFlag.MustBeByteRegister);
160 gen.lir.move(res, reg);
161 resultOperand = reg;
162 }
163 } else if (gen.compilation.target.arch.isSPARC()) {
164 loadItem();
165 } else {
166 Util.shouldNotReachHere();
167 }
168 }
169
170 public void loadNonconstant() {
171 if (gen.compilation.target.arch.isX86()) {
172 CiValue r = instruction.operand();
173 if (r.isConstant()) {
174 resultOperand = r;
175 } else {
176 loadItem();
177 }
178 } else if (gen.compilation.target.arch.isSPARC()) {
179 CiValue r = instruction.operand();
180 if (gen.canInlineAsConstant(instruction)) {
181 if (!r.isConstant()) {
182 r = instruction.asConstant();
183 }
184 resultOperand = r;
185 } else {
186 loadItem();
187 }
188 } else {
189 Util.shouldNotReachHere();
190 }
191 }
192
193 private void setResult(CiVariable operand) {
194 gen.setResult(instruction, operand);
195 resultOperand = operand;
196 }
197
198 /**
199 * Creates an operand containing the result of {@linkplain #instruction input instruction}.
200 */
201 public void loadItem() {
202 if (result().isIllegal()) {
203 // update the item's result
204 resultOperand = instruction.operand();
205 }
206 CiValue result = result();
207 if (!result.isVariableOrRegister()) {
208 CiVariable operand;
209 operand = gen.newVariable(instruction.kind);
210 gen.lir.move(result, operand);
211 if (result.isConstant()) {
212 resultOperand = operand;
213 } else {
214 setResult(operand);
215 }
216 }
217 }
218
219 @Override
220 public String toString() {
221 return result().toString();
222 }
223 }