Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Unified Diff: src/compiler/node-matchers.h

Issue 774193003: [turbofan] Use "leal" in even more situations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@765983002
Patch Set: Fix Windows Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/compiler/x64/code-generator-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/node-matchers.h
diff --git a/src/compiler/node-matchers.h b/src/compiler/node-matchers.h
index 6636794b377565839926860aa9e934cee9553d92..13f7e1911e754454c603c9ec1e18d22e389cdf99 100644
--- a/src/compiler/node-matchers.h
+++ b/src/compiler/node-matchers.h
@@ -171,76 +171,111 @@ typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
-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 this->left().node()->InputAt(0);
- }
- int ScaleExponent() const {
- DCHECK(HasScaledInput());
- return scale_exponent_;
- }
-
- private:
- int GetInputScaleExponent(Node* node) const {
+template <class BinopMatcher, IrOpcode::Value kMulOpcode,
+ IrOpcode::Value kShiftOpcode>
+struct ScaleMatcher {
+ explicit ScaleMatcher(Node* node, bool allow_power_of_two_plus_one = false)
+ : scale_(-1), power_of_two_plus_one_(false) {
+ if (node->InputCount() < 2) return;
+ BinopMatcher m(node);
if (node->opcode() == kShiftOpcode) {
- BinopMatcher m(node);
if (m.right().HasValue()) {
typename BinopMatcher::RightMatcher::ValueType value =
m.right().Value();
if (value >= 0 && value <= 3) {
- return static_cast<int>(value);
+ scale_ = static_cast<int>(value);
}
}
} else if (node->opcode() == kMulOpcode) {
- BinopMatcher m(node);
if (m.right().HasValue()) {
typename BinopMatcher::RightMatcher::ValueType value =
m.right().Value();
if (value == 1) {
- return 0;
+ scale_ = 0;
} else if (value == 2) {
- return 1;
+ scale_ = 1;
} else if (value == 4) {
- return 2;
+ scale_ = 2;
} else if (value == 8) {
- return 3;
+ scale_ = 3;
+ } else if (allow_power_of_two_plus_one) {
+ if (value == 3) {
+ scale_ = 1;
+ power_of_two_plus_one_ = true;
+ } else if (value == 5) {
+ scale_ = 2;
+ power_of_two_plus_one_ = true;
+ } else if (value == 9) {
+ scale_ = 3;
+ power_of_two_plus_one_ = true;
+ }
}
}
}
- return -1;
}
- void PutScaledInputOnLeft() {
- scale_exponent_ = GetInputScaleExponent(this->right().node());
- if (scale_exponent_ >= 0) {
- int left_scale_exponent = GetInputScaleExponent(this->left().node());
- if (left_scale_exponent == -1) {
- this->SwapInputs();
- } else {
- scale_exponent_ = left_scale_exponent;
- }
- } else {
- scale_exponent_ = GetInputScaleExponent(this->left().node());
- if (scale_exponent_ == -1) {
- if (this->right().opcode() == kAddOpcode &&
- this->left().opcode() != kAddOpcode) {
- this->SwapInputs();
- }
- }
+ bool matches() const { return scale_ != -1; }
+ int scale() const { return scale_; }
+ bool power_of_two_plus_one() const { return power_of_two_plus_one_; }
+
+ private:
+ int scale_;
+ bool power_of_two_plus_one_;
+};
+
+typedef ScaleMatcher<Int32BinopMatcher, IrOpcode::kInt32Mul,
+ IrOpcode::kWord32Shl> Int32ScaleMatcher;
+typedef ScaleMatcher<Int64BinopMatcher, IrOpcode::kInt64Mul,
+ IrOpcode::kWord64Shl> Int64ScaleMatcher;
+
+
+template <class BinopMatcher, IrOpcode::Value kAddOpcode,
+ IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode>
+struct AddMatcher : public BinopMatcher {
+ static const IrOpcode::Value kOpcode = kAddOpcode;
+ typedef ScaleMatcher<BinopMatcher, kMulOpcode, kShiftOpcode> Matcher;
+
+ explicit AddMatcher(Node* node)
+ : BinopMatcher(node), scale_(-1), power_of_two_plus_one_(false) {
+ Matcher left_matcher(this->left().node(), true);
+ if (left_matcher.matches()) {
+ scale_ = left_matcher.scale();
+ power_of_two_plus_one_ = left_matcher.power_of_two_plus_one();
+ return;
+ }
+
+ if (!this->HasProperty(Operator::kCommutative)) {
+ return;
+ }
+
+ Matcher right_matcher(this->right().node(), true);
+ if (right_matcher.matches()) {
+ scale_ = right_matcher.scale();
+ power_of_two_plus_one_ = right_matcher.power_of_two_plus_one();
+ this->SwapInputs();
+ return;
}
+
+ if (this->right().opcode() == kAddOpcode &&
+ this->left().opcode() != kAddOpcode) {
+ this->SwapInputs();
+ }
+ }
+
+ bool HasIndexInput() const { return scale_ != -1; }
+ Node* IndexInput() const {
+ DCHECK(HasIndexInput());
+ return this->left().node()->InputAt(0);
+ }
+ int scale() const {
+ DCHECK(HasIndexInput());
+ return scale_;
}
+ bool power_of_two_plus_one() const { return power_of_two_plus_one_; }
- int scale_exponent_;
+ private:
+ int scale_;
+ bool power_of_two_plus_one_;
};
typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul,
@@ -248,115 +283,128 @@ typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul,
typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul,
IrOpcode::kWord64Shl> Int64AddMatcher;
+
template <class AddMatcher>
-struct ScaledWithOffsetMatcher {
- explicit ScaledWithOffsetMatcher(Node* node)
+struct BaseWithIndexAndDisplacementMatcher {
+ explicit BaseWithIndexAndDisplacementMatcher(Node* node)
: matches_(false),
- scaled_(NULL),
- scale_exponent_(0),
- offset_(NULL),
- constant_(NULL) {
- // 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)
- // (S + O)
- // ((S + C) + O)
- // ((S + O) + C)
- // ((O + C) + O)
- // ((O + O) + C)
- // (O + C)
- // (O + O)
+ index_(NULL),
+ scale_(0),
+ base_(NULL),
+ displacement_(NULL) {
+ // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of
+ // displacements 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 = index * scale, B = base input, D =
+ // displacement input):
+ // (S + (B + D))
+ // (S + (B + B))
+ // (S + D)
+ // (S + B)
+ // ((S + D) + B)
+ // ((S + B) + D)
+ // ((B + D) + B)
+ // ((B + B) + D)
+ // (B + D)
+ // (B + B)
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();
+ AddMatcher m(node);
+ Node* left = m.left().node();
+ Node* right = m.right().node();
+ Node* displacement = NULL;
+ Node* base = NULL;
+ Node* index = NULL;
+ Node* scale_expression = NULL;
+ bool power_of_two_plus_one = false;
+ 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)) {
AddMatcher right_matcher(right);
if (right_matcher.right().HasValue()) {
- // (S + (O + C))
- offset_ = right_matcher.left().node();
- constant_ = right_matcher.right().node();
+ // (S + (B + D))
+ base = right_matcher.left().node();
+ displacement = right_matcher.right().node();
} else {
- // (S + (O + O))
- offset_ = right;
+ // (S + (B + B))
+ base = right;
}
- } else if (base_matcher.right().HasValue()) {
- // (S + C)
- constant_ = right;
+ } else if (m.right().HasValue()) {
+ // (S + D)
+ displacement = right;
} else {
- // (S + O)
- offset_ = right;
+ // (S + B)
+ base = right;
}
} else {
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)) {
+ if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) {
if (left_matcher.right().HasValue()) {
- // ((S + C) + O)
- scaled_ = left_matcher.ScaledInput();
- scale_exponent_ = left_matcher.ScaleExponent();
- constant_ = left_right;
- offset_ = right;
- } else if (base_matcher.right().HasValue()) {
- // ((S + O) + C)
- scaled_ = left_matcher.ScaledInput();
- scale_exponent_ = left_matcher.ScaleExponent();
- offset_ = left_right;
- constant_ = right;
+ // ((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 {
- // (O + O)
- scaled_ = left;
- offset_ = right;
+ // (B + B)
+ index = left;
+ base = right;
}
} else {
if (left_matcher.right().HasValue()) {
- // ((O + C) + O)
- scaled_ = left_left;
- constant_ = left_right;
- offset_ = right;
- } else if (base_matcher.right().HasValue()) {
- // ((O + O) + C)
- scaled_ = left_left;
- offset_ = left_right;
- constant_ = right;
+ // ((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 {
- // (O + O)
- scaled_ = left;
- offset_ = right;
+ // (B + B)
+ index = left;
+ base = right;
}
}
} else {
- if (base_matcher.right().HasValue()) {
- // (O + C)
- offset_ = left;
- constant_ = right;
+ if (m.right().HasValue()) {
+ // (B + D)
+ base = left;
+ displacement = right;
} else {
- // (O + O)
- offset_ = left;
- scaled_ = right;
+ // (B + B)
+ base = left;
+ index = right;
}
}
}
int64_t value = 0;
- if (constant_ != NULL) {
- switch (constant_->opcode()) {
+ if (displacement != NULL) {
+ switch (displacement->opcode()) {
case IrOpcode::kInt32Constant: {
- value = OpParameter<int32_t>(constant_);
+ value = OpParameter<int32_t>(displacement);
break;
}
case IrOpcode::kInt64Constant: {
- value = OpParameter<int64_t>(constant_);
+ value = OpParameter<int64_t>(displacement);
break;
}
default:
@@ -364,30 +412,48 @@ struct ScaledWithOffsetMatcher {
break;
}
if (value == 0) {
- constant_ = NULL;
+ displacement = NULL;
+ }
+ }
+ if (power_of_two_plus_one) {
+ if (base != NULL) {
+ // If the scale requires explicitly using the index as the base, but a
+ // base is already part of the match, then the (1 << N + 1) scale factor
+ // can't be folded into the match and the entire index * scale
+ // calculation must be computed separately.
+ index = scale_expression;
+ scale = 0;
+ } else {
+ base = index;
}
}
+ base_ = base;
+ displacement_ = displacement;
+ index_ = index;
+ scale_ = scale;
matches_ = true;
}
bool matches() const { return matches_; }
- Node* scaled() const { return scaled_; }
- int scale_exponent() const { return scale_exponent_; }
- Node* offset() const { return offset_; }
- Node* constant() const { return constant_; }
+ Node* index() const { return index_; }
+ int scale() const { return scale_; }
+ Node* base() const { return base_; }
+ Node* displacement() const { return displacement_; }
private:
bool matches_;
protected:
- Node* scaled_;
- int scale_exponent_;
- Node* offset_;
- Node* constant_;
+ Node* index_;
+ int scale_;
+ Node* base_;
+ Node* displacement_;
};
-typedef ScaledWithOffsetMatcher<Int32AddMatcher> ScaledWithOffset32Matcher;
-typedef ScaledWithOffsetMatcher<Int64AddMatcher> ScaledWithOffset64Matcher;
+typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher>
+ BaseWithIndexAndDisplacement32Matcher;
+typedef BaseWithIndexAndDisplacementMatcher<Int64AddMatcher>
+ BaseWithIndexAndDisplacement64Matcher;
} // namespace compiler
} // namespace internal
« no previous file with comments | « no previous file | src/compiler/x64/code-generator-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698