OLD | NEW |
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_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
6 | 6 |
7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
8 | 8 |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 for (intptr_t i = 0; i < block_order().length(); ++i) { | 496 for (intptr_t i = 0; i < block_order().length(); ++i) { |
497 // Compile the block entry. | 497 // Compile the block entry. |
498 BlockEntryInstr* entry = block_order()[i]; | 498 BlockEntryInstr* entry = block_order()[i]; |
499 assembler()->Comment("B%" Pd "", entry->block_id()); | 499 assembler()->Comment("B%" Pd "", entry->block_id()); |
500 set_current_block(entry); | 500 set_current_block(entry); |
501 | 501 |
502 if (WasCompacted(entry)) { | 502 if (WasCompacted(entry)) { |
503 continue; | 503 continue; |
504 } | 504 } |
505 | 505 |
506 #if defined(DEBUG) | 506 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC) |
507 if (!is_optimizing()) { | 507 if (!is_optimizing()) { |
508 FrameStateClear(); | 508 FrameStateClear(); |
509 } | 509 } |
510 #endif | 510 #endif |
511 | 511 |
512 LoopInfoComment(assembler(), *entry, *loop_headers); | 512 LoopInfoComment(assembler(), *entry, *loop_headers); |
513 | 513 |
514 entry->set_offset(assembler()->CodeSize()); | 514 entry->set_offset(assembler()->CodeSize()); |
515 BeginCodeSourceRange(); | 515 BeginCodeSourceRange(); |
516 entry->EmitNativeCode(this); | 516 entry->EmitNativeCode(this); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 BeginCodeSourceRange(); | 550 BeginCodeSourceRange(); |
551 EmitInstructionPrologue(instr); | 551 EmitInstructionPrologue(instr); |
552 ASSERT(pending_deoptimization_env_ == NULL); | 552 ASSERT(pending_deoptimization_env_ == NULL); |
553 pending_deoptimization_env_ = instr->env(); | 553 pending_deoptimization_env_ = instr->env(); |
554 instr->EmitNativeCode(this); | 554 instr->EmitNativeCode(this); |
555 pending_deoptimization_env_ = NULL; | 555 pending_deoptimization_env_ = NULL; |
556 EmitInstructionEpilogue(instr); | 556 EmitInstructionEpilogue(instr); |
557 EndCodeSourceRange(instr->token_pos()); | 557 EndCodeSourceRange(instr->token_pos()); |
558 } | 558 } |
559 | 559 |
560 #if defined(DEBUG) | 560 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC) |
561 if (!is_optimizing()) { | 561 if (!is_optimizing()) { |
562 FrameStateUpdateWith(instr); | 562 FrameStateUpdateWith(instr); |
563 } | 563 } |
564 #endif | 564 #endif |
565 } | 565 } |
566 | 566 |
567 #if defined(DEBUG) | 567 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC) |
568 ASSERT(is_optimizing() || FrameStateIsSafeToCall()); | 568 ASSERT(is_optimizing() || FrameStateIsSafeToCall()); |
569 #endif | 569 #endif |
570 } | 570 } |
571 | 571 |
572 if (is_optimizing()) { | 572 if (is_optimizing()) { |
573 LogBlock lb; | 573 LogBlock lb; |
574 intervals.Add( | 574 intervals.Add( |
575 IntervalStruct(prev_offset, prev_inlining_pos, prev_inlining_id)); | 575 IntervalStruct(prev_offset, prev_inlining_pos, prev_inlining_id)); |
576 inlined_code_intervals_ = | 576 inlined_code_intervals_ = |
577 Array::New(intervals.length() * Code::kInlIntNumEntries, Heap::kOld); | 577 Array::New(intervals.length() * Code::kInlIntNumEntries, Heap::kOld); |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 // branches from intrinsic code redirect to here where the slow-path | 1140 // branches from intrinsic code redirect to here where the slow-path |
1141 // (normal function body) starts. | 1141 // (normal function body) starts. |
1142 // This means that there must not be any side-effects in intrinsic code | 1142 // This means that there must not be any side-effects in intrinsic code |
1143 // before any deoptimization point. | 1143 // before any deoptimization point. |
1144 ASSERT(!intrinsic_slow_path_label_.IsBound()); | 1144 ASSERT(!intrinsic_slow_path_label_.IsBound()); |
1145 assembler()->Bind(&intrinsic_slow_path_label_); | 1145 assembler()->Bind(&intrinsic_slow_path_label_); |
1146 return false; | 1146 return false; |
1147 } | 1147 } |
1148 | 1148 |
1149 | 1149 |
| 1150 #if !defined(TARGET_ARCH_DBC) |
1150 void FlowGraphCompiler::GenerateInstanceCall( | 1151 void FlowGraphCompiler::GenerateInstanceCall( |
1151 intptr_t deopt_id, | 1152 intptr_t deopt_id, |
1152 TokenPosition token_pos, | 1153 TokenPosition token_pos, |
1153 intptr_t argument_count, | 1154 intptr_t argument_count, |
1154 LocationSummary* locs, | 1155 LocationSummary* locs, |
1155 const ICData& ic_data_in) { | 1156 const ICData& ic_data_in) { |
1156 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); | 1157 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); |
1157 if (FLAG_precompiled_mode) { | 1158 if (FLAG_precompiled_mode) { |
1158 EmitSwitchableInstanceCall(ic_data, argument_count, | 1159 EmitSwitchableInstanceCall(ic_data, argument_count, |
1159 deopt_id, token_pos, locs); | 1160 deopt_id, token_pos, locs); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 Label* is_instance_lbl) { | 1279 Label* is_instance_lbl) { |
1279 assembler()->Comment("ListTypeCheck"); | 1280 assembler()->Comment("ListTypeCheck"); |
1280 Label unknown; | 1281 Label unknown; |
1281 GrowableArray<intptr_t> args; | 1282 GrowableArray<intptr_t> args; |
1282 args.Add(kArrayCid); | 1283 args.Add(kArrayCid); |
1283 args.Add(kGrowableObjectArrayCid); | 1284 args.Add(kGrowableObjectArrayCid); |
1284 args.Add(kImmutableArrayCid); | 1285 args.Add(kImmutableArrayCid); |
1285 CheckClassIds(kClassIdReg, args, is_instance_lbl, &unknown); | 1286 CheckClassIds(kClassIdReg, args, is_instance_lbl, &unknown); |
1286 assembler()->Bind(&unknown); | 1287 assembler()->Bind(&unknown); |
1287 } | 1288 } |
1288 | 1289 #endif |
1289 | 1290 |
1290 void FlowGraphCompiler::EmitComment(Instruction* instr) { | 1291 void FlowGraphCompiler::EmitComment(Instruction* instr) { |
1291 if (!FLAG_support_il_printer || !FLAG_support_disassembler) { | 1292 if (!FLAG_support_il_printer || !FLAG_support_disassembler) { |
1292 return; | 1293 return; |
1293 } | 1294 } |
1294 #ifndef PRODUCT | 1295 #ifndef PRODUCT |
1295 char buffer[256]; | 1296 char buffer[256]; |
1296 BufferFormatter f(buffer, sizeof(buffer)); | 1297 BufferFormatter f(buffer, sizeof(buffer)); |
1297 instr->PrintTo(&f); | 1298 instr->PrintTo(&f); |
1298 assembler()->Comment("%s", buffer); | 1299 assembler()->Comment("%s", buffer); |
1299 #endif | 1300 #endif |
1300 } | 1301 } |
1301 | 1302 |
1302 | 1303 |
| 1304 #if !defined(TARGET_ARCH_DBC) |
1303 bool FlowGraphCompiler::NeedsEdgeCounter(TargetEntryInstr* block) { | 1305 bool FlowGraphCompiler::NeedsEdgeCounter(TargetEntryInstr* block) { |
1304 // Only emit an edge counter if there is not goto at the end of the block, | 1306 // Only emit an edge counter if there is not goto at the end of the block, |
1305 // except for the entry block. | 1307 // except for the entry block. |
1306 return (FLAG_reorder_basic_blocks | 1308 return (FLAG_reorder_basic_blocks |
1307 && (!block->last_instruction()->IsGoto() | 1309 && (!block->last_instruction()->IsGoto() |
1308 || (block == flow_graph().graph_entry()->normal_entry()))); | 1310 || (block == flow_graph().graph_entry()->normal_entry()))); |
1309 } | 1311 } |
1310 | 1312 |
1311 | 1313 |
1312 // Allocate a register that is not explicitly blocked. | 1314 // Allocate a register that is not explicitly blocked. |
1313 static Register AllocateFreeRegister(bool* blocked_registers) { | 1315 static Register AllocateFreeRegister(bool* blocked_registers) { |
1314 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) { | 1316 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) { |
1315 if (!blocked_registers[regno]) { | 1317 if (!blocked_registers[regno]) { |
1316 blocked_registers[regno] = true; | 1318 blocked_registers[regno] = true; |
1317 return static_cast<Register>(regno); | 1319 return static_cast<Register>(regno); |
1318 } | 1320 } |
1319 } | 1321 } |
1320 UNREACHABLE(); | 1322 UNREACHABLE(); |
1321 return kNoRegister; | 1323 return kNoRegister; |
1322 } | 1324 } |
1323 | 1325 #endif |
1324 | |
1325 static uword RegMaskBit(Register reg) { | |
1326 return ((reg) != kNoRegister) ? (1 << (reg)) : 0; | |
1327 } | |
1328 | 1326 |
1329 | 1327 |
1330 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { | 1328 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { |
1331 ASSERT(!is_optimizing()); | 1329 ASSERT(!is_optimizing()); |
1332 | |
1333 instr->InitializeLocationSummary(zone(), | 1330 instr->InitializeLocationSummary(zone(), |
1334 false); // Not optimizing. | 1331 false); // Not optimizing. |
| 1332 |
| 1333 #if !defined(TARGET_ARCH_DBC) |
1335 LocationSummary* locs = instr->locs(); | 1334 LocationSummary* locs = instr->locs(); |
1336 | 1335 |
1337 bool blocked_registers[kNumberOfCpuRegisters]; | 1336 bool blocked_registers[kNumberOfCpuRegisters]; |
1338 | 1337 |
1339 // Block all registers globally reserved by the assembler, etc and mark | 1338 // Block all registers globally reserved by the assembler, etc and mark |
1340 // the rest as free. | 1339 // the rest as free. |
1341 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | 1340 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
1342 blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0; | 1341 blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0; |
1343 } | 1342 } |
1344 | 1343 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 break; | 1413 break; |
1415 case Location::kSameAsFirstInput: | 1414 case Location::kSameAsFirstInput: |
1416 result_location = locs->in(0); | 1415 result_location = locs->in(0); |
1417 break; | 1416 break; |
1418 case Location::kRequiresFpuRegister: | 1417 case Location::kRequiresFpuRegister: |
1419 UNREACHABLE(); | 1418 UNREACHABLE(); |
1420 break; | 1419 break; |
1421 } | 1420 } |
1422 locs->set_out(0, result_location); | 1421 locs->set_out(0, result_location); |
1423 } | 1422 } |
| 1423 #endif |
1424 } | 1424 } |
1425 | 1425 |
1426 | 1426 |
| 1427 static uword RegMaskBit(Register reg) { |
| 1428 return ((reg) != kNoRegister) ? (1 << (reg)) : 0; |
| 1429 } |
| 1430 |
| 1431 |
1427 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler) | 1432 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler) |
1428 : compiler_(compiler), moves_(32) {} | 1433 : compiler_(compiler), moves_(32) {} |
1429 | 1434 |
1430 | 1435 |
1431 void ParallelMoveResolver::EmitNativeCode(ParallelMoveInstr* parallel_move) { | 1436 void ParallelMoveResolver::EmitNativeCode(ParallelMoveInstr* parallel_move) { |
1432 ASSERT(moves_.is_empty()); | 1437 ASSERT(moves_.is_empty()); |
1433 // Build up a worklist of moves. | 1438 // Build up a worklist of moves. |
1434 BuildInitialMoveList(parallel_move); | 1439 BuildInitialMoveList(parallel_move); |
1435 | 1440 |
1436 for (int i = 0; i < moves_.length(); ++i) { | 1441 for (int i = 0; i < moves_.length(); ++i) { |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1824 // |token_pos|. | 1829 // |token_pos|. |
1825 code_source_map_builder()->AddEntry(saved_code_size_, token_pos); | 1830 code_source_map_builder()->AddEntry(saved_code_size_, token_pos); |
1826 BeginCodeSourceRange(); | 1831 BeginCodeSourceRange(); |
1827 return true; | 1832 return true; |
1828 } | 1833 } |
1829 ); | 1834 ); |
1830 return false; | 1835 return false; |
1831 } | 1836 } |
1832 | 1837 |
1833 | 1838 |
| 1839 #if !defined(TARGET_ARCH_DBC) |
1834 void FlowGraphCompiler::EmitPolymorphicInstanceCall( | 1840 void FlowGraphCompiler::EmitPolymorphicInstanceCall( |
1835 const ICData& ic_data, | 1841 const ICData& ic_data, |
1836 intptr_t argument_count, | 1842 intptr_t argument_count, |
1837 const Array& argument_names, | 1843 const Array& argument_names, |
1838 intptr_t deopt_id, | 1844 intptr_t deopt_id, |
1839 TokenPosition token_pos, | 1845 TokenPosition token_pos, |
1840 LocationSummary* locs) { | 1846 LocationSummary* locs) { |
1841 if (FLAG_polymorphic_with_deopt) { | 1847 if (FLAG_polymorphic_with_deopt) { |
1842 Label* deopt = AddDeoptStub(deopt_id, | 1848 Label* deopt = AddDeoptStub(deopt_id, |
1843 ICData::kDeoptPolymorphicInstanceCallTestFail); | 1849 ICData::kDeoptPolymorphicInstanceCallTestFail); |
(...skipping 13 matching lines...) Expand all Loading... |
1857 AddSlowPathCode(slow_path); | 1863 AddSlowPathCode(slow_path); |
1858 EmitTestAndCall(ic_data, argument_count, argument_names, | 1864 EmitTestAndCall(ic_data, argument_count, argument_names, |
1859 slow_path->entry_label(), // No cid match. | 1865 slow_path->entry_label(), // No cid match. |
1860 &ok, // Found cid. | 1866 &ok, // Found cid. |
1861 deopt_id, token_pos, locs); | 1867 deopt_id, token_pos, locs); |
1862 | 1868 |
1863 assembler()->Bind(slow_path->exit_label()); | 1869 assembler()->Bind(slow_path->exit_label()); |
1864 assembler()->Bind(&ok); | 1870 assembler()->Bind(&ok); |
1865 } | 1871 } |
1866 } | 1872 } |
| 1873 #endif |
1867 | 1874 |
1868 | 1875 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC) |
1869 #if defined(DEBUG) | |
1870 void FlowGraphCompiler::FrameStateUpdateWith(Instruction* instr) { | 1876 void FlowGraphCompiler::FrameStateUpdateWith(Instruction* instr) { |
1871 ASSERT(!is_optimizing()); | 1877 ASSERT(!is_optimizing()); |
1872 | 1878 |
1873 switch (instr->tag()) { | 1879 switch (instr->tag()) { |
1874 case Instruction::kPushArgument: | 1880 case Instruction::kPushArgument: |
1875 case Instruction::kPushTemp: | 1881 case Instruction::kPushTemp: |
1876 // Do nothing. | 1882 // Do nothing. |
1877 break; | 1883 break; |
1878 | 1884 |
1879 case Instruction::kDropTemps: | 1885 case Instruction::kDropTemps: |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1934 | 1940 |
1935 | 1941 |
1936 void FlowGraphCompiler::FrameStateClear() { | 1942 void FlowGraphCompiler::FrameStateClear() { |
1937 ASSERT(!is_optimizing()); | 1943 ASSERT(!is_optimizing()); |
1938 frame_state_.TruncateTo(0); | 1944 frame_state_.TruncateTo(0); |
1939 } | 1945 } |
1940 #endif | 1946 #endif |
1941 | 1947 |
1942 | 1948 |
1943 } // namespace dart | 1949 } // namespace dart |
OLD | NEW |