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

Side by Side Diff: src/compiler/node-matchers.h

Issue 704713003: [turbofan] Optimize add operations to use 'leal' instruction on x64 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Tweaks Created 6 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_COMPILER_NODE_MATCHERS_H_ 5 #ifndef V8_COMPILER_NODE_MATCHERS_H_
6 #define V8_COMPILER_NODE_MATCHERS_H_ 6 #define V8_COMPILER_NODE_MATCHERS_H_
7 7
8 #include "src/compiler/node.h" 8 #include "src/compiler/node.h"
9 #include "src/compiler/operator.h" 9 #include "src/compiler/operator.h"
10 #include "src/unique.h" 10 #include "src/unique.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 : public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> { 109 : public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> {
110 explicit HeapObjectMatcher(Node* node) 110 explicit HeapObjectMatcher(Node* node)
111 : ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {} 111 : ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {}
112 }; 112 };
113 113
114 114
115 // For shorter pattern matching code, this struct matches both the left and 115 // For shorter pattern matching code, this struct matches both the left and
116 // right hand sides of a binary operation and can put constants on the right 116 // right hand sides of a binary operation and can put constants on the right
117 // if they appear on the left hand side of a commutative operation. 117 // if they appear on the left hand side of a commutative operation.
118 template <typename Left, typename Right> 118 template <typename Left, typename Right>
119 struct BinopMatcher FINAL : public NodeMatcher { 119 struct BinopMatcher : public NodeMatcher {
120 explicit BinopMatcher(Node* node) 120 explicit BinopMatcher(Node* node)
121 : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) { 121 : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) {
122 if (HasProperty(Operator::kCommutative)) PutConstantOnRight(); 122 if (HasProperty(Operator::kCommutative)) PutConstantOnRight();
123 } 123 }
124 124
125 const Left& left() const { return left_; } 125 const Left& left() const { return left_; }
126 const Right& right() const { return right_; } 126 const Right& right() const { return right_; }
127 127
128 bool IsFoldable() const { return left().HasValue() && right().HasValue(); } 128 bool IsFoldable() const { return left().HasValue() && right().HasValue(); }
129 bool LeftEqualsRight() const { return left().node() == right().node(); } 129 bool LeftEqualsRight() const { return left().node() == right().node(); }
130 130
131 protected:
132 void SwapInputs() {
133 std::swap(left_, right_);
134 node()->ReplaceInput(0, left().node());
135 node()->ReplaceInput(1, right().node());
136 }
137
131 private: 138 private:
132 void PutConstantOnRight() { 139 void PutConstantOnRight() {
133 if (left().HasValue() && !right().HasValue()) { 140 if (left().HasValue() && !right().HasValue()) {
134 std::swap(left_, right_); 141 SwapInputs();
135 node()->ReplaceInput(0, left().node());
136 node()->ReplaceInput(1, right().node());
137 } 142 }
138 } 143 }
139 144
140 Left left_; 145 Left left_;
141 Right right_; 146 Right right_;
142 }; 147 };
143 148
144 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher; 149 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher;
145 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher; 150 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher;
146 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher; 151 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher;
147 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher; 152 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
148 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher; 153 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher;
149 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher; 154 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
150 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher; 155 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
151 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher; 156 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
152 157
158 struct Int32AddMatcher : public Int32BinopMatcher {
159 explicit Int32AddMatcher(Node* node)
160 : Int32BinopMatcher(node), has_scaled_input_(false), scale_factor_(-1) {
161 PutScaledInputOnLeft();
162 if (HasScaledInput()) {
163 Int32BinopMatcher m(left().node());
164 if (m.opcode() == IrOpcode::kWord32Shl) {
165 scale_factor_ = 1 << m.right().Value();
166 } else {
167 DCHECK(m.opcode() == IrOpcode::kInt32Mul);
168 scale_factor_ = m.right().Value();
169 }
170 }
171 }
172
173 bool HasScaledInput() const { return has_scaled_input_; }
174 Node* ScaledInput() const {
175 DCHECK(HasScaledInput());
176 return left().node()->InputAt(0);
177 }
178 int ScaleFactor() const {
179 DCHECK(HasScaledInput());
180 return scale_factor_;
181 }
182
183 private:
184 bool IsScaledInput(Node* node) const {
titzer 2014/11/06 11:47:06 You could also have this method return the scaled
danno 2014/11/06 23:34:07 Done.
185 if (node->opcode() == IrOpcode::kWord32Shl) {
186 Int32BinopMatcher m(node->InputAt(1));
187 if (m.right().HasValue()) {
188 int32_t value = m.right().Value();
189 return (value == 0) || (value == 1) || (value == 2) || (value == 3);
190 }
191 } else if (node->opcode() == IrOpcode::kInt32Mul) {
192 Int32BinopMatcher m(node->InputAt(1));
193 if (m.right().HasValue()) {
194 int32_t value = m.right().Value();
195 return (value == 1) || (value == 2) || (value == 4) || (value == 8);
196 }
197 }
198 return false;
199 }
200
201 void PutScaledInputOnLeft() {
202 if (IsScaledInput(right().node()) && !IsScaledInput(left().node())) {
203 SwapInputs();
204 }
205
206 if (IsScaledInput(left().node())) {
207 has_scaled_input_ = true;
208 } else {
209 if (right().opcode() == IrOpcode::kInt32Add &&
210 left().opcode() != IrOpcode::kInt32Add) {
211 SwapInputs();
212 }
213 }
214 }
215
216 bool has_scaled_input_;
217 int scale_factor_;
218 };
219
220 struct ScaledWithOffsetMatcher {
221 explicit ScaledWithOffsetMatcher(Node* node)
222 : matches_(false),
223 scaled_(NULL),
224 scale_factor_(1),
225 offset_(NULL),
226 constant_(NULL) {
227 if (node->opcode() != IrOpcode::kInt32Add) return;
228
229 // The Int32AddMatcher canonicalizes the order of constants and scale
230 // factors that are used as inputs, so instead of enumerating all possible
231 // patterns by brute force, checking for node clusters using the following
232 // templates in the following order suffices to find all of the interesting
233 // cases (S = scaled input, O = offset input, C = constant input):
234 // (S + (O + C))
235 // (S + (O + O))
236 // (S + C)
237 // (S + O)
238 // ((S + C) + O)
239 // ((S + O) + C)
240 // ((O + C) + O)
241 // ((O + O) + C)
242 // (O + C)
243 // (O + O)
244 Int32AddMatcher base_matcher(node);
245 Node* left = base_matcher.left().node();
246 Node* right = base_matcher.right().node();
247 if (base_matcher.HasScaledInput() && left->OwnedBy(node)) {
248 scaled_ = base_matcher.ScaledInput();
249 scale_factor_ = base_matcher.ScaleFactor();
250 if (right->opcode() == IrOpcode::kInt32Add && right->OwnedBy(node)) {
251 Int32AddMatcher right_matcher(right);
252 if (right_matcher.right().HasValue()) {
253 // (S + (O + C))
254 offset_ = right_matcher.left().node();
255 constant_ = right_matcher.right().node();
256 } else {
257 // (S + (O + O))
258 offset_ = right;
259 }
260 } else if (base_matcher.right().HasValue()) {
261 // (S + C)
262 constant_ = right;
263 } else {
264 // (S + O)
265 offset_ = right;
266 }
267 } else {
268 if (left->opcode() == IrOpcode::kInt32Add && left->OwnedBy(node)) {
269 Int32AddMatcher left_matcher(left);
270 Node* left_left = left_matcher.left().node();
271 Node* left_right = left_matcher.right().node();
272 if (left_matcher.HasScaledInput() && left_left->OwnedBy(left)) {
273 scaled_ = left_matcher.ScaledInput();
274 scale_factor_ = left_matcher.ScaleFactor();
275 if (left_matcher.right().HasValue()) {
276 // ((S + C) + O)
277 constant_ = left_right;
278 offset_ = right;
279 } else if (base_matcher.right().HasValue()) {
280 // ((S + O) + C)
281 offset_ = left_right;
282 constant_ = right;
283 } else {
284 // (O + O)
285 scaled_ = left;
286 offset_ = right;
287 }
288 } else {
289 if (left_matcher.right().HasValue()) {
290 // ((O + C) + O)
291 scaled_ = left_left;
292 constant_ = left_right;
293 offset_ = right;
294 } else if (base_matcher.right().HasValue()) {
295 // ((O + O) + C)
296 scaled_ = left_left;
297 offset_ = left_right;
298 constant_ = right;
299 } else {
300 // (O + O)
301 scaled_ = left;
302 offset_ = right;
303 }
304 }
305 } else {
306 if (base_matcher.right().HasValue()) {
307 // (O + C)
308 offset_ = left;
309 constant_ = right;
310 } else {
311 // (O + O)
312 offset_ = left;
313 scaled_ = right;
314 }
315 }
316 }
317 matches_ = true;
318 }
319
320 bool Matches() const { return matches_; }
titzer 2014/11/06 11:47:06 Lower case for simple getters.
danno 2014/11/06 23:34:07 Done.
321 Node* Scaled() const { return scaled_; }
322 int ScaleFactor() const { return scale_factor_; }
323 Node* Offset() const { return offset_; }
324 Node* Constant() const { return constant_; }
325
326 private:
327 bool matches_;
328
329 protected:
330 Node* scaled_;
331 int scale_factor_;
332 Node* offset_;
333 Node* constant_;
334 };
335
153 } // namespace compiler 336 } // namespace compiler
154 } // namespace internal 337 } // namespace internal
155 } // namespace v8 338 } // namespace v8
156 339
157 #endif // V8_COMPILER_NODE_MATCHERS_H_ 340 #endif // V8_COMPILER_NODE_MATCHERS_H_
OLDNEW
« no previous file with comments | « no previous file | src/compiler/x64/instruction-selector-x64.cc » ('j') | src/compiler/x64/instruction-selector-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698