| Index: src/compiler/node-matchers.h
|
| diff --git a/src/compiler/node-matchers.h b/src/compiler/node-matchers.h
|
| index d6d0615150dcb0dec114a3adb9c8e643c23328c8..f77e7b073c6087b3db1ca9b6063ff3d507461de6 100644
|
| --- a/src/compiler/node-matchers.h
|
| +++ b/src/compiler/node-matchers.h
|
| @@ -318,11 +318,12 @@ typedef ScaleMatcher<Int32BinopMatcher, IrOpcode::kInt32Mul,
|
| typedef ScaleMatcher<Int64BinopMatcher, IrOpcode::kInt64Mul,
|
| IrOpcode::kWord64Shl> Int64ScaleMatcher;
|
|
|
| -
|
| -template <class BinopMatcher, IrOpcode::Value kAddOpcode,
|
| - IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode>
|
| +template <class BinopMatcher, IrOpcode::Value AddOpcode,
|
| + IrOpcode::Value SubOpcode, IrOpcode::Value kMulOpcode,
|
| + IrOpcode::Value kShiftOpcode>
|
| struct AddMatcher : public BinopMatcher {
|
| - static const IrOpcode::Value kOpcode = kAddOpcode;
|
| + static const IrOpcode::Value kAddOpcode = AddOpcode;
|
| + static const IrOpcode::Value kSubOpcode = SubOpcode;
|
| typedef ScaleMatcher<BinopMatcher, kMulOpcode, kShiftOpcode> Matcher;
|
|
|
| AddMatcher(Node* node, bool allow_input_swap)
|
| @@ -373,6 +374,9 @@ struct AddMatcher : public BinopMatcher {
|
| if (this->right().opcode() == kAddOpcode &&
|
| this->left().opcode() != kAddOpcode) {
|
| this->SwapInputs();
|
| + } else if (this->right().opcode() == kSubOpcode &&
|
| + this->left().opcode() != kSubOpcode) {
|
| + this->SwapInputs();
|
| }
|
| }
|
|
|
| @@ -380,11 +384,14 @@ struct AddMatcher : public BinopMatcher {
|
| bool power_of_two_plus_one_;
|
| };
|
|
|
| -typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul,
|
| - IrOpcode::kWord32Shl> Int32AddMatcher;
|
| -typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul,
|
| - IrOpcode::kWord64Shl> Int64AddMatcher;
|
| +typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Sub,
|
| + IrOpcode::kInt32Mul, IrOpcode::kWord32Shl>
|
| + Int32AddMatcher;
|
| +typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Sub,
|
| + IrOpcode::kInt64Mul, IrOpcode::kWord64Shl>
|
| + Int64AddMatcher;
|
|
|
| +enum DisplacementMode { kPositiveDisplacement, kNegativeDisplacement };
|
|
|
| template <class AddMatcher>
|
| struct BaseWithIndexAndDisplacementMatcher {
|
| @@ -393,7 +400,8 @@ struct BaseWithIndexAndDisplacementMatcher {
|
| index_(nullptr),
|
| scale_(0),
|
| base_(nullptr),
|
| - displacement_(nullptr) {
|
| + displacement_(nullptr),
|
| + displacement_mode_(kPositiveDisplacement) {
|
| Initialize(node, allow_input_swap);
|
| }
|
|
|
| @@ -402,7 +410,8 @@ struct BaseWithIndexAndDisplacementMatcher {
|
| index_(nullptr),
|
| scale_(0),
|
| base_(nullptr),
|
| - displacement_(nullptr) {
|
| + displacement_(nullptr),
|
| + displacement_mode_(kPositiveDisplacement) {
|
| Initialize(node, node->op()->HasProperty(Operator::kCommutative));
|
| }
|
|
|
| @@ -411,6 +420,7 @@ struct BaseWithIndexAndDisplacementMatcher {
|
| int scale() const { return scale_; }
|
| Node* base() const { return base_; }
|
| Node* displacement() const { return displacement_; }
|
| + DisplacementMode displacement_mode() const { return displacement_mode_; }
|
|
|
| private:
|
| bool matches_;
|
| @@ -418,6 +428,7 @@ struct BaseWithIndexAndDisplacementMatcher {
|
| int scale_;
|
| Node* base_;
|
| Node* displacement_;
|
| + DisplacementMode displacement_mode_;
|
|
|
| void Initialize(Node* node, bool allow_input_swap) {
|
| // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of
|
| @@ -445,83 +456,124 @@ struct BaseWithIndexAndDisplacementMatcher {
|
| Node* index = nullptr;
|
| Node* scale_expression = nullptr;
|
| bool power_of_two_plus_one = false;
|
| + DisplacementMode displacement_mode = kPositiveDisplacement;
|
| int scale = 0;
|
| if (m.HasIndexInput() && left->OwnedBy(node)) {
|
| index = m.IndexInput();
|
| scale = m.scale();
|
| scale_expression = left;
|
| power_of_two_plus_one = m.power_of_two_plus_one();
|
| - if (right->opcode() == AddMatcher::kOpcode && right->OwnedBy(node)) {
|
| + bool match_found = false;
|
| + if (right->opcode() == AddMatcher::kSubOpcode && right->OwnedBy(node)) {
|
| AddMatcher right_matcher(right);
|
| if (right_matcher.right().HasValue()) {
|
| - // (S + (B + D))
|
| + // (S + (B - D))
|
| base = right_matcher.left().node();
|
| displacement = right_matcher.right().node();
|
| + displacement_mode = kNegativeDisplacement;
|
| + match_found = true;
|
| + }
|
| + }
|
| + if (!match_found) {
|
| + if (right->opcode() == AddMatcher::kAddOpcode && right->OwnedBy(node)) {
|
| + AddMatcher right_matcher(right);
|
| + if (right_matcher.right().HasValue()) {
|
| + // (S + (B + D))
|
| + base = right_matcher.left().node();
|
| + displacement = right_matcher.right().node();
|
| + } else {
|
| + // (S + (B + B))
|
| + base = right;
|
| + }
|
| + } else if (m.right().HasValue()) {
|
| + // (S + D)
|
| + displacement = right;
|
| } else {
|
| - // (S + (B + B))
|
| + // (S + B)
|
| base = right;
|
| }
|
| - } else if (m.right().HasValue()) {
|
| - // (S + D)
|
| - displacement = right;
|
| - } else {
|
| - // (S + B)
|
| - base = right;
|
| }
|
| } else {
|
| - if (left->opcode() == AddMatcher::kOpcode && left->OwnedBy(node)) {
|
| + bool match_found = false;
|
| + if (left->opcode() == AddMatcher::kSubOpcode && left->OwnedBy(node)) {
|
| AddMatcher left_matcher(left);
|
| Node* left_left = left_matcher.left().node();
|
| Node* left_right = left_matcher.right().node();
|
| - if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) {
|
| - if (left_matcher.right().HasValue()) {
|
| - // ((S + D) + B)
|
| + if (left_matcher.right().HasValue()) {
|
| + if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) {
|
| + // ((S - D) + B)
|
| index = left_matcher.IndexInput();
|
| scale = left_matcher.scale();
|
| scale_expression = left_left;
|
| power_of_two_plus_one = left_matcher.power_of_two_plus_one();
|
| displacement = left_right;
|
| + displacement_mode = kNegativeDisplacement;
|
| base = right;
|
| - } else if (m.right().HasValue()) {
|
| - // ((S + B) + D)
|
| - index = left_matcher.IndexInput();
|
| - scale = left_matcher.scale();
|
| - scale_expression = left_left;
|
| - power_of_two_plus_one = left_matcher.power_of_two_plus_one();
|
| - base = left_right;
|
| - displacement = right;
|
| } else {
|
| - // (B + B)
|
| - index = left;
|
| - base = right;
|
| - }
|
| - } else {
|
| - if (left_matcher.right().HasValue()) {
|
| - // ((B + D) + B)
|
| + // ((B - D) + B)
|
| index = left_left;
|
| displacement = left_right;
|
| + displacement_mode = kNegativeDisplacement;
|
| base = right;
|
| - } else if (m.right().HasValue()) {
|
| - // ((B + B) + D)
|
| - index = left_left;
|
| - base = left_right;
|
| + }
|
| + match_found = true;
|
| + }
|
| + }
|
| + if (!match_found) {
|
| + if (left->opcode() == AddMatcher::kAddOpcode && left->OwnedBy(node)) {
|
| + AddMatcher left_matcher(left);
|
| + Node* left_left = left_matcher.left().node();
|
| + Node* left_right = left_matcher.right().node();
|
| + if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) {
|
| + if (left_matcher.right().HasValue()) {
|
| + // ((S + D) + B)
|
| + index = left_matcher.IndexInput();
|
| + scale = left_matcher.scale();
|
| + scale_expression = left_left;
|
| + power_of_two_plus_one = left_matcher.power_of_two_plus_one();
|
| + displacement = left_right;
|
| + base = right;
|
| + } else if (m.right().HasValue()) {
|
| + // ((S + B) + D)
|
| + index = left_matcher.IndexInput();
|
| + scale = left_matcher.scale();
|
| + scale_expression = left_left;
|
| + power_of_two_plus_one = left_matcher.power_of_two_plus_one();
|
| + base = left_right;
|
| + displacement = right;
|
| + } else {
|
| + // (B + B)
|
| + index = left;
|
| + base = right;
|
| + }
|
| + } else {
|
| + if (left_matcher.right().HasValue()) {
|
| + // ((B + D) + B)
|
| + index = left_left;
|
| + displacement = left_right;
|
| + base = right;
|
| + } else if (m.right().HasValue()) {
|
| + // ((B + B) + D)
|
| + index = left_left;
|
| + base = left_right;
|
| + displacement = right;
|
| + } else {
|
| + // (B + B)
|
| + index = left;
|
| + base = right;
|
| + }
|
| + }
|
| + } else {
|
| + if (m.right().HasValue()) {
|
| + // (B + D)
|
| + base = left;
|
| displacement = right;
|
| } else {
|
| // (B + B)
|
| - index = left;
|
| - base = right;
|
| + base = left;
|
| + index = right;
|
| }
|
| }
|
| - } else {
|
| - if (m.right().HasValue()) {
|
| - // (B + D)
|
| - base = left;
|
| - displacement = right;
|
| - } else {
|
| - // (B + B)
|
| - base = left;
|
| - index = right;
|
| - }
|
| }
|
| }
|
| int64_t value = 0;
|
| @@ -557,6 +609,7 @@ struct BaseWithIndexAndDisplacementMatcher {
|
| }
|
| base_ = base;
|
| displacement_ = displacement;
|
| + displacement_mode_ = displacement_mode;
|
| index_ = index;
|
| scale_ = scale;
|
| matches_ = true;
|
|
|