| Index: src/compiler/node-matchers.h
|
| diff --git a/src/compiler/node-matchers.h b/src/compiler/node-matchers.h
|
| index b1147a7369f9801a75e24f22a2442347fbbfdf70..98e9899f0c850dbf618cdb96104bd49833851f20 100644
|
| --- a/src/compiler/node-matchers.h
|
| +++ b/src/compiler/node-matchers.h
|
| @@ -39,8 +39,11 @@ struct NodeMatcher {
|
|
|
|
|
| // A pattern matcher for abitrary value constants.
|
| -template <typename T, IrOpcode::Value kOpcode>
|
| +template <typename T, IrOpcode::Value kMatchOpcode>
|
| struct ValueMatcher : public NodeMatcher {
|
| + typedef T ValueType;
|
| + static const IrOpcode::Value kOpcode = kMatchOpcode;
|
| +
|
| explicit ValueMatcher(Node* node)
|
| : NodeMatcher(node), value_(), has_value_(opcode() == kOpcode) {
|
| if (has_value_) {
|
| @@ -124,6 +127,9 @@ struct BinopMatcher : public NodeMatcher {
|
| if (HasProperty(Operator::kCommutative)) PutConstantOnRight();
|
| }
|
|
|
| + typedef Left LeftMatcher;
|
| + typedef Right RightMatcher;
|
| +
|
| const Left& left() const { return left_; }
|
| const Right& right() const { return right_; }
|
|
|
| @@ -157,16 +163,19 @@ typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
|
| typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
|
| typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
|
|
|
| -struct Int32AddMatcher : public Int32BinopMatcher {
|
| - explicit Int32AddMatcher(Node* node)
|
| - : Int32BinopMatcher(node), scale_exponent_(-1) {
|
| - PutScaledInputOnLeft();
|
| +template <class BinopMatcher, IrOpcode::Value kAddOpcode,
|
| + IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode>
|
| +struct AddMatcher : public BinopMatcher {
|
| + static const IrOpcode::Value kOpcode = kAddOpcode;
|
| +
|
| + explicit AddMatcher(Node* node) : BinopMatcher(node), scale_exponent_(-1) {
|
| + if (this->HasProperty(Operator::kCommutative)) PutScaledInputOnLeft();
|
| }
|
|
|
| bool HasScaledInput() const { return scale_exponent_ != -1; }
|
| Node* ScaledInput() const {
|
| DCHECK(HasScaledInput());
|
| - return left().node()->InputAt(0);
|
| + return this->left().node()->InputAt(0);
|
| }
|
| int ScaleExponent() const {
|
| DCHECK(HasScaledInput());
|
| @@ -175,18 +184,20 @@ struct Int32AddMatcher : public Int32BinopMatcher {
|
|
|
| private:
|
| int GetInputScaleExponent(Node* node) const {
|
| - if (node->opcode() == IrOpcode::kWord32Shl) {
|
| - Int32BinopMatcher m(node);
|
| + if (node->opcode() == kShiftOpcode) {
|
| + BinopMatcher m(node);
|
| if (m.right().HasValue()) {
|
| - int32_t value = m.right().Value();
|
| + typename BinopMatcher::RightMatcher::ValueType value =
|
| + m.right().Value();
|
| if (value >= 0 && value <= 3) {
|
| return value;
|
| }
|
| }
|
| - } else if (node->opcode() == IrOpcode::kInt32Mul) {
|
| - Int32BinopMatcher m(node);
|
| + } else if (node->opcode() == kMulOpcode) {
|
| + BinopMatcher m(node);
|
| if (m.right().HasValue()) {
|
| - int32_t value = m.right().Value();
|
| + typename BinopMatcher::RightMatcher::ValueType value =
|
| + m.right().Value();
|
| if (value == 1) {
|
| return 0;
|
| } else if (value == 2) {
|
| @@ -202,20 +213,20 @@ struct Int32AddMatcher : public Int32BinopMatcher {
|
| }
|
|
|
| void PutScaledInputOnLeft() {
|
| - scale_exponent_ = GetInputScaleExponent(right().node());
|
| + scale_exponent_ = GetInputScaleExponent(this->right().node());
|
| if (scale_exponent_ >= 0) {
|
| - int left_scale_exponent = GetInputScaleExponent(left().node());
|
| + int left_scale_exponent = GetInputScaleExponent(this->left().node());
|
| if (left_scale_exponent == -1) {
|
| - SwapInputs();
|
| + this->SwapInputs();
|
| } else {
|
| scale_exponent_ = left_scale_exponent;
|
| }
|
| } else {
|
| - scale_exponent_ = GetInputScaleExponent(left().node());
|
| + scale_exponent_ = GetInputScaleExponent(this->left().node());
|
| if (scale_exponent_ == -1) {
|
| - if (right().opcode() == IrOpcode::kInt32Add &&
|
| - left().opcode() != IrOpcode::kInt32Add) {
|
| - SwapInputs();
|
| + if (this->right().opcode() == kAddOpcode &&
|
| + this->left().opcode() != kAddOpcode) {
|
| + this->SwapInputs();
|
| }
|
| }
|
| }
|
| @@ -224,6 +235,12 @@ struct Int32AddMatcher : public Int32BinopMatcher {
|
| int scale_exponent_;
|
| };
|
|
|
| +typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul,
|
| + IrOpcode::kWord32Shl> Int32AddMatcher;
|
| +typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul,
|
| + IrOpcode::kWord64Shl> Int64AddMatcher;
|
| +
|
| +template <class AddMatcher>
|
| struct ScaledWithOffsetMatcher {
|
| explicit ScaledWithOffsetMatcher(Node* node)
|
| : matches_(false),
|
| @@ -231,13 +248,12 @@ struct ScaledWithOffsetMatcher {
|
| scale_exponent_(0),
|
| offset_(NULL),
|
| constant_(NULL) {
|
| - if (node->opcode() != IrOpcode::kInt32Add) return;
|
| -
|
| - // The Int32AddMatcher canonicalizes the order of constants and scale
|
| - // factors that are used as inputs, so instead of enumerating all possible
|
| - // patterns by brute force, checking for node clusters using the following
|
| - // templates in the following order suffices to find all of the interesting
|
| - // cases (S = scaled input, O = offset input, C = constant input):
|
| + // The ScaledWithOffsetMatcher canonicalizes the order of constants and
|
| + // scale factors that are used as inputs, so instead of enumerating all
|
| + // possible patterns by brute force, checking for node clusters using the
|
| + // following templates in the following order suffices to find all of the
|
| + // interesting cases (S = scaled input, O = offset input, C = constant
|
| + // input):
|
| // (S + (O + C))
|
| // (S + (O + O))
|
| // (S + C)
|
| @@ -248,14 +264,15 @@ struct ScaledWithOffsetMatcher {
|
| // ((O + O) + C)
|
| // (O + C)
|
| // (O + O)
|
| - Int32AddMatcher base_matcher(node);
|
| + if (node->InputCount() < 2) return;
|
| + AddMatcher base_matcher(node);
|
| Node* left = base_matcher.left().node();
|
| Node* right = base_matcher.right().node();
|
| if (base_matcher.HasScaledInput() && left->OwnedBy(node)) {
|
| scaled_ = base_matcher.ScaledInput();
|
| scale_exponent_ = base_matcher.ScaleExponent();
|
| - if (right->opcode() == IrOpcode::kInt32Add && right->OwnedBy(node)) {
|
| - Int32AddMatcher right_matcher(right);
|
| + if (right->opcode() == AddMatcher::kOpcode && right->OwnedBy(node)) {
|
| + AddMatcher right_matcher(right);
|
| if (right_matcher.right().HasValue()) {
|
| // (S + (O + C))
|
| offset_ = right_matcher.left().node();
|
| @@ -272,8 +289,8 @@ struct ScaledWithOffsetMatcher {
|
| offset_ = right;
|
| }
|
| } else {
|
| - if (left->opcode() == IrOpcode::kInt32Add && left->OwnedBy(node)) {
|
| - Int32AddMatcher left_matcher(left);
|
| + if (left->opcode() == AddMatcher::kOpcode && left->OwnedBy(node)) {
|
| + AddMatcher left_matcher(left);
|
| Node* left_left = left_matcher.left().node();
|
| Node* left_right = left_matcher.right().node();
|
| if (left_matcher.HasScaledInput() && left_left->OwnedBy(left)) {
|
| @@ -321,6 +338,25 @@ struct ScaledWithOffsetMatcher {
|
| }
|
| }
|
| }
|
| + int64_t value = 0;
|
| + if (constant_ != NULL) {
|
| + switch (constant_->opcode()) {
|
| + case IrOpcode::kInt32Constant: {
|
| + value = OpParameter<int32_t>(constant_);
|
| + break;
|
| + }
|
| + case IrOpcode::kInt64Constant: {
|
| + value = OpParameter<int64_t>(constant_);
|
| + break;
|
| + }
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + if (value == 0) {
|
| + constant_ = NULL;
|
| + }
|
| + }
|
| matches_ = true;
|
| }
|
|
|
| @@ -340,6 +376,9 @@ struct ScaledWithOffsetMatcher {
|
| Node* constant_;
|
| };
|
|
|
| +typedef ScaledWithOffsetMatcher<Int32AddMatcher> ScaledWithOffset32Matcher;
|
| +typedef ScaledWithOffsetMatcher<Int64AddMatcher> ScaledWithOffset64Matcher;
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|