[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:
bmeurer 2016-08-09 11:11:56 -07:00 committed by Commit bot
parent 2028c0931e
commit a12aa89151
14 changed files with 466 additions and 697 deletions

View File

@ -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);
}

View File

@ -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,

View File

@ -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();

View File

@ -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.

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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));

View File

@ -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());

View File

@ -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());

View File

@ -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)