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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 12218181: Recognize pattern (a << b) & c with c being a positive Smi and allow left shift to truncate the res… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months 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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 160
161 const bool with_checks = false; 161 const bool with_checks = false;
162 PolymorphicInstanceCallInstr* specialized = 162 PolymorphicInstanceCallInstr* specialized =
163 new PolymorphicInstanceCallInstr(call->instance_call(), 163 new PolymorphicInstanceCallInstr(call->instance_call(),
164 ic_data, 164 ic_data,
165 with_checks); 165 with_checks);
166 call->ReplaceWith(specialized, current_iterator()); 166 call->ReplaceWith(specialized, current_iterator());
167 } 167 }
168 168
169 169
170 static BinarySmiOpInstr* AsSmiLeftShiftInstruction(Value* v) {
171 BinarySmiOpInstr* instr = v->definition()->AsBinarySmiOp();
172 if ((instr != NULL) && (instr->op_kind() == Token::kSHL)) {
173 return instr;
174 }
175 return NULL;
176 }
177
178
179 Value* AsPositiveSmiConstValue(Value* v) {
180 if (v->BindsToConstant() && v->BoundConstant().IsSmi()) {
181 if (Smi::Cast(v->BoundConstant()).Value() >= 0) {
182 return v;
183 }
184 }
185 return NULL;
186 }
187
188
189 void FlowGraphOptimizer::OptimizeLeftShiftBitAndSmiOp(
190 Definition* bit_and_instr,
191 Value* left,
192 Value* right) {
193 // Both left and right may have only one use.
Vyacheslav Egorov (Google) 2013/02/20 00:37:06 The constant can have many uses it does not invali
srdjan 2013/02/21 00:47:17 Done.
194 if ((left->next_use() != NULL) || (left->previous_use() != NULL)) {
195 return;
196 }
197 if ((right->next_use() != NULL) || (right->previous_use() != NULL)) {
198 return;
199 }
Vyacheslav Egorov (Google) 2013/02/20 00:37:06 This does not check for environment uses. I think
srdjan 2013/02/21 00:47:17 It fails, thanks. Added to test suite. Punted on f
200 // Check for pattern
201 BinarySmiOpInstr* smi_left_shift = NULL;
202 Value* smi_const = AsPositiveSmiConstValue(left);
203 if (smi_const == NULL) {
204 smi_const = AsPositiveSmiConstValue(right);
205 if (smi_const != NULL) {
206 smi_left_shift = AsSmiLeftShiftInstruction(left);
207 }
208 } else {
209 smi_left_shift = AsSmiLeftShiftInstruction(right);
210 }
211 if ((smi_left_shift == NULL) || (smi_const == NULL)) {
212 // Not the pattern 'BIT_AND with smi-left-shift and smi-constant'.
213 return;
214 }
215 if (bit_and_instr->IsBinarySmiOp()) {
216 smi_left_shift->set_is_truncating(true);
217 } else {
218 ASSERT(bit_and_instr->IsBinaryMintOp());
219 smi_left_shift->set_is_truncating(true);
220 // Replace Mint op with Smi op.
221 BinarySmiOpInstr* smi_op = new BinarySmiOpInstr(
222 Token::kBIT_AND,
223 bit_and_instr->AsBinaryMintOp()->instance_call(),
224 left->Copy(),
225 right->Copy());
226 bit_and_instr->ReplaceWith(smi_op, current_iterator());
227 }
228 }
229
230
231 // Optimize (a << b) & c pattern: if c is a positive smi, then the
232 // shift can be a truncating Smi shift and result is always Smi.
233 void FlowGraphOptimizer::TryOptimizeLeftShiftWithBitAndPattern() {
234 ASSERT(current_iterator_ == NULL);
235 for (intptr_t i = 0; i < block_order_.length(); ++i) {
236 BlockEntryInstr* entry = block_order_[i];
237 ForwardInstructionIterator it(entry);
238 current_iterator_ = &it;
239 for (; !it.Done(); it.Advance()) {
240 if (it.Current()->IsBinarySmiOp()) {
241 BinarySmiOpInstr* binop = it.Current()->AsBinarySmiOp();
242 if (binop->op_kind() == Token::kBIT_AND) {
243 OptimizeLeftShiftBitAndSmiOp(binop, binop->left(), binop->right());
244 }
245 } else if (it.Current()->IsBinaryMintOp()) {
246 BinaryMintOpInstr* mintop = it.Current()->AsBinaryMintOp();
247 if (mintop->op_kind() == Token::kBIT_AND) {
248 OptimizeLeftShiftBitAndSmiOp(mintop, mintop->left(), mintop->right());
249 }
250 }
251 }
252 current_iterator_ = NULL;
253 }
254 }
255
256
170 static void EnsureSSATempIndex(FlowGraph* graph, 257 static void EnsureSSATempIndex(FlowGraph* graph,
171 Definition* defn, 258 Definition* defn,
172 Definition* replacement) { 259 Definition* replacement) {
173 if ((replacement->ssa_temp_index() == -1) && 260 if ((replacement->ssa_temp_index() == -1) &&
174 (defn->ssa_temp_index() != -1)) { 261 (defn->ssa_temp_index() != -1)) {
175 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index()); 262 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index());
176 } 263 }
177 } 264 }
178 265
179 266
(...skipping 4006 matching lines...) Expand 10 before | Expand all | Expand 10 after
4186 4273
4187 if (FLAG_trace_constant_propagation) { 4274 if (FLAG_trace_constant_propagation) {
4188 OS::Print("\n==== After constant propagation ====\n"); 4275 OS::Print("\n==== After constant propagation ====\n");
4189 FlowGraphPrinter printer(*graph_); 4276 FlowGraphPrinter printer(*graph_);
4190 printer.PrintBlocks(); 4277 printer.PrintBlocks();
4191 } 4278 }
4192 } 4279 }
4193 4280
4194 4281
4195 } // namespace dart 4282 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698