Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: src/compiler/machine-operator-reducer.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/machine-operator-reducer.h"
6
7 #include "src/compiler/common-node-cache.h"
8 #include "src/compiler/generic-node-inl.h"
9 #include "src/compiler/graph.h"
10 #include "src/compiler/node-matchers.h"
11
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15
16 MachineOperatorReducer::MachineOperatorReducer(Graph* graph)
17 : graph_(graph),
18 cache_(new(graph->zone()) CommonNodeCache(graph->zone())),
19 common_(graph->zone()),
20 machine_(graph->zone()) {
21 }
22
23
24 MachineOperatorReducer::MachineOperatorReducer(Graph* graph,
25 CommonNodeCache* cache)
26 : graph_(graph),
27 cache_(cache),
28 common_(graph->zone()),
29 machine_(graph->zone()) {}
30
31
32 Node* MachineOperatorReducer::Int32Constant(int32_t value) {
33 Node** loc = cache_->FindInt32Constant(value);
34 if (*loc == NULL) {
35 *loc = graph_->NewNode(common_.Int32Constant(value));
36 }
37 return *loc;
38 }
39
40
41 Node* MachineOperatorReducer::Float64Constant(volatile double value) {
42 Node** loc = cache_->FindFloat64Constant(value);
43 if (*loc == NULL) {
44 *loc = graph_->NewNode(common_.Float64Constant(value));
45 }
46 return *loc;
47 }
48
49
50 // Perform constant folding and strength reduction on machine operators.
51 Reduction MachineOperatorReducer::Reduce(Node* node) {
52 switch (node->opcode()) {
53 case IrOpcode::kWord32And: {
54 Int32BinopMatcher m(node);
55 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0
56 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x
57 if (m.IsFoldable()) { // K & K => K
58 return ReplaceInt32(m.left().Value() & m.right().Value());
59 }
60 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x
61 break;
62 }
63 case IrOpcode::kWord32Or: {
64 Int32BinopMatcher m(node);
65 if (m.right().Is(0)) return Replace(m.left().node()); // x | 0 => x
66 if (m.right().Is(-1)) return Replace(m.right().node()); // x | -1 => -1
67 if (m.IsFoldable()) { // K | K => K
68 return ReplaceInt32(m.left().Value() | m.right().Value());
69 }
70 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x
71 break;
72 }
73 case IrOpcode::kWord32Xor: {
74 Int32BinopMatcher m(node);
75 if (m.right().Is(0)) return Replace(m.left().node()); // x ^ 0 => x
76 if (m.IsFoldable()) { // K ^ K => K
77 return ReplaceInt32(m.left().Value() ^ m.right().Value());
78 }
79 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x ^ x => 0
80 break;
81 }
82 case IrOpcode::kWord32Shl: {
83 Int32BinopMatcher m(node);
84 if (m.right().Is(0)) return Replace(m.left().node()); // x << 0 => x
85 if (m.IsFoldable()) { // K << K => K
86 return ReplaceInt32(m.left().Value() << m.right().Value());
87 }
88 break;
89 }
90 case IrOpcode::kWord32Shr: {
91 Uint32BinopMatcher m(node);
92 if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x
93 if (m.IsFoldable()) { // K >>> K => K
94 return ReplaceInt32(m.left().Value() >> m.right().Value());
95 }
96 break;
97 }
98 case IrOpcode::kWord32Sar: {
99 Int32BinopMatcher m(node);
100 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x
101 if (m.IsFoldable()) { // K >> K => K
102 return ReplaceInt32(m.left().Value() >> m.right().Value());
103 }
104 break;
105 }
106 case IrOpcode::kWord32Equal: {
107 Int32BinopMatcher m(node);
108 if (m.IsFoldable()) { // K == K => K
109 return ReplaceBool(m.left().Value() == m.right().Value());
110 }
111 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y == 0 => x == y
112 Int32BinopMatcher msub(m.left().node());
113 node->ReplaceInput(0, msub.left().node());
114 node->ReplaceInput(1, msub.right().node());
115 return Changed(node);
116 }
117 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
118 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true
119 break;
120 }
121 case IrOpcode::kInt32Add: {
122 Int32BinopMatcher m(node);
123 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x
124 if (m.IsFoldable()) { // K + K => K
125 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) +
126 static_cast<uint32_t>(m.right().Value()));
127 }
128 break;
129 }
130 case IrOpcode::kInt32Sub: {
131 Int32BinopMatcher m(node);
132 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x
133 if (m.IsFoldable()) { // K - K => K
134 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
135 static_cast<uint32_t>(m.right().Value()));
136 }
137 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0
138 break;
139 }
140 case IrOpcode::kInt32Mul: {
141 Int32BinopMatcher m(node);
142 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0
143 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x
144 if (m.IsFoldable()) { // K * K => K
145 return ReplaceInt32(m.left().Value() * m.right().Value());
146 }
147 if (m.right().Is(-1)) { // x * -1 => 0 - x
148 graph_->ChangeOperator(node, machine_.Int32Sub());
149 node->ReplaceInput(0, Int32Constant(0));
150 node->ReplaceInput(1, m.left().node());
151 return Changed(node);
152 }
153 if (m.right().IsPowerOf2()) { // x * 2^n => x << n
154 graph_->ChangeOperator(node, machine_.Word32Shl());
155 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
156 return Changed(node);
157 }
158 break;
159 }
160 case IrOpcode::kInt32Div: {
161 Int32BinopMatcher m(node);
162 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
163 // TODO(turbofan): if (m.left().Is(0))
164 // TODO(turbofan): if (m.right().IsPowerOf2())
165 // TODO(turbofan): if (m.right().Is(0))
166 // TODO(turbofan): if (m.LeftEqualsRight())
167 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K
168 if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value());
169 return ReplaceInt32(m.left().Value() / m.right().Value());
170 }
171 if (m.right().Is(-1)) { // x / -1 => 0 - x
172 graph_->ChangeOperator(node, machine_.Int32Sub());
173 node->ReplaceInput(0, Int32Constant(0));
174 node->ReplaceInput(1, m.left().node());
175 return Changed(node);
176 }
177 break;
178 }
179 case IrOpcode::kInt32UDiv: {
180 Uint32BinopMatcher m(node);
181 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
182 // TODO(turbofan): if (m.left().Is(0))
183 // TODO(turbofan): if (m.right().Is(0))
184 // TODO(turbofan): if (m.LeftEqualsRight())
185 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K
186 return ReplaceInt32(m.left().Value() / m.right().Value());
187 }
188 if (m.right().IsPowerOf2()) { // x / 2^n => x >> n
189 graph_->ChangeOperator(node, machine_.Word32Shr());
190 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
191 return Changed(node);
192 }
193 break;
194 }
195 case IrOpcode::kInt32Mod: {
196 Int32BinopMatcher m(node);
197 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
198 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0
199 // TODO(turbofan): if (m.left().Is(0))
200 // TODO(turbofan): if (m.right().IsPowerOf2())
201 // TODO(turbofan): if (m.right().Is(0))
202 // TODO(turbofan): if (m.LeftEqualsRight())
203 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K
204 return ReplaceInt32(m.left().Value() % m.right().Value());
205 }
206 break;
207 }
208 case IrOpcode::kInt32UMod: {
209 Uint32BinopMatcher m(node);
210 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
211 // TODO(turbofan): if (m.left().Is(0))
212 // TODO(turbofan): if (m.right().Is(0))
213 // TODO(turbofan): if (m.LeftEqualsRight())
214 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K
215 return ReplaceInt32(m.left().Value() % m.right().Value());
216 }
217 if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1
218 graph_->ChangeOperator(node, machine_.Word32And());
219 node->ReplaceInput(1, Int32Constant(m.right().Value() - 1));
220 return Changed(node);
221 }
222 break;
223 }
224 case IrOpcode::kInt32LessThan: {
225 Int32BinopMatcher m(node);
226 if (m.IsFoldable()) { // K < K => K
227 return ReplaceBool(m.left().Value() < m.right().Value());
228 }
229 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y < 0 => x < y
230 Int32BinopMatcher msub(m.left().node());
231 node->ReplaceInput(0, msub.left().node());
232 node->ReplaceInput(1, msub.right().node());
233 return Changed(node);
234 }
235 if (m.left().Is(0) && m.right().IsInt32Sub()) { // 0 < x - y => y < x
236 Int32BinopMatcher msub(m.right().node());
237 node->ReplaceInput(0, msub.right().node());
238 node->ReplaceInput(1, msub.left().node());
239 return Changed(node);
240 }
241 if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
242 break;
243 }
244 case IrOpcode::kInt32LessThanOrEqual: {
245 Int32BinopMatcher m(node);
246 if (m.IsFoldable()) { // K <= K => K
247 return ReplaceBool(m.left().Value() <= m.right().Value());
248 }
249 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y <= 0 => x <= y
250 Int32BinopMatcher msub(m.left().node());
251 node->ReplaceInput(0, msub.left().node());
252 node->ReplaceInput(1, msub.right().node());
253 return Changed(node);
254 }
255 if (m.left().Is(0) && m.right().IsInt32Sub()) { // 0 <= x - y => y <= x
256 Int32BinopMatcher msub(m.right().node());
257 node->ReplaceInput(0, msub.right().node());
258 node->ReplaceInput(1, msub.left().node());
259 return Changed(node);
260 }
261 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
262 break;
263 }
264 case IrOpcode::kUint32LessThan: {
265 Uint32BinopMatcher m(node);
266 if (m.left().Is(kMaxUInt32)) return ReplaceBool(false); // M < x => false
267 if (m.right().Is(0)) return ReplaceBool(false); // x < 0 => false
268 if (m.IsFoldable()) { // K < K => K
269 return ReplaceBool(m.left().Value() < m.right().Value());
270 }
271 if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
272 break;
273 }
274 case IrOpcode::kUint32LessThanOrEqual: {
275 Uint32BinopMatcher m(node);
276 if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true
277 if (m.right().Is(kMaxUInt32)) return ReplaceBool(true); // x <= M => true
278 if (m.IsFoldable()) { // K <= K => K
279 return ReplaceBool(m.left().Value() <= m.right().Value());
280 }
281 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
282 break;
283 }
284 case IrOpcode::kFloat64Add: {
285 Float64BinopMatcher m(node);
286 if (m.IsFoldable()) { // K + K => K
287 return ReplaceFloat64(m.left().Value() + m.right().Value());
288 }
289 break;
290 }
291 case IrOpcode::kFloat64Sub: {
292 Float64BinopMatcher m(node);
293 if (m.IsFoldable()) { // K - K => K
294 return ReplaceFloat64(m.left().Value() - m.right().Value());
295 }
296 break;
297 }
298 case IrOpcode::kFloat64Mul: {
299 Float64BinopMatcher m(node);
300 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1.0 => x
301 if (m.right().IsNaN()) { // x * NaN => NaN
302 return Replace(m.right().node());
303 }
304 if (m.IsFoldable()) { // K * K => K
305 return ReplaceFloat64(m.left().Value() * m.right().Value());
306 }
307 break;
308 }
309 case IrOpcode::kFloat64Div: {
310 Float64BinopMatcher m(node);
311 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1.0 => x
312 if (m.right().IsNaN()) { // x / NaN => NaN
313 return Replace(m.right().node());
314 }
315 if (m.left().IsNaN()) { // NaN / x => NaN
316 return Replace(m.left().node());
317 }
318 if (m.IsFoldable()) { // K / K => K
319 return ReplaceFloat64(m.left().Value() / m.right().Value());
320 }
321 break;
322 }
323 case IrOpcode::kFloat64Mod: {
324 Float64BinopMatcher m(node);
325 if (m.right().IsNaN()) { // x % NaN => NaN
326 return Replace(m.right().node());
327 }
328 if (m.left().IsNaN()) { // NaN % x => NaN
329 return Replace(m.left().node());
330 }
331 if (m.IsFoldable()) { // K % K => K
332 return ReplaceFloat64(modulo(m.left().Value(), m.right().Value()));
333 }
334 break;
335 }
336 // TODO(turbofan): strength-reduce and fold floating point operations.
337 default: break;
338 }
339 return NoChange();
340 }
341
342 } } } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/machine-operator-reducer.h ('k') | src/compiler/node.h » ('j') | src/lithium-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698