Commit a12aa891 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Simplify BinaryOperationHints and CompareOperationHints.

Remove the useless information from the BinaryOperationHints and
CompareOperationHints, and cache the JS operators appropriately.

R=epertoso@chromium.org

Review-Url: https://codereview.chromium.org/2228983002
Cr-Commit-Position: refs/heads/master@{#38506}
parent 2028c093
...@@ -282,8 +282,7 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { ...@@ -282,8 +282,7 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
} }
Node* NewPathDispatchCondition(Node* t1, Node* t2) { Node* NewPathDispatchCondition(Node* t1, Node* t2) {
return owner_->NewNode( return owner_->NewNode(
owner_->javascript()->StrictEqual(CompareOperationHints::Any()), t1, owner_->javascript()->StrictEqual(CompareOperationHint::kAny), t1, t2);
t2);
} }
private: private:
...@@ -1274,14 +1273,14 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -1274,14 +1273,14 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
Node* label = environment()->Pop(); Node* label = environment()->Pop();
Node* tag = environment()->Top(); Node* tag = environment()->Top();
CompareOperationHints hints; CompareOperationHint hint;
if (!type_hint_analysis_ || if (!type_hint_analysis_ ||
!type_hint_analysis_->GetCompareOperationHints(clause->CompareId(), !type_hint_analysis_->GetCompareOperationHint(clause->CompareId(),
&hints)) { &hint)) {
hints = CompareOperationHints::Any(); hint = CompareOperationHint::kAny;
} }
const Operator* op = javascript()->StrictEqual(hints); const Operator* op = javascript()->StrictEqual(hint);
Node* condition = NewNode(op, tag, label); Node* condition = NewNode(op, tag, label);
compare_switch.BeginLabel(i, condition); compare_switch.BeginLabel(i, condition);
...@@ -1357,11 +1356,11 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { ...@@ -1357,11 +1356,11 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
for_block.BeginBlock(); for_block.BeginBlock();
// Check for null or undefined before entering loop. // Check for null or undefined before entering loop.
Node* is_null_cond = Node* is_null_cond =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object, NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object,
jsgraph()->NullConstant()); jsgraph()->NullConstant());
for_block.BreakWhen(is_null_cond, BranchHint::kFalse); for_block.BreakWhen(is_null_cond, BranchHint::kFalse);
Node* is_undefined_cond = Node* is_undefined_cond =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object, NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object,
jsgraph()->UndefinedConstant()); jsgraph()->UndefinedConstant());
for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse); for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse);
{ {
...@@ -1406,8 +1405,8 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { ...@@ -1406,8 +1405,8 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
OutputFrameStateCombine::Push()); OutputFrameStateCombine::Push());
IfBuilder test_value(this); IfBuilder test_value(this);
Node* test_value_cond = Node* test_value_cond =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), value,
value, jsgraph()->UndefinedConstant()); jsgraph()->UndefinedConstant());
test_value.If(test_value_cond, BranchHint::kFalse); test_value.If(test_value_cond, BranchHint::kFalse);
test_value.Then(); test_value.Then();
test_value.Else(); test_value.Else();
...@@ -2756,10 +2755,10 @@ void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, ...@@ -2756,10 +2755,10 @@ void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr,
const Operator* op = nullptr; const Operator* op = nullptr;
switch (expr->op()) { switch (expr->op()) {
case Token::EQ: case Token::EQ:
op = javascript()->Equal(CompareOperationHints::Any()); op = javascript()->Equal(CompareOperationHint::kAny);
break; break;
case Token::EQ_STRICT: case Token::EQ_STRICT:
op = javascript()->StrictEqual(CompareOperationHints::Any()); op = javascript()->StrictEqual(CompareOperationHint::kAny);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -2776,7 +2775,7 @@ void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, ...@@ -2776,7 +2775,7 @@ void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr,
Handle<String> check) { Handle<String> check) {
VisitTypeofExpression(sub_expr); VisitTypeofExpression(sub_expr);
Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop());
Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), Node* value = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
typeof_arg, jsgraph()->Constant(check)); typeof_arg, jsgraph()->Constant(check));
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
return ast_context()->ProduceValue(expr, value); return ast_context()->ProduceValue(expr, value);
...@@ -2799,38 +2798,38 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { ...@@ -2799,38 +2798,38 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant()); return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant());
} }
CompareOperationHints hints; CompareOperationHint hint;
if (!type_hint_analysis_ || if (!type_hint_analysis_ ||
!type_hint_analysis_->GetCompareOperationHints( !type_hint_analysis_->GetCompareOperationHint(
expr->CompareOperationFeedbackId(), &hints)) { expr->CompareOperationFeedbackId(), &hint)) {
hints = CompareOperationHints::Any(); hint = CompareOperationHint::kAny;
} }
const Operator* op; const Operator* op;
switch (expr->op()) { switch (expr->op()) {
case Token::EQ: case Token::EQ:
op = javascript()->Equal(hints); op = javascript()->Equal(hint);
break; break;
case Token::NE: case Token::NE:
op = javascript()->NotEqual(hints); op = javascript()->NotEqual(hint);
break; break;
case Token::EQ_STRICT: case Token::EQ_STRICT:
op = javascript()->StrictEqual(hints); op = javascript()->StrictEqual(hint);
break; break;
case Token::NE_STRICT: case Token::NE_STRICT:
op = javascript()->StrictNotEqual(hints); op = javascript()->StrictNotEqual(hint);
break; break;
case Token::LT: case Token::LT:
op = javascript()->LessThan(hints); op = javascript()->LessThan(hint);
break; break;
case Token::GT: case Token::GT:
op = javascript()->GreaterThan(hints); op = javascript()->GreaterThan(hint);
break; break;
case Token::LTE: case Token::LTE:
op = javascript()->LessThanOrEqual(hints); op = javascript()->LessThanOrEqual(hint);
break; break;
case Token::GTE: case Token::GTE:
op = javascript()->GreaterThanOrEqual(hints); op = javascript()->GreaterThanOrEqual(hint);
break; break;
case Token::INSTANCEOF: case Token::INSTANCEOF:
op = javascript()->InstanceOf(); op = javascript()->InstanceOf();
...@@ -3272,7 +3271,7 @@ Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, ...@@ -3272,7 +3271,7 @@ Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable,
BailoutId bailout_id) { BailoutId bailout_id) {
IfBuilder hole_check(this); IfBuilder hole_check(this);
Node* the_hole = jsgraph()->TheHoleConstant(); Node* the_hole = jsgraph()->TheHoleConstant();
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
value, the_hole); value, the_hole);
hole_check.If(check); hole_check.If(check);
hole_check.Then(); hole_check.Then();
...@@ -3290,7 +3289,7 @@ Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable, ...@@ -3290,7 +3289,7 @@ Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable,
BailoutId bailout_id) { BailoutId bailout_id) {
IfBuilder hole_check(this); IfBuilder hole_check(this);
Node* the_hole = jsgraph()->TheHoleConstant(); Node* the_hole = jsgraph()->TheHoleConstant();
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
value, the_hole); value, the_hole);
hole_check.If(check); hole_check.If(check);
hole_check.Then(); hole_check.Then();
...@@ -3308,7 +3307,7 @@ Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name, ...@@ -3308,7 +3307,7 @@ Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
IfBuilder prototype_check(this); IfBuilder prototype_check(this);
Node* prototype_string = Node* prototype_string =
jsgraph()->Constant(isolate()->factory()->prototype_string()); jsgraph()->Constant(isolate()->factory()->prototype_string());
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
name, prototype_string); name, prototype_string);
prototype_check.If(check); prototype_check.If(check);
prototype_check.Then(); prototype_check.Then();
...@@ -3778,44 +3777,44 @@ Node* AstGraphBuilder::BuildThrow(Node* exception_value) { ...@@ -3778,44 +3777,44 @@ Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op, Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op,
TypeFeedbackId feedback_id) { TypeFeedbackId feedback_id) {
const Operator* js_op; const Operator* js_op;
BinaryOperationHints hints; BinaryOperationHint hint;
if (!type_hint_analysis_ || if (!type_hint_analysis_ ||
!type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) { !type_hint_analysis_->GetBinaryOperationHint(feedback_id, &hint)) {
hints = BinaryOperationHints::Any(); hint = BinaryOperationHint::kAny;
} }
switch (op) { switch (op) {
case Token::BIT_OR: case Token::BIT_OR:
js_op = javascript()->BitwiseOr(hints); js_op = javascript()->BitwiseOr(hint);
break; break;
case Token::BIT_AND: case Token::BIT_AND:
js_op = javascript()->BitwiseAnd(hints); js_op = javascript()->BitwiseAnd(hint);
break; break;
case Token::BIT_XOR: case Token::BIT_XOR:
js_op = javascript()->BitwiseXor(hints); js_op = javascript()->BitwiseXor(hint);
break; break;
case Token::SHL: case Token::SHL:
js_op = javascript()->ShiftLeft(hints); js_op = javascript()->ShiftLeft(hint);
break; break;
case Token::SAR: case Token::SAR:
js_op = javascript()->ShiftRight(hints); js_op = javascript()->ShiftRight(hint);
break; break;
case Token::SHR: case Token::SHR:
js_op = javascript()->ShiftRightLogical(hints); js_op = javascript()->ShiftRightLogical(hint);
break; break;
case Token::ADD: case Token::ADD:
js_op = javascript()->Add(hints); js_op = javascript()->Add(hint);
break; break;
case Token::SUB: case Token::SUB:
js_op = javascript()->Subtract(hints); js_op = javascript()->Subtract(hint);
break; break;
case Token::MUL: case Token::MUL:
js_op = javascript()->Multiply(hints); js_op = javascript()->Multiply(hint);
break; break;
case Token::DIV: case Token::DIV:
js_op = javascript()->Divide(hints); js_op = javascript()->Divide(hint);
break; break;
case Token::MOD: case Token::MOD:
js_op = javascript()->Modulus(hints); js_op = javascript()->Modulus(hint);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -3860,7 +3859,7 @@ Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable, ...@@ -3860,7 +3859,7 @@ Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
current_context()); current_context());
Node* check = Node* check =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load, NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
jsgraph()->TheHoleConstant()); jsgraph()->TheHoleConstant());
fast_block.BreakUnless(check, BranchHint::kTrue); fast_block.BreakUnless(check, BranchHint::kTrue);
} }
...@@ -3907,7 +3906,7 @@ Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable, ...@@ -3907,7 +3906,7 @@ Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
current_context()); current_context());
Node* check = Node* check =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load, NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
jsgraph()->TheHoleConstant()); jsgraph()->TheHoleConstant());
fast_block.BreakUnless(check, BranchHint::kTrue); fast_block.BreakUnless(check, BranchHint::kTrue);
} }
......
...@@ -1172,21 +1172,21 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) { ...@@ -1172,21 +1172,21 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
// Helper function to create binary operation hint from the recorded type // Helper function to create binary operation hint from the recorded type
// feedback. // feedback.
BinaryOperationHints BytecodeGraphBuilder::GetBinaryOperationHint() { BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint() {
FeedbackVectorSlot slot = FeedbackVectorSlot slot =
feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(1)); feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(1));
DCHECK_EQ(FeedbackVectorSlotKind::GENERAL, feedback_vector()->GetKind(slot)); DCHECK_EQ(FeedbackVectorSlotKind::GENERAL, feedback_vector()->GetKind(slot));
Object* feedback = feedback_vector()->Get(slot); Object* feedback = feedback_vector()->Get(slot);
BinaryOperationHints::Hint hint = BinaryOperationHints::Hint::kAny; BinaryOperationHint hint = BinaryOperationHint::kAny;
if (feedback->IsSmi()) { if (feedback->IsSmi()) {
hint = BinaryOperationHintFromFeedback((Smi::cast(feedback))->value()); hint = BinaryOperationHintFromFeedback((Smi::cast(feedback))->value());
} }
return BinaryOperationHints(hint, hint, hint); return hint;
} }
void BytecodeGraphBuilder::VisitAdd() { void BytecodeGraphBuilder::VisitAdd() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->Add(hints)); BuildBinaryOp(javascript()->Add(hint));
} }
void BytecodeGraphBuilder::VisitSub() { void BytecodeGraphBuilder::VisitSub() {
...@@ -1194,48 +1194,48 @@ void BytecodeGraphBuilder::VisitSub() { ...@@ -1194,48 +1194,48 @@ void BytecodeGraphBuilder::VisitSub() {
} }
void BytecodeGraphBuilder::VisitMul() { void BytecodeGraphBuilder::VisitMul() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->Multiply(hints)); BuildBinaryOp(javascript()->Multiply(hint));
} }
void BytecodeGraphBuilder::VisitDiv() { void BytecodeGraphBuilder::VisitDiv() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->Divide(hints)); BuildBinaryOp(javascript()->Divide(hint));
} }
void BytecodeGraphBuilder::VisitMod() { void BytecodeGraphBuilder::VisitMod() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->Modulus(hints)); BuildBinaryOp(javascript()->Modulus(hint));
} }
void BytecodeGraphBuilder::VisitBitwiseOr() { void BytecodeGraphBuilder::VisitBitwiseOr() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->BitwiseOr(hints)); BuildBinaryOp(javascript()->BitwiseOr(hint));
} }
void BytecodeGraphBuilder::VisitBitwiseXor() { void BytecodeGraphBuilder::VisitBitwiseXor() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->BitwiseXor(hints)); BuildBinaryOp(javascript()->BitwiseXor(hint));
} }
void BytecodeGraphBuilder::VisitBitwiseAnd() { void BytecodeGraphBuilder::VisitBitwiseAnd() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->BitwiseAnd(hints)); BuildBinaryOp(javascript()->BitwiseAnd(hint));
} }
void BytecodeGraphBuilder::VisitShiftLeft() { void BytecodeGraphBuilder::VisitShiftLeft() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->ShiftLeft(hints)); BuildBinaryOp(javascript()->ShiftLeft(hint));
} }
void BytecodeGraphBuilder::VisitShiftRight() { void BytecodeGraphBuilder::VisitShiftRight() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->ShiftRight(hints)); BuildBinaryOp(javascript()->ShiftRight(hint));
} }
void BytecodeGraphBuilder::VisitShiftRightLogical() { void BytecodeGraphBuilder::VisitShiftRightLogical() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOp(javascript()->ShiftRightLogical(hints)); BuildBinaryOp(javascript()->ShiftRightLogical(hint));
} }
void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) { void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
...@@ -1248,40 +1248,40 @@ void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) { ...@@ -1248,40 +1248,40 @@ void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
} }
void BytecodeGraphBuilder::VisitAddSmi() { void BytecodeGraphBuilder::VisitAddSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOpWithImmediate(javascript()->Add(hints)); BuildBinaryOpWithImmediate(javascript()->Add(hint));
} }
void BytecodeGraphBuilder::VisitSubSmi() { void BytecodeGraphBuilder::VisitSubSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOpWithImmediate(javascript()->Subtract(hints)); BuildBinaryOpWithImmediate(javascript()->Subtract(hint));
} }
void BytecodeGraphBuilder::VisitBitwiseOrSmi() { void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOpWithImmediate(javascript()->BitwiseOr(hints)); BuildBinaryOpWithImmediate(javascript()->BitwiseOr(hint));
} }
void BytecodeGraphBuilder::VisitBitwiseAndSmi() { void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(hints)); BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(hint));
} }
void BytecodeGraphBuilder::VisitShiftLeftSmi() { void BytecodeGraphBuilder::VisitShiftLeftSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOpWithImmediate(javascript()->ShiftLeft(hints)); BuildBinaryOpWithImmediate(javascript()->ShiftLeft(hint));
} }
void BytecodeGraphBuilder::VisitShiftRightSmi() { void BytecodeGraphBuilder::VisitShiftRightSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any(); BinaryOperationHint hint = BinaryOperationHint::kAny;
BuildBinaryOpWithImmediate(javascript()->ShiftRight(hints)); BuildBinaryOpWithImmediate(javascript()->ShiftRight(hint));
} }
void BytecodeGraphBuilder::VisitInc() { void BytecodeGraphBuilder::VisitInc() {
FrameStateBeforeAndAfter states(this); FrameStateBeforeAndAfter states(this);
// Note: Use subtract -1 here instead of add 1 to ensure we always convert to // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
// a number, not a string. // a number, not a string.
const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any()); const Operator* js_op = javascript()->Subtract(BinaryOperationHint::kAny);
Node* node = NewNode(js_op, environment()->LookupAccumulator(), Node* node = NewNode(js_op, environment()->LookupAccumulator(),
jsgraph()->Constant(-1.0)); jsgraph()->Constant(-1.0));
environment()->BindAccumulator(node, &states); environment()->BindAccumulator(node, &states);
...@@ -1289,7 +1289,7 @@ void BytecodeGraphBuilder::VisitInc() { ...@@ -1289,7 +1289,7 @@ void BytecodeGraphBuilder::VisitInc() {
void BytecodeGraphBuilder::VisitDec() { void BytecodeGraphBuilder::VisitDec() {
FrameStateBeforeAndAfter states(this); FrameStateBeforeAndAfter states(this);
const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any()); const Operator* js_op = javascript()->Subtract(BinaryOperationHint::kAny);
Node* node = NewNode(js_op, environment()->LookupAccumulator(), Node* node = NewNode(js_op, environment()->LookupAccumulator(),
jsgraph()->OneConstant()); jsgraph()->OneConstant());
environment()->BindAccumulator(node, &states); environment()->BindAccumulator(node, &states);
...@@ -1344,38 +1344,38 @@ void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) { ...@@ -1344,38 +1344,38 @@ void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
} }
void BytecodeGraphBuilder::VisitTestEqual() { void BytecodeGraphBuilder::VisitTestEqual() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->Equal(hints)); BuildCompareOp(javascript()->Equal(hint));
} }
void BytecodeGraphBuilder::VisitTestNotEqual() { void BytecodeGraphBuilder::VisitTestNotEqual() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->NotEqual(hints)); BuildCompareOp(javascript()->NotEqual(hint));
} }
void BytecodeGraphBuilder::VisitTestEqualStrict() { void BytecodeGraphBuilder::VisitTestEqualStrict() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->StrictEqual(hints)); BuildCompareOp(javascript()->StrictEqual(hint));
} }
void BytecodeGraphBuilder::VisitTestLessThan() { void BytecodeGraphBuilder::VisitTestLessThan() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->LessThan(hints)); BuildCompareOp(javascript()->LessThan(hint));
} }
void BytecodeGraphBuilder::VisitTestGreaterThan() { void BytecodeGraphBuilder::VisitTestGreaterThan() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->GreaterThan(hints)); BuildCompareOp(javascript()->GreaterThan(hint));
} }
void BytecodeGraphBuilder::VisitTestLessThanOrEqual() { void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->LessThanOrEqual(hints)); BuildCompareOp(javascript()->LessThanOrEqual(hint));
} }
void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() { void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
CompareOperationHints hints = CompareOperationHints::Any(); CompareOperationHint hint = CompareOperationHint::kAny;
BuildCompareOp(javascript()->GreaterThanOrEqual(hints)); BuildCompareOp(javascript()->GreaterThanOrEqual(hint));
} }
void BytecodeGraphBuilder::VisitTestIn() { void BytecodeGraphBuilder::VisitTestIn() {
...@@ -1686,7 +1686,7 @@ void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) { ...@@ -1686,7 +1686,7 @@ void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) { void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
Node* accumulator = environment()->LookupAccumulator(); Node* accumulator = environment()->LookupAccumulator();
Node* condition = Node* condition =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
accumulator, comperand); accumulator, comperand);
BuildConditionalJump(condition); BuildConditionalJump(condition);
} }
...@@ -1697,15 +1697,15 @@ void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) { ...@@ -1697,15 +1697,15 @@ void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
Node* to_boolean = Node* to_boolean =
NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator); NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
Node* condition = Node* condition =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), to_boolean,
to_boolean, comperand); comperand);
BuildConditionalJump(condition); BuildConditionalJump(condition);
} }
void BytecodeGraphBuilder::BuildJumpIfNotHole() { void BytecodeGraphBuilder::BuildJumpIfNotHole() {
Node* accumulator = environment()->LookupAccumulator(); Node* accumulator = environment()->LookupAccumulator();
Node* condition = Node* condition =
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
accumulator, jsgraph()->TheHoleConstant()); accumulator, jsgraph()->TheHoleConstant());
Node* node = Node* node =
NewNode(common()->Select(MachineRepresentation::kTagged), condition, NewNode(common()->Select(MachineRepresentation::kTagged), condition,
......
...@@ -137,7 +137,7 @@ class BytecodeGraphBuilder { ...@@ -137,7 +137,7 @@ class BytecodeGraphBuilder {
// Helper function to create binary operation hint from the recorded // Helper function to create binary operation hint from the recorded
// type feedback. // type feedback.
BinaryOperationHints GetBinaryOperationHint(); BinaryOperationHint GetBinaryOperationHint();
// Control flow plumbing. // Control flow plumbing.
void BuildJump(); void BuildJump();
......
This diff is collapsed.
...@@ -374,9 +374,9 @@ std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&); ...@@ -374,9 +374,9 @@ std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&);
const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op); const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
const BinaryOperationHints& BinaryOperationHintsOf(const Operator* op); const BinaryOperationHint BinaryOperationHintOf(const Operator* op);
const CompareOperationHints& CompareOperationHintsOf(const Operator* op); const CompareOperationHint CompareOperationHintOf(const Operator* op);
// Interface for building JavaScript-level operators, e.g. directly from the // Interface for building JavaScript-level operators, e.g. directly from the
// AST. Most operators have no parameters, thus can be globally shared for all // AST. Most operators have no parameters, thus can be globally shared for all
...@@ -385,25 +385,26 @@ class JSOperatorBuilder final : public ZoneObject { ...@@ -385,25 +385,26 @@ class JSOperatorBuilder final : public ZoneObject {
public: public:
explicit JSOperatorBuilder(Zone* zone); explicit JSOperatorBuilder(Zone* zone);
const Operator* Equal(CompareOperationHints hints); const Operator* Equal(CompareOperationHint hint);
const Operator* NotEqual(CompareOperationHints hints); const Operator* NotEqual(CompareOperationHint hint);
const Operator* StrictEqual(CompareOperationHints hints); const Operator* StrictEqual(CompareOperationHint hint);
const Operator* StrictNotEqual(CompareOperationHints hints); const Operator* StrictNotEqual(CompareOperationHint hint);
const Operator* LessThan(CompareOperationHints hints); const Operator* LessThan(CompareOperationHint hint);
const Operator* GreaterThan(CompareOperationHints hints); const Operator* GreaterThan(CompareOperationHint hint);
const Operator* LessThanOrEqual(CompareOperationHints hints); const Operator* LessThanOrEqual(CompareOperationHint hint);
const Operator* GreaterThanOrEqual(CompareOperationHints hints); const Operator* GreaterThanOrEqual(CompareOperationHint hint);
const Operator* BitwiseOr(BinaryOperationHints hints);
const Operator* BitwiseXor(BinaryOperationHints hints); const Operator* BitwiseOr(BinaryOperationHint hint);
const Operator* BitwiseAnd(BinaryOperationHints hints); const Operator* BitwiseXor(BinaryOperationHint hint);
const Operator* ShiftLeft(BinaryOperationHints hints); const Operator* BitwiseAnd(BinaryOperationHint hint);
const Operator* ShiftRight(BinaryOperationHints hints); const Operator* ShiftLeft(BinaryOperationHint hint);
const Operator* ShiftRightLogical(BinaryOperationHints hints); const Operator* ShiftRight(BinaryOperationHint hint);
const Operator* Add(BinaryOperationHints hints); const Operator* ShiftRightLogical(BinaryOperationHint hint);
const Operator* Subtract(BinaryOperationHints hints); const Operator* Add(BinaryOperationHint hint);
const Operator* Multiply(BinaryOperationHints hints); const Operator* Subtract(BinaryOperationHint hint);
const Operator* Divide(BinaryOperationHints hints); const Operator* Multiply(BinaryOperationHint hint);
const Operator* Modulus(BinaryOperationHints hints); const Operator* Divide(BinaryOperationHint hint);
const Operator* Modulus(BinaryOperationHint hint);
const Operator* ToBoolean(ToBooleanHints hints); const Operator* ToBoolean(ToBooleanHints hints);
const Operator* ToInteger(); const Operator* ToInteger();
......
...@@ -33,20 +33,18 @@ class JSBinopReduction final { ...@@ -33,20 +33,18 @@ class JSBinopReduction final {
DCHECK_NE(0, node_->op()->ControlOutputCount()); DCHECK_NE(0, node_->op()->ControlOutputCount());
DCHECK_EQ(1, node_->op()->EffectOutputCount()); DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op())); DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
BinaryOperationHints hints = BinaryOperationHintsOf(node_->op()); switch (BinaryOperationHintOf(node_->op())) {
switch (hints.combined()) { case BinaryOperationHint::kSignedSmall:
case BinaryOperationHints::kSignedSmall:
*hint = NumberOperationHint::kSignedSmall; *hint = NumberOperationHint::kSignedSmall;
return true; return true;
case BinaryOperationHints::kSigned32: case BinaryOperationHint::kSigned32:
*hint = NumberOperationHint::kSigned32; *hint = NumberOperationHint::kSigned32;
return true; return true;
case BinaryOperationHints::kNumberOrOddball: case BinaryOperationHint::kNumberOrOddball:
*hint = NumberOperationHint::kNumberOrOddball; *hint = NumberOperationHint::kNumberOrOddball;
return true; return true;
case BinaryOperationHints::kAny: case BinaryOperationHint::kAny:
case BinaryOperationHints::kNone: case BinaryOperationHint::kNone:
case BinaryOperationHints::kString:
break; break;
} }
} }
...@@ -56,24 +54,18 @@ class JSBinopReduction final { ...@@ -56,24 +54,18 @@ class JSBinopReduction final {
bool GetCompareNumberOperationHint(NumberOperationHint* hint) { bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
DCHECK_EQ(1, node_->op()->EffectOutputCount()); DCHECK_EQ(1, node_->op()->EffectOutputCount());
CompareOperationHints hints = CompareOperationHintsOf(node_->op()); switch (CompareOperationHintOf(node_->op())) {
switch (hints.combined()) { case CompareOperationHint::kSignedSmall:
case CompareOperationHints::kSignedSmall:
*hint = NumberOperationHint::kSignedSmall; *hint = NumberOperationHint::kSignedSmall;
return true; return true;
case CompareOperationHints::kNumber: case CompareOperationHint::kNumber:
*hint = NumberOperationHint::kNumber; *hint = NumberOperationHint::kNumber;
return true; return true;
case CompareOperationHints::kNumberOrOddball: case CompareOperationHint::kNumberOrOddball:
*hint = NumberOperationHint::kNumberOrOddball; *hint = NumberOperationHint::kNumberOrOddball;
return true; return true;
case CompareOperationHints::kAny: case CompareOperationHint::kAny:
case CompareOperationHints::kNone: case CompareOperationHint::kNone:
case CompareOperationHints::kString:
case CompareOperationHints::kBoolean:
case CompareOperationHints::kUniqueName:
case CompareOperationHints::kInternalizedString:
case CompareOperationHints::kReceiver:
break; break;
} }
} }
......
...@@ -15,76 +15,69 @@ namespace compiler { ...@@ -15,76 +15,69 @@ namespace compiler {
namespace { namespace {
// TODO(bmeurer): This detour via types is ugly. BinaryOperationHint ToBinaryOperationHint(BinaryOpICState::Kind kind) {
BinaryOperationHints::Hint ToBinaryOperationHint(Type* type) { switch (kind) {
if (type->Is(Type::None())) return BinaryOperationHints::kNone; case BinaryOpICState::NONE:
if (type->Is(Type::SignedSmall())) return BinaryOperationHints::kSignedSmall; return BinaryOperationHint::kNone;
if (type->Is(Type::Signed32())) return BinaryOperationHints::kSigned32; case BinaryOpICState::SMI:
if (type->Is(Type::Number())) return BinaryOperationHints::kNumberOrOddball; return BinaryOperationHint::kSignedSmall;
if (type->Is(Type::String())) return BinaryOperationHints::kString; case BinaryOpICState::INT32:
return BinaryOperationHints::kAny; return BinaryOperationHint::kSigned32;
case BinaryOpICState::NUMBER:
return BinaryOperationHint::kNumberOrOddball;
case BinaryOpICState::STRING:
case BinaryOpICState::GENERIC:
return BinaryOperationHint::kAny;
}
UNREACHABLE();
return BinaryOperationHint::kNone;
} }
CompareOperationHints::Hint ToCompareOperationHint( CompareOperationHint ToCompareOperationHint(Token::Value op,
Token::Value op, CompareICState::State state) { CompareICState::State state) {
switch (state) { switch (state) {
case CompareICState::UNINITIALIZED: case CompareICState::UNINITIALIZED:
return CompareOperationHints::kNone; return CompareOperationHint::kNone;
case CompareICState::BOOLEAN:
return CompareOperationHints::kBoolean;
case CompareICState::SMI: case CompareICState::SMI:
return CompareOperationHints::kSignedSmall; return CompareOperationHint::kSignedSmall;
case CompareICState::NUMBER: case CompareICState::NUMBER:
return Token::IsOrderedRelationalCompareOp(op) return Token::IsOrderedRelationalCompareOp(op)
? CompareOperationHints::kNumberOrOddball ? CompareOperationHint::kNumberOrOddball
: CompareOperationHints::kNumber; : CompareOperationHint::kNumber;
case CompareICState::STRING: case CompareICState::STRING:
return CompareOperationHints::kString;
case CompareICState::INTERNALIZED_STRING: case CompareICState::INTERNALIZED_STRING:
return CompareOperationHints::kInternalizedString;
case CompareICState::UNIQUE_NAME: case CompareICState::UNIQUE_NAME:
return CompareOperationHints::kUniqueName;
case CompareICState::RECEIVER: case CompareICState::RECEIVER:
case CompareICState::KNOWN_RECEIVER: case CompareICState::KNOWN_RECEIVER:
return CompareOperationHints::kReceiver; case CompareICState::BOOLEAN:
case CompareICState::GENERIC: case CompareICState::GENERIC:
return CompareOperationHints::kAny; return CompareOperationHint::kAny;
} }
UNREACHABLE(); UNREACHABLE();
return CompareOperationHints::kAny; return CompareOperationHint::kNone;
} }
} // namespace } // namespace
bool TypeHintAnalysis::GetBinaryOperationHints( bool TypeHintAnalysis::GetBinaryOperationHint(TypeFeedbackId id,
TypeFeedbackId id, BinaryOperationHints* hints) const { BinaryOperationHint* hint) const {
auto i = infos_.find(id); auto i = infos_.find(id);
if (i == infos_.end()) return false; if (i == infos_.end()) return false;
Handle<Code> code = i->second; Handle<Code> code = i->second;
DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); DCHECK_EQ(Code::BINARY_OP_IC, code->kind());
BinaryOpICState state(code->GetIsolate(), code->extra_ic_state()); BinaryOpICState state(code->GetIsolate(), code->extra_ic_state());
*hints = BinaryOperationHints(ToBinaryOperationHint(state.GetLeftType()), *hint = ToBinaryOperationHint(state.kind());
ToBinaryOperationHint(state.GetRightType()),
ToBinaryOperationHint(state.GetResultType()));
return true; return true;
} }
bool TypeHintAnalysis::GetCompareOperationHints( bool TypeHintAnalysis::GetCompareOperationHint(
TypeFeedbackId id, CompareOperationHints* hints) const { TypeFeedbackId id, CompareOperationHint* hint) const {
auto i = infos_.find(id); auto i = infos_.find(id);
if (i == infos_.end()) return false; if (i == infos_.end()) return false;
Handle<Code> code = i->second; Handle<Code> code = i->second;
DCHECK_EQ(Code::COMPARE_IC, code->kind()); DCHECK_EQ(Code::COMPARE_IC, code->kind());
Handle<Map> map;
Map* raw_map = code->FindFirstMap();
if (raw_map != nullptr) Map::TryUpdate(handle(raw_map)).ToHandle(&map);
CompareICStub stub(code->stub_key(), code->GetIsolate()); CompareICStub stub(code->stub_key(), code->GetIsolate());
*hints = *hint = ToCompareOperationHint(stub.op(), stub.state());
CompareOperationHints(ToCompareOperationHint(stub.op(), stub.left()),
ToCompareOperationHint(stub.op(), stub.right()),
ToCompareOperationHint(stub.op(), stub.state()));
return true; return true;
} }
...@@ -139,18 +132,19 @@ TypeHintAnalysis* TypeHintAnalyzer::Analyze(Handle<Code> code) { ...@@ -139,18 +132,19 @@ TypeHintAnalysis* TypeHintAnalyzer::Analyze(Handle<Code> code) {
return new (zone()) TypeHintAnalysis(infos, zone()); return new (zone()) TypeHintAnalysis(infos, zone());
} }
// Helper function to transform the feedback to BinaryOperationHints // Helper function to transform the feedback to BinaryOperationHint.
BinaryOperationHints::Hint BinaryOperationHintFromFeedback(int type_feedback) { BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) {
switch (type_feedback) { switch (type_feedback) {
case BinaryOperationFeedback::kSignedSmall: case BinaryOperationFeedback::kSignedSmall:
return BinaryOperationHints::kSigned32; return BinaryOperationHint::kSigned32;
case BinaryOperationFeedback::kNumber: case BinaryOperationFeedback::kNumber:
return BinaryOperationHints::kNumberOrOddball; return BinaryOperationHint::kNumberOrOddball;
case BinaryOperationFeedback::kAny: case BinaryOperationFeedback::kAny:
default: default:
return BinaryOperationHints::kAny; return BinaryOperationHint::kAny;
} }
return BinaryOperationHints::kAny; UNREACHABLE();
return BinaryOperationHint::kNone;
} }
} // namespace compiler } // namespace compiler
......
...@@ -21,10 +21,10 @@ class TypeHintAnalysis final : public ZoneObject { ...@@ -21,10 +21,10 @@ class TypeHintAnalysis final : public ZoneObject {
explicit TypeHintAnalysis(Infos const& infos, Zone* zone) explicit TypeHintAnalysis(Infos const& infos, Zone* zone)
: infos_(infos), zone_(zone) {} : infos_(infos), zone_(zone) {}
bool GetBinaryOperationHints(TypeFeedbackId id, bool GetBinaryOperationHint(TypeFeedbackId id,
BinaryOperationHints* hints) const; BinaryOperationHint* hint) const;
bool GetCompareOperationHints(TypeFeedbackId id, bool GetCompareOperationHint(TypeFeedbackId id,
CompareOperationHints* hints) const; CompareOperationHint* hint) const;
bool GetToBooleanHints(TypeFeedbackId id, ToBooleanHints* hints) const; bool GetToBooleanHints(TypeFeedbackId id, ToBooleanHints* hints) const;
private: private:
...@@ -50,7 +50,7 @@ class TypeHintAnalyzer final { ...@@ -50,7 +50,7 @@ class TypeHintAnalyzer final {
DISALLOW_COPY_AND_ASSIGN(TypeHintAnalyzer); DISALLOW_COPY_AND_ASSIGN(TypeHintAnalyzer);
}; };
BinaryOperationHints::Hint BinaryOperationHintFromFeedback(int type_feedback); BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback);
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -8,61 +8,40 @@ namespace v8 { ...@@ -8,61 +8,40 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
std::ostream& operator<<(std::ostream& os, BinaryOperationHints::Hint hint) { std::ostream& operator<<(std::ostream& os, BinaryOperationHint hint) {
switch (hint) { switch (hint) {
case BinaryOperationHints::kNone: case BinaryOperationHint::kNone:
return os << "None"; return os << "None";
case BinaryOperationHints::kSignedSmall: case BinaryOperationHint::kSignedSmall:
return os << "SignedSmall"; return os << "SignedSmall";
case BinaryOperationHints::kSigned32: case BinaryOperationHint::kSigned32:
return os << "Signed32"; return os << "Signed32";
case BinaryOperationHints::kNumberOrOddball: case BinaryOperationHint::kNumberOrOddball:
return os << "NumberOrOddball"; return os << "NumberOrOddball";
case BinaryOperationHints::kString: case BinaryOperationHint::kAny:
return os << "String";
case BinaryOperationHints::kAny:
return os << "Any"; return os << "Any";
} }
UNREACHABLE(); UNREACHABLE();
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, BinaryOperationHints hints) { std::ostream& operator<<(std::ostream& os, CompareOperationHint hint) {
return os << hints.left() << "*" << hints.right() << "->" << hints.result();
}
std::ostream& operator<<(std::ostream& os, CompareOperationHints::Hint hint) {
switch (hint) { switch (hint) {
case CompareOperationHints::kNone: case CompareOperationHint::kNone:
return os << "None"; return os << "None";
case CompareOperationHints::kBoolean: case CompareOperationHint::kSignedSmall:
return os << "Boolean";
case CompareOperationHints::kSignedSmall:
return os << "SignedSmall"; return os << "SignedSmall";
case CompareOperationHints::kNumber: case CompareOperationHint::kNumber:
return os << "Number"; return os << "Number";
case CompareOperationHints::kNumberOrOddball: case CompareOperationHint::kNumberOrOddball:
return os << "NumberOrOddball"; return os << "NumberOrOddball";
case CompareOperationHints::kString: case CompareOperationHint::kAny:
return os << "String";
case CompareOperationHints::kInternalizedString:
return os << "InternalizedString";
case CompareOperationHints::kUniqueName:
return os << "UniqueName";
case CompareOperationHints::kReceiver:
return os << "Receiver";
case CompareOperationHints::kAny:
return os << "Any"; return os << "Any";
} }
UNREACHABLE(); UNREACHABLE();
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, CompareOperationHints hints) {
return os << hints.left() << "*" << hints.right() << " (" << hints.combined()
<< ")";
}
std::ostream& operator<<(std::ostream& os, ToBooleanHint hint) { std::ostream& operator<<(std::ostream& os, ToBooleanHint hint) {
switch (hint) { switch (hint) {
case ToBooleanHint::kNone: case ToBooleanHint::kNone:
...@@ -96,7 +75,7 @@ std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) { ...@@ -96,7 +75,7 @@ std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) {
if (hints == ToBooleanHint::kAny) return os << "Any"; if (hints == ToBooleanHint::kAny) return os << "Any";
if (hints == ToBooleanHint::kNone) return os << "None"; if (hints == ToBooleanHint::kNone) return os << "None";
bool first = true; bool first = true;
for (ToBooleanHints::mask_type i = 0; i < sizeof(i) * CHAR_BIT; ++i) { for (ToBooleanHints::mask_type i = 0; i < sizeof(i) * 8; ++i) {
ToBooleanHint const hint = static_cast<ToBooleanHint>(1u << i); ToBooleanHint const hint = static_cast<ToBooleanHint>(1u << i);
if (hints & hint) { if (hints & hint) {
if (!first) os << "|"; if (!first) os << "|";
...@@ -107,34 +86,6 @@ std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) { ...@@ -107,34 +86,6 @@ std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) {
return os; return os;
} }
// static
bool BinaryOperationHints::Is(Hint h1, Hint h2) {
if (h1 == h2) return true;
switch (h1) {
case kNone:
return true;
case kSignedSmall:
return h2 == kSigned32 || h2 == kNumberOrOddball || h2 == kAny;
case kSigned32:
return h2 == kNumberOrOddball || h2 == kAny;
case kNumberOrOddball:
return h2 == kAny;
case kString:
return h2 == kAny;
case kAny:
return false;
}
UNREACHABLE();
return false;
}
// static
BinaryOperationHints::Hint BinaryOperationHints::Combine(Hint h1, Hint h2) {
if (Is(h1, h2)) return h2;
if (Is(h2, h1)) return h1;
return kAny;
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -13,100 +13,34 @@ namespace internal { ...@@ -13,100 +13,34 @@ namespace internal {
namespace compiler { namespace compiler {
// Type hints for an binary operation. // Type hints for an binary operation.
class BinaryOperationHints final { enum class BinaryOperationHint : uint8_t {
public: kNone,
enum Hint { kNone, kSignedSmall, kSigned32, kNumberOrOddball, kString, kAny }; kSignedSmall,
kSigned32,
BinaryOperationHints() : BinaryOperationHints(kNone, kNone, kNone) {} kNumberOrOddball,
BinaryOperationHints(Hint left, Hint right, Hint result) kAny
: bit_field_(LeftField::encode(left) | RightField::encode(right) |
ResultField::encode(result)) {}
static BinaryOperationHints Any() {
return BinaryOperationHints(kAny, kAny, kAny);
}
Hint left() const { return LeftField::decode(bit_field_); }
Hint right() const { return RightField::decode(bit_field_); }
Hint result() const { return ResultField::decode(bit_field_); }
Hint combined() const { return Combine(Combine(left(), right()), result()); }
// Hint 'subtyping' and generalization.
static bool Is(Hint h1, Hint h2);
static Hint Combine(Hint h1, Hint h2);
bool operator==(BinaryOperationHints const& that) const {
return this->bit_field_ == that.bit_field_;
}
bool operator!=(BinaryOperationHints const& that) const {
return !(*this == that);
}
friend size_t hash_value(BinaryOperationHints const& hints) {
return hints.bit_field_;
}
private:
typedef BitField<Hint, 0, 3> LeftField;
typedef BitField<Hint, 3, 3> RightField;
typedef BitField<Hint, 6, 3> ResultField;
uint32_t bit_field_;
}; };
std::ostream& operator<<(std::ostream&, BinaryOperationHints::Hint); inline size_t hash_value(BinaryOperationHint hint) {
std::ostream& operator<<(std::ostream&, BinaryOperationHints); return static_cast<unsigned>(hint);
}
// Type hints for an binary operation. std::ostream& operator<<(std::ostream&, BinaryOperationHint);
class CompareOperationHints final {
public: // Type hints for an compare operation.
enum Hint { enum class CompareOperationHint : uint8_t {
kNone, kNone,
kBoolean,
kSignedSmall, kSignedSmall,
kNumber, kNumber,
kNumberOrOddball, kNumberOrOddball,
kString,
kInternalizedString,
kUniqueName,
kReceiver,
kAny kAny
};
CompareOperationHints() : CompareOperationHints(kNone, kNone, kNone) {}
CompareOperationHints(Hint left, Hint right, Hint combined)
: bit_field_(LeftField::encode(left) | RightField::encode(right) |
CombinedField::encode(combined)) {}
static CompareOperationHints Any() {
return CompareOperationHints(kAny, kAny, kAny);
}
Hint left() const { return LeftField::decode(bit_field_); }
Hint right() const { return RightField::decode(bit_field_); }
Hint combined() const { return CombinedField::decode(bit_field_); }
bool operator==(CompareOperationHints const& that) const {
return this->bit_field_ == that.bit_field_;
}
bool operator!=(CompareOperationHints const& that) const {
return !(*this == that);
}
friend size_t hash_value(CompareOperationHints const& hints) {
return hints.bit_field_;
}
private:
typedef BitField<Hint, 0, 4> LeftField;
typedef BitField<Hint, 4, 4> RightField;
typedef BitField<Hint, 8, 4> CombinedField;
uint32_t bit_field_;
}; };
std::ostream& operator<<(std::ostream&, CompareOperationHints::Hint); inline size_t hash_value(CompareOperationHint hint) {
std::ostream& operator<<(std::ostream&, CompareOperationHints); return static_cast<unsigned>(hint);
}
std::ostream& operator<<(std::ostream&, CompareOperationHint);
// Type hints for the ToBoolean type conversion. // Type hints for the ToBoolean type conversion.
enum class ToBooleanHint : uint16_t { enum class ToBooleanHint : uint16_t {
......
...@@ -128,11 +128,15 @@ class BinaryOpICState final BASE_EMBEDDED { ...@@ -128,11 +128,15 @@ class BinaryOpICState final BASE_EMBEDDED {
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
Kind kind() const {
return KindGeneralize(KindGeneralize(left_kind_, right_kind_),
result_kind_);
}
private: private:
friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s); friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
Kind UpdateKind(Handle<Object> object, Kind kind) const; Kind UpdateKind(Handle<Object> object, Kind kind) const;
static const char* KindToString(Kind kind); static const char* KindToString(Kind kind);
...@@ -140,6 +144,18 @@ class BinaryOpICState final BASE_EMBEDDED { ...@@ -140,6 +144,18 @@ class BinaryOpICState final BASE_EMBEDDED {
static bool KindMaybeSmi(Kind kind) { static bool KindMaybeSmi(Kind kind) {
return (kind >= SMI && kind <= NUMBER) || kind == GENERIC; return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
} }
static bool KindLessGeneralThan(Kind kind1, Kind kind2) {
if (kind1 == NONE) return true;
if (kind1 == kind2) return true;
if (kind2 == GENERIC) return true;
if (kind2 == STRING) return false;
return kind1 <= kind2;
}
static Kind KindGeneralize(Kind kind1, Kind kind2) {
if (KindLessGeneralThan(kind1, kind2)) return kind2;
if (KindLessGeneralThan(kind2, kind1)) return kind1;
return GENERIC;
}
// We truncate the last bit of the token. // We truncate the last bit of the token.
STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4)); STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
......
...@@ -51,8 +51,8 @@ class JSTypedLoweringTester : public HandleAndZoneScope { ...@@ -51,8 +51,8 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Typer typer; Typer typer;
Node* context_node; Node* context_node;
JSTypedLowering::Flags flags; JSTypedLowering::Flags flags;
BinaryOperationHints const binop_hints = BinaryOperationHints::Any(); BinaryOperationHint const binop_hints = BinaryOperationHint::kAny;
CompareOperationHints const compare_hints = CompareOperationHints::Any(); CompareOperationHint const compare_hints = CompareOperationHint::kAny;
Node* Parameter(Type* t, int32_t index = 0) { Node* Parameter(Type* t, int32_t index = 0) {
Node* n = graph.NewNode(common.Parameter(index), graph.start()); Node* n = graph.NewNode(common.Parameter(index), graph.start());
...@@ -247,7 +247,7 @@ TEST(AddNumber1) { ...@@ -247,7 +247,7 @@ TEST(AddNumber1) {
for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
Node* p0 = R.Parameter(kNumberTypes[i], 0); Node* p0 = R.Parameter(kNumberTypes[i], 0);
Node* p1 = R.Parameter(kNumberTypes[i], 1); Node* p1 = R.Parameter(kNumberTypes[i], 1);
Node* add = R.Binop(R.javascript.Add(BinaryOperationHints::Any()), p0, p1); Node* add = R.Binop(R.javascript.Add(BinaryOperationHint::kAny), p0, p1);
Node* r = R.reduce(add); Node* r = R.reduce(add);
R.CheckBinop(IrOpcode::kNumberAdd, r); R.CheckBinop(IrOpcode::kNumberAdd, r);
...@@ -575,13 +575,13 @@ TEST(StringComparison) { ...@@ -575,13 +575,13 @@ TEST(StringComparison) {
JSTypedLoweringTester R; JSTypedLoweringTester R;
const Operator* ops[] = { const Operator* ops[] = {
R.javascript.LessThan(CompareOperationHints::Any()), R.javascript.LessThan(CompareOperationHint::kAny),
R.simplified.StringLessThan(), R.simplified.StringLessThan(),
R.javascript.LessThanOrEqual(CompareOperationHints::Any()), R.javascript.LessThanOrEqual(CompareOperationHint::kAny),
R.simplified.StringLessThanOrEqual(), R.simplified.StringLessThanOrEqual(),
R.javascript.GreaterThan(CompareOperationHints::Any()), R.javascript.GreaterThan(CompareOperationHint::kAny),
R.simplified.StringLessThan(), R.simplified.StringLessThan(),
R.javascript.GreaterThanOrEqual(CompareOperationHints::Any()), R.javascript.GreaterThanOrEqual(CompareOperationHint::kAny),
R.simplified.StringLessThanOrEqual()}; R.simplified.StringLessThanOrEqual()};
for (size_t i = 0; i < arraysize(kStringTypes); i++) { for (size_t i = 0; i < arraysize(kStringTypes); i++) {
...@@ -623,13 +623,13 @@ TEST(NumberComparison) { ...@@ -623,13 +623,13 @@ TEST(NumberComparison) {
JSTypedLoweringTester R; JSTypedLoweringTester R;
const Operator* ops[] = { const Operator* ops[] = {
R.javascript.LessThan(CompareOperationHints::Any()), R.javascript.LessThan(CompareOperationHint::kAny),
R.simplified.NumberLessThan(), R.simplified.NumberLessThan(),
R.javascript.LessThanOrEqual(CompareOperationHints::Any()), R.javascript.LessThanOrEqual(CompareOperationHint::kAny),
R.simplified.NumberLessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
R.javascript.GreaterThan(CompareOperationHints::Any()), R.javascript.GreaterThan(CompareOperationHint::kAny),
R.simplified.NumberLessThan(), R.simplified.NumberLessThan(),
R.javascript.GreaterThanOrEqual(CompareOperationHints::Any()), R.javascript.GreaterThanOrEqual(CompareOperationHint::kAny),
R.simplified.NumberLessThanOrEqual()}; R.simplified.NumberLessThanOrEqual()};
Node* const p0 = R.Parameter(Type::Number(), 0); Node* const p0 = R.Parameter(Type::Number(), 0);
...@@ -665,7 +665,7 @@ TEST(MixedComparison1) { ...@@ -665,7 +665,7 @@ TEST(MixedComparison1) {
Node* p1 = R.Parameter(types[j], 1); Node* p1 = R.Parameter(types[j], 1);
{ {
const Operator* less_than = const Operator* less_than =
R.javascript.LessThan(CompareOperationHints::Any()); R.javascript.LessThan(CompareOperationHint::kAny);
Node* cmp = R.Binop(less_than, p0, p1); Node* cmp = R.Binop(less_than, p0, p1);
Node* r = R.reduce(cmp); Node* r = R.reduce(cmp);
if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) { if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
...@@ -811,8 +811,8 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l, ...@@ -811,8 +811,8 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
{ {
const Operator* op = const Operator* op =
strict ? R->javascript.StrictEqual(CompareOperationHints::Any()) strict ? R->javascript.StrictEqual(CompareOperationHint::kAny)
: R->javascript.Equal(CompareOperationHints::Any()); : R->javascript.Equal(CompareOperationHint::kAny);
Node* eq = R->Binop(op, p0, p1); Node* eq = R->Binop(op, p0, p1);
Node* r = R->reduce(eq); Node* r = R->reduce(eq);
R->CheckBinop(expected, r); R->CheckBinop(expected, r);
...@@ -820,8 +820,8 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l, ...@@ -820,8 +820,8 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
{ {
const Operator* op = const Operator* op =
strict ? R->javascript.StrictNotEqual(CompareOperationHints::Any()) strict ? R->javascript.StrictNotEqual(CompareOperationHint::kAny)
: R->javascript.NotEqual(CompareOperationHints::Any()); : R->javascript.NotEqual(CompareOperationHint::kAny);
Node* ne = R->Binop(op, p0, p1); Node* ne = R->Binop(op, p0, p1);
Node* n = R->reduce(ne); Node* n = R->reduce(ne);
CHECK_EQ(IrOpcode::kBooleanNot, n->opcode()); CHECK_EQ(IrOpcode::kBooleanNot, n->opcode());
......
...@@ -51,7 +51,7 @@ class TyperTest : public TypedGraphTest { ...@@ -51,7 +51,7 @@ class TyperTest : public TypedGraphTest {
Types types_; Types types_;
JSOperatorBuilder javascript_; JSOperatorBuilder javascript_;
BinaryOperationHints const hints_ = BinaryOperationHints::Any(); BinaryOperationHint const hints_ = BinaryOperationHint::kAny;
Node* context_node_; Node* context_node_;
v8::base::RandomNumberGenerator* rng_; v8::base::RandomNumberGenerator* rng_;
std::vector<double> integers; std::vector<double> integers;
...@@ -290,51 +290,51 @@ TEST_F(TyperTest, TypeJSShiftRight) { ...@@ -290,51 +290,51 @@ TEST_F(TyperTest, TypeJSShiftRight) {
TEST_F(TyperTest, TypeJSLessThan) { TEST_F(TyperTest, TypeJSLessThan) {
TestBinaryCompareOp(javascript_.LessThan(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny),
std::less<double>()); std::less<double>());
} }
TEST_F(TyperTest, TypeJSLessThanOrEqual) { TEST_F(TyperTest, TypeJSLessThanOrEqual) {
TestBinaryCompareOp(javascript_.LessThanOrEqual(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.LessThanOrEqual(CompareOperationHint::kAny),
std::less_equal<double>()); std::less_equal<double>());
} }
TEST_F(TyperTest, TypeJSGreaterThan) { TEST_F(TyperTest, TypeJSGreaterThan) {
TestBinaryCompareOp(javascript_.GreaterThan(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.GreaterThan(CompareOperationHint::kAny),
std::greater<double>()); std::greater<double>());
} }
TEST_F(TyperTest, TypeJSGreaterThanOrEqual) { TEST_F(TyperTest, TypeJSGreaterThanOrEqual) {
TestBinaryCompareOp( TestBinaryCompareOp(
javascript_.GreaterThanOrEqual(CompareOperationHints::Any()), javascript_.GreaterThanOrEqual(CompareOperationHint::kAny),
std::greater_equal<double>()); std::greater_equal<double>());
} }
TEST_F(TyperTest, TypeJSEqual) { TEST_F(TyperTest, TypeJSEqual) {
TestBinaryCompareOp(javascript_.Equal(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny),
std::equal_to<double>()); std::equal_to<double>());
} }
TEST_F(TyperTest, TypeJSNotEqual) { TEST_F(TyperTest, TypeJSNotEqual) {
TestBinaryCompareOp(javascript_.NotEqual(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.NotEqual(CompareOperationHint::kAny),
std::not_equal_to<double>()); std::not_equal_to<double>());
} }
// For numbers there's no difference between strict and non-strict equality. // For numbers there's no difference between strict and non-strict equality.
TEST_F(TyperTest, TypeJSStrictEqual) { TEST_F(TyperTest, TypeJSStrictEqual) {
TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHint::kAny),
std::equal_to<double>()); std::equal_to<double>());
} }
TEST_F(TyperTest, TypeJSStrictNotEqual) { TEST_F(TyperTest, TypeJSStrictNotEqual) {
TestBinaryCompareOp(javascript_.StrictNotEqual(CompareOperationHints::Any()), TestBinaryCompareOp(javascript_.StrictNotEqual(CompareOperationHint::kAny),
std::not_equal_to<double>()); std::not_equal_to<double>());
} }
...@@ -344,7 +344,7 @@ TEST_F(TyperTest, TypeJSStrictNotEqual) { ...@@ -344,7 +344,7 @@ TEST_F(TyperTest, TypeJSStrictNotEqual) {
#define TEST_BINARY_MONOTONICITY(name) \ #define TEST_BINARY_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \ TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(javascript_.name(CompareOperationHints::Any())); \ TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \
} }
TEST_BINARY_MONOTONICITY(Equal) TEST_BINARY_MONOTONICITY(Equal)
TEST_BINARY_MONOTONICITY(NotEqual) TEST_BINARY_MONOTONICITY(NotEqual)
...@@ -358,7 +358,7 @@ TEST_BINARY_MONOTONICITY(GreaterThanOrEqual) ...@@ -358,7 +358,7 @@ TEST_BINARY_MONOTONICITY(GreaterThanOrEqual)
#define TEST_BINARY_MONOTONICITY(name) \ #define TEST_BINARY_MONOTONICITY(name) \
TEST_F(TyperTest, Monotonicity_##name) { \ TEST_F(TyperTest, Monotonicity_##name) { \
TestBinaryMonotonicity(javascript_.name(BinaryOperationHints::Any())); \ TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \
} }
TEST_BINARY_MONOTONICITY(BitwiseOr) TEST_BINARY_MONOTONICITY(BitwiseOr)
TEST_BINARY_MONOTONICITY(BitwiseXor) TEST_BINARY_MONOTONICITY(BitwiseXor)
......
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