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

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

Issue 15697009: Enable code optimization on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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/deopt_instructions.cc ('k') | runtime/vm/flow_graph_compiler_ia32.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) 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/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 // Emit all kMaterializeObject instructions describing objects to be 56 // Emit all kMaterializeObject instructions describing objects to be
57 // materialized on the deoptimization as a prefix to the deoptimization info. 57 // materialized on the deoptimization as a prefix to the deoptimization info.
58 EmitMaterializations(deopt_env_, builder); 58 EmitMaterializations(deopt_env_, builder);
59 59
60 // The real frame starts here. 60 // The real frame starts here.
61 builder->MarkFrameStart(); 61 builder->MarkFrameStart();
62 62
63 // Current PP, FP, and PC. 63 // Current PP, FP, and PC.
64 builder->AddPp(current->function(), slot_ix++); 64 builder->AddPp(current->function(), slot_ix++);
65 builder->AddCallerFp(slot_ix++); 65 builder->AddCallerFp(slot_ix++);
66 builder->AddReturnAddress(current->function(), 66 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
67 deopt_id(),
68 slot_ix++);
69 67
70 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0. 68 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
71 builder->AddPcMarker(Function::Handle(), slot_ix++); 69 builder->AddPcMarker(Function::Handle(), slot_ix++);
72 70
73 // Emit all values that are needed for materialization as a part of the 71 // Emit all values that are needed for materialization as a part of the
74 // expression stack for the bottom-most frame. This guarantees that GC 72 // expression stack for the bottom-most frame. This guarantees that GC
75 // will be able to find them during materialization. 73 // will be able to find them during materialization.
76 slot_ix = builder->EmitMaterializationArguments(slot_ix); 74 slot_ix = builder->EmitMaterializationArguments(slot_ix);
77 75
78 // For the innermost environment, set outgoing arguments and the locals. 76 // For the innermost environment, set outgoing arguments and the locals.
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 return SubtypeTestCache::null(); 526 return SubtypeTestCache::null();
529 } 527 }
530 } 528 }
531 return GenerateUninstantiatedTypeTest(token_pos, 529 return GenerateUninstantiatedTypeTest(token_pos,
532 type, 530 type,
533 is_instance_lbl, 531 is_instance_lbl,
534 is_not_instance_lbl); 532 is_not_instance_lbl);
535 } 533 }
536 534
537 535
536 // If instanceof type test cannot be performed successfully at compile time and
537 // therefore eliminated, optimize it by adding inlined tests for:
538 // - NULL -> return false.
539 // - Smi -> compile time subtype check (only if dst class is not parameterized).
540 // - Class equality (only if class is not parameterized).
541 // Inputs:
542 // - R0: object.
543 // - R1: instantiator type arguments or raw_null.
544 // - R2: instantiator or raw_null.
545 // Returns:
546 // - true or false in R0.
538 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 547 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
539 intptr_t deopt_id, 548 intptr_t deopt_id,
540 const AbstractType& type, 549 const AbstractType& type,
541 bool negate_result, 550 bool negate_result,
542 LocationSummary* locs) { 551 LocationSummary* locs) {
543 UNIMPLEMENTED(); 552 ASSERT(type.IsFinalized() && !type.IsMalformed());
553
554 // Preserve instantiator (R2) and its type arguments (R1).
555 __ PushList((1 << R1) | (1 << R2));
556
557 Label is_instance, is_not_instance;
558 // If type is instantiated and non-parameterized, we can inline code
559 // checking whether the tested instance is a Smi.
560 if (type.IsInstantiated()) {
561 // A null object is only an instance of Object and dynamic, which has
562 // already been checked above (if the type is instantiated). So we can
563 // return false here if the instance is null (and if the type is
564 // instantiated).
565 // We can only inline this null check if the type is instantiated at compile
566 // time, since an uninstantiated type at compile time could be Object or
567 // dynamic at run time.
568 __ CompareImmediate(R0, reinterpret_cast<int32_t>(Object::null()));
569 __ b(&is_not_instance, EQ);
570 }
571
572 // Generate inline instanceof test.
573 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
574 test_cache = GenerateInlineInstanceof(token_pos, type,
575 &is_instance, &is_not_instance);
576
577 // test_cache is null if there is no fall-through.
578 Label done;
579 if (!test_cache.IsNull()) {
580 // Generate runtime call.
581 // Load instantiator (R2) and its type arguments (R1).
582 __ ldm(IA, SP, (1 << R1) | (1 << R2));
583 __ PushObject(Object::ZoneHandle()); // Make room for the result.
584 __ Push(R0); // Push the instance.
585 __ PushObject(type); // Push the type.
586 // Push instantiator (R2) and its type arguments (R1).
587 __ PushList((1 << R1) | (1 << R2));
588 __ LoadObject(R0, test_cache);
589 __ Push(R0);
590 GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs);
591 // Pop the parameters supplied to the runtime entry. The result of the
592 // instanceof runtime call will be left as the result of the operation.
593 __ Drop(5);
594 if (negate_result) {
595 __ Pop(R1);
596 __ LoadObject(R0, Bool::True());
597 __ cmp(R1, ShifterOperand(R0));
598 __ b(&done, NE);
599 __ LoadObject(R0, Bool::False());
600 } else {
601 __ Pop(R0);
602 }
603 __ b(&done);
604 }
605 __ Bind(&is_not_instance);
606 __ LoadObject(R0, negate_result ? Bool::True() : Bool::False());
607 __ b(&done);
608
609 __ Bind(&is_instance);
610 __ LoadObject(R0, negate_result ? Bool::False() : Bool::True());
611 __ Bind(&done);
612 // Remove instantiator (R2) and its type arguments (R1).
613 __ Drop(2);
544 } 614 }
545 615
546 616
547 // Optimize assignable type check by adding inlined tests for: 617 // Optimize assignable type check by adding inlined tests for:
548 // - NULL -> return NULL. 618 // - NULL -> return NULL.
549 // - Smi -> compile time subtype check (only if dst class is not parameterized). 619 // - Smi -> compile time subtype check (only if dst class is not parameterized).
550 // - Class equality (only if class is not parameterized). 620 // - Class equality (only if class is not parameterized).
551 // Inputs: 621 // Inputs:
552 // - R0: instance being type checked. 622 // - R0: instance being type checked.
553 // - R1: instantiator type arguments or raw_null. 623 // - R1: instantiator type arguments or raw_null.
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 // Second printing. 1164 // Second printing.
1095 OS::Print("Annotated "); 1165 OS::Print("Annotated ");
1096 } 1166 }
1097 AstPrinter::PrintFunctionScope(parsed_function()); 1167 AstPrinter::PrintFunctionScope(parsed_function());
1098 } 1168 }
1099 1169
1100 VisitBlocks(); 1170 VisitBlocks();
1101 1171
1102 __ bkpt(0); 1172 __ bkpt(0);
1103 GenerateDeferredCode(); 1173 GenerateDeferredCode();
1104 // Emit function patching code. This will be swapped with the first 5 bytes 1174 // Emit function patching code. This will be swapped with the first 3
1105 // at entry point. 1175 // instructions at entry point.
1106 AddCurrentDescriptor(PcDescriptors::kPatchCode, 1176 AddCurrentDescriptor(PcDescriptors::kPatchCode,
1107 Isolate::kNoDeoptId, 1177 Isolate::kNoDeoptId,
1108 0); // No token position. 1178 0); // No token position.
1109 __ Branch(&StubCode::FixCallersTargetLabel()); 1179 __ BranchPatchable(&StubCode::FixCallersTargetLabel());
1110 AddCurrentDescriptor(PcDescriptors::kLazyDeoptJump, 1180 AddCurrentDescriptor(PcDescriptors::kLazyDeoptJump,
1111 Isolate::kNoDeoptId, 1181 Isolate::kNoDeoptId,
1112 0); // No token position. 1182 0); // No token position.
1113 __ Branch(&StubCode::DeoptimizeLazyLabel()); 1183 __ Branch(&StubCode::DeoptimizeLazyLabel());
1114 } 1184 }
1115 1185
1116 1186
1117 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1187 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1118 const ExternalLabel* label, 1188 const ExternalLabel* label,
1119 PcDescriptors::Kind kind, 1189 PcDescriptors::Kind kind,
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 1380
1311 const intptr_t fpu_registers = locs->live_registers()->fpu_registers(); 1381 const intptr_t fpu_registers = locs->live_registers()->fpu_registers();
1312 if (fpu_registers > 0) { 1382 if (fpu_registers > 0) {
1313 UNIMPLEMENTED(); 1383 UNIMPLEMENTED();
1314 } 1384 }
1315 } 1385 }
1316 1386
1317 1387
1318 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1388 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1319 Register class_id_reg, 1389 Register class_id_reg,
1320 intptr_t arg_count, 1390 intptr_t argument_count,
1321 const Array& arg_names, 1391 const Array& argument_names,
1322 Label* deopt, 1392 Label* deopt,
1323 intptr_t deopt_id, 1393 intptr_t deopt_id,
1324 intptr_t token_index, 1394 intptr_t token_index,
1325 LocationSummary* locs) { 1395 LocationSummary* locs) {
1326 UNIMPLEMENTED(); 1396 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
1397 Label match_found;
1398 const intptr_t len = ic_data.NumberOfChecks();
1399 GrowableArray<CidTarget> sorted(len);
1400 SortICDataByCount(ic_data, &sorted);
1401 ASSERT(class_id_reg != R4);
1402 ASSERT(len > 0); // Why bother otherwise.
1403 const Array& arguments_descriptor =
1404 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
1405 argument_names));
1406 __ LoadObject(R4, arguments_descriptor);
1407 for (intptr_t i = 0; i < len; i++) {
1408 const bool is_last_check = (i == (len - 1));
1409 Label next_test;
1410 assembler()->CompareImmediate(class_id_reg, sorted[i].cid);
1411 if (is_last_check) {
1412 assembler()->b(deopt, NE);
1413 } else {
1414 assembler()->b(&next_test, NE);
1415 }
1416 // Do not use the code from the function, but let the code be patched so
1417 // that we can record the outgoing edges to other code.
1418 GenerateDartCall(deopt_id,
1419 token_index,
1420 &StubCode::CallStaticFunctionLabel(),
1421 PcDescriptors::kFuncCall,
1422 locs);
1423 const Function& function = *sorted[i].target;
1424 AddStaticCallTarget(function);
1425 __ Drop(argument_count);
1426 if (!is_last_check) {
1427 assembler()->b(&match_found);
1428 }
1429 assembler()->Bind(&next_test);
1430 }
1431 assembler()->Bind(&match_found);
1327 } 1432 }
1328 1433
1329 1434
1330 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition, 1435 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition,
1331 FpuRegister left, 1436 FpuRegister left,
1332 FpuRegister right, 1437 FpuRegister right,
1333 BranchInstr* branch) { 1438 BranchInstr* branch) {
1334 UNIMPLEMENTED(); 1439 UNIMPLEMENTED();
1335 } 1440 }
1336 1441
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1680 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1576 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); 1681 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex));
1577 } 1682 }
1578 1683
1579 1684
1580 #undef __ 1685 #undef __
1581 1686
1582 } // namespace dart 1687 } // namespace dart
1583 1688
1584 #endif // defined TARGET_ARCH_ARM 1689 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/deopt_instructions.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698