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

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

Issue 1858283002: Initial SIMDBC interpreter. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « runtime/vm/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_dbc.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_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
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
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
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 // DBC is very different from other architectures in how it performs instance
1151 // and static calls because it does not use stubs.
1152 #if !defined(TARGET_ARCH_DBC)
1150 void FlowGraphCompiler::GenerateInstanceCall( 1153 void FlowGraphCompiler::GenerateInstanceCall(
1151 intptr_t deopt_id, 1154 intptr_t deopt_id,
1152 TokenPosition token_pos, 1155 TokenPosition token_pos,
1153 intptr_t argument_count, 1156 intptr_t argument_count,
1154 LocationSummary* locs, 1157 LocationSummary* locs,
1155 const ICData& ic_data_in) { 1158 const ICData& ic_data_in) {
1156 ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); 1159 ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original());
1157 if (FLAG_precompiled_mode) { 1160 if (FLAG_precompiled_mode) {
1158 ic_data = ic_data.AsUnaryClassChecks(); 1161 ic_data = ic_data.AsUnaryClassChecks();
1159 EmitSwitchableInstanceCall(ic_data, argument_count, 1162 EmitSwitchableInstanceCall(ic_data, argument_count,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 Label* is_instance_lbl) { 1282 Label* is_instance_lbl) {
1280 assembler()->Comment("ListTypeCheck"); 1283 assembler()->Comment("ListTypeCheck");
1281 Label unknown; 1284 Label unknown;
1282 GrowableArray<intptr_t> args; 1285 GrowableArray<intptr_t> args;
1283 args.Add(kArrayCid); 1286 args.Add(kArrayCid);
1284 args.Add(kGrowableObjectArrayCid); 1287 args.Add(kGrowableObjectArrayCid);
1285 args.Add(kImmutableArrayCid); 1288 args.Add(kImmutableArrayCid);
1286 CheckClassIds(kClassIdReg, args, is_instance_lbl, &unknown); 1289 CheckClassIds(kClassIdReg, args, is_instance_lbl, &unknown);
1287 assembler()->Bind(&unknown); 1290 assembler()->Bind(&unknown);
1288 } 1291 }
1289 1292 #endif // !defined(TARGET_ARCH_DBC)
1290 1293
1291 void FlowGraphCompiler::EmitComment(Instruction* instr) { 1294 void FlowGraphCompiler::EmitComment(Instruction* instr) {
1292 if (!FLAG_support_il_printer || !FLAG_support_disassembler) { 1295 if (!FLAG_support_il_printer || !FLAG_support_disassembler) {
1293 return; 1296 return;
1294 } 1297 }
1295 #ifndef PRODUCT 1298 #ifndef PRODUCT
1296 char buffer[256]; 1299 char buffer[256];
1297 BufferFormatter f(buffer, sizeof(buffer)); 1300 BufferFormatter f(buffer, sizeof(buffer));
1298 instr->PrintTo(&f); 1301 instr->PrintTo(&f);
1299 assembler()->Comment("%s", buffer); 1302 assembler()->Comment("%s", buffer);
1300 #endif 1303 #endif
1301 } 1304 }
1302 1305
1303 1306
1307 #if !defined(TARGET_ARCH_DBC)
1308 // TODO(vegorov) enable edge-counters on DBC if we consider them beneficial.
1304 bool FlowGraphCompiler::NeedsEdgeCounter(TargetEntryInstr* block) { 1309 bool FlowGraphCompiler::NeedsEdgeCounter(TargetEntryInstr* block) {
1305 // Only emit an edge counter if there is not goto at the end of the block, 1310 // Only emit an edge counter if there is not goto at the end of the block,
1306 // except for the entry block. 1311 // except for the entry block.
1307 return (FLAG_reorder_basic_blocks 1312 return (FLAG_reorder_basic_blocks
1308 && (!block->last_instruction()->IsGoto() 1313 && (!block->last_instruction()->IsGoto()
1309 || (block == flow_graph().graph_entry()->normal_entry()))); 1314 || (block == flow_graph().graph_entry()->normal_entry())));
1310 } 1315 }
1311 1316
1312 1317
1313 // Allocate a register that is not explicitly blocked. 1318 // Allocate a register that is not explicitly blocked.
1314 static Register AllocateFreeRegister(bool* blocked_registers) { 1319 static Register AllocateFreeRegister(bool* blocked_registers) {
1315 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) { 1320 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) {
1316 if (!blocked_registers[regno]) { 1321 if (!blocked_registers[regno]) {
1317 blocked_registers[regno] = true; 1322 blocked_registers[regno] = true;
1318 return static_cast<Register>(regno); 1323 return static_cast<Register>(regno);
1319 } 1324 }
1320 } 1325 }
1321 UNREACHABLE(); 1326 UNREACHABLE();
1322 return kNoRegister; 1327 return kNoRegister;
1323 } 1328 }
1324 1329 #endif
1325
1326 static uword RegMaskBit(Register reg) {
1327 return ((reg) != kNoRegister) ? (1 << (reg)) : 0;
1328 }
1329 1330
1330 1331
1331 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { 1332 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
1332 ASSERT(!is_optimizing()); 1333 ASSERT(!is_optimizing());
1333
1334 instr->InitializeLocationSummary(zone(), 1334 instr->InitializeLocationSummary(zone(),
1335 false); // Not optimizing. 1335 false); // Not optimizing.
1336
1337 // No need to allocate registers based on LocationSummary on DBC as in
1338 // unoptimized mode it's a stack based bytecode just like IR itself.
1339 #if !defined(TARGET_ARCH_DBC)
1336 LocationSummary* locs = instr->locs(); 1340 LocationSummary* locs = instr->locs();
1337 1341
1338 bool blocked_registers[kNumberOfCpuRegisters]; 1342 bool blocked_registers[kNumberOfCpuRegisters];
1339 1343
1340 // Block all registers globally reserved by the assembler, etc and mark 1344 // Block all registers globally reserved by the assembler, etc and mark
1341 // the rest as free. 1345 // the rest as free.
1342 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { 1346 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
1343 blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0; 1347 blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0;
1344 } 1348 }
1345 1349
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 break; 1419 break;
1416 case Location::kSameAsFirstInput: 1420 case Location::kSameAsFirstInput:
1417 result_location = locs->in(0); 1421 result_location = locs->in(0);
1418 break; 1422 break;
1419 case Location::kRequiresFpuRegister: 1423 case Location::kRequiresFpuRegister:
1420 UNREACHABLE(); 1424 UNREACHABLE();
1421 break; 1425 break;
1422 } 1426 }
1423 locs->set_out(0, result_location); 1427 locs->set_out(0, result_location);
1424 } 1428 }
1429 #endif // !defined(TARGET_ARCH_DBC)
1425 } 1430 }
1426 1431
1427 1432
1433 static uword RegMaskBit(Register reg) {
1434 return ((reg) != kNoRegister) ? (1 << (reg)) : 0;
1435 }
1436
1437
1428 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler) 1438 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler)
1429 : compiler_(compiler), moves_(32) {} 1439 : compiler_(compiler), moves_(32) {}
1430 1440
1431 1441
1432 void ParallelMoveResolver::EmitNativeCode(ParallelMoveInstr* parallel_move) { 1442 void ParallelMoveResolver::EmitNativeCode(ParallelMoveInstr* parallel_move) {
1433 ASSERT(moves_.is_empty()); 1443 ASSERT(moves_.is_empty());
1434 // Build up a worklist of moves. 1444 // Build up a worklist of moves.
1435 BuildInitialMoveList(parallel_move); 1445 BuildInitialMoveList(parallel_move);
1436 1446
1437 for (int i = 0; i < moves_.length(); ++i) { 1447 for (int i = 0; i < moves_.length(); ++i) {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 // |token_pos|. 1841 // |token_pos|.
1832 code_source_map_builder()->AddEntry(saved_code_size_, token_pos); 1842 code_source_map_builder()->AddEntry(saved_code_size_, token_pos);
1833 BeginCodeSourceRange(); 1843 BeginCodeSourceRange();
1834 return true; 1844 return true;
1835 } 1845 }
1836 ); 1846 );
1837 return false; 1847 return false;
1838 } 1848 }
1839 1849
1840 1850
1851 #if !defined(TARGET_ARCH_DBC)
1852 // DBC emits calls very differently from other architectures due to its
1853 // interpreted nature.
1841 void FlowGraphCompiler::EmitPolymorphicInstanceCall( 1854 void FlowGraphCompiler::EmitPolymorphicInstanceCall(
1842 const ICData& ic_data, 1855 const ICData& ic_data,
1843 intptr_t argument_count, 1856 intptr_t argument_count,
1844 const Array& argument_names, 1857 const Array& argument_names,
1845 intptr_t deopt_id, 1858 intptr_t deopt_id,
1846 TokenPosition token_pos, 1859 TokenPosition token_pos,
1847 LocationSummary* locs, 1860 LocationSummary* locs,
1848 bool complete) { 1861 bool complete) {
1849 if (FLAG_polymorphic_with_deopt) { 1862 if (FLAG_polymorphic_with_deopt) {
1850 Label* deopt = AddDeoptStub(deopt_id, 1863 Label* deopt = AddDeoptStub(deopt_id,
(...skipping 23 matching lines...) Expand all
1874 EmitTestAndCall(ic_data, argument_count, argument_names, 1887 EmitTestAndCall(ic_data, argument_count, argument_names,
1875 slow_path->entry_label(), // No cid match. 1888 slow_path->entry_label(), // No cid match.
1876 &ok, // Found cid. 1889 &ok, // Found cid.
1877 deopt_id, token_pos, locs, false); 1890 deopt_id, token_pos, locs, false);
1878 1891
1879 assembler()->Bind(slow_path->exit_label()); 1892 assembler()->Bind(slow_path->exit_label());
1880 assembler()->Bind(&ok); 1893 assembler()->Bind(&ok);
1881 } 1894 }
1882 } 1895 }
1883 } 1896 }
1897 #endif
1884 1898
1885 1899 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC)
1886 #if defined(DEBUG) 1900 // TODO(vegorov) re-enable frame state tracking on DBC. It is
1901 // currently disabled because it relies on LocationSummaries and
1902 // we don't use them during unoptimized compilation on DBC.
1887 void FlowGraphCompiler::FrameStateUpdateWith(Instruction* instr) { 1903 void FlowGraphCompiler::FrameStateUpdateWith(Instruction* instr) {
1888 ASSERT(!is_optimizing()); 1904 ASSERT(!is_optimizing());
1889 1905
1890 switch (instr->tag()) { 1906 switch (instr->tag()) {
1891 case Instruction::kPushArgument: 1907 case Instruction::kPushArgument:
1892 case Instruction::kPushTemp: 1908 case Instruction::kPushTemp:
1893 // Do nothing. 1909 // Do nothing.
1894 break; 1910 break;
1895 1911
1896 case Instruction::kDropTemps: 1912 case Instruction::kDropTemps:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 } 1963 }
1948 } 1964 }
1949 return true; 1965 return true;
1950 } 1966 }
1951 1967
1952 1968
1953 void FlowGraphCompiler::FrameStateClear() { 1969 void FlowGraphCompiler::FrameStateClear() {
1954 ASSERT(!is_optimizing()); 1970 ASSERT(!is_optimizing());
1955 frame_state_.TruncateTo(0); 1971 frame_state_.TruncateTo(0);
1956 } 1972 }
1957 #endif 1973 #endif // defined(DEBUG) && !defined(TARGET_ARCH_DBC)
1958 1974
1959 1975
1960 } // namespace dart 1976 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698