Commit bd74f1cf authored by shiyu.zhang's avatar shiyu.zhang Committed by Commit bot

[turbofan] Relax limitation for using BaseWithIndexAndDisplacement for load/stores

Enable using BaseWithIndexAndDisplacement addressing mode for an address
used by multiple load/stores. It can reduce one instruction to calculate
the address and one register to store the address.

BUG=

Review-Url: https://codereview.chromium.org/2620293004
Cr-Commit-Position: refs/heads/master@{#43402}
parent 27fb7b83
...@@ -489,13 +489,14 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -489,13 +489,14 @@ struct BaseWithIndexAndDisplacementMatcher {
bool power_of_two_plus_one = false; bool power_of_two_plus_one = false;
DisplacementMode displacement_mode = kPositiveDisplacement; DisplacementMode displacement_mode = kPositiveDisplacement;
int scale = 0; int scale = 0;
if (m.HasIndexInput() && left->OwnedBy(node)) { if (m.HasIndexInput() && left->OwnedByAddressingOperand()) {
index = m.IndexInput(); index = m.IndexInput();
scale = m.scale(); scale = m.scale();
scale_expression = left; scale_expression = left;
power_of_two_plus_one = m.power_of_two_plus_one(); power_of_two_plus_one = m.power_of_two_plus_one();
bool match_found = false; bool match_found = false;
if (right->opcode() == AddMatcher::kSubOpcode && right->OwnedBy(node)) { if (right->opcode() == AddMatcher::kSubOpcode &&
right->OwnedByAddressingOperand()) {
AddMatcher right_matcher(right); AddMatcher right_matcher(right);
if (right_matcher.right().HasValue()) { if (right_matcher.right().HasValue()) {
// (S + (B - D)) // (S + (B - D))
...@@ -506,7 +507,8 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -506,7 +507,8 @@ struct BaseWithIndexAndDisplacementMatcher {
} }
} }
if (!match_found) { if (!match_found) {
if (right->opcode() == AddMatcher::kAddOpcode && right->OwnedBy(node)) { if (right->opcode() == AddMatcher::kAddOpcode &&
right->OwnedByAddressingOperand()) {
AddMatcher right_matcher(right); AddMatcher right_matcher(right);
if (right_matcher.right().HasValue()) { if (right_matcher.right().HasValue()) {
// (S + (B + D)) // (S + (B + D))
...@@ -526,7 +528,8 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -526,7 +528,8 @@ struct BaseWithIndexAndDisplacementMatcher {
} }
} else { } else {
bool match_found = false; bool match_found = false;
if (left->opcode() == AddMatcher::kSubOpcode && left->OwnedBy(node)) { if (left->opcode() == AddMatcher::kSubOpcode &&
left->OwnedByAddressingOperand()) {
AddMatcher left_matcher(left); AddMatcher left_matcher(left);
Node* left_left = left_matcher.left().node(); Node* left_left = left_matcher.left().node();
Node* left_right = left_matcher.right().node(); Node* left_right = left_matcher.right().node();
...@@ -551,7 +554,8 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -551,7 +554,8 @@ struct BaseWithIndexAndDisplacementMatcher {
} }
} }
if (!match_found) { if (!match_found) {
if (left->opcode() == AddMatcher::kAddOpcode && left->OwnedBy(node)) { if (left->opcode() == AddMatcher::kAddOpcode &&
left->OwnedByAddressingOperand()) {
AddMatcher left_matcher(left); AddMatcher left_matcher(left);
Node* left_left = left_matcher.left().node(); Node* left_left = left_matcher.left().node();
Node* left_right = left_matcher.right().node(); Node* left_right = left_matcher.right().node();
...@@ -565,6 +569,7 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -565,6 +569,7 @@ struct BaseWithIndexAndDisplacementMatcher {
displacement = left_right; displacement = left_right;
base = right; base = right;
} else if (m.right().HasValue()) { } else if (m.right().HasValue()) {
if (left->OwnedBy(node)) {
// ((S + B) + D) // ((S + B) + D)
index = left_matcher.IndexInput(); index = left_matcher.IndexInput();
scale = left_matcher.scale(); scale = left_matcher.scale();
...@@ -572,6 +577,11 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -572,6 +577,11 @@ struct BaseWithIndexAndDisplacementMatcher {
power_of_two_plus_one = left_matcher.power_of_two_plus_one(); power_of_two_plus_one = left_matcher.power_of_two_plus_one();
base = left_right; base = left_right;
displacement = right; displacement = right;
} else {
// (B + D)
base = left;
displacement = right;
}
} else { } else {
// (B + B) // (B + B)
index = left; index = left;
...@@ -584,10 +594,16 @@ struct BaseWithIndexAndDisplacementMatcher { ...@@ -584,10 +594,16 @@ struct BaseWithIndexAndDisplacementMatcher {
displacement = left_right; displacement = left_right;
base = right; base = right;
} else if (m.right().HasValue()) { } else if (m.right().HasValue()) {
if (left->OwnedBy(node)) {
// ((B + B) + D) // ((B + B) + D)
index = left_left; index = left_left;
base = left_right; base = left_right;
displacement = right; displacement = right;
} else {
// (B + D)
base = left;
displacement = right;
}
} else { } else {
// (B + B) // (B + B)
index = left; index = left;
......
...@@ -296,6 +296,19 @@ bool Node::OwnedBy(Node const* owner1, Node const* owner2) const { ...@@ -296,6 +296,19 @@ bool Node::OwnedBy(Node const* owner1, Node const* owner2) const {
return mask == 3; return mask == 3;
} }
bool Node::OwnedByAddressingOperand() const {
for (Use* use = first_use_; use; use = use->next) {
Node* from = use->from();
if (from->opcode() != IrOpcode::kLoad &&
// If {from} is store, make sure it does not use {this} as value
(from->opcode() != IrOpcode::kStore || from->InputAt(2) == this) &&
from->opcode() != IrOpcode::kInt32Add &&
from->opcode() != IrOpcode::kInt64Add) {
return false;
}
}
return true;
}
void Node::Print() const { void Node::Print() const {
OFStream os(stdout); OFStream os(stdout);
......
...@@ -158,6 +158,10 @@ class V8_EXPORT_PRIVATE Node final { ...@@ -158,6 +158,10 @@ class V8_EXPORT_PRIVATE Node final {
// Returns true if {owner1} and {owner2} are the only users of {this} node. // Returns true if {owner1} and {owner2} are the only users of {this} node.
bool OwnedBy(Node const* owner1, Node const* owner2) const; bool OwnedBy(Node const* owner1, Node const* owner2) const;
// Returns true if addressing related operands (such as load, store, lea)
// are the only users of {this} node.
bool OwnedByAddressingOperand() const;
void Print() const; void Print() const;
private: private:
......
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