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

Side by Side Diff: src/compiler/representation-change.cc

Issue 1821133002: [turbofan] Add more sanity checks to representation inference. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Type match Created 4 years, 9 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
« no previous file with comments | « src/compiler/representation-change.h ('k') | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/representation-change.h" 5 #include "src/compiler/representation-change.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 return GetFloat32RepresentationFor(node, output_rep, output_type, 135 return GetFloat32RepresentationFor(node, output_rep, output_type,
136 truncation); 136 truncation);
137 case MachineRepresentation::kFloat64: 137 case MachineRepresentation::kFloat64:
138 return GetFloat64RepresentationFor(node, output_rep, output_type, 138 return GetFloat64RepresentationFor(node, output_rep, output_type,
139 truncation); 139 truncation);
140 case MachineRepresentation::kBit: 140 case MachineRepresentation::kBit:
141 return GetBitRepresentationFor(node, output_rep, output_type); 141 return GetBitRepresentationFor(node, output_rep, output_type);
142 case MachineRepresentation::kWord8: 142 case MachineRepresentation::kWord8:
143 case MachineRepresentation::kWord16: 143 case MachineRepresentation::kWord16:
144 case MachineRepresentation::kWord32: 144 case MachineRepresentation::kWord32:
145 return GetWord32RepresentationFor(node, output_rep, output_type); 145 return GetWord32RepresentationFor(node, output_rep, output_type,
146 truncation);
146 case MachineRepresentation::kWord64: 147 case MachineRepresentation::kWord64:
147 return GetWord64RepresentationFor(node, output_rep, output_type); 148 return GetWord64RepresentationFor(node, output_rep, output_type);
148 case MachineRepresentation::kSimd128: // Fall through. 149 case MachineRepresentation::kSimd128: // Fall through.
149 // TODO(bbudge) Handle conversions between tagged and untagged. 150 // TODO(bbudge) Handle conversions between tagged and untagged.
150 break; 151 break;
151 case MachineRepresentation::kNone: 152 case MachineRepresentation::kNone:
152 return node; 153 return node;
153 } 154 }
154 UNREACHABLE(); 155 UNREACHABLE();
155 return nullptr; 156 return nullptr;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } else { 228 } else {
228 int32_t value = OpParameter<int32_t>(node); 229 int32_t value = OpParameter<int32_t>(node);
229 return jsgraph()->Float32Constant(static_cast<float>(value)); 230 return jsgraph()->Float32Constant(static_cast<float>(value));
230 } 231 }
231 case IrOpcode::kFloat32Constant: 232 case IrOpcode::kFloat32Constant:
232 return node; // No change necessary. 233 return node; // No change necessary.
233 default: 234 default:
234 break; 235 break;
235 } 236 }
236 // Select the correct X -> Float32 operator. 237 // Select the correct X -> Float32 operator.
237 const Operator* op; 238 const Operator* op = nullptr;
238 if (output_rep == MachineRepresentation::kBit) { 239 if (IsWord(output_rep)) {
239 return TypeError(node, output_rep, output_type,
240 MachineRepresentation::kFloat32);
241 } else if (IsWord(output_rep)) {
242 if (output_type->Is(Type::Signed32())) { 240 if (output_type->Is(Type::Signed32())) {
241 // int32 -> float64 -> float32
243 op = machine()->ChangeInt32ToFloat64(); 242 op = machine()->ChangeInt32ToFloat64();
244 } else { 243 node = jsgraph()->graph()->NewNode(op, node);
245 // Either the output is int32 or the uses only care about the 244 op = machine()->TruncateFloat64ToFloat32();
246 // low 32 bits (so we can pick int32 safely). 245 } else if (output_type->Is(Type::Unsigned32()) ||
247 DCHECK(output_type->Is(Type::Unsigned32()) || 246 truncation.TruncatesToWord32()) {
248 truncation.TruncatesToWord32()); 247 // Either the output is uint32 or the uses only care about the
248 // low 32 bits (so we can pick uint32 safely).
249
250 // uint32 -> float64 -> float32
249 op = machine()->ChangeUint32ToFloat64(); 251 op = machine()->ChangeUint32ToFloat64();
252 node = jsgraph()->graph()->NewNode(op, node);
253 op = machine()->TruncateFloat64ToFloat32();
250 } 254 }
251 // int32 -> float64 -> float32
252 node = jsgraph()->graph()->NewNode(op, node);
253 op = machine()->TruncateFloat64ToFloat32();
254 } else if (output_rep == MachineRepresentation::kTagged) { 255 } else if (output_rep == MachineRepresentation::kTagged) {
255 op = simplified()->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 256 if (output_type->Is(Type::Number())) {
256 node = jsgraph()->graph()->NewNode(op, node); 257 op = simplified()
257 op = machine()->TruncateFloat64ToFloat32(); 258 ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
259 node = jsgraph()->graph()->NewNode(op, node);
260 op = machine()->TruncateFloat64ToFloat32();
261 }
258 } else if (output_rep == MachineRepresentation::kFloat64) { 262 } else if (output_rep == MachineRepresentation::kFloat64) {
259 op = machine()->TruncateFloat64ToFloat32(); 263 op = machine()->TruncateFloat64ToFloat32();
260 } else { 264 }
265 if (op == nullptr) {
261 return TypeError(node, output_rep, output_type, 266 return TypeError(node, output_rep, output_type,
262 MachineRepresentation::kFloat32); 267 MachineRepresentation::kFloat32);
263 } 268 }
264 return jsgraph()->graph()->NewNode(op, node); 269 return jsgraph()->graph()->NewNode(op, node);
265 } 270 }
266 271
267 272
268 Node* RepresentationChanger::GetFloat64RepresentationFor( 273 Node* RepresentationChanger::GetFloat64RepresentationFor(
269 Node* node, MachineRepresentation output_rep, Type* output_type, 274 Node* node, MachineRepresentation output_rep, Type* output_type,
270 Truncation truncation) { 275 Truncation truncation) {
(...skipping 11 matching lines...) Expand all
282 return jsgraph()->Float64Constant(static_cast<double>(value)); 287 return jsgraph()->Float64Constant(static_cast<double>(value));
283 } 288 }
284 case IrOpcode::kFloat64Constant: 289 case IrOpcode::kFloat64Constant:
285 return node; // No change necessary. 290 return node; // No change necessary.
286 case IrOpcode::kFloat32Constant: 291 case IrOpcode::kFloat32Constant:
287 return jsgraph()->Float64Constant(OpParameter<float>(node)); 292 return jsgraph()->Float64Constant(OpParameter<float>(node));
288 default: 293 default:
289 break; 294 break;
290 } 295 }
291 // Select the correct X -> Float64 operator. 296 // Select the correct X -> Float64 operator.
292 const Operator* op; 297 const Operator* op = nullptr;
293 if (output_rep == MachineRepresentation::kBit) { 298 if (IsWord(output_rep)) {
294 return TypeError(node, output_rep, output_type,
295 MachineRepresentation::kFloat64);
296 } else if (IsWord(output_rep)) {
297 if (output_type->Is(Type::Signed32())) { 299 if (output_type->Is(Type::Signed32())) {
298 op = machine()->ChangeInt32ToFloat64(); 300 op = machine()->ChangeInt32ToFloat64();
299 } else { 301 } else if (output_type->Is(Type::Unsigned32()) ||
300 // Either the output is int32 or the uses only care about the 302 truncation.TruncatesToWord32()) {
301 // low 32 bits (so we can pick int32 safely). 303 // Either the output is uint32 or the uses only care about the
302 DCHECK(output_type->Is(Type::Unsigned32()) || 304 // low 32 bits (so we can pick uint32 safely).
303 truncation.TruncatesToWord32());
304 op = machine()->ChangeUint32ToFloat64(); 305 op = machine()->ChangeUint32ToFloat64();
305 } 306 }
306 } else if (output_rep == MachineRepresentation::kTagged) { 307 } else if (output_rep == MachineRepresentation::kTagged) {
307 op = simplified()->ChangeTaggedToFloat64(); 308 if (output_type->Is(Type::Number())) {
309 op = simplified()->ChangeTaggedToFloat64();
310 }
308 } else if (output_rep == MachineRepresentation::kFloat32) { 311 } else if (output_rep == MachineRepresentation::kFloat32) {
309 op = machine()->ChangeFloat32ToFloat64(); 312 op = machine()->ChangeFloat32ToFloat64();
310 } else { 313 }
314 if (op == nullptr) {
311 return TypeError(node, output_rep, output_type, 315 return TypeError(node, output_rep, output_type,
312 MachineRepresentation::kFloat64); 316 MachineRepresentation::kFloat64);
313 } 317 }
314 return jsgraph()->graph()->NewNode(op, node); 318 return jsgraph()->graph()->NewNode(op, node);
315 } 319 }
316 320
317 321
318 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { 322 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
319 return jsgraph()->Int32Constant(DoubleToInt32(value)); 323 return jsgraph()->Int32Constant(DoubleToInt32(value));
320 } 324 }
321 325
322
323 Node* RepresentationChanger::GetWord32RepresentationFor( 326 Node* RepresentationChanger::GetWord32RepresentationFor(
324 Node* node, MachineRepresentation output_rep, Type* output_type) { 327 Node* node, MachineRepresentation output_rep, Type* output_type,
328 Truncation truncation) {
325 // Eagerly fold representation changes for constants. 329 // Eagerly fold representation changes for constants.
326 switch (node->opcode()) { 330 switch (node->opcode()) {
327 case IrOpcode::kInt32Constant: 331 case IrOpcode::kInt32Constant:
328 return node; // No change necessary. 332 return node; // No change necessary.
329 case IrOpcode::kFloat32Constant: 333 case IrOpcode::kFloat32Constant:
330 return MakeTruncatedInt32Constant(OpParameter<float>(node)); 334 return MakeTruncatedInt32Constant(OpParameter<float>(node));
331 case IrOpcode::kNumberConstant: 335 case IrOpcode::kNumberConstant:
332 case IrOpcode::kFloat64Constant: 336 case IrOpcode::kFloat64Constant:
333 return MakeTruncatedInt32Constant(OpParameter<double>(node)); 337 return MakeTruncatedInt32Constant(OpParameter<double>(node));
334 default: 338 default:
335 break; 339 break;
336 } 340 }
337 // Select the correct X -> Word32 operator. 341 // Select the correct X -> Word32 operator.
338 const Operator* op; 342 const Operator* op = nullptr;
339 Type* type = NodeProperties::GetType(node);
340
341 if (output_rep == MachineRepresentation::kBit) { 343 if (output_rep == MachineRepresentation::kBit) {
342 return node; // Sloppy comparison -> word32 344 return node; // Sloppy comparison -> word32
343 } else if (output_rep == MachineRepresentation::kFloat64) { 345 } else if (output_rep == MachineRepresentation::kFloat64) {
344 // TODO(jarin) Use only output_type here, once we intersect it with the 346 if (output_type->Is(Type::Unsigned32())) {
345 // type inferred by the typer.
346 if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
347 op = machine()->ChangeFloat64ToUint32(); 347 op = machine()->ChangeFloat64ToUint32();
348 } else if (output_type->Is(Type::Signed32()) || 348 } else if (output_type->Is(Type::Signed32())) {
349 type->Is(Type::Signed32())) {
350 op = machine()->ChangeFloat64ToInt32(); 349 op = machine()->ChangeFloat64ToInt32();
351 } else { 350 } else if (truncation.TruncatesToWord32()) {
352 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); 351 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
353 } 352 }
354 } else if (output_rep == MachineRepresentation::kFloat32) { 353 } else if (output_rep == MachineRepresentation::kFloat32) {
355 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 354 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
356 if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) { 355 if (output_type->Is(Type::Unsigned32())) {
357 op = machine()->ChangeFloat64ToUint32(); 356 op = machine()->ChangeFloat64ToUint32();
358 } else if (output_type->Is(Type::Signed32()) || 357 } else if (output_type->Is(Type::Signed32())) {
359 type->Is(Type::Signed32())) {
360 op = machine()->ChangeFloat64ToInt32(); 358 op = machine()->ChangeFloat64ToInt32();
361 } else { 359 } else if (truncation.TruncatesToWord32()) {
362 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); 360 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
363 } 361 }
364 } else if (output_rep == MachineRepresentation::kTagged) { 362 } else if (output_rep == MachineRepresentation::kTagged) {
365 if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) { 363 if (output_type->Is(Type::Unsigned32())) {
366 op = simplified()->ChangeTaggedToUint32(); 364 op = simplified()->ChangeTaggedToUint32();
367 } else if (output_type->Is(Type::Signed32()) || 365 } else if (output_type->Is(Type::Signed32())) {
368 type->Is(Type::Signed32())) {
369 op = simplified()->ChangeTaggedToInt32(); 366 op = simplified()->ChangeTaggedToInt32();
370 } else { 367 } else if (truncation.TruncatesToWord32()) {
371 node = InsertChangeTaggedToFloat64(node); 368 node = InsertChangeTaggedToFloat64(node);
372 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); 369 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
373 } 370 }
374 } else { 371 }
372 if (op == nullptr) {
375 return TypeError(node, output_rep, output_type, 373 return TypeError(node, output_rep, output_type,
376 MachineRepresentation::kWord32); 374 MachineRepresentation::kWord32);
377 } 375 }
378 return jsgraph()->graph()->NewNode(op, node); 376 return jsgraph()->graph()->NewNode(op, node);
379 } 377 }
380 378
381 379
382 Node* RepresentationChanger::GetBitRepresentationFor( 380 Node* RepresentationChanger::GetBitRepresentationFor(
383 Node* node, MachineRepresentation output_rep, Type* output_type) { 381 Node* node, MachineRepresentation output_rep, Type* output_type) {
384 // Eagerly fold representation changes for constants. 382 // Eagerly fold representation changes for constants.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 528
531 529
532 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { 530 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
533 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 531 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
534 node); 532 node);
535 } 533 }
536 534
537 } // namespace compiler 535 } // namespace compiler
538 } // namespace internal 536 } // namespace internal
539 } // namespace v8 537 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698