[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}
This commit is contained in:
parent
2028c0931e
commit
a12aa89151
@ -282,8 +282,7 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
|
||||
}
|
||||
Node* NewPathDispatchCondition(Node* t1, Node* t2) {
|
||||
return owner_->NewNode(
|
||||
owner_->javascript()->StrictEqual(CompareOperationHints::Any()), t1,
|
||||
t2);
|
||||
owner_->javascript()->StrictEqual(CompareOperationHint::kAny), t1, t2);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1274,14 +1273,14 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
Node* label = environment()->Pop();
|
||||
Node* tag = environment()->Top();
|
||||
|
||||
CompareOperationHints hints;
|
||||
CompareOperationHint hint;
|
||||
if (!type_hint_analysis_ ||
|
||||
!type_hint_analysis_->GetCompareOperationHints(clause->CompareId(),
|
||||
&hints)) {
|
||||
hints = CompareOperationHints::Any();
|
||||
!type_hint_analysis_->GetCompareOperationHint(clause->CompareId(),
|
||||
&hint)) {
|
||||
hint = CompareOperationHint::kAny;
|
||||
}
|
||||
|
||||
const Operator* op = javascript()->StrictEqual(hints);
|
||||
const Operator* op = javascript()->StrictEqual(hint);
|
||||
Node* condition = NewNode(op, tag, label);
|
||||
compare_switch.BeginLabel(i, condition);
|
||||
|
||||
@ -1357,11 +1356,11 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
||||
for_block.BeginBlock();
|
||||
// Check for null or undefined before entering loop.
|
||||
Node* is_null_cond =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object,
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object,
|
||||
jsgraph()->NullConstant());
|
||||
for_block.BreakWhen(is_null_cond, BranchHint::kFalse);
|
||||
Node* is_undefined_cond =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object,
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object,
|
||||
jsgraph()->UndefinedConstant());
|
||||
for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse);
|
||||
{
|
||||
@ -1406,8 +1405,8 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
||||
OutputFrameStateCombine::Push());
|
||||
IfBuilder test_value(this);
|
||||
Node* test_value_cond =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
value, jsgraph()->UndefinedConstant());
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), value,
|
||||
jsgraph()->UndefinedConstant());
|
||||
test_value.If(test_value_cond, BranchHint::kFalse);
|
||||
test_value.Then();
|
||||
test_value.Else();
|
||||
@ -2756,10 +2755,10 @@ void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr,
|
||||
const Operator* op = nullptr;
|
||||
switch (expr->op()) {
|
||||
case Token::EQ:
|
||||
op = javascript()->Equal(CompareOperationHints::Any());
|
||||
op = javascript()->Equal(CompareOperationHint::kAny);
|
||||
break;
|
||||
case Token::EQ_STRICT:
|
||||
op = javascript()->StrictEqual(CompareOperationHints::Any());
|
||||
op = javascript()->StrictEqual(CompareOperationHint::kAny);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -2776,7 +2775,7 @@ void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr,
|
||||
Handle<String> check) {
|
||||
VisitTypeofExpression(sub_expr);
|
||||
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));
|
||||
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
|
||||
return ast_context()->ProduceValue(expr, value);
|
||||
@ -2799,38 +2798,38 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
||||
return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant());
|
||||
}
|
||||
|
||||
CompareOperationHints hints;
|
||||
CompareOperationHint hint;
|
||||
if (!type_hint_analysis_ ||
|
||||
!type_hint_analysis_->GetCompareOperationHints(
|
||||
expr->CompareOperationFeedbackId(), &hints)) {
|
||||
hints = CompareOperationHints::Any();
|
||||
!type_hint_analysis_->GetCompareOperationHint(
|
||||
expr->CompareOperationFeedbackId(), &hint)) {
|
||||
hint = CompareOperationHint::kAny;
|
||||
}
|
||||
|
||||
const Operator* op;
|
||||
switch (expr->op()) {
|
||||
case Token::EQ:
|
||||
op = javascript()->Equal(hints);
|
||||
op = javascript()->Equal(hint);
|
||||
break;
|
||||
case Token::NE:
|
||||
op = javascript()->NotEqual(hints);
|
||||
op = javascript()->NotEqual(hint);
|
||||
break;
|
||||
case Token::EQ_STRICT:
|
||||
op = javascript()->StrictEqual(hints);
|
||||
op = javascript()->StrictEqual(hint);
|
||||
break;
|
||||
case Token::NE_STRICT:
|
||||
op = javascript()->StrictNotEqual(hints);
|
||||
op = javascript()->StrictNotEqual(hint);
|
||||
break;
|
||||
case Token::LT:
|
||||
op = javascript()->LessThan(hints);
|
||||
op = javascript()->LessThan(hint);
|
||||
break;
|
||||
case Token::GT:
|
||||
op = javascript()->GreaterThan(hints);
|
||||
op = javascript()->GreaterThan(hint);
|
||||
break;
|
||||
case Token::LTE:
|
||||
op = javascript()->LessThanOrEqual(hints);
|
||||
op = javascript()->LessThanOrEqual(hint);
|
||||
break;
|
||||
case Token::GTE:
|
||||
op = javascript()->GreaterThanOrEqual(hints);
|
||||
op = javascript()->GreaterThanOrEqual(hint);
|
||||
break;
|
||||
case Token::INSTANCEOF:
|
||||
op = javascript()->InstanceOf();
|
||||
@ -3272,7 +3271,7 @@ Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable,
|
||||
BailoutId bailout_id) {
|
||||
IfBuilder hole_check(this);
|
||||
Node* the_hole = jsgraph()->TheHoleConstant();
|
||||
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
|
||||
value, the_hole);
|
||||
hole_check.If(check);
|
||||
hole_check.Then();
|
||||
@ -3290,7 +3289,7 @@ Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable,
|
||||
BailoutId bailout_id) {
|
||||
IfBuilder hole_check(this);
|
||||
Node* the_hole = jsgraph()->TheHoleConstant();
|
||||
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
|
||||
value, the_hole);
|
||||
hole_check.If(check);
|
||||
hole_check.Then();
|
||||
@ -3308,7 +3307,7 @@ Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
|
||||
IfBuilder prototype_check(this);
|
||||
Node* 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);
|
||||
prototype_check.If(check);
|
||||
prototype_check.Then();
|
||||
@ -3778,44 +3777,44 @@ Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
|
||||
Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op,
|
||||
TypeFeedbackId feedback_id) {
|
||||
const Operator* js_op;
|
||||
BinaryOperationHints hints;
|
||||
BinaryOperationHint hint;
|
||||
if (!type_hint_analysis_ ||
|
||||
!type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) {
|
||||
hints = BinaryOperationHints::Any();
|
||||
!type_hint_analysis_->GetBinaryOperationHint(feedback_id, &hint)) {
|
||||
hint = BinaryOperationHint::kAny;
|
||||
}
|
||||
switch (op) {
|
||||
case Token::BIT_OR:
|
||||
js_op = javascript()->BitwiseOr(hints);
|
||||
js_op = javascript()->BitwiseOr(hint);
|
||||
break;
|
||||
case Token::BIT_AND:
|
||||
js_op = javascript()->BitwiseAnd(hints);
|
||||
js_op = javascript()->BitwiseAnd(hint);
|
||||
break;
|
||||
case Token::BIT_XOR:
|
||||
js_op = javascript()->BitwiseXor(hints);
|
||||
js_op = javascript()->BitwiseXor(hint);
|
||||
break;
|
||||
case Token::SHL:
|
||||
js_op = javascript()->ShiftLeft(hints);
|
||||
js_op = javascript()->ShiftLeft(hint);
|
||||
break;
|
||||
case Token::SAR:
|
||||
js_op = javascript()->ShiftRight(hints);
|
||||
js_op = javascript()->ShiftRight(hint);
|
||||
break;
|
||||
case Token::SHR:
|
||||
js_op = javascript()->ShiftRightLogical(hints);
|
||||
js_op = javascript()->ShiftRightLogical(hint);
|
||||
break;
|
||||
case Token::ADD:
|
||||
js_op = javascript()->Add(hints);
|
||||
js_op = javascript()->Add(hint);
|
||||
break;
|
||||
case Token::SUB:
|
||||
js_op = javascript()->Subtract(hints);
|
||||
js_op = javascript()->Subtract(hint);
|
||||
break;
|
||||
case Token::MUL:
|
||||
js_op = javascript()->Multiply(hints);
|
||||
js_op = javascript()->Multiply(hint);
|
||||
break;
|
||||
case Token::DIV:
|
||||
js_op = javascript()->Divide(hints);
|
||||
js_op = javascript()->Divide(hint);
|
||||
break;
|
||||
case Token::MOD:
|
||||
js_op = javascript()->Modulus(hints);
|
||||
js_op = javascript()->Modulus(hint);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -3860,7 +3859,7 @@ Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
|
||||
javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
|
||||
current_context());
|
||||
Node* check =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load,
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
|
||||
jsgraph()->TheHoleConstant());
|
||||
fast_block.BreakUnless(check, BranchHint::kTrue);
|
||||
}
|
||||
@ -3907,7 +3906,7 @@ Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
|
||||
javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
|
||||
current_context());
|
||||
Node* check =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load,
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
|
||||
jsgraph()->TheHoleConstant());
|
||||
fast_block.BreakUnless(check, BranchHint::kTrue);
|
||||
}
|
||||
|
@ -1172,21 +1172,21 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
|
||||
|
||||
// Helper function to create binary operation hint from the recorded type
|
||||
// feedback.
|
||||
BinaryOperationHints BytecodeGraphBuilder::GetBinaryOperationHint() {
|
||||
BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint() {
|
||||
FeedbackVectorSlot slot =
|
||||
feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(1));
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::GENERAL, feedback_vector()->GetKind(slot));
|
||||
Object* feedback = feedback_vector()->Get(slot);
|
||||
BinaryOperationHints::Hint hint = BinaryOperationHints::Hint::kAny;
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
if (feedback->IsSmi()) {
|
||||
hint = BinaryOperationHintFromFeedback((Smi::cast(feedback))->value());
|
||||
}
|
||||
return BinaryOperationHints(hint, hint, hint);
|
||||
return hint;
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitAdd() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->Add(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->Add(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitSub() {
|
||||
@ -1194,48 +1194,48 @@ void BytecodeGraphBuilder::VisitSub() {
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitMul() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->Multiply(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->Multiply(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitDiv() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->Divide(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->Divide(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitMod() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->Modulus(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->Modulus(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitBitwiseOr() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->BitwiseOr(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->BitwiseOr(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitBitwiseXor() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->BitwiseXor(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->BitwiseXor(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitBitwiseAnd() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->BitwiseAnd(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->BitwiseAnd(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitShiftLeft() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->ShiftLeft(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->ShiftLeft(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitShiftRight() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->ShiftRight(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->ShiftRight(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitShiftRightLogical() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOp(javascript()->ShiftRightLogical(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOp(javascript()->ShiftRightLogical(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
|
||||
@ -1248,40 +1248,40 @@ void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitAddSmi() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOpWithImmediate(javascript()->Add(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOpWithImmediate(javascript()->Add(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitSubSmi() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOpWithImmediate(javascript()->Subtract(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOpWithImmediate(javascript()->Subtract(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOpWithImmediate(javascript()->BitwiseOr(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOpWithImmediate(javascript()->BitwiseOr(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitShiftLeftSmi() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOpWithImmediate(javascript()->ShiftLeft(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOpWithImmediate(javascript()->ShiftLeft(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitShiftRightSmi() {
|
||||
BinaryOperationHints hints = BinaryOperationHints::Any();
|
||||
BuildBinaryOpWithImmediate(javascript()->ShiftRight(hints));
|
||||
BinaryOperationHint hint = BinaryOperationHint::kAny;
|
||||
BuildBinaryOpWithImmediate(javascript()->ShiftRight(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitInc() {
|
||||
FrameStateBeforeAndAfter states(this);
|
||||
// Note: Use subtract -1 here instead of add 1 to ensure we always convert to
|
||||
// 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(),
|
||||
jsgraph()->Constant(-1.0));
|
||||
environment()->BindAccumulator(node, &states);
|
||||
@ -1289,7 +1289,7 @@ void BytecodeGraphBuilder::VisitInc() {
|
||||
|
||||
void BytecodeGraphBuilder::VisitDec() {
|
||||
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(),
|
||||
jsgraph()->OneConstant());
|
||||
environment()->BindAccumulator(node, &states);
|
||||
@ -1344,38 +1344,38 @@ void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestEqual() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->Equal(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->Equal(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestNotEqual() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->NotEqual(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->NotEqual(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestEqualStrict() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->StrictEqual(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->StrictEqual(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestLessThan() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->LessThan(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->LessThan(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestGreaterThan() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->GreaterThan(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->GreaterThan(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->LessThanOrEqual(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->LessThanOrEqual(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
|
||||
CompareOperationHints hints = CompareOperationHints::Any();
|
||||
BuildCompareOp(javascript()->GreaterThanOrEqual(hints));
|
||||
CompareOperationHint hint = CompareOperationHint::kAny;
|
||||
BuildCompareOp(javascript()->GreaterThanOrEqual(hint));
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitTestIn() {
|
||||
@ -1686,7 +1686,7 @@ void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
|
||||
void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
|
||||
Node* accumulator = environment()->LookupAccumulator();
|
||||
Node* condition =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
|
||||
accumulator, comperand);
|
||||
BuildConditionalJump(condition);
|
||||
}
|
||||
@ -1697,15 +1697,15 @@ void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
|
||||
Node* to_boolean =
|
||||
NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
|
||||
Node* condition =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
to_boolean, comperand);
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), to_boolean,
|
||||
comperand);
|
||||
BuildConditionalJump(condition);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfNotHole() {
|
||||
Node* accumulator = environment()->LookupAccumulator();
|
||||
Node* condition =
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
|
||||
accumulator, jsgraph()->TheHoleConstant());
|
||||
Node* node =
|
||||
NewNode(common()->Select(MachineRepresentation::kTagged), condition,
|
||||
|
@ -137,7 +137,7 @@ class BytecodeGraphBuilder {
|
||||
|
||||
// Helper function to create binary operation hint from the recorded
|
||||
// type feedback.
|
||||
BinaryOperationHints GetBinaryOperationHint();
|
||||
BinaryOperationHint GetBinaryOperationHint();
|
||||
|
||||
// Control flow plumbing.
|
||||
void BuildJump();
|
||||
|
@ -376,7 +376,7 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
|
||||
return OpParameter<CreateLiteralParameters>(op);
|
||||
}
|
||||
|
||||
const BinaryOperationHints& BinaryOperationHintsOf(const Operator* op) {
|
||||
const BinaryOperationHint BinaryOperationHintOf(const Operator* op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr ||
|
||||
op->opcode() == IrOpcode::kJSBitwiseXor ||
|
||||
op->opcode() == IrOpcode::kJSBitwiseAnd ||
|
||||
@ -388,10 +388,10 @@ const BinaryOperationHints& BinaryOperationHintsOf(const Operator* op) {
|
||||
op->opcode() == IrOpcode::kJSMultiply ||
|
||||
op->opcode() == IrOpcode::kJSDivide ||
|
||||
op->opcode() == IrOpcode::kJSModulus);
|
||||
return OpParameter<BinaryOperationHints>(op);
|
||||
return OpParameter<BinaryOperationHint>(op);
|
||||
}
|
||||
|
||||
const CompareOperationHints& CompareOperationHintsOf(const Operator* op) {
|
||||
const CompareOperationHint CompareOperationHintOf(const Operator* op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kJSEqual ||
|
||||
op->opcode() == IrOpcode::kJSNotEqual ||
|
||||
op->opcode() == IrOpcode::kJSStrictEqual ||
|
||||
@ -400,7 +400,7 @@ const CompareOperationHints& CompareOperationHintsOf(const Operator* op) {
|
||||
op->opcode() == IrOpcode::kJSGreaterThan ||
|
||||
op->opcode() == IrOpcode::kJSLessThanOrEqual ||
|
||||
op->opcode() == IrOpcode::kJSGreaterThanOrEqual);
|
||||
return OpParameter<CompareOperationHints>(op);
|
||||
return OpParameter<CompareOperationHint>(op);
|
||||
}
|
||||
|
||||
#define CACHED_OP_LIST(V) \
|
||||
@ -425,210 +425,132 @@ const CompareOperationHints& CompareOperationHintsOf(const Operator* op) {
|
||||
V(StackCheck, Operator::kNoWrite, 0, 0) \
|
||||
V(CreateWithContext, Operator::kNoProperties, 2, 1)
|
||||
|
||||
struct JSOperatorGlobalCache final {
|
||||
#define CACHED(Name, properties, value_input_count, value_output_count) \
|
||||
struct Name##Operator final : public Operator { \
|
||||
Name##Operator() \
|
||||
: Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \
|
||||
value_input_count, Operator::ZeroIfPure(properties), \
|
||||
Operator::ZeroIfEliminatable(properties), \
|
||||
value_output_count, Operator::ZeroIfPure(properties), \
|
||||
Operator::ZeroIfNoThrow(properties)) {} \
|
||||
}; \
|
||||
Name##Operator k##Name##Operator;
|
||||
CACHED_OP_LIST(CACHED)
|
||||
#undef CACHED
|
||||
};
|
||||
#define BINARY_OP_LIST(V) \
|
||||
V(BitwiseOr) \
|
||||
V(BitwiseXor) \
|
||||
V(BitwiseAnd) \
|
||||
V(ShiftLeft) \
|
||||
V(ShiftRight) \
|
||||
V(ShiftRightLogical) \
|
||||
V(Add) \
|
||||
V(Subtract) \
|
||||
V(Multiply) \
|
||||
V(Divide) \
|
||||
V(Modulus)
|
||||
|
||||
#define COMPARE_OP_LIST(V) \
|
||||
V(Equal, Operator::kNoProperties) \
|
||||
V(NotEqual, Operator::kNoProperties) \
|
||||
V(StrictEqual, Operator::kPure) \
|
||||
V(StrictNotEqual, Operator::kPure) \
|
||||
V(LessThan, Operator::kNoProperties) \
|
||||
V(GreaterThan, Operator::kNoProperties) \
|
||||
V(LessThanOrEqual, Operator::kNoProperties) \
|
||||
V(GreaterThanOrEqual, Operator::kNoProperties)
|
||||
|
||||
struct JSOperatorGlobalCache final {
|
||||
#define CACHED_OP(Name, properties, value_input_count, value_output_count) \
|
||||
struct Name##Operator final : public Operator { \
|
||||
Name##Operator() \
|
||||
: Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \
|
||||
value_input_count, Operator::ZeroIfPure(properties), \
|
||||
Operator::ZeroIfEliminatable(properties), \
|
||||
value_output_count, Operator::ZeroIfPure(properties), \
|
||||
Operator::ZeroIfNoThrow(properties)) {} \
|
||||
}; \
|
||||
Name##Operator k##Name##Operator;
|
||||
CACHED_OP_LIST(CACHED_OP)
|
||||
#undef CACHED_OP
|
||||
|
||||
#define BINARY_OP(Name) \
|
||||
template <BinaryOperationHint kHint> \
|
||||
struct Name##Operator final : public Operator1<BinaryOperationHint> { \
|
||||
Name##Operator() \
|
||||
: Operator1<BinaryOperationHint>(IrOpcode::kJS##Name, \
|
||||
Operator::kNoProperties, "JS" #Name, \
|
||||
2, 1, 1, 1, 1, 2, kHint) {} \
|
||||
}; \
|
||||
Name##Operator<BinaryOperationHint::kNone> k##Name##NoneOperator; \
|
||||
Name##Operator<BinaryOperationHint::kSignedSmall> \
|
||||
k##Name##SignedSmallOperator; \
|
||||
Name##Operator<BinaryOperationHint::kSigned32> k##Name##Signed32Operator; \
|
||||
Name##Operator<BinaryOperationHint::kNumberOrOddball> \
|
||||
k##Name##NumberOrOddballOperator; \
|
||||
Name##Operator<BinaryOperationHint::kAny> k##Name##AnyOperator;
|
||||
BINARY_OP_LIST(BINARY_OP)
|
||||
#undef BINARY_OP
|
||||
|
||||
#define COMPARE_OP(Name, properties) \
|
||||
template <CompareOperationHint kHint> \
|
||||
struct Name##Operator final : public Operator1<CompareOperationHint> { \
|
||||
Name##Operator() \
|
||||
: Operator1<CompareOperationHint>( \
|
||||
IrOpcode::kJS##Name, properties, "JS" #Name, 2, 1, 1, 1, 1, \
|
||||
Operator::ZeroIfNoThrow(properties), kHint) {} \
|
||||
}; \
|
||||
Name##Operator<CompareOperationHint::kNone> k##Name##NoneOperator; \
|
||||
Name##Operator<CompareOperationHint::kSignedSmall> \
|
||||
k##Name##SignedSmallOperator; \
|
||||
Name##Operator<CompareOperationHint::kNumber> k##Name##NumberOperator; \
|
||||
Name##Operator<CompareOperationHint::kNumberOrOddball> \
|
||||
k##Name##NumberOrOddballOperator; \
|
||||
Name##Operator<CompareOperationHint::kAny> k##Name##AnyOperator;
|
||||
COMPARE_OP_LIST(COMPARE_OP)
|
||||
#undef COMPARE_OP
|
||||
};
|
||||
|
||||
static base::LazyInstance<JSOperatorGlobalCache>::type kCache =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
|
||||
JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
|
||||
: cache_(kCache.Get()), zone_(zone) {}
|
||||
|
||||
|
||||
#define CACHED(Name, properties, value_input_count, value_output_count) \
|
||||
const Operator* JSOperatorBuilder::Name() { \
|
||||
return &cache_.k##Name##Operator; \
|
||||
#define CACHED_OP(Name, properties, value_input_count, value_output_count) \
|
||||
const Operator* JSOperatorBuilder::Name() { \
|
||||
return &cache_.k##Name##Operator; \
|
||||
}
|
||||
CACHED_OP_LIST(CACHED)
|
||||
#undef CACHED
|
||||
CACHED_OP_LIST(CACHED_OP)
|
||||
#undef CACHED_OP
|
||||
|
||||
const Operator* JSOperatorBuilder::BitwiseOr(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSBitwiseOr, Operator::kNoProperties, // opcode
|
||||
"JSBitwiseOr", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
#define BINARY_OP(Name) \
|
||||
const Operator* JSOperatorBuilder::Name(BinaryOperationHint hint) { \
|
||||
switch (hint) { \
|
||||
case BinaryOperationHint::kNone: \
|
||||
return &cache_.k##Name##NoneOperator; \
|
||||
case BinaryOperationHint::kSignedSmall: \
|
||||
return &cache_.k##Name##SignedSmallOperator; \
|
||||
case BinaryOperationHint::kSigned32: \
|
||||
return &cache_.k##Name##Signed32Operator; \
|
||||
case BinaryOperationHint::kNumberOrOddball: \
|
||||
return &cache_.k##Name##NumberOrOddballOperator; \
|
||||
case BinaryOperationHint::kAny: \
|
||||
return &cache_.k##Name##AnyOperator; \
|
||||
} \
|
||||
UNREACHABLE(); \
|
||||
return nullptr; \
|
||||
}
|
||||
BINARY_OP_LIST(BINARY_OP)
|
||||
#undef BINARY_OP
|
||||
|
||||
const Operator* JSOperatorBuilder::BitwiseXor(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSBitwiseXor, Operator::kNoProperties, // opcode
|
||||
"JSBitwiseXor", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::BitwiseAnd(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSBitwiseAnd, Operator::kNoProperties, // opcode
|
||||
"JSBitwiseAnd", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::ShiftLeft(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSShiftLeft, Operator::kNoProperties, // opcode
|
||||
"JSShiftLeft", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::ShiftRight(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSShiftRight, Operator::kNoProperties, // opcode
|
||||
"JSShiftRight", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::ShiftRightLogical(
|
||||
BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSShiftRightLogical, Operator::kNoProperties, // opcode
|
||||
"JSShiftRightLogical", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::Add(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSAdd, Operator::kNoProperties, // opcode
|
||||
"JSAdd", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::Subtract(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSSubtract, Operator::kNoProperties, // opcode
|
||||
"JSSubtract", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::Multiply(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSMultiply, Operator::kNoProperties, // opcode
|
||||
"JSMultiply", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::Divide(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSDivide, Operator::kNoProperties, // opcode
|
||||
"JSDivide", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::Modulus(BinaryOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<BinaryOperationHints>( //--
|
||||
IrOpcode::kJSModulus, Operator::kNoProperties, // opcode
|
||||
"JSModulus", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::Equal(CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSEqual, Operator::kNoProperties, // opcode
|
||||
"JSEqual", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::NotEqual(CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSNotEqual, Operator::kNoProperties, // opcode
|
||||
"JSNotEqual", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::StrictEqual(CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSStrictEqual, Operator::kPure, // opcode
|
||||
"JSStrictEqual", // name
|
||||
2, 1, 1, 1, 1, 0, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::StrictNotEqual(CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSStrictNotEqual, Operator::kPure, // opcode
|
||||
"JSStrictNotEqual", // name
|
||||
2, 1, 1, 1, 1, 0, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::LessThan(CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSLessThan, Operator::kNoProperties, // opcode
|
||||
"JSLessThan", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::GreaterThan(CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSGreaterThan, Operator::kNoProperties, // opcode
|
||||
"JSGreaterThan", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::LessThanOrEqual(
|
||||
CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSLessThanOrEqual, Operator::kNoProperties, // opcode
|
||||
"JSLessThanOrEqual", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::GreaterThanOrEqual(
|
||||
CompareOperationHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
return new (zone()) Operator1<CompareOperationHints>( //--
|
||||
IrOpcode::kJSGreaterThanOrEqual, Operator::kNoProperties, // opcode
|
||||
"JSGreaterThanOrEqual", // name
|
||||
2, 1, 1, 1, 1, 2, // inputs/outputs
|
||||
hints); // parameter
|
||||
}
|
||||
#define COMPARE_OP(Name, ...) \
|
||||
const Operator* JSOperatorBuilder::Name(CompareOperationHint hint) { \
|
||||
switch (hint) { \
|
||||
case CompareOperationHint::kNone: \
|
||||
return &cache_.k##Name##NoneOperator; \
|
||||
case CompareOperationHint::kSignedSmall: \
|
||||
return &cache_.k##Name##SignedSmallOperator; \
|
||||
case CompareOperationHint::kNumber: \
|
||||
return &cache_.k##Name##NumberOperator; \
|
||||
case CompareOperationHint::kNumberOrOddball: \
|
||||
return &cache_.k##Name##NumberOrOddballOperator; \
|
||||
case CompareOperationHint::kAny: \
|
||||
return &cache_.k##Name##AnyOperator; \
|
||||
} \
|
||||
UNREACHABLE(); \
|
||||
return nullptr; \
|
||||
}
|
||||
COMPARE_OP_LIST(COMPARE_OP)
|
||||
#undef COMPARE_OP
|
||||
|
||||
const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
|
||||
// TODO(turbofan): Cache most important versions of this operator.
|
||||
|
@ -374,9 +374,9 @@ std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&);
|
||||
|
||||
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
|
||||
// AST. Most operators have no parameters, thus can be globally shared for all
|
||||
@ -385,25 +385,26 @@ class JSOperatorBuilder final : public ZoneObject {
|
||||
public:
|
||||
explicit JSOperatorBuilder(Zone* zone);
|
||||
|
||||
const Operator* Equal(CompareOperationHints hints);
|
||||
const Operator* NotEqual(CompareOperationHints hints);
|
||||
const Operator* StrictEqual(CompareOperationHints hints);
|
||||
const Operator* StrictNotEqual(CompareOperationHints hints);
|
||||
const Operator* LessThan(CompareOperationHints hints);
|
||||
const Operator* GreaterThan(CompareOperationHints hints);
|
||||
const Operator* LessThanOrEqual(CompareOperationHints hints);
|
||||
const Operator* GreaterThanOrEqual(CompareOperationHints hints);
|
||||
const Operator* BitwiseOr(BinaryOperationHints hints);
|
||||
const Operator* BitwiseXor(BinaryOperationHints hints);
|
||||
const Operator* BitwiseAnd(BinaryOperationHints hints);
|
||||
const Operator* ShiftLeft(BinaryOperationHints hints);
|
||||
const Operator* ShiftRight(BinaryOperationHints hints);
|
||||
const Operator* ShiftRightLogical(BinaryOperationHints hints);
|
||||
const Operator* Add(BinaryOperationHints hints);
|
||||
const Operator* Subtract(BinaryOperationHints hints);
|
||||
const Operator* Multiply(BinaryOperationHints hints);
|
||||
const Operator* Divide(BinaryOperationHints hints);
|
||||
const Operator* Modulus(BinaryOperationHints hints);
|
||||
const Operator* Equal(CompareOperationHint hint);
|
||||
const Operator* NotEqual(CompareOperationHint hint);
|
||||
const Operator* StrictEqual(CompareOperationHint hint);
|
||||
const Operator* StrictNotEqual(CompareOperationHint hint);
|
||||
const Operator* LessThan(CompareOperationHint hint);
|
||||
const Operator* GreaterThan(CompareOperationHint hint);
|
||||
const Operator* LessThanOrEqual(CompareOperationHint hint);
|
||||
const Operator* GreaterThanOrEqual(CompareOperationHint hint);
|
||||
|
||||
const Operator* BitwiseOr(BinaryOperationHint hint);
|
||||
const Operator* BitwiseXor(BinaryOperationHint hint);
|
||||
const Operator* BitwiseAnd(BinaryOperationHint hint);
|
||||
const Operator* ShiftLeft(BinaryOperationHint hint);
|
||||
const Operator* ShiftRight(BinaryOperationHint hint);
|
||||
const Operator* ShiftRightLogical(BinaryOperationHint hint);
|
||||
const Operator* Add(BinaryOperationHint hint);
|
||||
const Operator* Subtract(BinaryOperationHint hint);
|
||||
const Operator* Multiply(BinaryOperationHint hint);
|
||||
const Operator* Divide(BinaryOperationHint hint);
|
||||
const Operator* Modulus(BinaryOperationHint hint);
|
||||
|
||||
const Operator* ToBoolean(ToBooleanHints hints);
|
||||
const Operator* ToInteger();
|
||||
|
@ -33,20 +33,18 @@ class JSBinopReduction final {
|
||||
DCHECK_NE(0, node_->op()->ControlOutputCount());
|
||||
DCHECK_EQ(1, node_->op()->EffectOutputCount());
|
||||
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
|
||||
BinaryOperationHints hints = BinaryOperationHintsOf(node_->op());
|
||||
switch (hints.combined()) {
|
||||
case BinaryOperationHints::kSignedSmall:
|
||||
switch (BinaryOperationHintOf(node_->op())) {
|
||||
case BinaryOperationHint::kSignedSmall:
|
||||
*hint = NumberOperationHint::kSignedSmall;
|
||||
return true;
|
||||
case BinaryOperationHints::kSigned32:
|
||||
case BinaryOperationHint::kSigned32:
|
||||
*hint = NumberOperationHint::kSigned32;
|
||||
return true;
|
||||
case BinaryOperationHints::kNumberOrOddball:
|
||||
case BinaryOperationHint::kNumberOrOddball:
|
||||
*hint = NumberOperationHint::kNumberOrOddball;
|
||||
return true;
|
||||
case BinaryOperationHints::kAny:
|
||||
case BinaryOperationHints::kNone:
|
||||
case BinaryOperationHints::kString:
|
||||
case BinaryOperationHint::kAny:
|
||||
case BinaryOperationHint::kNone:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -56,24 +54,18 @@ class JSBinopReduction final {
|
||||
bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
|
||||
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
|
||||
DCHECK_EQ(1, node_->op()->EffectOutputCount());
|
||||
CompareOperationHints hints = CompareOperationHintsOf(node_->op());
|
||||
switch (hints.combined()) {
|
||||
case CompareOperationHints::kSignedSmall:
|
||||
switch (CompareOperationHintOf(node_->op())) {
|
||||
case CompareOperationHint::kSignedSmall:
|
||||
*hint = NumberOperationHint::kSignedSmall;
|
||||
return true;
|
||||
case CompareOperationHints::kNumber:
|
||||
case CompareOperationHint::kNumber:
|
||||
*hint = NumberOperationHint::kNumber;
|
||||
return true;
|
||||
case CompareOperationHints::kNumberOrOddball:
|
||||
case CompareOperationHint::kNumberOrOddball:
|
||||
*hint = NumberOperationHint::kNumberOrOddball;
|
||||
return true;
|
||||
case CompareOperationHints::kAny:
|
||||
case CompareOperationHints::kNone:
|
||||
case CompareOperationHints::kString:
|
||||
case CompareOperationHints::kBoolean:
|
||||
case CompareOperationHints::kUniqueName:
|
||||
case CompareOperationHints::kInternalizedString:
|
||||
case CompareOperationHints::kReceiver:
|
||||
case CompareOperationHint::kAny:
|
||||
case CompareOperationHint::kNone:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -15,76 +15,69 @@ namespace compiler {
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(bmeurer): This detour via types is ugly.
|
||||
BinaryOperationHints::Hint ToBinaryOperationHint(Type* type) {
|
||||
if (type->Is(Type::None())) return BinaryOperationHints::kNone;
|
||||
if (type->Is(Type::SignedSmall())) return BinaryOperationHints::kSignedSmall;
|
||||
if (type->Is(Type::Signed32())) return BinaryOperationHints::kSigned32;
|
||||
if (type->Is(Type::Number())) return BinaryOperationHints::kNumberOrOddball;
|
||||
if (type->Is(Type::String())) return BinaryOperationHints::kString;
|
||||
return BinaryOperationHints::kAny;
|
||||
}
|
||||
|
||||
CompareOperationHints::Hint ToCompareOperationHint(
|
||||
Token::Value op, CompareICState::State state) {
|
||||
switch (state) {
|
||||
case CompareICState::UNINITIALIZED:
|
||||
return CompareOperationHints::kNone;
|
||||
case CompareICState::BOOLEAN:
|
||||
return CompareOperationHints::kBoolean;
|
||||
case CompareICState::SMI:
|
||||
return CompareOperationHints::kSignedSmall;
|
||||
case CompareICState::NUMBER:
|
||||
return Token::IsOrderedRelationalCompareOp(op)
|
||||
? CompareOperationHints::kNumberOrOddball
|
||||
: CompareOperationHints::kNumber;
|
||||
case CompareICState::STRING:
|
||||
return CompareOperationHints::kString;
|
||||
case CompareICState::INTERNALIZED_STRING:
|
||||
return CompareOperationHints::kInternalizedString;
|
||||
case CompareICState::UNIQUE_NAME:
|
||||
return CompareOperationHints::kUniqueName;
|
||||
case CompareICState::RECEIVER:
|
||||
case CompareICState::KNOWN_RECEIVER:
|
||||
return CompareOperationHints::kReceiver;
|
||||
case CompareICState::GENERIC:
|
||||
return CompareOperationHints::kAny;
|
||||
BinaryOperationHint ToBinaryOperationHint(BinaryOpICState::Kind kind) {
|
||||
switch (kind) {
|
||||
case BinaryOpICState::NONE:
|
||||
return BinaryOperationHint::kNone;
|
||||
case BinaryOpICState::SMI:
|
||||
return BinaryOperationHint::kSignedSmall;
|
||||
case BinaryOpICState::INT32:
|
||||
return BinaryOperationHint::kSigned32;
|
||||
case BinaryOpICState::NUMBER:
|
||||
return BinaryOperationHint::kNumberOrOddball;
|
||||
case BinaryOpICState::STRING:
|
||||
case BinaryOpICState::GENERIC:
|
||||
return BinaryOperationHint::kAny;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return CompareOperationHints::kAny;
|
||||
return BinaryOperationHint::kNone;
|
||||
}
|
||||
|
||||
CompareOperationHint ToCompareOperationHint(Token::Value op,
|
||||
CompareICState::State state) {
|
||||
switch (state) {
|
||||
case CompareICState::UNINITIALIZED:
|
||||
return CompareOperationHint::kNone;
|
||||
case CompareICState::SMI:
|
||||
return CompareOperationHint::kSignedSmall;
|
||||
case CompareICState::NUMBER:
|
||||
return Token::IsOrderedRelationalCompareOp(op)
|
||||
? CompareOperationHint::kNumberOrOddball
|
||||
: CompareOperationHint::kNumber;
|
||||
case CompareICState::STRING:
|
||||
case CompareICState::INTERNALIZED_STRING:
|
||||
case CompareICState::UNIQUE_NAME:
|
||||
case CompareICState::RECEIVER:
|
||||
case CompareICState::KNOWN_RECEIVER:
|
||||
case CompareICState::BOOLEAN:
|
||||
case CompareICState::GENERIC:
|
||||
return CompareOperationHint::kAny;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return CompareOperationHint::kNone;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool TypeHintAnalysis::GetBinaryOperationHints(
|
||||
TypeFeedbackId id, BinaryOperationHints* hints) const {
|
||||
bool TypeHintAnalysis::GetBinaryOperationHint(TypeFeedbackId id,
|
||||
BinaryOperationHint* hint) const {
|
||||
auto i = infos_.find(id);
|
||||
if (i == infos_.end()) return false;
|
||||
Handle<Code> code = i->second;
|
||||
DCHECK_EQ(Code::BINARY_OP_IC, code->kind());
|
||||
BinaryOpICState state(code->GetIsolate(), code->extra_ic_state());
|
||||
*hints = BinaryOperationHints(ToBinaryOperationHint(state.GetLeftType()),
|
||||
ToBinaryOperationHint(state.GetRightType()),
|
||||
ToBinaryOperationHint(state.GetResultType()));
|
||||
*hint = ToBinaryOperationHint(state.kind());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeHintAnalysis::GetCompareOperationHints(
|
||||
TypeFeedbackId id, CompareOperationHints* hints) const {
|
||||
bool TypeHintAnalysis::GetCompareOperationHint(
|
||||
TypeFeedbackId id, CompareOperationHint* hint) const {
|
||||
auto i = infos_.find(id);
|
||||
if (i == infos_.end()) return false;
|
||||
Handle<Code> code = i->second;
|
||||
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());
|
||||
*hints =
|
||||
CompareOperationHints(ToCompareOperationHint(stub.op(), stub.left()),
|
||||
ToCompareOperationHint(stub.op(), stub.right()),
|
||||
ToCompareOperationHint(stub.op(), stub.state()));
|
||||
*hint = ToCompareOperationHint(stub.op(), stub.state());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -139,18 +132,19 @@ TypeHintAnalysis* TypeHintAnalyzer::Analyze(Handle<Code> code) {
|
||||
return new (zone()) TypeHintAnalysis(infos, zone());
|
||||
}
|
||||
|
||||
// Helper function to transform the feedback to BinaryOperationHints
|
||||
BinaryOperationHints::Hint BinaryOperationHintFromFeedback(int type_feedback) {
|
||||
// Helper function to transform the feedback to BinaryOperationHint.
|
||||
BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) {
|
||||
switch (type_feedback) {
|
||||
case BinaryOperationFeedback::kSignedSmall:
|
||||
return BinaryOperationHints::kSigned32;
|
||||
return BinaryOperationHint::kSigned32;
|
||||
case BinaryOperationFeedback::kNumber:
|
||||
return BinaryOperationHints::kNumberOrOddball;
|
||||
return BinaryOperationHint::kNumberOrOddball;
|
||||
case BinaryOperationFeedback::kAny:
|
||||
default:
|
||||
return BinaryOperationHints::kAny;
|
||||
return BinaryOperationHint::kAny;
|
||||
}
|
||||
return BinaryOperationHints::kAny;
|
||||
UNREACHABLE();
|
||||
return BinaryOperationHint::kNone;
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
|
@ -21,10 +21,10 @@ class TypeHintAnalysis final : public ZoneObject {
|
||||
explicit TypeHintAnalysis(Infos const& infos, Zone* zone)
|
||||
: infos_(infos), zone_(zone) {}
|
||||
|
||||
bool GetBinaryOperationHints(TypeFeedbackId id,
|
||||
BinaryOperationHints* hints) const;
|
||||
bool GetCompareOperationHints(TypeFeedbackId id,
|
||||
CompareOperationHints* hints) const;
|
||||
bool GetBinaryOperationHint(TypeFeedbackId id,
|
||||
BinaryOperationHint* hint) const;
|
||||
bool GetCompareOperationHint(TypeFeedbackId id,
|
||||
CompareOperationHint* hint) const;
|
||||
bool GetToBooleanHints(TypeFeedbackId id, ToBooleanHints* hints) const;
|
||||
|
||||
private:
|
||||
@ -50,7 +50,7 @@ class TypeHintAnalyzer final {
|
||||
DISALLOW_COPY_AND_ASSIGN(TypeHintAnalyzer);
|
||||
};
|
||||
|
||||
BinaryOperationHints::Hint BinaryOperationHintFromFeedback(int type_feedback);
|
||||
BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback);
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
|
@ -8,61 +8,40 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, BinaryOperationHints::Hint hint) {
|
||||
std::ostream& operator<<(std::ostream& os, BinaryOperationHint hint) {
|
||||
switch (hint) {
|
||||
case BinaryOperationHints::kNone:
|
||||
case BinaryOperationHint::kNone:
|
||||
return os << "None";
|
||||
case BinaryOperationHints::kSignedSmall:
|
||||
case BinaryOperationHint::kSignedSmall:
|
||||
return os << "SignedSmall";
|
||||
case BinaryOperationHints::kSigned32:
|
||||
case BinaryOperationHint::kSigned32:
|
||||
return os << "Signed32";
|
||||
case BinaryOperationHints::kNumberOrOddball:
|
||||
case BinaryOperationHint::kNumberOrOddball:
|
||||
return os << "NumberOrOddball";
|
||||
case BinaryOperationHints::kString:
|
||||
return os << "String";
|
||||
case BinaryOperationHints::kAny:
|
||||
case BinaryOperationHint::kAny:
|
||||
return os << "Any";
|
||||
}
|
||||
UNREACHABLE();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, BinaryOperationHints hints) {
|
||||
return os << hints.left() << "*" << hints.right() << "->" << hints.result();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CompareOperationHints::Hint hint) {
|
||||
std::ostream& operator<<(std::ostream& os, CompareOperationHint hint) {
|
||||
switch (hint) {
|
||||
case CompareOperationHints::kNone:
|
||||
case CompareOperationHint::kNone:
|
||||
return os << "None";
|
||||
case CompareOperationHints::kBoolean:
|
||||
return os << "Boolean";
|
||||
case CompareOperationHints::kSignedSmall:
|
||||
case CompareOperationHint::kSignedSmall:
|
||||
return os << "SignedSmall";
|
||||
case CompareOperationHints::kNumber:
|
||||
case CompareOperationHint::kNumber:
|
||||
return os << "Number";
|
||||
case CompareOperationHints::kNumberOrOddball:
|
||||
case CompareOperationHint::kNumberOrOddball:
|
||||
return os << "NumberOrOddball";
|
||||
case CompareOperationHints::kString:
|
||||
return os << "String";
|
||||
case CompareOperationHints::kInternalizedString:
|
||||
return os << "InternalizedString";
|
||||
case CompareOperationHints::kUniqueName:
|
||||
return os << "UniqueName";
|
||||
case CompareOperationHints::kReceiver:
|
||||
return os << "Receiver";
|
||||
case CompareOperationHints::kAny:
|
||||
case CompareOperationHint::kAny:
|
||||
return os << "Any";
|
||||
}
|
||||
UNREACHABLE();
|
||||
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) {
|
||||
switch (hint) {
|
||||
case ToBooleanHint::kNone:
|
||||
@ -96,7 +75,7 @@ std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) {
|
||||
if (hints == ToBooleanHint::kAny) return os << "Any";
|
||||
if (hints == ToBooleanHint::kNone) return os << "None";
|
||||
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);
|
||||
if (hints & hint) {
|
||||
if (!first) os << "|";
|
||||
@ -107,34 +86,6 @@ std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) {
|
||||
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 internal
|
||||
} // namespace v8
|
||||
|
@ -13,100 +13,34 @@ namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
// Type hints for an binary operation.
|
||||
class BinaryOperationHints final {
|
||||
public:
|
||||
enum Hint { kNone, kSignedSmall, kSigned32, kNumberOrOddball, kString, kAny };
|
||||
|
||||
BinaryOperationHints() : BinaryOperationHints(kNone, kNone, kNone) {}
|
||||
BinaryOperationHints(Hint left, Hint right, Hint result)
|
||||
: 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_;
|
||||
enum class BinaryOperationHint : uint8_t {
|
||||
kNone,
|
||||
kSignedSmall,
|
||||
kSigned32,
|
||||
kNumberOrOddball,
|
||||
kAny
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, BinaryOperationHints::Hint);
|
||||
std::ostream& operator<<(std::ostream&, BinaryOperationHints);
|
||||
inline size_t hash_value(BinaryOperationHint hint) {
|
||||
return static_cast<unsigned>(hint);
|
||||
}
|
||||
|
||||
// Type hints for an binary operation.
|
||||
class CompareOperationHints final {
|
||||
public:
|
||||
enum Hint {
|
||||
kNone,
|
||||
kBoolean,
|
||||
kSignedSmall,
|
||||
kNumber,
|
||||
kNumberOrOddball,
|
||||
kString,
|
||||
kInternalizedString,
|
||||
kUniqueName,
|
||||
kReceiver,
|
||||
kAny
|
||||
};
|
||||
std::ostream& operator<<(std::ostream&, BinaryOperationHint);
|
||||
|
||||
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_;
|
||||
// Type hints for an compare operation.
|
||||
enum class CompareOperationHint : uint8_t {
|
||||
kNone,
|
||||
kSignedSmall,
|
||||
kNumber,
|
||||
kNumberOrOddball,
|
||||
kAny
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, CompareOperationHints::Hint);
|
||||
std::ostream& operator<<(std::ostream&, CompareOperationHints);
|
||||
inline size_t hash_value(CompareOperationHint hint) {
|
||||
return static_cast<unsigned>(hint);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream&, CompareOperationHint);
|
||||
|
||||
// Type hints for the ToBoolean type conversion.
|
||||
enum class ToBooleanHint : uint16_t {
|
||||
|
@ -128,11 +128,15 @@ class BinaryOpICState final BASE_EMBEDDED {
|
||||
|
||||
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:
|
||||
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;
|
||||
|
||||
static const char* KindToString(Kind kind);
|
||||
@ -140,6 +144,18 @@ class BinaryOpICState final BASE_EMBEDDED {
|
||||
static bool KindMaybeSmi(Kind kind) {
|
||||
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.
|
||||
STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
|
||||
|
@ -51,8 +51,8 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
|
||||
Typer typer;
|
||||
Node* context_node;
|
||||
JSTypedLowering::Flags flags;
|
||||
BinaryOperationHints const binop_hints = BinaryOperationHints::Any();
|
||||
CompareOperationHints const compare_hints = CompareOperationHints::Any();
|
||||
BinaryOperationHint const binop_hints = BinaryOperationHint::kAny;
|
||||
CompareOperationHint const compare_hints = CompareOperationHint::kAny;
|
||||
|
||||
Node* Parameter(Type* t, int32_t index = 0) {
|
||||
Node* n = graph.NewNode(common.Parameter(index), graph.start());
|
||||
@ -247,7 +247,7 @@ TEST(AddNumber1) {
|
||||
for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
|
||||
Node* p0 = R.Parameter(kNumberTypes[i], 0);
|
||||
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);
|
||||
|
||||
R.CheckBinop(IrOpcode::kNumberAdd, r);
|
||||
@ -575,13 +575,13 @@ TEST(StringComparison) {
|
||||
JSTypedLoweringTester R;
|
||||
|
||||
const Operator* ops[] = {
|
||||
R.javascript.LessThan(CompareOperationHints::Any()),
|
||||
R.javascript.LessThan(CompareOperationHint::kAny),
|
||||
R.simplified.StringLessThan(),
|
||||
R.javascript.LessThanOrEqual(CompareOperationHints::Any()),
|
||||
R.javascript.LessThanOrEqual(CompareOperationHint::kAny),
|
||||
R.simplified.StringLessThanOrEqual(),
|
||||
R.javascript.GreaterThan(CompareOperationHints::Any()),
|
||||
R.javascript.GreaterThan(CompareOperationHint::kAny),
|
||||
R.simplified.StringLessThan(),
|
||||
R.javascript.GreaterThanOrEqual(CompareOperationHints::Any()),
|
||||
R.javascript.GreaterThanOrEqual(CompareOperationHint::kAny),
|
||||
R.simplified.StringLessThanOrEqual()};
|
||||
|
||||
for (size_t i = 0; i < arraysize(kStringTypes); i++) {
|
||||
@ -623,13 +623,13 @@ TEST(NumberComparison) {
|
||||
JSTypedLoweringTester R;
|
||||
|
||||
const Operator* ops[] = {
|
||||
R.javascript.LessThan(CompareOperationHints::Any()),
|
||||
R.javascript.LessThan(CompareOperationHint::kAny),
|
||||
R.simplified.NumberLessThan(),
|
||||
R.javascript.LessThanOrEqual(CompareOperationHints::Any()),
|
||||
R.javascript.LessThanOrEqual(CompareOperationHint::kAny),
|
||||
R.simplified.NumberLessThanOrEqual(),
|
||||
R.javascript.GreaterThan(CompareOperationHints::Any()),
|
||||
R.javascript.GreaterThan(CompareOperationHint::kAny),
|
||||
R.simplified.NumberLessThan(),
|
||||
R.javascript.GreaterThanOrEqual(CompareOperationHints::Any()),
|
||||
R.javascript.GreaterThanOrEqual(CompareOperationHint::kAny),
|
||||
R.simplified.NumberLessThanOrEqual()};
|
||||
|
||||
Node* const p0 = R.Parameter(Type::Number(), 0);
|
||||
@ -665,7 +665,7 @@ TEST(MixedComparison1) {
|
||||
Node* p1 = R.Parameter(types[j], 1);
|
||||
{
|
||||
const Operator* less_than =
|
||||
R.javascript.LessThan(CompareOperationHints::Any());
|
||||
R.javascript.LessThan(CompareOperationHint::kAny);
|
||||
Node* cmp = R.Binop(less_than, p0, p1);
|
||||
Node* r = R.reduce(cmp);
|
||||
if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
|
||||
@ -811,8 +811,8 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
|
||||
|
||||
{
|
||||
const Operator* op =
|
||||
strict ? R->javascript.StrictEqual(CompareOperationHints::Any())
|
||||
: R->javascript.Equal(CompareOperationHints::Any());
|
||||
strict ? R->javascript.StrictEqual(CompareOperationHint::kAny)
|
||||
: R->javascript.Equal(CompareOperationHint::kAny);
|
||||
Node* eq = R->Binop(op, p0, p1);
|
||||
Node* r = R->reduce(eq);
|
||||
R->CheckBinop(expected, r);
|
||||
@ -820,8 +820,8 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
|
||||
|
||||
{
|
||||
const Operator* op =
|
||||
strict ? R->javascript.StrictNotEqual(CompareOperationHints::Any())
|
||||
: R->javascript.NotEqual(CompareOperationHints::Any());
|
||||
strict ? R->javascript.StrictNotEqual(CompareOperationHint::kAny)
|
||||
: R->javascript.NotEqual(CompareOperationHint::kAny);
|
||||
Node* ne = R->Binop(op, p0, p1);
|
||||
Node* n = R->reduce(ne);
|
||||
CHECK_EQ(IrOpcode::kBooleanNot, n->opcode());
|
||||
|
@ -394,9 +394,9 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
|
||||
Node* const control = graph()->start();
|
||||
TRACED_FOREACH(Type*, type, kJSTypes) {
|
||||
Node* const lhs = Parameter(type);
|
||||
Reduction r = Reduce(graph()->NewNode(
|
||||
javascript()->StrictEqual(CompareOperationHints::Any()), lhs, the_hole,
|
||||
context, effect, control));
|
||||
Reduction r = Reduce(
|
||||
graph()->NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
|
||||
lhs, the_hole, context, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsFalseConstant());
|
||||
}
|
||||
@ -410,7 +410,7 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
Reduction r = Reduce(
|
||||
graph()->NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
|
||||
graph()->NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
|
||||
lhs, rhs, context, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
|
||||
@ -421,13 +421,13 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
|
||||
// JSShiftLeft
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* const lhs = Parameter(Type::Signed32());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
TRACED_FORRANGE(double, rhs, 0, 31) {
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hint), lhs,
|
||||
NumberConstant(rhs), context,
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -437,30 +437,28 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* const lhs = Parameter(Type::Signed32());
|
||||
Node* const rhs = Parameter(Type::Unsigned32());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ShiftLeft(hints), lhs, rhs, context,
|
||||
Reduce(graph()->NewNode(javascript()->ShiftLeft(hint), lhs, rhs, context,
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsNumberShiftLeft(lhs, rhs));
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftLeftWithSignedSmallHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hints), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hint), lhs, rhs,
|
||||
UndefinedConstant(), EmptyFrameState(),
|
||||
effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsSpeculativeNumberShiftLeft(NumberOperationHint::kSignedSmall,
|
||||
@ -468,16 +466,14 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSignedSmallHint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32Hint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSigned32;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hints), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hint), lhs, rhs,
|
||||
UndefinedConstant(), EmptyFrameState(),
|
||||
effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsSpeculativeNumberShiftLeft(NumberOperationHint::kSigned32, lhs,
|
||||
@ -485,16 +481,14 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32Hint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftLeftWithNumberOrOddballHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kNumberOrOddball;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hints), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hint), lhs, rhs,
|
||||
UndefinedConstant(), EmptyFrameState(),
|
||||
effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsSpeculativeNumberShiftLeft(
|
||||
NumberOperationHint::kNumberOrOddball, lhs,
|
||||
@ -506,13 +500,13 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithNumberOrOddballHint) {
|
||||
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* const lhs = Parameter(Type::Signed32());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
TRACED_FORRANGE(double, rhs, 0, 31) {
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hint), lhs,
|
||||
NumberConstant(rhs), context,
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -523,28 +517,26 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
|
||||
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* const lhs = Parameter(Type::Signed32());
|
||||
Node* const rhs = Parameter(Type::Unsigned32());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ShiftRight(hints), lhs, rhs,
|
||||
context, EmptyFrameState(), effect, control));
|
||||
Reduce(graph()->NewNode(javascript()->ShiftRight(hint), lhs, rhs, context,
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsNumberShiftRight(lhs, rhs));
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightWithSignedSmallHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -554,14 +546,12 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSignedSmallHint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32Hint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSigned32;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -571,14 +561,12 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32Hint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightWithNumberOrOddballHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kNumberOrOddball;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -593,15 +581,15 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithNumberOrOddballHint) {
|
||||
|
||||
TEST_F(JSTypedLoweringTest,
|
||||
JSShiftRightLogicalWithUnsigned32AndConstant) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* const lhs = Parameter(Type::Unsigned32());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
TRACED_FORRANGE(double, rhs, 0, 31) {
|
||||
Reduction r = Reduce(graph()->NewNode(
|
||||
javascript()->ShiftRightLogical(hints), lhs, NumberConstant(rhs),
|
||||
context, EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hint),
|
||||
lhs, NumberConstant(rhs), context,
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsNumberShiftRightLogical(lhs, IsNumberConstant(BitEq(rhs))));
|
||||
@ -610,28 +598,26 @@ TEST_F(JSTypedLoweringTest,
|
||||
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* const lhs = Parameter(Type::Unsigned32());
|
||||
Node* const rhs = Parameter(Type::Unsigned32());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hints), lhs, rhs,
|
||||
Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hint), lhs, rhs,
|
||||
context, EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsNumberShiftRightLogical(lhs, rhs));
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithSignedSmallHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hints),
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hint),
|
||||
lhs, rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -641,14 +627,12 @@ TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithSignedSmallHint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithSigned32Hint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSigned32;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hints),
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hint),
|
||||
lhs, rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -658,14 +642,12 @@ TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithSigned32Hint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithNumberOrOddballHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kNumberOrOddball;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hints),
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hint),
|
||||
lhs, rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -985,14 +967,14 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) {
|
||||
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSAddWithString) {
|
||||
BinaryOperationHints const hints = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kAny;
|
||||
Node* lhs = Parameter(Type::String(), 0);
|
||||
Node* rhs = Parameter(Type::String(), 1);
|
||||
Node* context = Parameter(Type::Any(), 2);
|
||||
Node* frame_state = EmptyFrameState();
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->Add(hints), lhs, rhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->Add(hint), lhs, rhs,
|
||||
context, frame_state, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
@ -1004,16 +986,14 @@ TEST_F(JSTypedLoweringTest, JSAddWithString) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSAddSmis) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 0);
|
||||
Node* rhs = Parameter(Type::Number(), 1);
|
||||
Node* context = Parameter(Type::Any(), 2);
|
||||
Node* frame_state = EmptyFrameState();
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->Add(hints), lhs, rhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->Add(hint), lhs, rhs,
|
||||
context, frame_state, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
@ -1025,16 +1005,14 @@ TEST_F(JSTypedLoweringTest, JSAddSmis) {
|
||||
// JSSubtract
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSSubtractSmis) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 0);
|
||||
Node* rhs = Parameter(Type::Number(), 1);
|
||||
Node* context = Parameter(Type::Any(), 2);
|
||||
Node* frame_state = EmptyFrameState();
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->Subtract(hints), lhs, rhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->Subtract(hint), lhs, rhs,
|
||||
context, frame_state, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
@ -1108,14 +1086,12 @@ TEST_F(JSTypedLoweringTest, JSInstanceOfNoSpecialization) {
|
||||
// JSBitwiseAnd
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseAndWithSignedSmallHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseAnd(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseAnd(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -1125,14 +1101,12 @@ TEST_F(JSTypedLoweringTest, JSBitwiseAndWithSignedSmallHint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseAndWithSigned32Hint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSigned32;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseAnd(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseAnd(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -1142,14 +1116,12 @@ TEST_F(JSTypedLoweringTest, JSBitwiseAndWithSigned32Hint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseAndWithNumberOrOddballHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kNumberOrOddball;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseAnd(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseAnd(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -1162,16 +1134,14 @@ TEST_F(JSTypedLoweringTest, JSBitwiseAndWithNumberOrOddballHint) {
|
||||
// JSBitwiseOr
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseOrWithSignedSmallHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseOr(hints), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseOr(hint), lhs, rhs,
|
||||
UndefinedConstant(), EmptyFrameState(),
|
||||
effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsSpeculativeNumberBitwiseOr(NumberOperationHint::kSignedSmall,
|
||||
@ -1179,16 +1149,14 @@ TEST_F(JSTypedLoweringTest, JSBitwiseOrWithSignedSmallHint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseOrWithSigned32Hint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSigned32;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseOr(hints), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseOr(hint), lhs, rhs,
|
||||
UndefinedConstant(), EmptyFrameState(),
|
||||
effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsSpeculativeNumberBitwiseOr(NumberOperationHint::kSigned32, lhs,
|
||||
@ -1196,16 +1164,14 @@ TEST_F(JSTypedLoweringTest, JSBitwiseOrWithSigned32Hint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseOrWithNumberOrOddballHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kNumberOrOddball;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseOr(hints), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseOr(hint), lhs, rhs,
|
||||
UndefinedConstant(), EmptyFrameState(),
|
||||
effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseOr(
|
||||
NumberOperationHint::kNumberOrOddball, lhs,
|
||||
@ -1216,14 +1182,12 @@ TEST_F(JSTypedLoweringTest, JSBitwiseOrWithNumberOrOddballHint) {
|
||||
// JSBitwiseXor
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseXorWithSignedSmallHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall,
|
||||
BinaryOperationHints::kSignedSmall);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseXor(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseXor(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -1233,14 +1197,12 @@ TEST_F(JSTypedLoweringTest, JSBitwiseXorWithSignedSmallHint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseXorWithSigned32Hint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32,
|
||||
BinaryOperationHints::kSigned32);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kSigned32;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseXor(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseXor(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
@ -1250,14 +1212,12 @@ TEST_F(JSTypedLoweringTest, JSBitwiseXorWithSigned32Hint) {
|
||||
}
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSBitwiseXorWithNumberOrOddballHint) {
|
||||
BinaryOperationHints const hints(BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball,
|
||||
BinaryOperationHints::kNumberOrOddball);
|
||||
BinaryOperationHint const hint = BinaryOperationHint::kNumberOrOddball;
|
||||
Node* lhs = Parameter(Type::Number(), 2);
|
||||
Node* rhs = Parameter(Type::Number(), 3);
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseXor(hints), lhs,
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->BitwiseXor(hint), lhs,
|
||||
rhs, UndefinedConstant(),
|
||||
EmptyFrameState(), effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
|
@ -51,7 +51,7 @@ class TyperTest : public TypedGraphTest {
|
||||
|
||||
Types types_;
|
||||
JSOperatorBuilder javascript_;
|
||||
BinaryOperationHints const hints_ = BinaryOperationHints::Any();
|
||||
BinaryOperationHint const hints_ = BinaryOperationHint::kAny;
|
||||
Node* context_node_;
|
||||
v8::base::RandomNumberGenerator* rng_;
|
||||
std::vector<double> integers;
|
||||
@ -290,51 +290,51 @@ TEST_F(TyperTest, TypeJSShiftRight) {
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSLessThan) {
|
||||
TestBinaryCompareOp(javascript_.LessThan(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny),
|
||||
std::less<double>());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSLessThanOrEqual) {
|
||||
TestBinaryCompareOp(javascript_.LessThanOrEqual(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.LessThanOrEqual(CompareOperationHint::kAny),
|
||||
std::less_equal<double>());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSGreaterThan) {
|
||||
TestBinaryCompareOp(javascript_.GreaterThan(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.GreaterThan(CompareOperationHint::kAny),
|
||||
std::greater<double>());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSGreaterThanOrEqual) {
|
||||
TestBinaryCompareOp(
|
||||
javascript_.GreaterThanOrEqual(CompareOperationHints::Any()),
|
||||
javascript_.GreaterThanOrEqual(CompareOperationHint::kAny),
|
||||
std::greater_equal<double>());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSEqual) {
|
||||
TestBinaryCompareOp(javascript_.Equal(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny),
|
||||
std::equal_to<double>());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSNotEqual) {
|
||||
TestBinaryCompareOp(javascript_.NotEqual(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.NotEqual(CompareOperationHint::kAny),
|
||||
std::not_equal_to<double>());
|
||||
}
|
||||
|
||||
|
||||
// For numbers there's no difference between strict and non-strict equality.
|
||||
TEST_F(TyperTest, TypeJSStrictEqual) {
|
||||
TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHint::kAny),
|
||||
std::equal_to<double>());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TyperTest, TypeJSStrictNotEqual) {
|
||||
TestBinaryCompareOp(javascript_.StrictNotEqual(CompareOperationHints::Any()),
|
||||
TestBinaryCompareOp(javascript_.StrictNotEqual(CompareOperationHint::kAny),
|
||||
std::not_equal_to<double>());
|
||||
}
|
||||
|
||||
@ -342,9 +342,9 @@ TEST_F(TyperTest, TypeJSStrictNotEqual) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Monotonicity
|
||||
|
||||
#define TEST_BINARY_MONOTONICITY(name) \
|
||||
TEST_F(TyperTest, Monotonicity_##name) { \
|
||||
TestBinaryMonotonicity(javascript_.name(CompareOperationHints::Any())); \
|
||||
#define TEST_BINARY_MONOTONICITY(name) \
|
||||
TEST_F(TyperTest, Monotonicity_##name) { \
|
||||
TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \
|
||||
}
|
||||
TEST_BINARY_MONOTONICITY(Equal)
|
||||
TEST_BINARY_MONOTONICITY(NotEqual)
|
||||
@ -356,9 +356,9 @@ TEST_BINARY_MONOTONICITY(LessThanOrEqual)
|
||||
TEST_BINARY_MONOTONICITY(GreaterThanOrEqual)
|
||||
#undef TEST_BINARY_MONOTONICITY
|
||||
|
||||
#define TEST_BINARY_MONOTONICITY(name) \
|
||||
TEST_F(TyperTest, Monotonicity_##name) { \
|
||||
TestBinaryMonotonicity(javascript_.name(BinaryOperationHints::Any())); \
|
||||
#define TEST_BINARY_MONOTONICITY(name) \
|
||||
TEST_F(TyperTest, Monotonicity_##name) { \
|
||||
TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \
|
||||
}
|
||||
TEST_BINARY_MONOTONICITY(BitwiseOr)
|
||||
TEST_BINARY_MONOTONICITY(BitwiseXor)
|
||||
|
Loading…
Reference in New Issue
Block a user