Commit 877d9758 authored by neis's avatar neis Committed by Commit bot

[compiler] Add more tests for monotonicity of typing.

R=jarin@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2753543009
Cr-Commit-Position: refs/heads/master@{#43885}
parent 86fa01c7
...@@ -23,7 +23,7 @@ class Operator; ...@@ -23,7 +23,7 @@ class Operator;
class Type; class Type;
class TypeCache; class TypeCache;
class OperationTyper { class V8_EXPORT_PRIVATE OperationTyper {
public: public:
OperationTyper(Isolate* isolate, Zone* zone); OperationTyper(Isolate* isolate, Zone* zone);
......
...@@ -22,6 +22,7 @@ class TyperTest : public TypedGraphTest { ...@@ -22,6 +22,7 @@ class TyperTest : public TypedGraphTest {
public: public:
TyperTest() TyperTest()
: TypedGraphTest(3), : TypedGraphTest(3),
operation_typer_(isolate(), zone()),
types_(zone(), isolate(), random_number_generator()), types_(zone(), isolate(), random_number_generator()),
javascript_(zone()), javascript_(zone()),
simplified_(zone()) { simplified_(zone()) {
...@@ -52,6 +53,9 @@ class TyperTest : public TypedGraphTest { ...@@ -52,6 +53,9 @@ class TyperTest : public TypedGraphTest {
} }
} }
const int kRepetitions = 50;
OperationTyper operation_typer_;
Types types_; Types types_;
JSOperatorBuilder javascript_; JSOperatorBuilder javascript_;
SimplifiedOperatorBuilder simplified_; SimplifiedOperatorBuilder simplified_;
...@@ -123,6 +127,14 @@ class TyperTest : public TypedGraphTest { ...@@ -123,6 +127,14 @@ class TyperTest : public TypedGraphTest {
return RandomInt(range->Min(), range->Max()); return RandomInt(range->Min(), range->Max());
} }
Type* RandomSubtype(Type* type) {
Type* subtype;
do {
subtype = types_.Fuzz();
} while (!subtype->Is(type));
return subtype;
}
// Careful, this function runs O(max_width^5) trials. // Careful, this function runs O(max_width^5) trials.
template <class BinaryFunction> template <class BinaryFunction>
void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun, void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun,
...@@ -213,24 +225,43 @@ class TyperTest : public TypedGraphTest { ...@@ -213,24 +225,43 @@ class TyperTest : public TypedGraphTest {
} }
} }
Type* RandomSubtype(Type* type) { typedef std::function<Type*(Type*)> UnaryTyper;
Type* subtype; typedef std::function<Type*(Type*, Type*)> BinaryTyper;
do {
subtype = types_.Fuzz(); void TestUnaryMonotonicity(UnaryTyper typer, Type* upper1 = Type::Any()) {
} while (!subtype->Is(type)); Type* type1 = Type::Intersect(types_.Fuzz(), upper1, zone());
return subtype; DCHECK(type1->Is(upper1));
Type* type = typer(type1);
Type* subtype1 = RandomSubtype(type1);
Type* subtype = typer(subtype1);
EXPECT_TRUE(subtype->Is(type));
} }
void TestBinaryMonotonicity(const Operator* op) { void TestBinaryMonotonicity(BinaryTyper typer, Type* upper1 = Type::Any(),
for (int i = 0; i < 50; ++i) { Type* upper2 = Type::Any()) {
Type* type1 = types_.Fuzz(); Type* type1 = Type::Intersect(types_.Fuzz(), upper1, zone());
Type* type2 = types_.Fuzz(); DCHECK(type1->Is(upper1));
Type* type = TypeBinaryOp(op, type1, type2); Type* type2 = Type::Intersect(types_.Fuzz(), upper2, zone());
DCHECK(type2->Is(upper2));
Type* type = typer(type1, type2);
Type* subtype1 = RandomSubtype(type1); Type* subtype1 = RandomSubtype(type1);
Type* subtype2 = RandomSubtype(type2); Type* subtype2 = RandomSubtype(type2);
Type* subtype = TypeBinaryOp(op, subtype1, subtype2); Type* subtype = typer(subtype1, subtype2);
EXPECT_TRUE(subtype->Is(type)); EXPECT_TRUE(subtype->Is(type));
} }
void TestBinaryMonotonicity(const Operator* op, Type* upper1 = Type::Any(),
Type* upper2 = Type::Any()) {
BinaryTyper typer = [&](Type* type1, Type* type2) {
return TypeBinaryOp(op, type1, type2);
};
for (int i = 0; i < kRepetitions; ++i) {
TestBinaryMonotonicity(typer, upper1, upper2);
}
} }
}; };
...@@ -252,57 +283,46 @@ int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; } ...@@ -252,57 +283,46 @@ int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; }
// that have a direct equivalent in C++. Also, testing is currently limited // that have a direct equivalent in C++. Also, testing is currently limited
// to ranges as input types. // to ranges as input types.
TEST_F(TyperTest, TypeJSAdd) { TEST_F(TyperTest, TypeJSAdd) {
TestBinaryArithOp(javascript_.Add(hints_), std::plus<double>()); TestBinaryArithOp(javascript_.Add(hints_), std::plus<double>());
} }
TEST_F(TyperTest, TypeJSSubtract) { TEST_F(TyperTest, TypeJSSubtract) {
TestBinaryArithOp(javascript_.Subtract(), std::minus<double>()); TestBinaryArithOp(javascript_.Subtract(), std::minus<double>());
} }
TEST_F(TyperTest, TypeJSMultiply) { TEST_F(TyperTest, TypeJSMultiply) {
TestBinaryArithOp(javascript_.Multiply(), std::multiplies<double>()); TestBinaryArithOp(javascript_.Multiply(), std::multiplies<double>());
} }
TEST_F(TyperTest, TypeJSDivide) { TEST_F(TyperTest, TypeJSDivide) {
TestBinaryArithOp(javascript_.Divide(), std::divides<double>()); TestBinaryArithOp(javascript_.Divide(), std::divides<double>());
} }
TEST_F(TyperTest, TypeJSModulus) { TEST_F(TyperTest, TypeJSModulus) {
TestBinaryArithOp(javascript_.Modulus(), modulo); TestBinaryArithOp(javascript_.Modulus(), modulo);
} }
TEST_F(TyperTest, TypeJSBitwiseOr) { TEST_F(TyperTest, TypeJSBitwiseOr) {
TestBinaryBitOp(javascript_.BitwiseOr(), bit_or); TestBinaryBitOp(javascript_.BitwiseOr(), bit_or);
} }
TEST_F(TyperTest, TypeJSBitwiseAnd) { TEST_F(TyperTest, TypeJSBitwiseAnd) {
TestBinaryBitOp(javascript_.BitwiseAnd(), bit_and); TestBinaryBitOp(javascript_.BitwiseAnd(), bit_and);
} }
TEST_F(TyperTest, TypeJSBitwiseXor) { TEST_F(TyperTest, TypeJSBitwiseXor) {
TestBinaryBitOp(javascript_.BitwiseXor(), bit_xor); TestBinaryBitOp(javascript_.BitwiseXor(), bit_xor);
} }
TEST_F(TyperTest, TypeJSShiftLeft) { TEST_F(TyperTest, TypeJSShiftLeft) {
TestBinaryBitOp(javascript_.ShiftLeft(), shift_left); TestBinaryBitOp(javascript_.ShiftLeft(), shift_left);
} }
TEST_F(TyperTest, TypeJSShiftRight) { TEST_F(TyperTest, TypeJSShiftRight) {
TestBinaryBitOp(javascript_.ShiftRight(), shift_right); TestBinaryBitOp(javascript_.ShiftRight(), shift_right);
} }
TEST_F(TyperTest, TypeJSLessThan) { TEST_F(TyperTest, TypeJSLessThan) {
TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny), TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny),
std::less<double>()); std::less<double>());
...@@ -346,7 +366,6 @@ TEST_F(TyperTest, TypeJSGreaterThanOrEqual) { ...@@ -346,7 +366,6 @@ TEST_F(TyperTest, TypeJSGreaterThanOrEqual) {
std::greater_equal<double>()); std::greater_equal<double>());
} }
TEST_F(TyperTest, TypeJSEqual) { TEST_F(TyperTest, TypeJSEqual) {
TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny), TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny),
std::equal_to<double>()); std::equal_to<double>());
...@@ -368,44 +387,125 @@ TEST_F(TyperTest, TypeJSStrictEqual) { ...@@ -368,44 +387,125 @@ TEST_F(TyperTest, TypeJSStrictEqual) {
std::equal_to<double>()); std::equal_to<double>());
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Monotonicity // Typer Monotonicity
#define TEST_BINARY_MONOTONICITY(name) \ // JS BINOPs with CompareOperationHint
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \ TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \ TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \
} }
TEST_BINARY_MONOTONICITY(Equal) TEST_MONOTONICITY(Equal)
TEST_BINARY_MONOTONICITY(StrictEqual) TEST_MONOTONICITY(StrictEqual)
TEST_BINARY_MONOTONICITY(LessThan) TEST_MONOTONICITY(LessThan)
TEST_BINARY_MONOTONICITY(GreaterThan) TEST_MONOTONICITY(GreaterThan)
TEST_BINARY_MONOTONICITY(LessThanOrEqual) TEST_MONOTONICITY(LessThanOrEqual)
TEST_BINARY_MONOTONICITY(GreaterThanOrEqual) TEST_MONOTONICITY(GreaterThanOrEqual)
#undef TEST_BINARY_MONOTONICITY #undef TEST_MONOTONICITY
// JS BINOPs with BinaryOperationHint
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \
}
TEST_MONOTONICITY(Add)
#undef TEST_MONOTONICITY
#define TEST_BINARY_MONOTONICITY(name) \ // JS BINOPS without hint
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \ TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(javascript_.name()); \ TestBinaryMonotonicity(javascript_.name()); \
} }
TEST_BINARY_MONOTONICITY(BitwiseOr) TEST_MONOTONICITY(BitwiseOr)
TEST_BINARY_MONOTONICITY(BitwiseXor) TEST_MONOTONICITY(BitwiseXor)
TEST_BINARY_MONOTONICITY(BitwiseAnd) TEST_MONOTONICITY(BitwiseAnd)
TEST_BINARY_MONOTONICITY(ShiftLeft) TEST_MONOTONICITY(ShiftLeft)
TEST_BINARY_MONOTONICITY(ShiftRight) TEST_MONOTONICITY(ShiftRight)
TEST_BINARY_MONOTONICITY(ShiftRightLogical) TEST_MONOTONICITY(ShiftRightLogical)
TEST_BINARY_MONOTONICITY(Subtract) TEST_MONOTONICITY(Subtract)
TEST_BINARY_MONOTONICITY(Multiply) TEST_MONOTONICITY(Multiply)
TEST_BINARY_MONOTONICITY(Divide) TEST_MONOTONICITY(Divide)
TEST_BINARY_MONOTONICITY(Modulus) TEST_MONOTONICITY(Modulus)
#undef TEST_BINARY_MONOTONICITY #undef TEST_MONOTONICITY
#define TEST_BINARY_MONOTONICITY(name) \ // SIMPLIFIED BINOPs without hint, with Number input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \ TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \ TestBinaryMonotonicity(simplified_.name(), Type::Number(), \
Type::Number()); \
} }
TEST_BINARY_MONOTONICITY(Add) SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY);
#undef TEST_BINARY_MONOTONICITY #undef TEST_MONOTONICITY
// SIMPLIFIED BINOPs without hint, without input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(simplified_.name()); \
}
TEST_MONOTONICITY(NumberLessThan)
TEST_MONOTONICITY(NumberLessThanOrEqual)
TEST_MONOTONICITY(NumberEqual)
#undef TEST_MONOTONICITY
// SIMPLIFIED BINOPs with NumberOperationHint, without input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(simplified_.name(NumberOperationHint::kNumber)); \
}
TEST_MONOTONICITY(SpeculativeNumberEqual)
TEST_MONOTONICITY(SpeculativeNumberLessThan)
TEST_MONOTONICITY(SpeculativeNumberLessThanOrEqual)
#undef TEST_MONOTONICITY
// SIMPLIFIED BINOPs with NumberOperationHint, without input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(simplified_.name(NumberOperationHint::kNumber)); \
}
SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY)
#undef TEST_MONOTONICITY
//------------------------------------------------------------------------------
// OperationTyper Monotonicity
// SIMPLIFIED UNOPs with Number input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_Operation_##name) { \
UnaryTyper typer = [&](Type* type1) { \
return operation_typer_.name(type1); \
}; \
for (int i = 0; i < kRepetitions; ++i) { \
TestUnaryMonotonicity(typer, Type::Number()); \
} \
}
SIMPLIFIED_NUMBER_UNOP_LIST(TEST_MONOTONICITY)
#undef TEST_MONOTONICITY
// SIMPLIFIED BINOPs with Number input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_Operation_##name) { \
BinaryTyper typer = [&](Type* type1, Type* type2) { \
return operation_typer_.name(type1, type2); \
}; \
for (int i = 0; i < kRepetitions; ++i) { \
TestBinaryMonotonicity(typer, Type::Number(), Type::Number()); \
} \
}
SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY)
#undef TEST_MONOTONICITY
// SIMPLIFIED BINOPs without input restriction
#define TEST_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_Operation_##name) { \
BinaryTyper typer = [&](Type* type1, Type* type2) { \
return operation_typer_.name(type1, type2); \
}; \
for (int i = 0; i < kRepetitions; ++i) { \
TestBinaryMonotonicity(typer); \
} \
}
SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY)
#undef TEST_MONOTONICITY
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment