| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 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/v8.h" | 5 #include "src/v8.h" |
| 6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
| 7 | 7 |
| 8 #include "src/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
| 9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 | 165 |
| 166 | 166 |
| 167 static IrOpcode::Value NumberToI32(bool is_signed) { | 167 static IrOpcode::Value NumberToI32(bool is_signed) { |
| 168 return is_signed ? IrOpcode::kNumberToInt32 : IrOpcode::kNumberToUint32; | 168 return is_signed ? IrOpcode::kNumberToInt32 : IrOpcode::kNumberToUint32; |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 TEST(StringBinops) { | 172 TEST(StringBinops) { |
| 173 JSTypedLoweringTester R; | 173 JSTypedLoweringTester R; |
| 174 | 174 |
| 175 for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); ++i) { | 175 for (size_t i = 0; i < arraysize(kStringTypes); ++i) { |
| 176 Node* p0 = R.Parameter(kStringTypes[i], 0); | 176 Node* p0 = R.Parameter(kStringTypes[i], 0); |
| 177 | 177 |
| 178 for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); ++j) { | 178 for (size_t j = 0; j < arraysize(kStringTypes); ++j) { |
| 179 Node* p1 = R.Parameter(kStringTypes[j], 1); | 179 Node* p1 = R.Parameter(kStringTypes[j], 1); |
| 180 | 180 |
| 181 Node* add = R.Binop(R.javascript.Add(), p0, p1); | 181 Node* add = R.Binop(R.javascript.Add(), p0, p1); |
| 182 Node* r = R.reduce(add); | 182 Node* r = R.reduce(add); |
| 183 | 183 |
| 184 R.CheckPureBinop(IrOpcode::kStringAdd, r); | 184 R.CheckPureBinop(IrOpcode::kStringAdd, r); |
| 185 CHECK_EQ(p0, r->InputAt(0)); | 185 CHECK_EQ(p0, r->InputAt(0)); |
| 186 CHECK_EQ(p1, r->InputAt(1)); | 186 CHECK_EQ(p1, r->InputAt(1)); |
| 187 } | 187 } |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 | 190 |
| 191 | 191 |
| 192 TEST(AddNumber1) { | 192 TEST(AddNumber1) { |
| 193 JSTypedLoweringTester R; | 193 JSTypedLoweringTester R; |
| 194 for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) { | 194 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { |
| 195 Node* p0 = R.Parameter(kNumberTypes[i], 0); | 195 Node* p0 = R.Parameter(kNumberTypes[i], 0); |
| 196 Node* p1 = R.Parameter(kNumberTypes[i], 1); | 196 Node* p1 = R.Parameter(kNumberTypes[i], 1); |
| 197 Node* add = R.Binop(R.javascript.Add(), p0, p1); | 197 Node* add = R.Binop(R.javascript.Add(), p0, p1); |
| 198 Node* r = R.reduce(add); | 198 Node* r = R.reduce(add); |
| 199 | 199 |
| 200 R.CheckPureBinop(IrOpcode::kNumberAdd, r); | 200 R.CheckPureBinop(IrOpcode::kNumberAdd, r); |
| 201 CHECK_EQ(p0, r->InputAt(0)); | 201 CHECK_EQ(p0, r->InputAt(0)); |
| 202 CHECK_EQ(p1, r->InputAt(1)); | 202 CHECK_EQ(p1, r->InputAt(1)); |
| 203 } | 203 } |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 TEST(NumberBinops) { | 207 TEST(NumberBinops) { |
| 208 JSTypedLoweringTester R; | 208 JSTypedLoweringTester R; |
| 209 Operator* ops[] = { | 209 Operator* ops[] = { |
| 210 R.javascript.Add(), R.simplified.NumberAdd(), | 210 R.javascript.Add(), R.simplified.NumberAdd(), |
| 211 R.javascript.Subtract(), R.simplified.NumberSubtract(), | 211 R.javascript.Subtract(), R.simplified.NumberSubtract(), |
| 212 R.javascript.Multiply(), R.simplified.NumberMultiply(), | 212 R.javascript.Multiply(), R.simplified.NumberMultiply(), |
| 213 R.javascript.Divide(), R.simplified.NumberDivide(), | 213 R.javascript.Divide(), R.simplified.NumberDivide(), |
| 214 R.javascript.Modulus(), R.simplified.NumberModulus(), | 214 R.javascript.Modulus(), R.simplified.NumberModulus(), |
| 215 }; | 215 }; |
| 216 | 216 |
| 217 for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) { | 217 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { |
| 218 Node* p0 = R.Parameter(kNumberTypes[i], 0); | 218 Node* p0 = R.Parameter(kNumberTypes[i], 0); |
| 219 | 219 |
| 220 for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); ++j) { | 220 for (size_t j = 0; j < arraysize(kNumberTypes); ++j) { |
| 221 Node* p1 = R.Parameter(kNumberTypes[j], 1); | 221 Node* p1 = R.Parameter(kNumberTypes[j], 1); |
| 222 | 222 |
| 223 for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) { | 223 for (size_t k = 0; k < arraysize(ops); k += 2) { |
| 224 Node* add = R.Binop(ops[k], p0, p1); | 224 Node* add = R.Binop(ops[k], p0, p1); |
| 225 Node* r = R.reduce(add); | 225 Node* r = R.reduce(add); |
| 226 | 226 |
| 227 R.CheckPureBinop(ops[k + 1], r); | 227 R.CheckPureBinop(ops[k + 1], r); |
| 228 CHECK_EQ(p0, r->InputAt(0)); | 228 CHECK_EQ(p0, r->InputAt(0)); |
| 229 CHECK_EQ(p1, r->InputAt(1)); | 229 CHECK_EQ(p1, r->InputAt(1)); |
| 230 } | 230 } |
| 231 } | 231 } |
| 232 } | 232 } |
| 233 } | 233 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 TEST(Int32BitwiseShifts) { | 277 TEST(Int32BitwiseShifts) { |
| 278 JSBitwiseShiftTypedLoweringTester R; | 278 JSBitwiseShiftTypedLoweringTester R; |
| 279 | 279 |
| 280 Type* types[] = { | 280 Type* types[] = { |
| 281 Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(), | 281 Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(), |
| 282 Type::Unsigned32(), Type::Signed32(), Type::MinusZero(), | 282 Type::Unsigned32(), Type::Signed32(), Type::MinusZero(), |
| 283 Type::NaN(), Type::OtherNumber(), Type::Undefined(), | 283 Type::NaN(), Type::OtherNumber(), Type::Undefined(), |
| 284 Type::Null(), Type::Boolean(), Type::Number(), | 284 Type::Null(), Type::Boolean(), Type::Number(), |
| 285 Type::String(), Type::Object()}; | 285 Type::String(), Type::Object()}; |
| 286 | 286 |
| 287 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 287 for (size_t i = 0; i < arraysize(types); ++i) { |
| 288 Node* p0 = R.Parameter(types[i], 0); | 288 Node* p0 = R.Parameter(types[i], 0); |
| 289 | 289 |
| 290 for (size_t j = 0; j < ARRAY_SIZE(types); ++j) { | 290 for (size_t j = 0; j < arraysize(types); ++j) { |
| 291 Node* p1 = R.Parameter(types[j], 1); | 291 Node* p1 = R.Parameter(types[j], 1); |
| 292 | 292 |
| 293 for (int k = 0; k < R.kNumberOps; k += 2) { | 293 for (int k = 0; k < R.kNumberOps; k += 2) { |
| 294 Node* add = R.Binop(R.ops[k], p0, p1); | 294 Node* add = R.Binop(R.ops[k], p0, p1); |
| 295 Node* r = R.reduce(add); | 295 Node* r = R.reduce(add); |
| 296 | 296 |
| 297 R.CheckPureBinop(R.ops[k + 1], r); | 297 R.CheckPureBinop(R.ops[k + 1], r); |
| 298 Node* r0 = r->InputAt(0); | 298 Node* r0 = r->InputAt(0); |
| 299 Node* r1 = r->InputAt(1); | 299 Node* r1 = r->InputAt(1); |
| 300 | 300 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 TEST(Int32BitwiseBinops) { | 337 TEST(Int32BitwiseBinops) { |
| 338 JSBitwiseTypedLoweringTester R; | 338 JSBitwiseTypedLoweringTester R; |
| 339 | 339 |
| 340 Type* types[] = { | 340 Type* types[] = { |
| 341 Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(), | 341 Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(), |
| 342 Type::Unsigned32(), Type::Signed32(), Type::MinusZero(), | 342 Type::Unsigned32(), Type::Signed32(), Type::MinusZero(), |
| 343 Type::NaN(), Type::OtherNumber(), Type::Undefined(), | 343 Type::NaN(), Type::OtherNumber(), Type::Undefined(), |
| 344 Type::Null(), Type::Boolean(), Type::Number(), | 344 Type::Null(), Type::Boolean(), Type::Number(), |
| 345 Type::String(), Type::Object()}; | 345 Type::String(), Type::Object()}; |
| 346 | 346 |
| 347 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 347 for (size_t i = 0; i < arraysize(types); ++i) { |
| 348 Node* p0 = R.Parameter(types[i], 0); | 348 Node* p0 = R.Parameter(types[i], 0); |
| 349 | 349 |
| 350 for (size_t j = 0; j < ARRAY_SIZE(types); ++j) { | 350 for (size_t j = 0; j < arraysize(types); ++j) { |
| 351 Node* p1 = R.Parameter(types[j], 1); | 351 Node* p1 = R.Parameter(types[j], 1); |
| 352 | 352 |
| 353 for (int k = 0; k < R.kNumberOps; k += 2) { | 353 for (int k = 0; k < R.kNumberOps; k += 2) { |
| 354 Node* add = R.Binop(R.ops[k], p0, p1); | 354 Node* add = R.Binop(R.ops[k], p0, p1); |
| 355 Node* r = R.reduce(add); | 355 Node* r = R.reduce(add); |
| 356 | 356 |
| 357 R.CheckPureBinop(R.ops[k + 1], r); | 357 R.CheckPureBinop(R.ops[k + 1], r); |
| 358 | 358 |
| 359 CheckToI32(p0, r->InputAt(0), R.signedness[k]); | 359 CheckToI32(p0, r->InputAt(0), R.signedness[k]); |
| 360 CheckToI32(p1, r->InputAt(1), R.signedness[k + 1]); | 360 CheckToI32(p1, r->InputAt(1), R.signedness[k + 1]); |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 | 366 |
| 367 TEST(JSToNumber1) { | 367 TEST(JSToNumber1) { |
| 368 JSTypedLoweringTester R; | 368 JSTypedLoweringTester R; |
| 369 Operator* ton = R.javascript.ToNumber(); | 369 Operator* ton = R.javascript.ToNumber(); |
| 370 | 370 |
| 371 for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) { // ToNumber(number) | 371 for (size_t i = 0; i < arraysize(kNumberTypes); i++) { // ToNumber(number) |
| 372 Node* r = R.ReduceUnop(ton, kNumberTypes[i]); | 372 Node* r = R.ReduceUnop(ton, kNumberTypes[i]); |
| 373 CHECK_EQ(IrOpcode::kParameter, r->opcode()); | 373 CHECK_EQ(IrOpcode::kParameter, r->opcode()); |
| 374 } | 374 } |
| 375 | 375 |
| 376 { // ToNumber(undefined) | 376 { // ToNumber(undefined) |
| 377 Node* r = R.ReduceUnop(ton, Type::Undefined()); | 377 Node* r = R.ReduceUnop(ton, Type::Undefined()); |
| 378 R.CheckNaN(r); | 378 R.CheckNaN(r); |
| 379 } | 379 } |
| 380 | 380 |
| 381 { // ToNumber(null) | 381 { // ToNumber(null) |
| 382 Node* r = R.ReduceUnop(ton, Type::Null()); | 382 Node* r = R.ReduceUnop(ton, Type::Null()); |
| 383 R.CheckNumberConstant(0.0, r); | 383 R.CheckNumberConstant(0.0, r); |
| 384 } | 384 } |
| 385 } | 385 } |
| 386 | 386 |
| 387 | 387 |
| 388 TEST(JSToNumber_replacement) { | 388 TEST(JSToNumber_replacement) { |
| 389 JSTypedLoweringTester R; | 389 JSTypedLoweringTester R; |
| 390 | 390 |
| 391 Type* types[] = {Type::Null(), Type::Undefined(), Type::Number()}; | 391 Type* types[] = {Type::Null(), Type::Undefined(), Type::Number()}; |
| 392 | 392 |
| 393 for (size_t i = 0; i < ARRAY_SIZE(types); i++) { | 393 for (size_t i = 0; i < arraysize(types); i++) { |
| 394 Node* n = R.Parameter(types[i]); | 394 Node* n = R.Parameter(types[i]); |
| 395 Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(), | 395 Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(), |
| 396 R.start(), R.start()); | 396 R.start(), R.start()); |
| 397 Node* effect_use = R.UseForEffect(c); | 397 Node* effect_use = R.UseForEffect(c); |
| 398 Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c); | 398 Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c); |
| 399 | 399 |
| 400 R.CheckEffectInput(c, effect_use); | 400 R.CheckEffectInput(c, effect_use); |
| 401 Node* r = R.reduce(c); | 401 Node* r = R.reduce(c); |
| 402 | 402 |
| 403 if (types[i]->Is(Type::Number())) { | 403 if (types[i]->Is(Type::Number())) { |
| 404 CHECK_EQ(n, r); | 404 CHECK_EQ(n, r); |
| 405 } else { | 405 } else { |
| 406 CHECK_EQ(IrOpcode::kNumberConstant, r->opcode()); | 406 CHECK_EQ(IrOpcode::kNumberConstant, r->opcode()); |
| 407 } | 407 } |
| 408 | 408 |
| 409 CHECK_EQ(n, add->InputAt(0)); | 409 CHECK_EQ(n, add->InputAt(0)); |
| 410 CHECK_EQ(r, add->InputAt(1)); | 410 CHECK_EQ(r, add->InputAt(1)); |
| 411 R.CheckEffectInput(R.start(), effect_use); | 411 R.CheckEffectInput(R.start(), effect_use); |
| 412 } | 412 } |
| 413 } | 413 } |
| 414 | 414 |
| 415 | 415 |
| 416 TEST(JSToNumberOfConstant) { | 416 TEST(JSToNumberOfConstant) { |
| 417 JSTypedLoweringTester R; | 417 JSTypedLoweringTester R; |
| 418 | 418 |
| 419 Operator* ops[] = {R.common.NumberConstant(0), R.common.NumberConstant(-1), | 419 Operator* ops[] = {R.common.NumberConstant(0), R.common.NumberConstant(-1), |
| 420 R.common.NumberConstant(0.1), R.common.Int32Constant(1177), | 420 R.common.NumberConstant(0.1), R.common.Int32Constant(1177), |
| 421 R.common.Float64Constant(0.99)}; | 421 R.common.Float64Constant(0.99)}; |
| 422 | 422 |
| 423 for (size_t i = 0; i < ARRAY_SIZE(ops); i++) { | 423 for (size_t i = 0; i < arraysize(ops); i++) { |
| 424 Node* n = R.graph.NewNode(ops[i]); | 424 Node* n = R.graph.NewNode(ops[i]); |
| 425 Node* convert = R.Unop(R.javascript.ToNumber(), n); | 425 Node* convert = R.Unop(R.javascript.ToNumber(), n); |
| 426 Node* r = R.reduce(convert); | 426 Node* r = R.reduce(convert); |
| 427 // Note that either outcome below is correct. It only depends on whether | 427 // Note that either outcome below is correct. It only depends on whether |
| 428 // the types of constants are eagerly computed or only computed by the | 428 // the types of constants are eagerly computed or only computed by the |
| 429 // typing pass. | 429 // typing pass. |
| 430 if (NodeProperties::GetBounds(n).upper->Is(Type::Number())) { | 430 if (NodeProperties::GetBounds(n).upper->Is(Type::Number())) { |
| 431 // If number constants are eagerly typed, then reduction should | 431 // If number constants are eagerly typed, then reduction should |
| 432 // remove the ToNumber. | 432 // remove the ToNumber. |
| 433 CHECK_EQ(n, r); | 433 CHECK_EQ(n, r); |
| 434 } else { | 434 } else { |
| 435 // Otherwise, type-based lowering should only look at the type, and | 435 // Otherwise, type-based lowering should only look at the type, and |
| 436 // *not* try to constant fold. | 436 // *not* try to constant fold. |
| 437 CHECK_EQ(convert, r); | 437 CHECK_EQ(convert, r); |
| 438 } | 438 } |
| 439 } | 439 } |
| 440 } | 440 } |
| 441 | 441 |
| 442 | 442 |
| 443 TEST(JSToNumberOfNumberOrOtherPrimitive) { | 443 TEST(JSToNumberOfNumberOrOtherPrimitive) { |
| 444 JSTypedLoweringTester R; | 444 JSTypedLoweringTester R; |
| 445 Type* others[] = {Type::Undefined(), Type::Null(), Type::Boolean(), | 445 Type* others[] = {Type::Undefined(), Type::Null(), Type::Boolean(), |
| 446 Type::String()}; | 446 Type::String()}; |
| 447 | 447 |
| 448 for (size_t i = 0; i < ARRAY_SIZE(others); i++) { | 448 for (size_t i = 0; i < arraysize(others); i++) { |
| 449 Type* t = Type::Union(Type::Number(), others[i], R.main_zone()); | 449 Type* t = Type::Union(Type::Number(), others[i], R.main_zone()); |
| 450 Node* r = R.ReduceUnop(R.javascript.ToNumber(), t); | 450 Node* r = R.ReduceUnop(R.javascript.ToNumber(), t); |
| 451 CHECK_EQ(IrOpcode::kJSToNumber, r->opcode()); | 451 CHECK_EQ(IrOpcode::kJSToNumber, r->opcode()); |
| 452 } | 452 } |
| 453 } | 453 } |
| 454 | 454 |
| 455 | 455 |
| 456 TEST(JSToBoolean) { | 456 TEST(JSToBoolean) { |
| 457 JSTypedLoweringTester R; | 457 JSTypedLoweringTester R; |
| 458 Operator* op = R.javascript.ToBoolean(); | 458 Operator* op = R.javascript.ToBoolean(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 } | 502 } |
| 503 } | 503 } |
| 504 | 504 |
| 505 | 505 |
| 506 TEST(JSToBoolean_replacement) { | 506 TEST(JSToBoolean_replacement) { |
| 507 JSTypedLoweringTester R; | 507 JSTypedLoweringTester R; |
| 508 | 508 |
| 509 Type* types[] = {Type::Null(), Type::Undefined(), Type::Boolean(), | 509 Type* types[] = {Type::Null(), Type::Undefined(), Type::Boolean(), |
| 510 Type::DetectableObject(), Type::Undetectable()}; | 510 Type::DetectableObject(), Type::Undetectable()}; |
| 511 | 511 |
| 512 for (size_t i = 0; i < ARRAY_SIZE(types); i++) { | 512 for (size_t i = 0; i < arraysize(types); i++) { |
| 513 Node* n = R.Parameter(types[i]); | 513 Node* n = R.Parameter(types[i]); |
| 514 Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context(), | 514 Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context(), |
| 515 R.start(), R.start()); | 515 R.start(), R.start()); |
| 516 Node* effect_use = R.UseForEffect(c); | 516 Node* effect_use = R.UseForEffect(c); |
| 517 Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c); | 517 Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c); |
| 518 | 518 |
| 519 R.CheckEffectInput(c, effect_use); | 519 R.CheckEffectInput(c, effect_use); |
| 520 Node* r = R.reduce(c); | 520 Node* r = R.reduce(c); |
| 521 | 521 |
| 522 if (types[i]->Is(Type::Boolean())) { | 522 if (types[i]->Is(Type::Boolean())) { |
| 523 CHECK_EQ(n, r); | 523 CHECK_EQ(n, r); |
| 524 } else { | 524 } else { |
| 525 CHECK_EQ(IrOpcode::kHeapConstant, r->opcode()); | 525 CHECK_EQ(IrOpcode::kHeapConstant, r->opcode()); |
| 526 } | 526 } |
| 527 | 527 |
| 528 CHECK_EQ(n, add->InputAt(0)); | 528 CHECK_EQ(n, add->InputAt(0)); |
| 529 CHECK_EQ(r, add->InputAt(1)); | 529 CHECK_EQ(r, add->InputAt(1)); |
| 530 R.CheckEffectInput(R.start(), effect_use); | 530 R.CheckEffectInput(R.start(), effect_use); |
| 531 } | 531 } |
| 532 } | 532 } |
| 533 | 533 |
| 534 | 534 |
| 535 TEST(JSToString1) { | 535 TEST(JSToString1) { |
| 536 JSTypedLoweringTester R; | 536 JSTypedLoweringTester R; |
| 537 | 537 |
| 538 for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) { | 538 for (size_t i = 0; i < arraysize(kStringTypes); i++) { |
| 539 Node* r = R.ReduceUnop(R.javascript.ToString(), kStringTypes[i]); | 539 Node* r = R.ReduceUnop(R.javascript.ToString(), kStringTypes[i]); |
| 540 CHECK_EQ(IrOpcode::kParameter, r->opcode()); | 540 CHECK_EQ(IrOpcode::kParameter, r->opcode()); |
| 541 } | 541 } |
| 542 | 542 |
| 543 Operator* op = R.javascript.ToString(); | 543 Operator* op = R.javascript.ToString(); |
| 544 | 544 |
| 545 { // ToString(undefined) => "undefined" | 545 { // ToString(undefined) => "undefined" |
| 546 Node* r = R.ReduceUnop(op, Type::Undefined()); | 546 Node* r = R.ReduceUnop(op, Type::Undefined()); |
| 547 R.CheckHandle(R.isolate->factory()->undefined_string(), r); | 547 R.CheckHandle(R.isolate->factory()->undefined_string(), r); |
| 548 } | 548 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 574 CHECK_EQ(IrOpcode::kJSToString, r->opcode()); // No reduction. | 574 CHECK_EQ(IrOpcode::kJSToString, r->opcode()); // No reduction. |
| 575 } | 575 } |
| 576 } | 576 } |
| 577 | 577 |
| 578 | 578 |
| 579 TEST(JSToString_replacement) { | 579 TEST(JSToString_replacement) { |
| 580 JSTypedLoweringTester R; | 580 JSTypedLoweringTester R; |
| 581 | 581 |
| 582 Type* types[] = {Type::Null(), Type::Undefined(), Type::String()}; | 582 Type* types[] = {Type::Null(), Type::Undefined(), Type::String()}; |
| 583 | 583 |
| 584 for (size_t i = 0; i < ARRAY_SIZE(types); i++) { | 584 for (size_t i = 0; i < arraysize(types); i++) { |
| 585 Node* n = R.Parameter(types[i]); | 585 Node* n = R.Parameter(types[i]); |
| 586 Node* c = R.graph.NewNode(R.javascript.ToString(), n, R.context(), | 586 Node* c = R.graph.NewNode(R.javascript.ToString(), n, R.context(), |
| 587 R.start(), R.start()); | 587 R.start(), R.start()); |
| 588 Node* effect_use = R.UseForEffect(c); | 588 Node* effect_use = R.UseForEffect(c); |
| 589 Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c); | 589 Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c); |
| 590 | 590 |
| 591 R.CheckEffectInput(c, effect_use); | 591 R.CheckEffectInput(c, effect_use); |
| 592 Node* r = R.reduce(c); | 592 Node* r = R.reduce(c); |
| 593 | 593 |
| 594 if (types[i]->Is(Type::String())) { | 594 if (types[i]->Is(Type::String())) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 606 | 606 |
| 607 TEST(StringComparison) { | 607 TEST(StringComparison) { |
| 608 JSTypedLoweringTester R; | 608 JSTypedLoweringTester R; |
| 609 | 609 |
| 610 Operator* ops[] = { | 610 Operator* ops[] = { |
| 611 R.javascript.LessThan(), R.simplified.StringLessThan(), | 611 R.javascript.LessThan(), R.simplified.StringLessThan(), |
| 612 R.javascript.LessThanOrEqual(), R.simplified.StringLessThanOrEqual(), | 612 R.javascript.LessThanOrEqual(), R.simplified.StringLessThanOrEqual(), |
| 613 R.javascript.GreaterThan(), R.simplified.StringLessThan(), | 613 R.javascript.GreaterThan(), R.simplified.StringLessThan(), |
| 614 R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()}; | 614 R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()}; |
| 615 | 615 |
| 616 for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) { | 616 for (size_t i = 0; i < arraysize(kStringTypes); i++) { |
| 617 Node* p0 = R.Parameter(kStringTypes[i], 0); | 617 Node* p0 = R.Parameter(kStringTypes[i], 0); |
| 618 for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); j++) { | 618 for (size_t j = 0; j < arraysize(kStringTypes); j++) { |
| 619 Node* p1 = R.Parameter(kStringTypes[j], 1); | 619 Node* p1 = R.Parameter(kStringTypes[j], 1); |
| 620 | 620 |
| 621 for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) { | 621 for (size_t k = 0; k < arraysize(ops); k += 2) { |
| 622 Node* cmp = R.Binop(ops[k], p0, p1); | 622 Node* cmp = R.Binop(ops[k], p0, p1); |
| 623 Node* r = R.reduce(cmp); | 623 Node* r = R.reduce(cmp); |
| 624 | 624 |
| 625 R.CheckPureBinop(ops[k + 1], r); | 625 R.CheckPureBinop(ops[k + 1], r); |
| 626 if (k >= 4) { | 626 if (k >= 4) { |
| 627 // GreaterThan and GreaterThanOrEqual commute the inputs | 627 // GreaterThan and GreaterThanOrEqual commute the inputs |
| 628 // and use the LessThan and LessThanOrEqual operators. | 628 // and use the LessThan and LessThanOrEqual operators. |
| 629 CHECK_EQ(p1, r->InputAt(0)); | 629 CHECK_EQ(p1, r->InputAt(0)); |
| 630 CHECK_EQ(p0, r->InputAt(1)); | 630 CHECK_EQ(p0, r->InputAt(1)); |
| 631 } else { | 631 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 651 | 651 |
| 652 TEST(NumberComparison) { | 652 TEST(NumberComparison) { |
| 653 JSTypedLoweringTester R; | 653 JSTypedLoweringTester R; |
| 654 | 654 |
| 655 Operator* ops[] = { | 655 Operator* ops[] = { |
| 656 R.javascript.LessThan(), R.simplified.NumberLessThan(), | 656 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
| 657 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 657 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 658 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 658 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
| 659 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; | 659 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; |
| 660 | 660 |
| 661 for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) { | 661 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
| 662 Type* t0 = kJSTypes[i]; | 662 Type* t0 = kJSTypes[i]; |
| 663 if (t0->Is(Type::String())) continue; // skip Type::String | 663 if (t0->Is(Type::String())) continue; // skip Type::String |
| 664 Node* p0 = R.Parameter(t0, 0); | 664 Node* p0 = R.Parameter(t0, 0); |
| 665 | 665 |
| 666 for (size_t j = 0; j < ARRAY_SIZE(kJSTypes); j++) { | 666 for (size_t j = 0; j < arraysize(kJSTypes); j++) { |
| 667 Type* t1 = kJSTypes[j]; | 667 Type* t1 = kJSTypes[j]; |
| 668 if (t1->Is(Type::String())) continue; // skip Type::String | 668 if (t1->Is(Type::String())) continue; // skip Type::String |
| 669 Node* p1 = R.Parameter(t1, 1); | 669 Node* p1 = R.Parameter(t1, 1); |
| 670 | 670 |
| 671 for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) { | 671 for (size_t k = 0; k < arraysize(ops); k += 2) { |
| 672 Node* cmp = R.Binop(ops[k], p0, p1); | 672 Node* cmp = R.Binop(ops[k], p0, p1); |
| 673 Node* r = R.reduce(cmp); | 673 Node* r = R.reduce(cmp); |
| 674 | 674 |
| 675 R.CheckPureBinop(ops[k + 1], r); | 675 R.CheckPureBinop(ops[k + 1], r); |
| 676 if (k >= 4) { | 676 if (k >= 4) { |
| 677 // GreaterThan and GreaterThanOrEqual commute the inputs | 677 // GreaterThan and GreaterThanOrEqual commute the inputs |
| 678 // and use the LessThan and LessThanOrEqual operators. | 678 // and use the LessThan and LessThanOrEqual operators. |
| 679 CheckIsConvertedToNumber(p1, r->InputAt(0)); | 679 CheckIsConvertedToNumber(p1, r->InputAt(0)); |
| 680 CheckIsConvertedToNumber(p0, r->InputAt(1)); | 680 CheckIsConvertedToNumber(p0, r->InputAt(1)); |
| 681 } else { | 681 } else { |
| 682 CheckIsConvertedToNumber(p0, r->InputAt(0)); | 682 CheckIsConvertedToNumber(p0, r->InputAt(0)); |
| 683 CheckIsConvertedToNumber(p1, r->InputAt(1)); | 683 CheckIsConvertedToNumber(p1, r->InputAt(1)); |
| 684 } | 684 } |
| 685 } | 685 } |
| 686 } | 686 } |
| 687 } | 687 } |
| 688 } | 688 } |
| 689 | 689 |
| 690 | 690 |
| 691 TEST(MixedComparison1) { | 691 TEST(MixedComparison1) { |
| 692 JSTypedLoweringTester R; | 692 JSTypedLoweringTester R; |
| 693 | 693 |
| 694 Type* types[] = {Type::Number(), Type::String(), | 694 Type* types[] = {Type::Number(), Type::String(), |
| 695 Type::Union(Type::Number(), Type::String(), R.main_zone())}; | 695 Type::Union(Type::Number(), Type::String(), R.main_zone())}; |
| 696 | 696 |
| 697 for (size_t i = 0; i < ARRAY_SIZE(types); i++) { | 697 for (size_t i = 0; i < arraysize(types); i++) { |
| 698 Node* p0 = R.Parameter(types[i], 0); | 698 Node* p0 = R.Parameter(types[i], 0); |
| 699 | 699 |
| 700 for (size_t j = 0; j < ARRAY_SIZE(types); j++) { | 700 for (size_t j = 0; j < arraysize(types); j++) { |
| 701 Node* p1 = R.Parameter(types[j], 1); | 701 Node* p1 = R.Parameter(types[j], 1); |
| 702 { | 702 { |
| 703 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); | 703 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); |
| 704 Node* r = R.reduce(cmp); | 704 Node* r = R.reduce(cmp); |
| 705 | 705 |
| 706 if (!types[i]->Maybe(Type::String()) || | 706 if (!types[i]->Maybe(Type::String()) || |
| 707 !types[j]->Maybe(Type::String())) { | 707 !types[j]->Maybe(Type::String())) { |
| 708 if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) { | 708 if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) { |
| 709 R.CheckPureBinop(R.simplified.StringLessThan(), r); | 709 R.CheckPureBinop(R.simplified.StringLessThan(), r); |
| 710 } else { | 710 } else { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 R.CheckEffectInput(R.start(), i0); | 747 R.CheckEffectInput(R.start(), i0); |
| 748 R.CheckEffectInput(i0, i1); | 748 R.CheckEffectInput(i0, i1); |
| 749 R.CheckEffectInput(i1, effect_use); | 749 R.CheckEffectInput(i1, effect_use); |
| 750 } | 750 } |
| 751 | 751 |
| 752 | 752 |
| 753 TEST(UnaryNot) { | 753 TEST(UnaryNot) { |
| 754 JSTypedLoweringTester R; | 754 JSTypedLoweringTester R; |
| 755 Operator* opnot = R.javascript.UnaryNot(); | 755 Operator* opnot = R.javascript.UnaryNot(); |
| 756 | 756 |
| 757 for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) { | 757 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
| 758 Node* r = R.ReduceUnop(opnot, kJSTypes[i]); | 758 Node* r = R.ReduceUnop(opnot, kJSTypes[i]); |
| 759 // TODO(titzer): test will break if/when js-typed-lowering constant folds. | 759 // TODO(titzer): test will break if/when js-typed-lowering constant folds. |
| 760 CHECK_EQ(IrOpcode::kBooleanNot, r->opcode()); | 760 CHECK_EQ(IrOpcode::kBooleanNot, r->opcode()); |
| 761 } | 761 } |
| 762 } | 762 } |
| 763 | 763 |
| 764 | 764 |
| 765 TEST(RemoveToNumberEffects) { | 765 TEST(RemoveToNumberEffects) { |
| 766 JSTypedLoweringTester R; | 766 JSTypedLoweringTester R; |
| 767 | 767 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 | 901 |
| 902 | 902 |
| 903 TEST(EqualityForNumbers) { | 903 TEST(EqualityForNumbers) { |
| 904 JSTypedLoweringTester R; | 904 JSTypedLoweringTester R; |
| 905 | 905 |
| 906 Type* simple_number_types[] = {Type::UnsignedSmall(), Type::SignedSmall(), | 906 Type* simple_number_types[] = {Type::UnsignedSmall(), Type::SignedSmall(), |
| 907 Type::Signed32(), Type::Unsigned32(), | 907 Type::Signed32(), Type::Unsigned32(), |
| 908 Type::Number()}; | 908 Type::Number()}; |
| 909 | 909 |
| 910 | 910 |
| 911 for (size_t i = 0; i < ARRAY_SIZE(simple_number_types); ++i) { | 911 for (size_t i = 0; i < arraysize(simple_number_types); ++i) { |
| 912 Node* p0 = R.Parameter(simple_number_types[i], 0); | 912 Node* p0 = R.Parameter(simple_number_types[i], 0); |
| 913 | 913 |
| 914 for (size_t j = 0; j < ARRAY_SIZE(simple_number_types); ++j) { | 914 for (size_t j = 0; j < arraysize(simple_number_types); ++j) { |
| 915 Node* p1 = R.Parameter(simple_number_types[j], 1); | 915 Node* p1 = R.Parameter(simple_number_types[j], 1); |
| 916 | 916 |
| 917 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kNumberEqual); | 917 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kNumberEqual); |
| 918 CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kNumberEqual); | 918 CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kNumberEqual); |
| 919 } | 919 } |
| 920 } | 920 } |
| 921 } | 921 } |
| 922 | 922 |
| 923 | 923 |
| 924 TEST(StrictEqualityForRefEqualTypes) { | 924 TEST(StrictEqualityForRefEqualTypes) { |
| 925 JSTypedLoweringTester R; | 925 JSTypedLoweringTester R; |
| 926 | 926 |
| 927 Type* types[] = {Type::Undefined(), Type::Null(), Type::Boolean(), | 927 Type* types[] = {Type::Undefined(), Type::Null(), Type::Boolean(), |
| 928 Type::Object(), Type::Receiver()}; | 928 Type::Object(), Type::Receiver()}; |
| 929 | 929 |
| 930 Node* p0 = R.Parameter(Type::Any()); | 930 Node* p0 = R.Parameter(Type::Any()); |
| 931 for (size_t i = 0; i < ARRAY_SIZE(types); i++) { | 931 for (size_t i = 0; i < arraysize(types); i++) { |
| 932 Node* p1 = R.Parameter(types[i]); | 932 Node* p1 = R.Parameter(types[i]); |
| 933 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual); | 933 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual); |
| 934 } | 934 } |
| 935 // TODO(titzer): Equal(RefEqualTypes) | 935 // TODO(titzer): Equal(RefEqualTypes) |
| 936 } | 936 } |
| 937 | 937 |
| 938 | 938 |
| 939 TEST(StringEquality) { | 939 TEST(StringEquality) { |
| 940 JSTypedLoweringTester R; | 940 JSTypedLoweringTester R; |
| 941 Node* p0 = R.Parameter(Type::String()); | 941 Node* p0 = R.Parameter(Type::String()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 953 R.javascript.Equal(), R.simplified.NumberEqual(), | 953 R.javascript.Equal(), R.simplified.NumberEqual(), |
| 954 R.javascript.Add(), R.simplified.NumberAdd(), | 954 R.javascript.Add(), R.simplified.NumberAdd(), |
| 955 R.javascript.Subtract(), R.simplified.NumberSubtract(), | 955 R.javascript.Subtract(), R.simplified.NumberSubtract(), |
| 956 R.javascript.Multiply(), R.simplified.NumberMultiply(), | 956 R.javascript.Multiply(), R.simplified.NumberMultiply(), |
| 957 R.javascript.Divide(), R.simplified.NumberDivide(), | 957 R.javascript.Divide(), R.simplified.NumberDivide(), |
| 958 R.javascript.Modulus(), R.simplified.NumberModulus(), | 958 R.javascript.Modulus(), R.simplified.NumberModulus(), |
| 959 R.javascript.LessThan(), R.simplified.NumberLessThan(), | 959 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
| 960 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 960 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 961 }; | 961 }; |
| 962 | 962 |
| 963 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 963 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 964 BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); | 964 BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); |
| 965 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 965 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
| 966 | 966 |
| 967 B.R.CheckPureBinop(B.result->opcode(), B.result); | 967 B.R.CheckPureBinop(B.result->opcode(), B.result); |
| 968 | 968 |
| 969 B.CheckNoOp(0); | 969 B.CheckNoOp(0); |
| 970 B.CheckNoOp(1); | 970 B.CheckNoOp(1); |
| 971 | 971 |
| 972 B.CheckEffectsRemoved(); | 972 B.CheckEffectsRemoved(); |
| 973 } | 973 } |
| 974 } | 974 } |
| 975 | 975 |
| 976 | 976 |
| 977 TEST(OrderNumberBinopEffects1) { | 977 TEST(OrderNumberBinopEffects1) { |
| 978 JSTypedLoweringTester R; | 978 JSTypedLoweringTester R; |
| 979 | 979 |
| 980 Operator* ops[] = { | 980 Operator* ops[] = { |
| 981 R.javascript.Subtract(), R.simplified.NumberSubtract(), | 981 R.javascript.Subtract(), R.simplified.NumberSubtract(), |
| 982 R.javascript.Multiply(), R.simplified.NumberMultiply(), | 982 R.javascript.Multiply(), R.simplified.NumberMultiply(), |
| 983 R.javascript.Divide(), R.simplified.NumberDivide(), | 983 R.javascript.Divide(), R.simplified.NumberDivide(), |
| 984 R.javascript.Modulus(), R.simplified.NumberModulus(), | 984 R.javascript.Modulus(), R.simplified.NumberModulus(), |
| 985 }; | 985 }; |
| 986 | 986 |
| 987 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 987 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 988 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); | 988 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); |
| 989 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 989 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
| 990 | 990 |
| 991 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 991 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 992 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 992 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 993 | 993 |
| 994 CHECK_EQ(B.p0, i0->InputAt(0)); | 994 CHECK_EQ(B.p0, i0->InputAt(0)); |
| 995 CHECK_EQ(B.p1, i1->InputAt(0)); | 995 CHECK_EQ(B.p1, i1->InputAt(0)); |
| 996 | 996 |
| 997 // Effects should be ordered start -> i0 -> i1 -> effect_use | 997 // Effects should be ordered start -> i0 -> i1 -> effect_use |
| 998 B.CheckEffectOrdering(i0, i1); | 998 B.CheckEffectOrdering(i0, i1); |
| 999 } | 999 } |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 | 1002 |
| 1003 TEST(OrderNumberBinopEffects2) { | 1003 TEST(OrderNumberBinopEffects2) { |
| 1004 JSTypedLoweringTester R; | 1004 JSTypedLoweringTester R; |
| 1005 | 1005 |
| 1006 Operator* ops[] = { | 1006 Operator* ops[] = { |
| 1007 R.javascript.Add(), R.simplified.NumberAdd(), | 1007 R.javascript.Add(), R.simplified.NumberAdd(), |
| 1008 R.javascript.Subtract(), R.simplified.NumberSubtract(), | 1008 R.javascript.Subtract(), R.simplified.NumberSubtract(), |
| 1009 R.javascript.Multiply(), R.simplified.NumberMultiply(), | 1009 R.javascript.Multiply(), R.simplified.NumberMultiply(), |
| 1010 R.javascript.Divide(), R.simplified.NumberDivide(), | 1010 R.javascript.Divide(), R.simplified.NumberDivide(), |
| 1011 R.javascript.Modulus(), R.simplified.NumberModulus(), | 1011 R.javascript.Modulus(), R.simplified.NumberModulus(), |
| 1012 }; | 1012 }; |
| 1013 | 1013 |
| 1014 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 1014 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1015 BinopEffectsTester B(ops[j], Type::Number(), Type::Object()); | 1015 BinopEffectsTester B(ops[j], Type::Number(), Type::Object()); |
| 1016 | 1016 |
| 1017 Node* i0 = B.CheckNoOp(0); | 1017 Node* i0 = B.CheckNoOp(0); |
| 1018 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1018 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 1019 | 1019 |
| 1020 CHECK_EQ(B.p0, i0); | 1020 CHECK_EQ(B.p0, i0); |
| 1021 CHECK_EQ(B.p1, i1->InputAt(0)); | 1021 CHECK_EQ(B.p1, i1->InputAt(0)); |
| 1022 | 1022 |
| 1023 // Effects should be ordered start -> i1 -> effect_use | 1023 // Effects should be ordered start -> i1 -> effect_use |
| 1024 B.CheckEffectOrdering(i1); | 1024 B.CheckEffectOrdering(i1); |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 1027 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1028 BinopEffectsTester B(ops[j], Type::Object(), Type::Number()); | 1028 BinopEffectsTester B(ops[j], Type::Object(), Type::Number()); |
| 1029 | 1029 |
| 1030 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1030 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 1031 Node* i1 = B.CheckNoOp(1); | 1031 Node* i1 = B.CheckNoOp(1); |
| 1032 | 1032 |
| 1033 CHECK_EQ(B.p0, i0->InputAt(0)); | 1033 CHECK_EQ(B.p0, i0->InputAt(0)); |
| 1034 CHECK_EQ(B.p1, i1); | 1034 CHECK_EQ(B.p1, i1); |
| 1035 | 1035 |
| 1036 // Effects should be ordered start -> i0 -> effect_use | 1036 // Effects should be ordered start -> i0 -> effect_use |
| 1037 B.CheckEffectOrdering(i0); | 1037 B.CheckEffectOrdering(i0); |
| 1038 } | 1038 } |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 | 1041 |
| 1042 TEST(OrderCompareEffects) { | 1042 TEST(OrderCompareEffects) { |
| 1043 JSTypedLoweringTester R; | 1043 JSTypedLoweringTester R; |
| 1044 | 1044 |
| 1045 Operator* ops[] = { | 1045 Operator* ops[] = { |
| 1046 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 1046 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
| 1047 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 1047 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 1048 }; | 1048 }; |
| 1049 | 1049 |
| 1050 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 1050 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1051 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); | 1051 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); |
| 1052 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 1052 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
| 1053 | 1053 |
| 1054 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1054 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 1055 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1055 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 1056 | 1056 |
| 1057 // Inputs should be commuted. | 1057 // Inputs should be commuted. |
| 1058 CHECK_EQ(B.p1, i0->InputAt(0)); | 1058 CHECK_EQ(B.p1, i0->InputAt(0)); |
| 1059 CHECK_EQ(B.p0, i1->InputAt(0)); | 1059 CHECK_EQ(B.p0, i1->InputAt(0)); |
| 1060 | 1060 |
| 1061 // But effects should be ordered start -> i1 -> i0 -> effect_use | 1061 // But effects should be ordered start -> i1 -> i0 -> effect_use |
| 1062 B.CheckEffectOrdering(i1, i0); | 1062 B.CheckEffectOrdering(i1, i0); |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 1065 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1066 BinopEffectsTester B(ops[j], Type::Number(), Type::Object()); | 1066 BinopEffectsTester B(ops[j], Type::Number(), Type::Object()); |
| 1067 | 1067 |
| 1068 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1068 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 1069 Node* i1 = B.result->InputAt(1); | 1069 Node* i1 = B.result->InputAt(1); |
| 1070 | 1070 |
| 1071 CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted. | 1071 CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted. |
| 1072 CHECK_EQ(B.p0, i1); | 1072 CHECK_EQ(B.p0, i1); |
| 1073 | 1073 |
| 1074 // Effects should be ordered start -> i1 -> effect_use | 1074 // Effects should be ordered start -> i1 -> effect_use |
| 1075 B.CheckEffectOrdering(i0); | 1075 B.CheckEffectOrdering(i0); |
| 1076 } | 1076 } |
| 1077 | 1077 |
| 1078 for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) { | 1078 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1079 BinopEffectsTester B(ops[j], Type::Object(), Type::Number()); | 1079 BinopEffectsTester B(ops[j], Type::Object(), Type::Number()); |
| 1080 | 1080 |
| 1081 Node* i0 = B.result->InputAt(0); | 1081 Node* i0 = B.result->InputAt(0); |
| 1082 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1082 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 1083 | 1083 |
| 1084 CHECK_EQ(B.p1, i0); // Should be commuted. | 1084 CHECK_EQ(B.p1, i0); // Should be commuted. |
| 1085 CHECK_EQ(B.p0, i1->InputAt(0)); | 1085 CHECK_EQ(B.p0, i1->InputAt(0)); |
| 1086 | 1086 |
| 1087 // Effects should be ordered start -> i0 -> effect_use | 1087 // Effects should be ordered start -> i0 -> effect_use |
| 1088 B.CheckEffectOrdering(i1); | 1088 B.CheckEffectOrdering(i1); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 | 1170 |
| 1171 B.CheckEffectOrdering(ii0, ii1); | 1171 B.CheckEffectOrdering(ii0, ii1); |
| 1172 } | 1172 } |
| 1173 } | 1173 } |
| 1174 | 1174 |
| 1175 | 1175 |
| 1176 TEST(UnaryNotEffects) { | 1176 TEST(UnaryNotEffects) { |
| 1177 JSTypedLoweringTester R; | 1177 JSTypedLoweringTester R; |
| 1178 Operator* opnot = R.javascript.UnaryNot(); | 1178 Operator* opnot = R.javascript.UnaryNot(); |
| 1179 | 1179 |
| 1180 for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) { | 1180 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
| 1181 Node* p0 = R.Parameter(kJSTypes[i], 0); | 1181 Node* p0 = R.Parameter(kJSTypes[i], 0); |
| 1182 Node* orig = R.Unop(opnot, p0); | 1182 Node* orig = R.Unop(opnot, p0); |
| 1183 Node* effect_use = R.UseForEffect(orig); | 1183 Node* effect_use = R.UseForEffect(orig); |
| 1184 Node* value_use = R.graph.NewNode(R.common.Return(), orig); | 1184 Node* value_use = R.graph.NewNode(R.common.Return(), orig); |
| 1185 Node* r = R.reduce(orig); | 1185 Node* r = R.reduce(orig); |
| 1186 // TODO(titzer): test will break if/when js-typed-lowering constant folds. | 1186 // TODO(titzer): test will break if/when js-typed-lowering constant folds. |
| 1187 CHECK_EQ(IrOpcode::kBooleanNot, r->opcode()); | 1187 CHECK_EQ(IrOpcode::kBooleanNot, r->opcode()); |
| 1188 | 1188 |
| 1189 CHECK_EQ(r, value_use->InputAt(0)); | 1189 CHECK_EQ(r, value_use->InputAt(0)); |
| 1190 | 1190 |
| 1191 if (r->InputAt(0) == orig && orig->opcode() == IrOpcode::kJSToBoolean) { | 1191 if (r->InputAt(0) == orig && orig->opcode() == IrOpcode::kJSToBoolean) { |
| 1192 // The original node was turned into a ToBoolean, which has an effect. | 1192 // The original node was turned into a ToBoolean, which has an effect. |
| 1193 R.CheckEffectInput(R.start(), orig); | 1193 R.CheckEffectInput(R.start(), orig); |
| 1194 R.CheckEffectInput(orig, effect_use); | 1194 R.CheckEffectInput(orig, effect_use); |
| 1195 } else { | 1195 } else { |
| 1196 // effect should have been removed from this node. | 1196 // effect should have been removed from this node. |
| 1197 R.CheckEffectInput(R.start(), effect_use); | 1197 R.CheckEffectInput(R.start(), effect_use); |
| 1198 } | 1198 } |
| 1199 } | 1199 } |
| 1200 } | 1200 } |
| 1201 | 1201 |
| 1202 | 1202 |
| 1203 TEST(Int32AddNarrowing) { | 1203 TEST(Int32AddNarrowing) { |
| 1204 { | 1204 { |
| 1205 JSBitwiseTypedLoweringTester R; | 1205 JSBitwiseTypedLoweringTester R; |
| 1206 | 1206 |
| 1207 for (int o = 0; o < R.kNumberOps; o += 2) { | 1207 for (int o = 0; o < R.kNumberOps; o += 2) { |
| 1208 for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) { | 1208 for (size_t i = 0; i < arraysize(kInt32Types); i++) { |
| 1209 Node* n0 = R.Parameter(kInt32Types[i]); | 1209 Node* n0 = R.Parameter(kInt32Types[i]); |
| 1210 for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) { | 1210 for (size_t j = 0; j < arraysize(kInt32Types); j++) { |
| 1211 Node* n1 = R.Parameter(kInt32Types[j]); | 1211 Node* n1 = R.Parameter(kInt32Types[j]); |
| 1212 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); | 1212 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); |
| 1213 | 1213 |
| 1214 for (int l = 0; l < 2; l++) { | 1214 for (int l = 0; l < 2; l++) { |
| 1215 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); | 1215 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); |
| 1216 Node* or_node = | 1216 Node* or_node = |
| 1217 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); | 1217 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); |
| 1218 Node* r = R.reduce(or_node); | 1218 Node* r = R.reduce(or_node); |
| 1219 | 1219 |
| 1220 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); | 1220 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); |
| 1221 CHECK_EQ(IrOpcode::kInt32Add, add_node->opcode()); | 1221 CHECK_EQ(IrOpcode::kInt32Add, add_node->opcode()); |
| 1222 bool is_signed = l ? R.signedness[o] : R.signedness[o + 1]; | 1222 bool is_signed = l ? R.signedness[o] : R.signedness[o + 1]; |
| 1223 | 1223 |
| 1224 Type* add_type = NodeProperties::GetBounds(add_node).upper; | 1224 Type* add_type = NodeProperties::GetBounds(add_node).upper; |
| 1225 CHECK(add_type->Is(I32Type(is_signed))); | 1225 CHECK(add_type->Is(I32Type(is_signed))); |
| 1226 } | 1226 } |
| 1227 } | 1227 } |
| 1228 } | 1228 } |
| 1229 } | 1229 } |
| 1230 } | 1230 } |
| 1231 { | 1231 { |
| 1232 JSBitwiseShiftTypedLoweringTester R; | 1232 JSBitwiseShiftTypedLoweringTester R; |
| 1233 | 1233 |
| 1234 for (int o = 0; o < R.kNumberOps; o += 2) { | 1234 for (int o = 0; o < R.kNumberOps; o += 2) { |
| 1235 for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) { | 1235 for (size_t i = 0; i < arraysize(kInt32Types); i++) { |
| 1236 Node* n0 = R.Parameter(kInt32Types[i]); | 1236 Node* n0 = R.Parameter(kInt32Types[i]); |
| 1237 for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) { | 1237 for (size_t j = 0; j < arraysize(kInt32Types); j++) { |
| 1238 Node* n1 = R.Parameter(kInt32Types[j]); | 1238 Node* n1 = R.Parameter(kInt32Types[j]); |
| 1239 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); | 1239 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); |
| 1240 | 1240 |
| 1241 for (int l = 0; l < 2; l++) { | 1241 for (int l = 0; l < 2; l++) { |
| 1242 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); | 1242 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); |
| 1243 Node* or_node = | 1243 Node* or_node = |
| 1244 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); | 1244 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); |
| 1245 Node* r = R.reduce(or_node); | 1245 Node* r = R.reduce(or_node); |
| 1246 | 1246 |
| 1247 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); | 1247 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false}, | 1299 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false}, |
| 1300 {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(), | 1300 {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(), |
| 1301 R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 1301 R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 1302 false}, | 1302 false}, |
| 1303 {R.javascript.GreaterThan(), R.machine.Uint32LessThan(), | 1303 {R.javascript.GreaterThan(), R.machine.Uint32LessThan(), |
| 1304 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true}, | 1304 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true}, |
| 1305 {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(), | 1305 {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(), |
| 1306 R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 1306 R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 1307 true}}; | 1307 true}}; |
| 1308 | 1308 |
| 1309 for (size_t o = 0; o < ARRAY_SIZE(ops); o++) { | 1309 for (size_t o = 0; o < arraysize(ops); o++) { |
| 1310 for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) { | 1310 for (size_t i = 0; i < arraysize(kNumberTypes); i++) { |
| 1311 Type* t0 = kNumberTypes[i]; | 1311 Type* t0 = kNumberTypes[i]; |
| 1312 Node* p0 = R.Parameter(t0, 0); | 1312 Node* p0 = R.Parameter(t0, 0); |
| 1313 | 1313 |
| 1314 for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); j++) { | 1314 for (size_t j = 0; j < arraysize(kNumberTypes); j++) { |
| 1315 Type* t1 = kNumberTypes[j]; | 1315 Type* t1 = kNumberTypes[j]; |
| 1316 Node* p1 = R.Parameter(t1, 1); | 1316 Node* p1 = R.Parameter(t1, 1); |
| 1317 | 1317 |
| 1318 Node* cmp = R.Binop(ops[o].js_op, p0, p1); | 1318 Node* cmp = R.Binop(ops[o].js_op, p0, p1); |
| 1319 Node* r = R.reduce(cmp); | 1319 Node* r = R.reduce(cmp); |
| 1320 | 1320 |
| 1321 Operator* expected; | 1321 Operator* expected; |
| 1322 if (t0->Is(Type::Unsigned32()) && t1->Is(Type::Unsigned32())) { | 1322 if (t0->Is(Type::Unsigned32()) && t1->Is(Type::Unsigned32())) { |
| 1323 expected = ops[o].uint_op; | 1323 expected = ops[o].uint_op; |
| 1324 } else if (t0->Is(Type::Signed32()) && t1->Is(Type::Signed32())) { | 1324 } else if (t0->Is(Type::Signed32()) && t1->Is(Type::Signed32())) { |
| 1325 expected = ops[o].int_op; | 1325 expected = ops[o].int_op; |
| 1326 } else { | 1326 } else { |
| 1327 expected = ops[o].num_op; | 1327 expected = ops[o].num_op; |
| 1328 } | 1328 } |
| 1329 R.CheckPureBinop(expected, r); | 1329 R.CheckPureBinop(expected, r); |
| 1330 if (ops[o].commute) { | 1330 if (ops[o].commute) { |
| 1331 CHECK_EQ(p1, r->InputAt(0)); | 1331 CHECK_EQ(p1, r->InputAt(0)); |
| 1332 CHECK_EQ(p0, r->InputAt(1)); | 1332 CHECK_EQ(p0, r->InputAt(1)); |
| 1333 } else { | 1333 } else { |
| 1334 CHECK_EQ(p0, r->InputAt(0)); | 1334 CHECK_EQ(p0, r->InputAt(0)); |
| 1335 CHECK_EQ(p1, r->InputAt(1)); | 1335 CHECK_EQ(p1, r->InputAt(1)); |
| 1336 } | 1336 } |
| 1337 } | 1337 } |
| 1338 } | 1338 } |
| 1339 } | 1339 } |
| 1340 } | 1340 } |
| OLD | NEW |