| OLD | NEW |
| 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 <functional> | 5 #include <functional> |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
| 9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
| 10 #include "src/compiler/operator-properties.h" | 10 #include "src/compiler/operator-properties.h" |
| 11 #include "src/compiler/simplified-operator.h" | 11 #include "src/compiler/simplified-operator.h" |
| 12 #include "src/objects-inl.h" | 12 #include "src/objects-inl.h" |
| 13 #include "test/cctest/types-fuzz.h" | 13 #include "test/cctest/types-fuzz.h" |
| 14 #include "test/unittests/compiler/graph-unittest.h" | 14 #include "test/unittests/compiler/graph-unittest.h" |
| 15 | 15 |
| 16 namespace v8 { | 16 namespace v8 { |
| 17 namespace internal { | 17 namespace internal { |
| 18 namespace compiler { | 18 namespace compiler { |
| 19 | 19 |
| 20 // TODO(titzer): generate a large set of deterministic inputs for these tests. | 20 // TODO(titzer): generate a large set of deterministic inputs for these tests. |
| 21 class TyperTest : public TypedGraphTest { | 21 class TyperTest : public TypedGraphTest { |
| 22 public: | 22 public: |
| 23 TyperTest() | 23 TyperTest() |
| 24 : TypedGraphTest(3), | 24 : TypedGraphTest(3), |
| 25 operation_typer_(isolate(), zone()), |
| 25 types_(zone(), isolate(), random_number_generator()), | 26 types_(zone(), isolate(), random_number_generator()), |
| 26 javascript_(zone()), | 27 javascript_(zone()), |
| 27 simplified_(zone()) { | 28 simplified_(zone()) { |
| 28 context_node_ = graph()->NewNode(common()->Parameter(2), graph()->start()); | 29 context_node_ = graph()->NewNode(common()->Parameter(2), graph()->start()); |
| 29 rng_ = random_number_generator(); | 30 rng_ = random_number_generator(); |
| 30 | 31 |
| 31 integers.push_back(0); | 32 integers.push_back(0); |
| 32 integers.push_back(0); | 33 integers.push_back(0); |
| 33 integers.push_back(-1); | 34 integers.push_back(-1); |
| 34 integers.push_back(+1); | 35 integers.push_back(+1); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 45 int32s.push_back(0); | 46 int32s.push_back(0); |
| 46 int32s.push_back(-1); | 47 int32s.push_back(-1); |
| 47 int32s.push_back(+1); | 48 int32s.push_back(+1); |
| 48 int32s.push_back(kMinInt); | 49 int32s.push_back(kMinInt); |
| 49 int32s.push_back(kMaxInt); | 50 int32s.push_back(kMaxInt); |
| 50 for (int i = 0; i < 10; ++i) { | 51 for (int i = 0; i < 10; ++i) { |
| 51 int32s.push_back(rng_->NextInt()); | 52 int32s.push_back(rng_->NextInt()); |
| 52 } | 53 } |
| 53 } | 54 } |
| 54 | 55 |
| 56 const int kRepetitions = 50; |
| 57 |
| 58 OperationTyper operation_typer_; |
| 55 Types types_; | 59 Types types_; |
| 56 JSOperatorBuilder javascript_; | 60 JSOperatorBuilder javascript_; |
| 57 SimplifiedOperatorBuilder simplified_; | 61 SimplifiedOperatorBuilder simplified_; |
| 58 BinaryOperationHint const hints_ = BinaryOperationHint::kAny; | 62 BinaryOperationHint const hints_ = BinaryOperationHint::kAny; |
| 59 Node* context_node_; | 63 Node* context_node_; |
| 60 v8::base::RandomNumberGenerator* rng_; | 64 v8::base::RandomNumberGenerator* rng_; |
| 61 std::vector<double> integers; | 65 std::vector<double> integers; |
| 62 std::vector<double> int32s; | 66 std::vector<double> int32s; |
| 63 | 67 |
| 64 Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) { | 68 Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 if (IsMinusZero(result)) return 0; | 120 if (IsMinusZero(result)) return 0; |
| 117 if (std::isnan(result)) return rng_->NextInt(2) ? min : max; | 121 if (std::isnan(result)) return rng_->NextInt(2) ? min : max; |
| 118 DCHECK(min <= result && result <= max); | 122 DCHECK(min <= result && result <= max); |
| 119 return result; | 123 return result; |
| 120 } | 124 } |
| 121 | 125 |
| 122 double RandomInt(RangeType* range) { | 126 double RandomInt(RangeType* range) { |
| 123 return RandomInt(range->Min(), range->Max()); | 127 return RandomInt(range->Min(), range->Max()); |
| 124 } | 128 } |
| 125 | 129 |
| 130 Type* RandomSubtype(Type* type) { |
| 131 Type* subtype; |
| 132 do { |
| 133 subtype = types_.Fuzz(); |
| 134 } while (!subtype->Is(type)); |
| 135 return subtype; |
| 136 } |
| 137 |
| 126 // Careful, this function runs O(max_width^5) trials. | 138 // Careful, this function runs O(max_width^5) trials. |
| 127 template <class BinaryFunction> | 139 template <class BinaryFunction> |
| 128 void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun, | 140 void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun, |
| 129 int max_width) { | 141 int max_width) { |
| 130 const int min_min = -2 - max_width / 2; | 142 const int min_min = -2 - max_width / 2; |
| 131 const int max_min = 2 + max_width / 2; | 143 const int max_min = 2 + max_width / 2; |
| 132 for (int width = 0; width < max_width; width++) { | 144 for (int width = 0; width < max_width; width++) { |
| 133 for (int lmin = min_min; lmin <= max_min; lmin++) { | 145 for (int lmin = min_min; lmin <= max_min; lmin++) { |
| 134 for (int rmin = min_min; rmin <= max_min; rmin++) { | 146 for (int rmin = min_min; rmin <= max_min; rmin++) { |
| 135 Type* r1 = NewRange(lmin, lmin + width); | 147 Type* r1 = NewRange(lmin, lmin + width); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange())); | 218 int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange())); |
| 207 int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange())); | 219 int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange())); |
| 208 double result_value = opfun(x1, x2); | 220 double result_value = opfun(x1, x2); |
| 209 Type* result_type = Type::NewConstant( | 221 Type* result_type = Type::NewConstant( |
| 210 isolate()->factory()->NewNumber(result_value), zone()); | 222 isolate()->factory()->NewNumber(result_value), zone()); |
| 211 EXPECT_TRUE(result_type->Is(expected_type)); | 223 EXPECT_TRUE(result_type->Is(expected_type)); |
| 212 } | 224 } |
| 213 } | 225 } |
| 214 } | 226 } |
| 215 | 227 |
| 216 Type* RandomSubtype(Type* type) { | 228 typedef std::function<Type*(Type*)> UnaryTyper; |
| 217 Type* subtype; | 229 typedef std::function<Type*(Type*, Type*)> BinaryTyper; |
| 218 do { | 230 |
| 219 subtype = types_.Fuzz(); | 231 void TestUnaryMonotonicity(UnaryTyper typer, Type* upper1 = Type::Any()) { |
| 220 } while (!subtype->Is(type)); | 232 Type* type1 = Type::Intersect(types_.Fuzz(), upper1, zone()); |
| 221 return subtype; | 233 DCHECK(type1->Is(upper1)); |
| 234 Type* type = typer(type1); |
| 235 |
| 236 Type* subtype1 = RandomSubtype(type1); |
| 237 Type* subtype = typer(subtype1); |
| 238 |
| 239 EXPECT_TRUE(subtype->Is(type)); |
| 222 } | 240 } |
| 223 | 241 |
| 224 void TestBinaryMonotonicity(const Operator* op) { | 242 void TestBinaryMonotonicity(BinaryTyper typer, Type* upper1 = Type::Any(), |
| 225 for (int i = 0; i < 50; ++i) { | 243 Type* upper2 = Type::Any()) { |
| 226 Type* type1 = types_.Fuzz(); | 244 Type* type1 = Type::Intersect(types_.Fuzz(), upper1, zone()); |
| 227 Type* type2 = types_.Fuzz(); | 245 DCHECK(type1->Is(upper1)); |
| 228 Type* type = TypeBinaryOp(op, type1, type2); | 246 Type* type2 = Type::Intersect(types_.Fuzz(), upper2, zone()); |
| 229 Type* subtype1 = RandomSubtype(type1); | 247 DCHECK(type2->Is(upper2)); |
| 230 Type* subtype2 = RandomSubtype(type2); | 248 Type* type = typer(type1, type2); |
| 231 Type* subtype = TypeBinaryOp(op, subtype1, subtype2); | 249 |
| 232 EXPECT_TRUE(subtype->Is(type)); | 250 Type* subtype1 = RandomSubtype(type1); |
| 251 Type* subtype2 = RandomSubtype(type2); |
| 252 Type* subtype = typer(subtype1, subtype2); |
| 253 |
| 254 EXPECT_TRUE(subtype->Is(type)); |
| 255 } |
| 256 |
| 257 void TestBinaryMonotonicity(const Operator* op, Type* upper1 = Type::Any(), |
| 258 Type* upper2 = Type::Any()) { |
| 259 BinaryTyper typer = [&](Type* type1, Type* type2) { |
| 260 return TypeBinaryOp(op, type1, type2); |
| 261 }; |
| 262 for (int i = 0; i < kRepetitions; ++i) { |
| 263 TestBinaryMonotonicity(typer, upper1, upper2); |
| 233 } | 264 } |
| 234 } | 265 } |
| 235 }; | 266 }; |
| 236 | 267 |
| 237 | 268 |
| 238 namespace { | 269 namespace { |
| 239 | 270 |
| 240 int32_t shift_left(int32_t x, int32_t y) { return x << (y & 0x1f); } | 271 int32_t shift_left(int32_t x, int32_t y) { return x << (y & 0x1f); } |
| 241 int32_t shift_right(int32_t x, int32_t y) { return x >> (y & 0x1f); } | 272 int32_t shift_right(int32_t x, int32_t y) { return x >> (y & 0x1f); } |
| 242 int32_t bit_or(int32_t x, int32_t y) { return x | y; } | 273 int32_t bit_or(int32_t x, int32_t y) { return x | y; } |
| 243 int32_t bit_and(int32_t x, int32_t y) { return x & y; } | 274 int32_t bit_and(int32_t x, int32_t y) { return x & y; } |
| 244 int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; } | 275 int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; } |
| 245 | 276 |
| 246 } // namespace | 277 } // namespace |
| 247 | 278 |
| 248 | 279 |
| 249 //------------------------------------------------------------------------------ | 280 //------------------------------------------------------------------------------ |
| 250 // Soundness | 281 // Soundness |
| 251 // For simplicity, we currently only test soundness on expression operators | 282 // For simplicity, we currently only test soundness on expression operators |
| 252 // that have a direct equivalent in C++. Also, testing is currently limited | 283 // that have a direct equivalent in C++. Also, testing is currently limited |
| 253 // to ranges as input types. | 284 // to ranges as input types. |
| 254 | 285 |
| 255 | |
| 256 TEST_F(TyperTest, TypeJSAdd) { | 286 TEST_F(TyperTest, TypeJSAdd) { |
| 257 TestBinaryArithOp(javascript_.Add(hints_), std::plus<double>()); | 287 TestBinaryArithOp(javascript_.Add(hints_), std::plus<double>()); |
| 258 } | 288 } |
| 259 | 289 |
| 260 | |
| 261 TEST_F(TyperTest, TypeJSSubtract) { | 290 TEST_F(TyperTest, TypeJSSubtract) { |
| 262 TestBinaryArithOp(javascript_.Subtract(), std::minus<double>()); | 291 TestBinaryArithOp(javascript_.Subtract(), std::minus<double>()); |
| 263 } | 292 } |
| 264 | 293 |
| 265 | |
| 266 TEST_F(TyperTest, TypeJSMultiply) { | 294 TEST_F(TyperTest, TypeJSMultiply) { |
| 267 TestBinaryArithOp(javascript_.Multiply(), std::multiplies<double>()); | 295 TestBinaryArithOp(javascript_.Multiply(), std::multiplies<double>()); |
| 268 } | 296 } |
| 269 | 297 |
| 270 | |
| 271 TEST_F(TyperTest, TypeJSDivide) { | 298 TEST_F(TyperTest, TypeJSDivide) { |
| 272 TestBinaryArithOp(javascript_.Divide(), std::divides<double>()); | 299 TestBinaryArithOp(javascript_.Divide(), std::divides<double>()); |
| 273 } | 300 } |
| 274 | 301 |
| 275 | |
| 276 TEST_F(TyperTest, TypeJSModulus) { | 302 TEST_F(TyperTest, TypeJSModulus) { |
| 277 TestBinaryArithOp(javascript_.Modulus(), modulo); | 303 TestBinaryArithOp(javascript_.Modulus(), modulo); |
| 278 } | 304 } |
| 279 | 305 |
| 280 | |
| 281 TEST_F(TyperTest, TypeJSBitwiseOr) { | 306 TEST_F(TyperTest, TypeJSBitwiseOr) { |
| 282 TestBinaryBitOp(javascript_.BitwiseOr(), bit_or); | 307 TestBinaryBitOp(javascript_.BitwiseOr(), bit_or); |
| 283 } | 308 } |
| 284 | 309 |
| 285 | |
| 286 TEST_F(TyperTest, TypeJSBitwiseAnd) { | 310 TEST_F(TyperTest, TypeJSBitwiseAnd) { |
| 287 TestBinaryBitOp(javascript_.BitwiseAnd(), bit_and); | 311 TestBinaryBitOp(javascript_.BitwiseAnd(), bit_and); |
| 288 } | 312 } |
| 289 | 313 |
| 290 | |
| 291 TEST_F(TyperTest, TypeJSBitwiseXor) { | 314 TEST_F(TyperTest, TypeJSBitwiseXor) { |
| 292 TestBinaryBitOp(javascript_.BitwiseXor(), bit_xor); | 315 TestBinaryBitOp(javascript_.BitwiseXor(), bit_xor); |
| 293 } | 316 } |
| 294 | 317 |
| 295 | |
| 296 TEST_F(TyperTest, TypeJSShiftLeft) { | 318 TEST_F(TyperTest, TypeJSShiftLeft) { |
| 297 TestBinaryBitOp(javascript_.ShiftLeft(), shift_left); | 319 TestBinaryBitOp(javascript_.ShiftLeft(), shift_left); |
| 298 } | 320 } |
| 299 | 321 |
| 300 | |
| 301 TEST_F(TyperTest, TypeJSShiftRight) { | 322 TEST_F(TyperTest, TypeJSShiftRight) { |
| 302 TestBinaryBitOp(javascript_.ShiftRight(), shift_right); | 323 TestBinaryBitOp(javascript_.ShiftRight(), shift_right); |
| 303 } | 324 } |
| 304 | 325 |
| 305 | |
| 306 TEST_F(TyperTest, TypeJSLessThan) { | 326 TEST_F(TyperTest, TypeJSLessThan) { |
| 307 TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny), | 327 TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny), |
| 308 std::less<double>()); | 328 std::less<double>()); |
| 309 } | 329 } |
| 310 | 330 |
| 311 TEST_F(TyperTest, TypeNumberLessThan) { | 331 TEST_F(TyperTest, TypeNumberLessThan) { |
| 312 TestBinaryCompareOp(simplified_.NumberLessThan(), std::less<double>()); | 332 TestBinaryCompareOp(simplified_.NumberLessThan(), std::less<double>()); |
| 313 } | 333 } |
| 314 | 334 |
| 315 TEST_F(TyperTest, TypeSpeculativeNumberLessThan) { | 335 TEST_F(TyperTest, TypeSpeculativeNumberLessThan) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 339 std::greater<double>()); | 359 std::greater<double>()); |
| 340 } | 360 } |
| 341 | 361 |
| 342 | 362 |
| 343 TEST_F(TyperTest, TypeJSGreaterThanOrEqual) { | 363 TEST_F(TyperTest, TypeJSGreaterThanOrEqual) { |
| 344 TestBinaryCompareOp( | 364 TestBinaryCompareOp( |
| 345 javascript_.GreaterThanOrEqual(CompareOperationHint::kAny), | 365 javascript_.GreaterThanOrEqual(CompareOperationHint::kAny), |
| 346 std::greater_equal<double>()); | 366 std::greater_equal<double>()); |
| 347 } | 367 } |
| 348 | 368 |
| 349 | |
| 350 TEST_F(TyperTest, TypeJSEqual) { | 369 TEST_F(TyperTest, TypeJSEqual) { |
| 351 TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny), | 370 TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny), |
| 352 std::equal_to<double>()); | 371 std::equal_to<double>()); |
| 353 } | 372 } |
| 354 | 373 |
| 355 TEST_F(TyperTest, TypeNumberEqual) { | 374 TEST_F(TyperTest, TypeNumberEqual) { |
| 356 TestBinaryCompareOp(simplified_.NumberEqual(), std::equal_to<double>()); | 375 TestBinaryCompareOp(simplified_.NumberEqual(), std::equal_to<double>()); |
| 357 } | 376 } |
| 358 | 377 |
| 359 TEST_F(TyperTest, TypeSpeculativeNumberEqual) { | 378 TEST_F(TyperTest, TypeSpeculativeNumberEqual) { |
| 360 TestBinaryCompareOp( | 379 TestBinaryCompareOp( |
| 361 simplified_.SpeculativeNumberEqual(NumberOperationHint::kNumberOrOddball), | 380 simplified_.SpeculativeNumberEqual(NumberOperationHint::kNumberOrOddball), |
| 362 std::equal_to<double>()); | 381 std::equal_to<double>()); |
| 363 } | 382 } |
| 364 | 383 |
| 365 // For numbers there's no difference between strict and non-strict equality. | 384 // For numbers there's no difference between strict and non-strict equality. |
| 366 TEST_F(TyperTest, TypeJSStrictEqual) { | 385 TEST_F(TyperTest, TypeJSStrictEqual) { |
| 367 TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHint::kAny), | 386 TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHint::kAny), |
| 368 std::equal_to<double>()); | 387 std::equal_to<double>()); |
| 369 } | 388 } |
| 370 | 389 |
| 390 //------------------------------------------------------------------------------ |
| 391 // Typer Monotonicity |
| 371 | 392 |
| 372 //------------------------------------------------------------------------------ | 393 // JS BINOPs with CompareOperationHint |
| 373 // Monotonicity | 394 #define TEST_MONOTONICITY(name) \ |
| 374 | |
| 375 #define TEST_BINARY_MONOTONICITY(name) \ | |
| 376 TEST_F(TyperTest, Monotonicity_##name) { \ | 395 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 377 TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \ | 396 TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \ |
| 378 } | 397 } |
| 379 TEST_BINARY_MONOTONICITY(Equal) | 398 TEST_MONOTONICITY(Equal) |
| 380 TEST_BINARY_MONOTONICITY(StrictEqual) | 399 TEST_MONOTONICITY(StrictEqual) |
| 381 TEST_BINARY_MONOTONICITY(LessThan) | 400 TEST_MONOTONICITY(LessThan) |
| 382 TEST_BINARY_MONOTONICITY(GreaterThan) | 401 TEST_MONOTONICITY(GreaterThan) |
| 383 TEST_BINARY_MONOTONICITY(LessThanOrEqual) | 402 TEST_MONOTONICITY(LessThanOrEqual) |
| 384 TEST_BINARY_MONOTONICITY(GreaterThanOrEqual) | 403 TEST_MONOTONICITY(GreaterThanOrEqual) |
| 385 #undef TEST_BINARY_MONOTONICITY | 404 #undef TEST_MONOTONICITY |
| 386 | 405 |
| 387 #define TEST_BINARY_MONOTONICITY(name) \ | 406 // JS BINOPs with BinaryOperationHint |
| 407 #define TEST_MONOTONICITY(name) \ |
| 408 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 409 TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \ |
| 410 } |
| 411 TEST_MONOTONICITY(Add) |
| 412 #undef TEST_MONOTONICITY |
| 413 |
| 414 // JS BINOPS without hint |
| 415 #define TEST_MONOTONICITY(name) \ |
| 388 TEST_F(TyperTest, Monotonicity_##name) { \ | 416 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 389 TestBinaryMonotonicity(javascript_.name()); \ | 417 TestBinaryMonotonicity(javascript_.name()); \ |
| 390 } | 418 } |
| 391 TEST_BINARY_MONOTONICITY(BitwiseOr) | 419 TEST_MONOTONICITY(BitwiseOr) |
| 392 TEST_BINARY_MONOTONICITY(BitwiseXor) | 420 TEST_MONOTONICITY(BitwiseXor) |
| 393 TEST_BINARY_MONOTONICITY(BitwiseAnd) | 421 TEST_MONOTONICITY(BitwiseAnd) |
| 394 TEST_BINARY_MONOTONICITY(ShiftLeft) | 422 TEST_MONOTONICITY(ShiftLeft) |
| 395 TEST_BINARY_MONOTONICITY(ShiftRight) | 423 TEST_MONOTONICITY(ShiftRight) |
| 396 TEST_BINARY_MONOTONICITY(ShiftRightLogical) | 424 TEST_MONOTONICITY(ShiftRightLogical) |
| 397 TEST_BINARY_MONOTONICITY(Subtract) | 425 TEST_MONOTONICITY(Subtract) |
| 398 TEST_BINARY_MONOTONICITY(Multiply) | 426 TEST_MONOTONICITY(Multiply) |
| 399 TEST_BINARY_MONOTONICITY(Divide) | 427 TEST_MONOTONICITY(Divide) |
| 400 TEST_BINARY_MONOTONICITY(Modulus) | 428 TEST_MONOTONICITY(Modulus) |
| 401 #undef TEST_BINARY_MONOTONICITY | 429 #undef TEST_MONOTONICITY |
| 402 | 430 |
| 403 #define TEST_BINARY_MONOTONICITY(name) \ | 431 // SIMPLIFIED BINOPs without hint, with Number input restriction |
| 404 TEST_F(TyperTest, Monotonicity_##name) { \ | 432 #define TEST_MONOTONICITY(name) \ |
| 405 TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \ | 433 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 434 TestBinaryMonotonicity(simplified_.name(), Type::Number(), \ |
| 435 Type::Number()); \ |
| 406 } | 436 } |
| 407 TEST_BINARY_MONOTONICITY(Add) | 437 SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY); |
| 408 #undef TEST_BINARY_MONOTONICITY | 438 #undef TEST_MONOTONICITY |
| 439 |
| 440 // SIMPLIFIED BINOPs without hint, without input restriction |
| 441 #define TEST_MONOTONICITY(name) \ |
| 442 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 443 TestBinaryMonotonicity(simplified_.name()); \ |
| 444 } |
| 445 TEST_MONOTONICITY(NumberLessThan) |
| 446 TEST_MONOTONICITY(NumberLessThanOrEqual) |
| 447 TEST_MONOTONICITY(NumberEqual) |
| 448 #undef TEST_MONOTONICITY |
| 449 |
| 450 // SIMPLIFIED BINOPs with NumberOperationHint, without input restriction |
| 451 #define TEST_MONOTONICITY(name) \ |
| 452 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 453 TestBinaryMonotonicity(simplified_.name(NumberOperationHint::kNumber)); \ |
| 454 } |
| 455 TEST_MONOTONICITY(SpeculativeNumberEqual) |
| 456 TEST_MONOTONICITY(SpeculativeNumberLessThan) |
| 457 TEST_MONOTONICITY(SpeculativeNumberLessThanOrEqual) |
| 458 #undef TEST_MONOTONICITY |
| 459 |
| 460 // SIMPLIFIED BINOPs with NumberOperationHint, without input restriction |
| 461 #define TEST_MONOTONICITY(name) \ |
| 462 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 463 TestBinaryMonotonicity(simplified_.name(NumberOperationHint::kNumber)); \ |
| 464 } |
| 465 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY) |
| 466 #undef TEST_MONOTONICITY |
| 467 |
| 468 //------------------------------------------------------------------------------ |
| 469 // OperationTyper Monotonicity |
| 470 |
| 471 // SIMPLIFIED UNOPs with Number input restriction |
| 472 #define TEST_MONOTONICITY(name) \ |
| 473 TEST_F(TyperTest, Monotonicity_Operation_##name) { \ |
| 474 UnaryTyper typer = [&](Type* type1) { \ |
| 475 return operation_typer_.name(type1); \ |
| 476 }; \ |
| 477 for (int i = 0; i < kRepetitions; ++i) { \ |
| 478 TestUnaryMonotonicity(typer, Type::Number()); \ |
| 479 } \ |
| 480 } |
| 481 SIMPLIFIED_NUMBER_UNOP_LIST(TEST_MONOTONICITY) |
| 482 #undef TEST_MONOTONICITY |
| 483 |
| 484 // SIMPLIFIED BINOPs with Number input restriction |
| 485 #define TEST_MONOTONICITY(name) \ |
| 486 TEST_F(TyperTest, Monotonicity_Operation_##name) { \ |
| 487 BinaryTyper typer = [&](Type* type1, Type* type2) { \ |
| 488 return operation_typer_.name(type1, type2); \ |
| 489 }; \ |
| 490 for (int i = 0; i < kRepetitions; ++i) { \ |
| 491 TestBinaryMonotonicity(typer, Type::Number(), Type::Number()); \ |
| 492 } \ |
| 493 } |
| 494 SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY) |
| 495 #undef TEST_MONOTONICITY |
| 496 |
| 497 // SIMPLIFIED BINOPs without input restriction |
| 498 #define TEST_MONOTONICITY(name) \ |
| 499 TEST_F(TyperTest, Monotonicity_Operation_##name) { \ |
| 500 BinaryTyper typer = [&](Type* type1, Type* type2) { \ |
| 501 return operation_typer_.name(type1, type2); \ |
| 502 }; \ |
| 503 for (int i = 0; i < kRepetitions; ++i) { \ |
| 504 TestBinaryMonotonicity(typer); \ |
| 505 } \ |
| 506 } |
| 507 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY) |
| 508 #undef TEST_MONOTONICITY |
| 409 | 509 |
| 410 } // namespace compiler | 510 } // namespace compiler |
| 411 } // namespace internal | 511 } // namespace internal |
| 412 } // namespace v8 | 512 } // namespace v8 |
| OLD | NEW |