Mercurial > hg > truffle
comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java @ 5061:e808627bd16f
Renamed projects.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Thu, 08 Mar 2012 19:24:17 +0100 |
parents | graal/com.oracle.max.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java@4ed4295ce15f |
children | 1093243c09ad |
comparison
equal
deleted
inserted
replaced
5060:4ed4295ce15f | 5061:e808627bd16f |
---|---|
1 /* | |
2 * Copyright (c) 2011, 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.oracle.graal.nodes.calc; | |
24 | |
25 import com.oracle.max.cri.ci.*; | |
26 import com.oracle.max.cri.ri.*; | |
27 import com.oracle.graal.nodes.*; | |
28 import com.oracle.graal.nodes.spi.*; | |
29 import com.oracle.graal.nodes.type.*; | |
30 | |
31 /* TODO (thomaswue/gdub) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node) | |
32 * But in the back-end the comparison should not always be materialized (for example in x86 the comparison result will not be in a register but in a flag) | |
33 * | |
34 * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed | |
35 * into variants that do not materialize the value (CompareIf, CompareGuard...) | |
36 */ | |
37 public final class CompareNode extends BooleanNode implements Canonicalizable, LIRLowerable { | |
38 | |
39 @Input private ValueNode x; | |
40 @Input private ValueNode y; | |
41 | |
42 @Data private final Condition condition; | |
43 @Data private final boolean unorderedIsTrue; | |
44 | |
45 public ValueNode x() { | |
46 return x; | |
47 } | |
48 | |
49 public ValueNode y() { | |
50 return y; | |
51 } | |
52 | |
53 /** | |
54 * Constructs a new Compare instruction. | |
55 * | |
56 * @param x the instruction producing the first input to the instruction | |
57 * @param condition the condition (comparison operation) | |
58 * @param y the instruction that produces the second input to this instruction | |
59 * @param graph | |
60 */ | |
61 public CompareNode(ValueNode x, Condition condition, ValueNode y) { | |
62 this(x, condition, false, y); | |
63 } | |
64 | |
65 /** | |
66 * Constructs a new Compare instruction. | |
67 * | |
68 * @param x the instruction producing the first input to the instruction | |
69 * @param condition the condition (comparison operation) | |
70 * @param y the instruction that produces the second input to this instruction | |
71 * @param graph | |
72 */ | |
73 public CompareNode(ValueNode x, Condition condition, boolean unorderedIsTrue, ValueNode y) { | |
74 super(StampFactory.illegal()); | |
75 assert (x == null && y == null) || x.kind() == y.kind(); | |
76 this.condition = condition; | |
77 this.unorderedIsTrue = unorderedIsTrue; | |
78 this.x = x; | |
79 this.y = y; | |
80 } | |
81 | |
82 /** | |
83 * Gets the condition (comparison operation) for this instruction. | |
84 * | |
85 * @return the condition | |
86 */ | |
87 public Condition condition() { | |
88 return condition; | |
89 } | |
90 | |
91 /** | |
92 * Checks whether unordered inputs mean true or false. | |
93 * | |
94 * @return {@code true} if unordered inputs produce true | |
95 */ | |
96 public boolean unorderedIsTrue() { | |
97 return unorderedIsTrue; | |
98 } | |
99 | |
100 @Override | |
101 public BooleanNode negate() { | |
102 return graph().unique(new CompareNode(x(), condition.negate(), !unorderedIsTrue, y())); | |
103 } | |
104 | |
105 @Override | |
106 public void generate(LIRGeneratorTool gen) { | |
107 } | |
108 | |
109 @Override | |
110 public String toString(Verbosity verbosity) { | |
111 if (verbosity == Verbosity.Name) { | |
112 return super.toString(Verbosity.Name) + " " + condition.operator; | |
113 } else { | |
114 return super.toString(verbosity); | |
115 } | |
116 } | |
117 | |
118 private ValueNode optimizeMaterialize(CiConstant constant, MaterializeNode materializeNode, RiRuntime runtime) { | |
119 CiConstant trueConstant = materializeNode.trueValue().asConstant(); | |
120 CiConstant falseConstant = materializeNode.falseValue().asConstant(); | |
121 | |
122 if (falseConstant != null && trueConstant != null) { | |
123 Boolean trueResult = condition().foldCondition(trueConstant, constant, runtime, unorderedIsTrue()); | |
124 Boolean falseResult = condition().foldCondition(falseConstant, constant, runtime, unorderedIsTrue()); | |
125 | |
126 if (trueResult != null && falseResult != null) { | |
127 boolean trueUnboxedResult = trueResult; | |
128 boolean falseUnboxedResult = falseResult; | |
129 if (trueUnboxedResult == falseUnboxedResult) { | |
130 return ConstantNode.forBoolean(trueUnboxedResult, graph()); | |
131 } else { | |
132 if (trueUnboxedResult) { | |
133 assert falseUnboxedResult == false; | |
134 return materializeNode.condition(); | |
135 } else { | |
136 assert falseUnboxedResult == true; | |
137 return materializeNode.condition().negate(); | |
138 | |
139 } | |
140 } | |
141 } | |
142 } | |
143 return this; | |
144 } | |
145 | |
146 private ValueNode optimizeNormalizeCmp(CiConstant constant, NormalizeCompareNode normalizeNode) { | |
147 if (constant.kind == CiKind.Int && constant.asInt() == 0) { | |
148 Condition cond = condition(); | |
149 boolean isLess = cond == Condition.LE || cond == Condition.LT || cond == Condition.BE || cond == Condition.BT; | |
150 boolean canonUnorderedIsTrue = cond != Condition.EQ && (cond == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess)); | |
151 CompareNode result = graph().unique(new CompareNode(normalizeNode.x(), cond, canonUnorderedIsTrue, normalizeNode.y())); | |
152 return result; | |
153 } | |
154 return this; | |
155 } | |
156 | |
157 @Override | |
158 public ValueNode canonical(CanonicalizerTool tool) { | |
159 if (x().isConstant() && !y().isConstant()) { // move constants to the left (y) | |
160 return graph().unique(new CompareNode(y(), condition.mirror(), unorderedIsTrue(), x())); | |
161 } else if (x().isConstant() && y().isConstant()) { | |
162 CiConstant constX = x().asConstant(); | |
163 CiConstant constY = y().asConstant(); | |
164 Boolean result = condition().foldCondition(constX, constY, tool.runtime(), unorderedIsTrue()); | |
165 if (result != null) { | |
166 return ConstantNode.forBoolean(result, graph()); | |
167 } | |
168 } | |
169 | |
170 if (y().isConstant()) { | |
171 if (x() instanceof MaterializeNode) { | |
172 return optimizeMaterialize(y().asConstant(), (MaterializeNode) x(), tool.runtime()); | |
173 } else if (x() instanceof NormalizeCompareNode) { | |
174 return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x()); | |
175 } | |
176 } | |
177 | |
178 if (x() == y() && x().kind() != CiKind.Float && x().kind() != CiKind.Double) { | |
179 return ConstantNode.forBoolean(condition().check(1, 1), graph()); | |
180 } | |
181 if ((condition == Condition.NE || condition == Condition.EQ) && x().kind() == CiKind.Object) { | |
182 ValueNode object = null; | |
183 if (x().isNullConstant()) { | |
184 object = y(); | |
185 } else if (y().isNullConstant()) { | |
186 object = x(); | |
187 } | |
188 if (object != null) { | |
189 return graph().unique(new NullCheckNode(object, condition == Condition.EQ)); | |
190 } else { | |
191 Stamp xStamp = x.stamp(); | |
192 Stamp yStamp = y.stamp(); | |
193 if (xStamp.alwaysDistinct(yStamp)) { | |
194 return ConstantNode.forBoolean(condition == Condition.NE, graph()); | |
195 } | |
196 } | |
197 } | |
198 return this; | |
199 } | |
200 } |