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

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

Issue 10875030: Add support for XMM registers in SSA code generation pipeline. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix a bug pointed out by Florian Created 8 years, 4 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/cha.h" 7 #include "vm/cha.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/hash_map.h" 9 #include "vm/hash_map.h"
10 #include "vm/il_printer.h" 10 #include "vm/il_printer.h"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 #include "vm/scopes.h" 13 #include "vm/scopes.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, eliminate_type_checks); 18 DECLARE_FLAG(bool, eliminate_type_checks);
19 DECLARE_FLAG(bool, enable_type_checks); 19 DECLARE_FLAG(bool, enable_type_checks);
20 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); 20 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
21 DECLARE_FLAG(bool, trace_type_check_elimination); 21 DECLARE_FLAG(bool, trace_type_check_elimination);
22 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); 22 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
23 DEFINE_FLAG(bool, use_unboxed_doubles, true, "Try unboxing double values.");
23 24
24 void FlowGraphOptimizer::ApplyICData() { 25 void FlowGraphOptimizer::ApplyICData() {
25 VisitBlocks(); 26 VisitBlocks();
26 } 27 }
27 28
28 29
29 void FlowGraphOptimizer::OptimizeComputations() { 30 void FlowGraphOptimizer::OptimizeComputations() {
30 for (intptr_t i = 0; i < block_order_.length(); ++i) { 31 for (intptr_t i = 0; i < block_order_.length(); ++i) {
31 BlockEntryInstr* entry = block_order_[i]; 32 BlockEntryInstr* entry = block_order_[i];
32 entry->Accept(this); 33 entry->Accept(this);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 if (ic_data.NumberOfChecks() != 1) return kIllegalCid; 185 if (ic_data.NumberOfChecks() != 1) return kIllegalCid;
185 ASSERT(HasOneTarget(ic_data)); 186 ASSERT(HasOneTarget(ic_data));
186 187
187 Function& target = Function::Handle(); 188 Function& target = Function::Handle();
188 intptr_t class_id; 189 intptr_t class_id;
189 ic_data.GetOneClassCheckAt(0, &class_id, &target); 190 ic_data.GetOneClassCheckAt(0, &class_id, &target);
190 return class_id; 191 return class_id;
191 } 192 }
192 193
193 194
194 // Insert a check computation before an instruction and set the environment 195 void FlowGraphOptimizer::AddCheckClass(BindInstr* instr,
195 // of the check to the same as the instruction. 196 InstanceCallComp* comp,
196 static void InsertCheckBefore(BindInstr* instr, 197 Value* value) {
197 Computation* check,
198 Environment* env) {
199 BindInstr* check_instr = new BindInstr(BindInstr::kUnused, check);
200 check_instr->InsertBefore(instr);
201 ASSERT(env != NULL);
202 // Attach an environment to the check instruction.
203 check_instr->set_env(env);
204 }
205
206
207 static void AddCheckClass(BindInstr* instr,
208 InstanceCallComp* comp,
209 Value* value) {
210 // Type propagation has not run yet, we cannot eliminate the check. 198 // Type propagation has not run yet, we cannot eliminate the check.
211 CheckClassComp* check = new CheckClassComp(value, comp); 199 CheckClassComp* check = new CheckClassComp(value, comp);
212 const ICData& unary_checks = 200 const ICData& unary_checks =
213 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks()); 201 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
214 check->set_ic_data(&unary_checks); 202 check->set_ic_data(&unary_checks);
215 InsertCheckBefore(instr, check, instr->env()); 203 InsertBefore(instr, check, instr->env(), BindInstr::kUnused);
216 // Detach environment from the original instruction because it can't 204 // Detach environment from the original instruction because it can't
217 // deoptimize. 205 // deoptimize.
218 instr->set_env(NULL); 206 instr->set_env(NULL);
219 } 207 }
220 208
221 209
222 bool FlowGraphOptimizer::TryReplaceWithArrayOp(BindInstr* instr, 210 bool FlowGraphOptimizer::TryReplaceWithArrayOp(BindInstr* instr,
223 InstanceCallComp* comp, 211 InstanceCallComp* comp,
224 Token::Kind op_kind) { 212 Token::Kind op_kind) {
225 // TODO(fschneider): Optimize []= operator in checked mode as well. 213 // TODO(fschneider): Optimize []= operator in checked mode as well.
(...skipping 25 matching lines...) Expand all
251 instr->set_computation(array_op); 239 instr->set_computation(array_op);
252 RemovePushArguments(comp); 240 RemovePushArguments(comp);
253 return true; 241 return true;
254 } 242 }
255 default: 243 default:
256 return false; 244 return false;
257 } 245 }
258 } 246 }
259 247
260 248
249 BindInstr* FlowGraphOptimizer::InsertBefore(Instruction* instr,
250 Computation* comp,
251 Environment* env,
252 BindInstr::UseKind use_kind) {
253 BindInstr* bind = new BindInstr(use_kind, comp);
254 if (env != NULL) bind->set_env(env->Copy());
255 if (use_kind == BindInstr::kUsed) {
256 bind->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
257 }
258 bind->InsertBefore(instr);
259 return bind;
260 }
261
262
263 BindInstr* FlowGraphOptimizer::InsertAfter(Instruction* instr,
264 Computation* comp,
265 Environment* env,
266 BindInstr::UseKind use_kind) {
267 BindInstr* bind = new BindInstr(use_kind, comp);
268 if (env != NULL) bind->set_env(env->Copy());
269 if (use_kind == BindInstr::kUsed) {
270 bind->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
271 }
272 bind->InsertAfter(instr);
273 return bind;
274 }
275
276
261 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(BindInstr* instr, 277 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(BindInstr* instr,
262 InstanceCallComp* comp, 278 InstanceCallComp* comp,
263 Token::Kind op_kind) { 279 Token::Kind op_kind) {
264 intptr_t operands_type = kIllegalCid; 280 intptr_t operands_type = kIllegalCid;
265 ASSERT(comp->HasICData()); 281 ASSERT(comp->HasICData());
266 const ICData& ic_data = *comp->ic_data(); 282 const ICData& ic_data = *comp->ic_data();
267 switch (op_kind) { 283 switch (op_kind) {
268 case Token::kADD: 284 case Token::kADD:
269 case Token::kSUB: 285 case Token::kSUB:
270 case Token::kMUL: 286 case Token::kMUL:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 } else { 318 } else {
303 return false; 319 return false;
304 } 320 }
305 break; 321 break;
306 default: 322 default:
307 UNREACHABLE(); 323 UNREACHABLE();
308 }; 324 };
309 325
310 ASSERT(comp->ArgumentCount() == 2); 326 ASSERT(comp->ArgumentCount() == 2);
311 if (operands_type == kDoubleCid) { 327 if (operands_type == kDoubleCid) {
312 BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp); 328 if (FLAG_use_unboxed_doubles) {
313 double_bin_op->set_ic_data(comp->ic_data()); 329 Value* left = comp->ArgumentAt(0)->value();
314 instr->set_computation(double_bin_op); 330 Value* right = comp->ArgumentAt(1)->value();
331
332 // Check that either left or right are not a smi. Result or a
333 // binary operation with two smis is a smi not a double.
334 InsertBefore(instr,
335 new CheckEitherNonSmiComp(left, right, comp),
336 instr->env(),
337 BindInstr::kUnused);
338
339 // Unbox operands.
340 BindInstr* unbox_left = InsertBefore(
341 instr,
342 new UnboxDoubleComp(left->CopyValue(), comp),
343 instr->env(),
344 BindInstr::kUsed);
345 BindInstr* unbox_right = InsertBefore(
346 instr,
347 new UnboxDoubleComp(right->CopyValue(), comp),
348 instr->env(),
349 BindInstr::kUsed);
350
351 UnboxedDoubleBinaryOpComp* double_bin_op =
352 new UnboxedDoubleBinaryOpComp(op_kind,
353 new UseVal(unbox_left),
354 new UseVal(unbox_right));
355 double_bin_op->set_ic_data(comp->ic_data());
356 instr->set_computation(double_bin_op);
357
358 if (instr->is_used()) {
359 // Box result.
360 UseVal* use_val = new UseVal(instr);
361 BindInstr* bind = InsertAfter(instr,
362 new BoxDoubleComp(use_val, comp),
363 NULL,
364 BindInstr::kUsed);
365 instr->ReplaceUsesWith(bind);
366 }
367
368 RemovePushArguments(comp);
369 } else {
370 BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp);
371 double_bin_op->set_ic_data(comp->ic_data());
372 instr->set_computation(double_bin_op);
373 }
315 } else if (operands_type == kMintCid) { 374 } else if (operands_type == kMintCid) {
316 Value* left = comp->ArgumentAt(0)->value(); 375 Value* left = comp->ArgumentAt(0)->value();
317 Value* right = comp->ArgumentAt(1)->value(); 376 Value* right = comp->ArgumentAt(1)->value();
318 BinaryMintOpComp* bin_op = new BinaryMintOpComp(op_kind, 377 BinaryMintOpComp* bin_op = new BinaryMintOpComp(op_kind,
319 comp, 378 comp,
320 left, 379 left,
321 right); 380 right);
322 bin_op->set_ic_data(comp->ic_data()); 381 bin_op->set_ic_data(comp->ic_data());
323 instr->set_computation(bin_op); 382 instr->set_computation(bin_op);
324 RemovePushArguments(comp); 383 RemovePushArguments(comp);
325 } else { 384 } else {
326 ASSERT(operands_type == kSmiCid); 385 ASSERT(operands_type == kSmiCid);
327 Value* left = comp->ArgumentAt(0)->value(); 386 Value* left = comp->ArgumentAt(0)->value();
328 Value* right = comp->ArgumentAt(1)->value(); 387 Value* right = comp->ArgumentAt(1)->value();
329 // Insert two smi checks and attach a copy of the original 388 // Insert two smi checks and attach a copy of the original
330 // environment because the smi operation can still deoptimize. 389 // environment because the smi operation can still deoptimize.
331 InsertCheckBefore(instr, 390 InsertBefore(instr,
332 new CheckSmiComp(left->CopyValue(), comp), 391 new CheckSmiComp(left->CopyValue(), comp),
333 instr->env()->Copy()); 392 instr->env(),
334 InsertCheckBefore(instr, 393 BindInstr::kUnused);
335 new CheckSmiComp(right->CopyValue(), comp), 394 InsertBefore(instr,
336 instr->env()->Copy()); 395 new CheckSmiComp(right->CopyValue(), comp),
396 instr->env(),
397 BindInstr::kUnused);
337 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind, 398 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind,
338 comp, 399 comp,
339 left, 400 left,
340 right); 401 right);
341 bin_op->set_ic_data(comp->ic_data()); 402 bin_op->set_ic_data(comp->ic_data());
342 instr->set_computation(bin_op); 403 instr->set_computation(bin_op);
343 RemovePushArguments(comp); 404 RemovePushArguments(comp);
344 } 405 }
345 return true; 406 return true;
346 } 407 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 const ICData& unary_checks = 602 const ICData& unary_checks =
542 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks()); 603 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
543 bool call_with_checks; 604 bool call_with_checks;
544 // TODO(srdjan): Add check class comp for mixed smi/non-smi. 605 // TODO(srdjan): Add check class comp for mixed smi/non-smi.
545 if (HasOneTarget(unary_checks) && 606 if (HasOneTarget(unary_checks) &&
546 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) { 607 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) {
547 Value* value = comp->ArgumentAt(0)->value()->CopyValue(); 608 Value* value = comp->ArgumentAt(0)->value()->CopyValue();
548 // Type propagation has not run yet, we cannot eliminate the check. 609 // Type propagation has not run yet, we cannot eliminate the check.
549 CheckClassComp* check = new CheckClassComp(value, comp); 610 CheckClassComp* check = new CheckClassComp(value, comp);
550 check->set_ic_data(&unary_checks); 611 check->set_ic_data(&unary_checks);
551 InsertCheckBefore(instr, check, instr->env()->Copy()); 612 InsertBefore(instr, check, instr->env(), BindInstr::kUnused);
552 // Call can still deoptimize, do not detach environment from instr. 613 // Call can still deoptimize, do not detach environment from instr.
553 call_with_checks = false; 614 call_with_checks = false;
554 } else { 615 } else {
555 call_with_checks = true; 616 call_with_checks = true;
556 } 617 }
557 PolymorphicInstanceCallComp* call = 618 PolymorphicInstanceCallComp* call =
558 new PolymorphicInstanceCallComp(comp, call_with_checks); 619 new PolymorphicInstanceCallComp(comp, call_with_checks);
559 call->set_ic_data(&unary_checks); 620 call->set_ic_data(&unary_checks);
560 instr->set_computation(call); 621 instr->set_computation(call);
561 } 622 }
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map. 1063 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map.
1003 OptimizeRecursive(child, &child_map); 1064 OptimizeRecursive(child, &child_map);
1004 } else { 1065 } else {
1005 OptimizeRecursive(child, map); // Reuse map for the last child. 1066 OptimizeRecursive(child, map); // Reuse map for the last child.
1006 } 1067 }
1007 } 1068 }
1008 } 1069 }
1009 1070
1010 1071
1011 } // namespace dart 1072 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698