Commit 2c8b5144 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Add NumberOperationHint for speculative number operations.

Introduce a dedicated NumberOperationHint enum that represents the
feedback we can use for speculative number operations.

BUG=v8:4930

Review-Url: https://codereview.chromium.org/2220573002
Cr-Commit-Position: refs/heads/master@{#38411}
parent 96c90f6c
This diff is collapsed.
...@@ -24,6 +24,7 @@ namespace compiler { ...@@ -24,6 +24,7 @@ namespace compiler {
class CommonOperatorBuilder; class CommonOperatorBuilder;
class JSGraph; class JSGraph;
class JSOperatorBuilder; class JSOperatorBuilder;
class MachineOperatorBuilder;
class SimplifiedOperatorBuilder; class SimplifiedOperatorBuilder;
...@@ -85,7 +86,7 @@ class JSTypedLowering final : public AdvancedReducer { ...@@ -85,7 +86,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSSubtract(Node* node); Reduction ReduceJSSubtract(Node* node);
Reduction ReduceJSDivide(Node* node); Reduction ReduceJSDivide(Node* node);
Reduction ReduceInt32Binop(Node* node, const Operator* intOp); Reduction ReduceInt32Binop(Node* node, const Operator* intOp);
Reduction ReduceUI32Shift(Node* node, Signedness left_signedness, Reduction ReduceUI32Shift(Node* node, Signedness signedness,
const Operator* shift_op); const Operator* shift_op);
Factory* factory() const; Factory* factory() const;
......
This diff is collapsed.
...@@ -269,7 +269,24 @@ ElementsTransition ElementsTransitionOf(const Operator* op) { ...@@ -269,7 +269,24 @@ ElementsTransition ElementsTransitionOf(const Operator* op) {
return OpParameter<ElementsTransition>(op); return OpParameter<ElementsTransition>(op);
} }
BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) { std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
switch (hint) {
case NumberOperationHint::kSignedSmall:
return os << "SignedSmall";
case NumberOperationHint::kSigned32:
return os << "Signed32";
case NumberOperationHint::kNumberOrOddball:
return os << "NumberOrOddball";
}
UNREACHABLE();
return os;
}
size_t hash_value(NumberOperationHint hint) {
return static_cast<uint8_t>(hint);
}
NumberOperationHint NumberOperationHintOf(const Operator* op) {
DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
op->opcode() == IrOpcode::kSpeculativeNumberSubtract || op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
op->opcode() == IrOpcode::kSpeculativeNumberMultiply || op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
...@@ -280,15 +297,11 @@ BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) { ...@@ -280,15 +297,11 @@ BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) {
op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical || op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd || op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr || op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor); op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
return OpParameter<BinaryOperationHints::Hint>(op); op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
}
CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
op->opcode() == IrOpcode::kSpeculativeNumberLessThan || op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual);
return OpParameter<CompareOperationHints::Hint>(op); return OpParameter<NumberOperationHint>(op);
} }
#define PURE_OP_LIST(V) \ #define PURE_OP_LIST(V) \
...@@ -370,18 +383,11 @@ CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) { ...@@ -370,18 +383,11 @@ CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
V(StringLessThan, Operator::kNoProperties, 2, 0) \ V(StringLessThan, Operator::kNoProperties, 2, 0) \
V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0)
#define SPECULATIVE_BINOP_LIST(V) \ #define SPECULATIVE_NUMBER_BINOP_LIST(V) \
V(SpeculativeNumberAdd) \ SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
V(SpeculativeNumberSubtract) \ V(SpeculativeNumberEqual) \
V(SpeculativeNumberDivide) \ V(SpeculativeNumberLessThan) \
V(SpeculativeNumberMultiply) \ V(SpeculativeNumberLessThanOrEqual)
V(SpeculativeNumberModulus) \
V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical) \
V(SpeculativeNumberBitwiseAnd) \
V(SpeculativeNumberBitwiseOr) \
V(SpeculativeNumberBitwiseXor)
#define CHECKED_OP_LIST(V) \ #define CHECKED_OP_LIST(V) \
V(CheckBounds, 2, 1) \ V(CheckBounds, 2, 1) \
...@@ -513,6 +519,22 @@ struct SimplifiedOperatorGlobalCache final { ...@@ -513,6 +519,22 @@ struct SimplifiedOperatorGlobalCache final {
}; };
EnsureWritableFastElementsOperator kEnsureWritableFastElements; EnsureWritableFastElementsOperator kEnsureWritableFastElements;
#define SPECULATIVE_NUMBER_BINOP(Name) \
template <NumberOperationHint kHint> \
struct Name##Operator final : public Operator1<NumberOperationHint> { \
Name##Operator() \
: Operator1<NumberOperationHint>( \
IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
#Name, 2, 1, 1, 1, 1, 0, kHint) {} \
}; \
Name##Operator<NumberOperationHint::kSignedSmall> \
k##Name##SignedSmallOperator; \
Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \
Name##Operator<NumberOperationHint::kNumberOrOddball> \
k##Name##NumberOrOddballOperator;
SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
#undef SPECULATIVE_NUMBER_BINOP
#define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \
struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \
LoadBuffer##Type##Operator() \ LoadBuffer##Type##Operator() \
...@@ -679,39 +701,21 @@ const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) { ...@@ -679,39 +701,21 @@ const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) {
return nullptr; return nullptr;
} }
#define SPECULATIVE_BINOP_DEF(Name) \ #define SPECULATIVE_NUMBER_BINOP(Name) \
const Operator* SimplifiedOperatorBuilder::Name( \ const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
BinaryOperationHints::Hint hint) { \ switch (hint) { \
return new (zone()) Operator1<BinaryOperationHints::Hint>( \ case NumberOperationHint::kSignedSmall: \
IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, 2, \ return &cache_.k##Name##SignedSmallOperator; \
1, 1, 1, 1, 0, hint); \ case NumberOperationHint::kSigned32: \
return &cache_.k##Name##Signed32Operator; \
case NumberOperationHint::kNumberOrOddball: \
return &cache_.k##Name##NumberOrOddballOperator; \
} \
UNREACHABLE(); \
return nullptr; \
} }
SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP_DEF) SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
#undef SPECULATIVE_BINOP_DEF #undef SPECULATIVE_NUMBER_BINOP
const Operator* SimplifiedOperatorBuilder::SpeculativeNumberEqual(
CompareOperationHints::Hint hint) {
return new (zone()) Operator1<CompareOperationHints::Hint>(
IrOpcode::kSpeculativeNumberEqual,
Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberEqual", 2, 1,
1, 1, 1, 0, hint);
}
const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThan(
CompareOperationHints::Hint hint) {
return new (zone()) Operator1<CompareOperationHints::Hint>(
IrOpcode::kSpeculativeNumberLessThan,
Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberLessThan", 2,
1, 1, 1, 1, 0, hint);
}
const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThanOrEqual(
CompareOperationHints::Hint hint) {
return new (zone()) Operator1<CompareOperationHints::Hint>(
IrOpcode::kSpeculativeNumberLessThanOrEqual,
Operator::kFoldable | Operator::kNoThrow,
"SpeculativeNumberLessThanOrEqual", 2, 1, 1, 1, 1, 0, hint);
}
#define ACCESS_OP_LIST(V) \ #define ACCESS_OP_LIST(V) \
V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <iosfwd> #include <iosfwd>
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
#include "src/compiler/type-hints.h"
#include "src/handles.h" #include "src/handles.h"
#include "src/machine-type.h" #include "src/machine-type.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -154,9 +153,19 @@ std::ostream& operator<<(std::ostream&, ElementsTransition); ...@@ -154,9 +153,19 @@ std::ostream& operator<<(std::ostream&, ElementsTransition);
ElementsTransition ElementsTransitionOf(const Operator* op) WARN_UNUSED_RESULT; ElementsTransition ElementsTransitionOf(const Operator* op) WARN_UNUSED_RESULT;
BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op); // A hint for speculative number operations.
enum class NumberOperationHint : uint8_t {
kSignedSmall, // Inputs were always Smi so far, output was in Smi range.
kSigned32, // Inputs and output were Signed32 so far.
kNumberOrOddball, // Inputs were Number or Oddball, output was Number.
};
size_t hash_value(NumberOperationHint);
std::ostream& operator<<(std::ostream&, NumberOperationHint);
CompareOperationHints::Hint CompareOperationHintOf(const Operator* op); NumberOperationHint NumberOperationHintOf(const Operator* op)
WARN_UNUSED_RESULT;
// Interface for building simplified operators, which represent the // Interface for building simplified operators, which represent the
// medium-level operations of V8, including adding numbers, allocating objects, // medium-level operations of V8, including adding numbers, allocating objects,
...@@ -238,23 +247,21 @@ class SimplifiedOperatorBuilder final : public ZoneObject { ...@@ -238,23 +247,21 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* NumberSilenceNaN(); const Operator* NumberSilenceNaN();
const Operator* SpeculativeNumberAdd(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
const Operator* SpeculativeNumberSubtract(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
const Operator* SpeculativeNumberMultiply(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
const Operator* SpeculativeNumberDivide(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
const Operator* SpeculativeNumberModulus(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
const Operator* SpeculativeNumberShiftLeft(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
const Operator* SpeculativeNumberShiftRight(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
const Operator* SpeculativeNumberShiftRightLogical( const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
const Operator* SpeculativeNumberBitwiseAnd(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
const Operator* SpeculativeNumberBitwiseOr(BinaryOperationHints::Hint hint); const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
const Operator* SpeculativeNumberBitwiseXor(BinaryOperationHints::Hint hint);
const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
const Operator* SpeculativeNumberLessThan(CompareOperationHints::Hint hint); const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
const Operator* SpeculativeNumberLessThanOrEqual( const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
CompareOperationHints::Hint hint);
const Operator* SpeculativeNumberEqual(CompareOperationHints::Hint hint);
const Operator* ReferenceEqual(Type* type); const Operator* ReferenceEqual(Type* type);
......
...@@ -802,10 +802,10 @@ class IsReferenceEqualMatcher final : public NodeMatcher { ...@@ -802,10 +802,10 @@ class IsReferenceEqualMatcher final : public NodeMatcher {
class IsSpeculativeBinopMatcher final : public NodeMatcher { class IsSpeculativeBinopMatcher final : public NodeMatcher {
public: public:
IsSpeculativeBinopMatcher( IsSpeculativeBinopMatcher(IrOpcode::Value opcode,
IrOpcode::Value opcode, const Matcher<NumberOperationHint>& hint_matcher,
const Matcher<BinaryOperationHints::Hint>& hint_matcher, const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher, const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) const Matcher<Node*>& control_matcher)
: NodeMatcher(opcode), : NodeMatcher(opcode),
...@@ -818,9 +818,8 @@ class IsSpeculativeBinopMatcher final : public NodeMatcher { ...@@ -818,9 +818,8 @@ class IsSpeculativeBinopMatcher final : public NodeMatcher {
bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
return (NodeMatcher::MatchAndExplain(node, listener) && return (NodeMatcher::MatchAndExplain(node, listener) &&
// TODO(bmeurer): The type parameter is currently ignored. // TODO(bmeurer): The type parameter is currently ignored.
PrintMatchAndExplain( PrintMatchAndExplain(OpParameter<NumberOperationHint>(node->op()),
OpParameter<BinaryOperationHints::Hint>(node->op()), "hints", "hints", hint_matcher_, listener) &&
hint_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
lhs_matcher_, listener) && lhs_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
...@@ -832,7 +831,7 @@ class IsSpeculativeBinopMatcher final : public NodeMatcher { ...@@ -832,7 +831,7 @@ class IsSpeculativeBinopMatcher final : public NodeMatcher {
} }
private: private:
const Matcher<BinaryOperationHints::Hint> hint_matcher_; const Matcher<NumberOperationHint> hint_matcher_;
const Matcher<Type*> type_matcher_; const Matcher<Type*> type_matcher_;
const Matcher<Node*> lhs_matcher_; const Matcher<Node*> lhs_matcher_;
const Matcher<Node*> rhs_matcher_; const Matcher<Node*> rhs_matcher_;
...@@ -2044,9 +2043,9 @@ Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, ...@@ -2044,9 +2043,9 @@ Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
} }
#define DEFINE_SPECULATIVE_BINOP_MATCHER(opcode) \ #define DEFINE_SPECULATIVE_BINOP_MATCHER(opcode) \
Matcher<Node*> Is##opcode( \ Matcher<Node*> Is##opcode(const Matcher<NumberOperationHint>& hint_matcher, \
const Matcher<BinaryOperationHints::Hint>& hint_matcher, \ const Matcher<Node*>& lhs_matcher, \
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, \ const Matcher<Node*>& rhs_matcher, \
const Matcher<Node*>& effect_matcher, \ const Matcher<Node*>& effect_matcher, \
const Matcher<Node*>& control_matcher) { \ const Matcher<Node*>& control_matcher) { \
return MakeMatcher(new IsSpeculativeBinopMatcher( \ return MakeMatcher(new IsSpeculativeBinopMatcher( \
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define V8_UNITTESTS_COMPILER_NODE_TEST_UTILS_H_ #define V8_UNITTESTS_COMPILER_NODE_TEST_UTILS_H_
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/compiler/type-hints.h" #include "src/compiler/simplified-operator.h"
#include "src/machine-type.h" #include "src/machine-type.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -213,9 +213,9 @@ Matcher<Node*> IsNumberAdd(const Matcher<Node*>& lhs_matcher, ...@@ -213,9 +213,9 @@ Matcher<Node*> IsNumberAdd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher); const Matcher<Node*>& rhs_matcher);
#define DECLARE_SPECULATIVE_BINOP_MATCHER(opcode) \ #define DECLARE_SPECULATIVE_BINOP_MATCHER(opcode) \
Matcher<Node*> Is##opcode( \ Matcher<Node*> Is##opcode(const Matcher<NumberOperationHint>& hint_matcher, \
const Matcher<BinaryOperationHints::Hint>& hint_matcher, \ const Matcher<Node*>& lhs_matcher, \
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, \ const Matcher<Node*>& rhs_matcher, \
const Matcher<Node*>& effect_matcher, \ const Matcher<Node*>& effect_matcher, \
const Matcher<Node*>& control_matcher); const Matcher<Node*>& control_matcher);
SPECULATIVE_BINOPS(DECLARE_SPECULATIVE_BINOP_MATCHER); SPECULATIVE_BINOPS(DECLARE_SPECULATIVE_BINOP_MATCHER);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment