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 {
bool power_of_two_plus_one = false;
DisplacementMode displacement_mode = kPositiveDisplacement;
int scale = 0;
if (m.HasIndexInput() && left->OwnedBy(node)) {
if (m.HasIndexInput() && left->OwnedByAddressingOperand()) {
index = m.IndexInput();
scale = m.scale();
scale_expression = left;
power_of_two_plus_one = m.power_of_two_plus_one();
bool match_found = false;
if (right->opcode() == AddMatcher::kSubOpcode && right->OwnedBy(node)) {
if (right->opcode() == AddMatcher::kSubOpcode &&
right->OwnedByAddressingOperand()) {
AddMatcher right_matcher(right);
if (right_matcher.right().HasValue()) {
// (S + (B - D))
......@@ -506,7 +507,8 @@ struct BaseWithIndexAndDisplacementMatcher {
}
}
if (!match_found) {
if (right->opcode() == AddMatcher::kAddOpcode && right->OwnedBy(node)) {
if (right->opcode() == AddMatcher::kAddOpcode &&
right->OwnedByAddressingOperand()) {
AddMatcher right_matcher(right);
if (right_matcher.right().HasValue()) {
// (S + (B + D))
......@@ -526,7 +528,8 @@ struct BaseWithIndexAndDisplacementMatcher {
}
} else {
bool match_found = false;
if (left->opcode() == AddMatcher::kSubOpcode && left->OwnedBy(node)) {
if (left->opcode() == AddMatcher::kSubOpcode &&
left->OwnedByAddressingOperand()) {
AddMatcher left_matcher(left);
Node* left_left = left_matcher.left().node();
Node* left_right = left_matcher.right().node();
......@@ -551,7 +554,8 @@ struct BaseWithIndexAndDisplacementMatcher {
}
}
if (!match_found) {
if (left->opcode() == AddMatcher::kAddOpcode && left->OwnedBy(node)) {
if (left->opcode() == AddMatcher::kAddOpcode &&
left->OwnedByAddressingOperand()) {
AddMatcher left_matcher(left);
Node* left_left = left_matcher.left().node();
Node* left_right = left_matcher.right().node();
......@@ -565,13 +569,19 @@ struct BaseWithIndexAndDisplacementMatcher {
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;
if (left->OwnedBy(node)) {
// ((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 + D)
base = left;
displacement = right;
}
} else {
// (B + B)
index = left;
......@@ -584,10 +594,16 @@ struct BaseWithIndexAndDisplacementMatcher {
displacement = left_right;
base = right;
} else if (m.right().HasValue()) {
// ((B + B) + D)
index = left_left;
base = left_right;
displacement = right;
if (left->OwnedBy(node)) {
// ((B + B) + D)
index = left_left;
base = left_right;
displacement = right;
} else {
// (B + D)
base = left;
displacement = right;
}
} else {
// (B + B)
index = left;
......
......@@ -296,6 +296,19 @@ bool Node::OwnedBy(Node const* owner1, Node const* owner2) const {
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 {
OFStream os(stdout);
......
......@@ -158,6 +158,10 @@ class V8_EXPORT_PRIVATE Node final {
// Returns true if {owner1} and {owner2} are the only users of {this} node.
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;
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