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
24
25 package org.graalvm.compiler.word;
26
27 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
28 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
29
30 import org.graalvm.compiler.core.common.LIRKind;
31 import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
32 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
33 import org.graalvm.compiler.core.common.type.IntegerStamp;
34 import org.graalvm.compiler.core.common.type.ObjectStamp;
35 import org.graalvm.compiler.core.common.type.Stamp;
36 import org.graalvm.compiler.core.common.type.StampFactory;
37 import org.graalvm.compiler.graph.Node;
38 import org.graalvm.compiler.graph.NodeClass;
39 import org.graalvm.compiler.graph.spi.Canonicalizable;
40 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
41 import org.graalvm.compiler.lir.ConstantValue;
42 import org.graalvm.compiler.nodeinfo.NodeInfo;
43 import org.graalvm.compiler.nodes.ConstantNode;
44 import org.graalvm.compiler.nodes.FixedWithNextNode;
45 import org.graalvm.compiler.nodes.NodeView;
46 import org.graalvm.compiler.nodes.ValueNode;
47 import org.graalvm.compiler.nodes.spi.LIRLowerable;
48 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
49 import org.graalvm.compiler.nodes.type.NarrowOopStamp;
50
51 import jdk.vm.ci.meta.AllocatableValue;
123
124 private static Stamp objectStampFor(ValueNode input) {
125 Stamp inputStamp = input.stamp(NodeView.DEFAULT);
126 if (inputStamp instanceof AbstractPointerStamp) {
127 AbstractPointerStamp pointerStamp = (AbstractPointerStamp) inputStamp;
128 if (pointerStamp.alwaysNull()) {
129 return StampFactory.alwaysNull();
130 } else if (pointerStamp.nonNull()) {
131 return StampFactory.objectNonNull();
132 }
133 } else if (inputStamp instanceof IntegerStamp && !((IntegerStamp) inputStamp).contains(0)) {
134 return StampFactory.objectNonNull();
135 } else if (input.isConstant() && isZeroConstant(input)) {
136 return StampFactory.alwaysNull();
137 }
138 return StampFactory.object();
139 }
140
141 @Override
142 public boolean inferStamp() {
143 if (stamp.equals(StampFactory.object())) {
144 return updateStamp(objectStampFor(input));
145 }
146 return false;
147 }
148
149 @Override
150 public Node canonical(CanonicalizerTool tool) {
151 if (tool.allUsagesAvailable() && hasNoUsages()) {
152 /* If the cast is unused, it can be eliminated. */
153 return input;
154 }
155
156 assert !stamp(NodeView.DEFAULT).isCompatible(input.stamp(NodeView.DEFAULT));
157 if (input.isConstant()) {
158 /* Null pointers are uncritical for GC, so they can be constant folded. */
159 if (input.asJavaConstant().isNull()) {
160 return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
161 } else if (isZeroConstant(input)) {
162 return ConstantNode.forConstant(stamp(NodeView.DEFAULT), JavaConstant.NULL_POINTER, tool.getMetaAccess());
163 }
164 }
165
166 return this;
167 }
168
169 @Override
170 public void generate(NodeLIRBuilderTool generator) {
171 Value value = generator.operand(input);
172 ValueKind<?> kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
173 assert kind.getPlatformKind().getSizeInBytes() == value.getPlatformKind().getSizeInBytes();
174
175 if (trackedPointer && LIRKind.isValue(kind) && !LIRKind.isValue(value)) {
176 // just change the PlatformKind, but don't drop reference information
177 kind = value.getValueKind().changeType(kind.getPlatformKind());
178 }
179
180 if (kind.equals(value.getValueKind()) && !(value instanceof ConstantValue)) {
181 generator.setResult(this, value);
182 } else {
183 AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind);
184 if (stamp.equals(StampFactory.object())) {
185 generator.getLIRGeneratorTool().emitConvertZeroToNull(result, value);
186 } else if (!trackedPointer && !((AbstractObjectStamp) input.stamp(NodeView.DEFAULT)).nonNull()) {
187 generator.getLIRGeneratorTool().emitConvertNullToZero(result, value);
188 } else {
189 generator.getLIRGeneratorTool().emitMove(result, value);
190 }
191 generator.setResult(this, result);
192 }
193 }
194 }
|
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
24
25 package org.graalvm.compiler.word;
26
27 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
28 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
29
30 import org.graalvm.compiler.core.common.LIRKind;
31 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
32 import org.graalvm.compiler.core.common.type.IntegerStamp;
33 import org.graalvm.compiler.core.common.type.ObjectStamp;
34 import org.graalvm.compiler.core.common.type.Stamp;
35 import org.graalvm.compiler.core.common.type.StampFactory;
36 import org.graalvm.compiler.graph.Node;
37 import org.graalvm.compiler.graph.NodeClass;
38 import org.graalvm.compiler.graph.spi.Canonicalizable;
39 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
40 import org.graalvm.compiler.lir.ConstantValue;
41 import org.graalvm.compiler.nodeinfo.NodeInfo;
42 import org.graalvm.compiler.nodes.ConstantNode;
43 import org.graalvm.compiler.nodes.FixedWithNextNode;
44 import org.graalvm.compiler.nodes.NodeView;
45 import org.graalvm.compiler.nodes.ValueNode;
46 import org.graalvm.compiler.nodes.spi.LIRLowerable;
47 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
48 import org.graalvm.compiler.nodes.type.NarrowOopStamp;
49
50 import jdk.vm.ci.meta.AllocatableValue;
122
123 private static Stamp objectStampFor(ValueNode input) {
124 Stamp inputStamp = input.stamp(NodeView.DEFAULT);
125 if (inputStamp instanceof AbstractPointerStamp) {
126 AbstractPointerStamp pointerStamp = (AbstractPointerStamp) inputStamp;
127 if (pointerStamp.alwaysNull()) {
128 return StampFactory.alwaysNull();
129 } else if (pointerStamp.nonNull()) {
130 return StampFactory.objectNonNull();
131 }
132 } else if (inputStamp instanceof IntegerStamp && !((IntegerStamp) inputStamp).contains(0)) {
133 return StampFactory.objectNonNull();
134 } else if (input.isConstant() && isZeroConstant(input)) {
135 return StampFactory.alwaysNull();
136 }
137 return StampFactory.object();
138 }
139
140 @Override
141 public boolean inferStamp() {
142 if (stamp instanceof AbstractPointerStamp) {
143 AbstractPointerStamp objectStamp = (AbstractPointerStamp) stamp;
144 if (!objectStamp.alwaysNull() && !objectStamp.nonNull()) {
145 Stamp newStamp = stamp;
146 Stamp inputStamp = input.stamp(NodeView.DEFAULT);
147 if (inputStamp instanceof AbstractPointerStamp) {
148 AbstractPointerStamp pointerStamp = (AbstractPointerStamp) inputStamp;
149 if (pointerStamp.alwaysNull()) {
150 newStamp = objectStamp.asAlwaysNull();
151 } else if (pointerStamp.nonNull()) {
152 newStamp = objectStamp.asNonNull();
153 }
154 } else if (inputStamp instanceof IntegerStamp && !((IntegerStamp) inputStamp).contains(0)) {
155 newStamp = objectStamp.asNonNull();
156 } else if (input.isConstant() && isZeroConstant(input)) {
157 newStamp = objectStamp.asAlwaysNull();
158 }
159 return updateStamp(newStamp);
160 }
161 }
162 return false;
163 }
164
165 @Override
166 public Node canonical(CanonicalizerTool tool) {
167 if (tool.allUsagesAvailable() && hasNoUsages()) {
168 /* If the cast is unused, it can be eliminated. */
169 return input;
170 }
171
172 assert !stamp.isCompatible(input.stamp(NodeView.DEFAULT));
173 if (input.isConstant()) {
174 /* Null pointers are uncritical for GC, so they can be constant folded. */
175 if (input.asJavaConstant().isNull()) {
176 return ConstantNode.forIntegerStamp(stamp, 0);
177 } else if (isZeroConstant(input)) {
178 return ConstantNode.forConstant(stamp, ((AbstractPointerStamp) stamp).nullConstant(), tool.getMetaAccess());
179 }
180 }
181
182 return this;
183 }
184
185 @Override
186 public void generate(NodeLIRBuilderTool generator) {
187 Value value = generator.operand(input);
188 ValueKind<?> kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
189 assert kind.getPlatformKind().getSizeInBytes() == value.getPlatformKind().getSizeInBytes();
190
191 if (trackedPointer && LIRKind.isValue(kind) && !LIRKind.isValue(value)) {
192 // just change the PlatformKind, but don't drop reference information
193 kind = value.getValueKind().changeType(kind.getPlatformKind());
194 }
195
196 if (kind.equals(value.getValueKind()) && !(value instanceof ConstantValue)) {
197 generator.setResult(this, value);
198 } else {
199 AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind);
200 if (stamp.equals(StampFactory.object())) {
201 generator.getLIRGeneratorTool().emitConvertZeroToNull(result, value);
202 } else if (!trackedPointer && !((AbstractPointerStamp) input.stamp(NodeView.DEFAULT)).nonNull()) {
203 generator.getLIRGeneratorTool().emitConvertNullToZero(result, value);
204 } else {
205 generator.getLIRGeneratorTool().emitMove(result, value);
206 }
207 generator.setResult(this, result);
208 }
209 }
210 }
|