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

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

Issue 10832411: Remove support for non-ssa optimizing code generation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
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/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/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/debugger.h" 10 #include "vm/debugger.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 70 }
71 71
72 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); 72 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo());
73 return deopt_info.raw(); 73 return deopt_info.raw();
74 } 74 }
75 75
76 76
77 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, 77 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler,
78 const FlowGraph& flow_graph, 78 const FlowGraph& flow_graph,
79 bool is_optimizing, 79 bool is_optimizing,
80 bool is_ssa,
81 bool is_leaf) 80 bool is_leaf)
82 : assembler_(assembler), 81 : assembler_(assembler),
83 parsed_function_(flow_graph.parsed_function()), 82 parsed_function_(flow_graph.parsed_function()),
84 block_order_(flow_graph.reverse_postorder()), 83 block_order_(flow_graph.reverse_postorder()),
85 current_block_(NULL), 84 current_block_(NULL),
86 exception_handlers_list_(NULL), 85 exception_handlers_list_(NULL),
87 pc_descriptors_list_(NULL), 86 pc_descriptors_list_(NULL),
88 stackmap_table_builder_(NULL), 87 stackmap_table_builder_(NULL),
89 block_info_(block_order_.length()), 88 block_info_(block_order_.length()),
90 deopt_stubs_(), 89 deopt_stubs_(),
91 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())), 90 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())),
92 is_optimizing_(is_optimizing), 91 is_optimizing_(is_optimizing),
93 is_ssa_(is_ssa),
94 is_dart_leaf_(is_leaf), 92 is_dart_leaf_(is_leaf),
95 bool_true_(Bool::ZoneHandle(Bool::True())), 93 bool_true_(Bool::ZoneHandle(Bool::True())),
96 bool_false_(Bool::ZoneHandle(Bool::False())), 94 bool_false_(Bool::ZoneHandle(Bool::False())),
97 double_class_(Class::ZoneHandle( 95 double_class_(Class::ZoneHandle(
98 Isolate::Current()->object_store()->double_class())), 96 Isolate::Current()->object_store()->double_class())),
99 frame_register_allocator_(this, is_optimizing, is_ssa),
100 parallel_move_resolver_(this) { 97 parallel_move_resolver_(this) {
101 ASSERT(assembler != NULL); 98 ASSERT(assembler != NULL);
102 ASSERT(is_optimizing_ || !is_ssa_); 99 if (is_optimizing_) {
103 if (is_ssa_) {
104 stackmap_table_builder_ = new StackmapTableBuilder(StackSize()); 100 stackmap_table_builder_ = new StackmapTableBuilder(StackSize());
105 } 101 }
106 } 102 }
107 103
108 104
109 FlowGraphCompiler::~FlowGraphCompiler() { 105 FlowGraphCompiler::~FlowGraphCompiler() {
110 // BlockInfos are zone-allocated, so their destructors are not called. 106 // BlockInfos are zone-allocated, so their destructors are not called.
111 // Verify the labels explicitly here. 107 // Verify the labels explicitly here.
112 for (int i = 0; i < block_info_.length(); ++i) { 108 for (int i = 0; i < block_info_.length(); ++i) {
113 ASSERT(!block_info_[i]->label.IsLinked()); 109 ASSERT(!block_info_[i]->label.IsLinked());
(...skipping 26 matching lines...) Expand all
140 136
141 bool FlowGraphCompiler::CanOptimize() { 137 bool FlowGraphCompiler::CanOptimize() {
142 return !FLAG_report_usage_count && 138 return !FLAG_report_usage_count &&
143 (FLAG_optimization_counter_threshold >= 0) && 139 (FLAG_optimization_counter_threshold >= 0) &&
144 !Isolate::Current()->debugger()->IsActive(); 140 !Isolate::Current()->debugger()->IsActive();
145 } 141 }
146 142
147 143
148 void FlowGraphCompiler::VisitBlocks() { 144 void FlowGraphCompiler::VisitBlocks() {
149 for (intptr_t i = 0; i < block_order().length(); ++i) { 145 for (intptr_t i = 0; i < block_order().length(); ++i) {
150 ASSERT(frame_register_allocator()->IsSpilled());
151 assembler()->Comment("B%d", i); 146 assembler()->Comment("B%d", i);
152 // Compile the block entry. 147 // Compile the block entry.
153 BlockEntryInstr* entry = block_order()[i]; 148 BlockEntryInstr* entry = block_order()[i];
154 set_current_block(entry); 149 set_current_block(entry);
155 entry->PrepareEntry(this); 150 entry->PrepareEntry(this);
156 // Compile all successors until an exit, branch, or a block entry. 151 // Compile all successors until an exit, branch, or a block entry.
157 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 152 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
158 Instruction* instr = it.Current(); 153 Instruction* instr = it.Current();
159 if (FLAG_code_comments) EmitComment(instr); 154 if (FLAG_code_comments) EmitComment(instr);
160 if (instr->IsParallelMove()) { 155 if (instr->IsParallelMove()) {
(...skipping 15 matching lines...) Expand all
176 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 171 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
177 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 172 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
178 OS::SNPrint(chars, len, kFormat, function_name, reason); 173 OS::SNPrint(chars, len, kFormat, function_name, reason);
179 const Error& error = Error::Handle( 174 const Error& error = Error::Handle(
180 LanguageError::New(String::Handle(String::New(chars)))); 175 LanguageError::New(String::Handle(String::New(chars))));
181 Isolate::Current()->long_jump_base()->Jump(1, error); 176 Isolate::Current()->long_jump_base()->Jump(1, error);
182 } 177 }
183 178
184 179
185 intptr_t FlowGraphCompiler::StackSize() const { 180 intptr_t FlowGraphCompiler::StackSize() const {
186 if (is_ssa_) { 181 if (is_optimizing_) {
187 return block_order_[0]->AsGraphEntry()->spill_slot_count(); 182 return block_order_[0]->AsGraphEntry()->spill_slot_count();
188 } else { 183 } else {
189 return parsed_function_.stack_local_count() + 184 return parsed_function_.stack_local_count() +
190 parsed_function_.copied_parameter_count(); 185 parsed_function_.copied_parameter_count();
191 } 186 }
192 } 187 }
193 188
194 189
195 Label* FlowGraphCompiler::GetBlockLabel( 190 Label* FlowGraphCompiler::GetBlockLabel(
196 BlockEntryInstr* block_entry) const { 191 BlockEntryInstr* block_entry) const {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 intptr_t pc_offset) { 241 intptr_t pc_offset) {
247 exception_handlers_list_->AddHandler(try_index, pc_offset); 242 exception_handlers_list_->AddHandler(try_index, pc_offset);
248 } 243 }
249 244
250 245
251 // Uses current pc position and try-index. 246 // Uses current pc position and try-index.
252 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, 247 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
253 intptr_t deopt_id, 248 intptr_t deopt_id,
254 intptr_t token_pos, 249 intptr_t token_pos,
255 intptr_t try_index) { 250 intptr_t try_index) {
256 ASSERT((kind != PcDescriptors::kDeopt) ||
257 frame_register_allocator()->IsSpilled());
258 pc_descriptors_list()->AddDescriptor(kind, 251 pc_descriptors_list()->AddDescriptor(kind,
259 assembler()->CodeSize(), 252 assembler()->CodeSize(),
260 deopt_id, 253 deopt_id,
261 token_pos, 254 token_pos,
262 try_index); 255 try_index);
263 } 256 }
264 257
265 258
266 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, 259 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
267 intptr_t try_index, 260 intptr_t try_index,
268 DeoptReasonId reason, 261 DeoptReasonId reason) {
269 Register reg1,
270 Register reg2,
271 Register reg3) {
272 DeoptimizationStub* stub = 262 DeoptimizationStub* stub =
273 new DeoptimizationStub(deopt_id, try_index, reason); 263 new DeoptimizationStub(deopt_id, try_index, reason);
274 if (pending_deoptimization_env_ == NULL) { 264 ASSERT(is_optimizing_);
275 ASSERT(!is_ssa_); 265 ASSERT(pending_deoptimization_env_ != NULL);
276 frame_register_allocator()->SpillInDeoptStub(stub); 266 stub->set_deoptimization_env(pending_deoptimization_env_);
277 if (reg1 != kNoRegister) stub->Push(reg1);
278 if (reg2 != kNoRegister) stub->Push(reg2);
279 if (reg3 != kNoRegister) stub->Push(reg3);
280 } else {
281 ASSERT(pending_deoptimization_env_ != NULL);
282 stub->set_deoptimization_env(pending_deoptimization_env_);
283 }
284 deopt_stubs_.Add(stub); 267 deopt_stubs_.Add(stub);
285 return stub->entry_label(); 268 return stub->entry_label();
286 } 269 }
287 270
288 271
289 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 272 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
290 ASSERT(exception_handlers_list_ != NULL); 273 ASSERT(exception_handlers_list_ != NULL);
291 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( 274 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
292 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); 275 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
293 code.set_exception_handlers(handlers); 276 code.set_exception_handlers(handlers);
(...skipping 24 matching lines...) Expand all
318 301
319 302
320 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { 303 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
321 if (stackmap_table_builder_ == NULL) { 304 if (stackmap_table_builder_ == NULL) {
322 // The unoptimizing compiler has no stack maps. 305 // The unoptimizing compiler has no stack maps.
323 code.set_stackmaps(Array::Handle()); 306 code.set_stackmaps(Array::Handle());
324 } else { 307 } else {
325 // Finalize the stack map array and add it to the code object. 308 // Finalize the stack map array and add it to the code object.
326 code.set_stackmaps( 309 code.set_stackmaps(
327 Array::Handle(stackmap_table_builder_->FinalizeStackmaps(code))); 310 Array::Handle(stackmap_table_builder_->FinalizeStackmaps(code)));
328 ASSERT(is_ssa() && is_optimizing()); 311 ASSERT(is_optimizing());
329 } 312 }
330 } 313 }
331 314
332 315
333 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) { 316 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
334 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle( 317 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
335 parsed_function_.node_sequence()->scope()->GetVarDescriptors( 318 parsed_function_.node_sequence()->scope()->GetVarDescriptors(
336 parsed_function_.function())); 319 parsed_function_.function()));
337 code.set_var_descriptors(var_descs); 320 code.set_var_descriptors(var_descs);
338 } 321 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 void FlowGraphCompiler::GenerateInstanceCall( 370 void FlowGraphCompiler::GenerateInstanceCall(
388 intptr_t deopt_id, 371 intptr_t deopt_id,
389 intptr_t token_pos, 372 intptr_t token_pos,
390 intptr_t try_index, 373 intptr_t try_index,
391 const String& function_name, 374 const String& function_name,
392 intptr_t argument_count, 375 intptr_t argument_count,
393 const Array& argument_names, 376 const Array& argument_names,
394 intptr_t checked_argument_count, 377 intptr_t checked_argument_count,
395 BitmapBuilder* stack_bitmap) { 378 BitmapBuilder* stack_bitmap) {
396 ASSERT(!IsLeaf()); 379 ASSERT(!IsLeaf());
397 ASSERT(frame_register_allocator()->IsSpilled());
398 ICData& ic_data = 380 ICData& ic_data =
399 ICData::ZoneHandle(ICData::New(parsed_function().function(), 381 ICData::ZoneHandle(ICData::New(parsed_function().function(),
400 function_name, 382 function_name,
401 deopt_id, 383 deopt_id,
402 checked_argument_count)); 384 checked_argument_count));
403 const Array& arguments_descriptor = 385 const Array& arguments_descriptor =
404 DartEntry::ArgumentsDescriptor(argument_count, argument_names); 386 DartEntry::ArgumentsDescriptor(argument_count, argument_names);
405 uword label_address = 0; 387 uword label_address = 0;
406 switch (checked_argument_count) { 388 switch (checked_argument_count) {
407 case 1: 389 case 1:
408 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); 390 label_address = StubCode::OneArgCheckInlineCacheEntryPoint();
409 break; 391 break;
410 case 2: 392 case 2:
411 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); 393 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint();
412 break; 394 break;
413 default: 395 default:
414 UNIMPLEMENTED(); 396 UNIMPLEMENTED();
415 } 397 }
416 ExternalLabel target_label("InlineCache", label_address); 398 ExternalLabel target_label("InlineCache", label_address);
417 399
418 const intptr_t descr_offset = EmitInstanceCall(&target_label, 400 const intptr_t descr_offset = EmitInstanceCall(&target_label,
419 ic_data, 401 ic_data,
420 arguments_descriptor, 402 arguments_descriptor,
421 argument_count); 403 argument_count);
422 if (is_ssa() && (stack_bitmap != NULL)) { 404 if (is_optimizing() && (stack_bitmap != NULL)) {
423 stackmap_table_builder_->AddEntry(descr_offset, stack_bitmap); 405 stackmap_table_builder_->AddEntry(descr_offset, stack_bitmap);
424 } 406 }
425 pc_descriptors_list()->AddDescriptor(PcDescriptors::kIcCall, 407 pc_descriptors_list()->AddDescriptor(PcDescriptors::kIcCall,
426 descr_offset, 408 descr_offset,
427 deopt_id, 409 deopt_id,
428 token_pos, 410 token_pos,
429 try_index); 411 try_index);
430 } 412 }
431 413
432 414
433 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, 415 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id,
434 intptr_t token_pos, 416 intptr_t token_pos,
435 intptr_t try_index, 417 intptr_t try_index,
436 const Function& function, 418 const Function& function,
437 intptr_t argument_count, 419 intptr_t argument_count,
438 const Array& argument_names, 420 const Array& argument_names,
439 BitmapBuilder* stack_bitmap) { 421 BitmapBuilder* stack_bitmap) {
440 ASSERT(frame_register_allocator()->IsSpilled());
441
442 const Array& arguments_descriptor = 422 const Array& arguments_descriptor =
443 DartEntry::ArgumentsDescriptor(argument_count, argument_names); 423 DartEntry::ArgumentsDescriptor(argument_count, argument_names);
444 const intptr_t descr_offset = EmitStaticCall(function, 424 const intptr_t descr_offset = EmitStaticCall(function,
445 arguments_descriptor, 425 arguments_descriptor,
446 argument_count); 426 argument_count);
447 if (is_ssa() && (stack_bitmap != NULL)) { 427 if (is_optimizing() && (stack_bitmap != NULL)) {
448 stackmap_table_builder_->AddEntry(descr_offset, stack_bitmap); 428 stackmap_table_builder_->AddEntry(descr_offset, stack_bitmap);
449 } 429 }
450 pc_descriptors_list()->AddDescriptor(PcDescriptors::kFuncCall, 430 pc_descriptors_list()->AddDescriptor(PcDescriptors::kFuncCall,
451 descr_offset, 431 descr_offset,
452 deopt_id, 432 deopt_id,
453 token_pos, 433 token_pos,
454 try_index); 434 try_index);
455 } 435 }
456 436
457 437
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 assembler()->j(true_condition, &is_true, Assembler::kNearJump); 553 assembler()->j(true_condition, &is_true, Assembler::kNearJump);
574 assembler()->Bind(&is_false); 554 assembler()->Bind(&is_false);
575 assembler()->LoadObject(result, bool_false()); 555 assembler()->LoadObject(result, bool_false());
576 assembler()->jmp(&done); 556 assembler()->jmp(&done);
577 assembler()->Bind(&is_true); 557 assembler()->Bind(&is_true);
578 assembler()->LoadObject(result, bool_true()); 558 assembler()->LoadObject(result, bool_true());
579 assembler()->Bind(&done); 559 assembler()->Bind(&done);
580 } 560 }
581 561
582 562
583 Register FrameRegisterAllocator::AllocateFreeRegister(bool* blocked_registers) { 563 // Allocate a register that is not explicitly blocked.
564 static Register AllocateFreeRegister(bool* blocked_registers) {
584 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) { 565 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) {
585 if (!blocked_registers[regno] && (registers_[regno] == NULL)) { 566 if (!blocked_registers[regno]) {
586 blocked_registers[regno] = true; 567 blocked_registers[regno] = true;
587 return static_cast<Register>(regno); 568 return static_cast<Register>(regno);
588 } 569 }
589 } 570 }
590 return SpillFirst(); 571 UNREACHABLE();
572 return kNoRegister;
591 } 573 }
592 574
593 575
594 Register FrameRegisterAllocator::SpillFirst() { 576 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
595 ASSERT(!stack_.is_empty()); 577 ASSERT(!is_optimizing());
596 Register reg = stack_[0];
597 stack_.RemoveFirst();
598 compiler()->assembler()->PushRegister(reg);
599 registers_[reg] = NULL;
600 return reg;
601 }
602
603
604 void FrameRegisterAllocator::SpillRegister(Register reg) {
605 while (registers_[reg] != NULL) SpillFirst();
606 }
607
608
609 void FrameRegisterAllocator::AllocateRegisters(Instruction* instr) {
610 if (is_ssa_) return;
611 578
612 LocationSummary* locs = instr->locs(); 579 LocationSummary* locs = instr->locs();
613 580
614 bool blocked_registers[kNumberOfCpuRegisters]; 581 bool blocked_registers[kNumberOfCpuRegisters];
615 bool blocked_temp_registers[kNumberOfCpuRegisters];
616
617 bool spill = false;
618 582
619 // Mark all available registers free. 583 // Mark all available registers free.
620 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { 584 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
621 blocked_registers[i] = false; 585 blocked_registers[i] = false;
622 blocked_temp_registers[i] = false;
623 } 586 }
624 587
625 // Mark all fixed input, temp and output registers as used. 588 // Mark all fixed input, temp and output registers as used.
626 for (intptr_t i = 0; i < locs->input_count(); i++) { 589 for (intptr_t i = 0; i < locs->input_count(); i++) {
627 Location loc = locs->in(i); 590 Location loc = locs->in(i);
628 if (loc.IsRegister()) { 591 if (loc.IsRegister()) {
629 ASSERT(!blocked_registers[loc.reg()]); 592 ASSERT(!blocked_registers[loc.reg()]);
630 blocked_registers[loc.reg()] = true; 593 blocked_registers[loc.reg()] = true;
631 if (registers_[loc.reg()] != NULL) {
632 intptr_t stack_index = stack_.length() - (locs->input_count() - i);
633 if ((stack_index < 0) || (stack_[stack_index] != loc.reg())) {
634 spill = true;
635 }
636 }
637 } 594 }
638 } 595 }
639 596
640 if (spill) Spill();
641
642 for (intptr_t i = 0; i < locs->temp_count(); i++) { 597 for (intptr_t i = 0; i < locs->temp_count(); i++) {
643 Location loc = locs->temp(i); 598 Location loc = locs->temp(i);
644 if (loc.IsRegister()) { 599 if (loc.IsRegister()) {
645 ASSERT(!blocked_registers[loc.reg()]); 600 ASSERT(!blocked_registers[loc.reg()]);
646 blocked_registers[loc.reg()] = true; 601 blocked_registers[loc.reg()] = true;
647 blocked_temp_registers[loc.reg()] = true;
648 } 602 }
649 } 603 }
650 604
651 if (locs->out().IsRegister()) { 605 if (locs->out().IsRegister()) {
652 // Fixed output registers are allowed to overlap with 606 // Fixed output registers are allowed to overlap with
653 // temps and inputs. 607 // temps and inputs.
654 blocked_registers[locs->out().reg()] = true; 608 blocked_registers[locs->out().reg()] = true;
655 } 609 }
656 610
657 // Do not allocate known registers. 611 // Do not allocate known registers.
658 blocked_registers[CTX] = true; 612 blocked_registers[CTX] = true;
659 blocked_registers[SPREG] = true; 613 blocked_registers[SPREG] = true;
660 blocked_registers[FPREG] = true; 614 blocked_registers[FPREG] = true;
661 if (TMP != kNoRegister) { 615 if (TMP != kNoRegister) {
662 blocked_registers[TMP] = true; 616 blocked_registers[TMP] = true;
663 } 617 }
664 618
665 // Allocate all unallocated input locations. 619 // Allocate all unallocated input locations.
620 const bool should_pop = !instr->IsPushArgument();
666 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { 621 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
667 Location loc = locs->in(i); 622 Location loc = locs->in(i);
668 Register reg = kNoRegister; 623 Register reg = kNoRegister;
669 if (loc.IsRegister()) { 624 if (loc.IsRegister()) {
670 reg = loc.reg(); 625 reg = loc.reg();
671 } else if (loc.IsUnallocated()) { 626 } else if (loc.IsUnallocated()) {
672 ASSERT(loc.policy() == Location::kRequiresRegister); 627 ASSERT(loc.policy() == Location::kRequiresRegister);
673 if (!stack_.is_empty() && !blocked_temp_registers[stack_.Last()]) { 628 reg = AllocateFreeRegister(blocked_registers);
674 reg = stack_.Last();
675 blocked_registers[reg] = true;
676 } else {
677 reg = AllocateFreeRegister(blocked_registers);
678 }
679 locs->set_in(i, Location::RegisterLocation(reg)); 629 locs->set_in(i, Location::RegisterLocation(reg));
680 } 630 }
681 631
682 // Inputs are consumed from the simulated frame. In case of a call argument 632 // Inputs are consumed from the simulated frame. In case of a call argument
683 // we leave it until the call instruction. 633 // we leave it until the call instruction.
684 if (!instr->IsPushArgument()) Pop(reg, instr->InputAt(i)); 634 if (should_pop) {
685 } 635 assembler()->PopRegister(reg);
686 636 }
687 // If this instruction is call spill everything that was not consumed by
688 // input locations.
689 if (locs->can_call() || instr->IsBranch() || instr->IsGoto()) {
690 Spill();
691 } 637 }
692 638
693 // Allocate all unallocated temp locations. 639 // Allocate all unallocated temp locations.
694 for (intptr_t i = 0; i < locs->temp_count(); i++) { 640 for (intptr_t i = 0; i < locs->temp_count(); i++) {
695 Location loc = locs->temp(i); 641 Location loc = locs->temp(i);
696 if (loc.IsUnallocated()) { 642 if (loc.IsUnallocated()) {
697 ASSERT(loc.policy() == Location::kRequiresRegister); 643 ASSERT(loc.policy() == Location::kRequiresRegister);
698 loc = Location::RegisterLocation( 644 loc = Location::RegisterLocation(
699 AllocateFreeRegister(blocked_registers)); 645 AllocateFreeRegister(blocked_registers));
700 locs->set_temp(i, loc); 646 locs->set_temp(i, loc);
701 } 647 }
702 SpillRegister(loc.reg());
703 } 648 }
704 649
705 Location result_location = locs->out(); 650 Location result_location = locs->out();
706 if (result_location.IsUnallocated()) { 651 if (result_location.IsUnallocated()) {
707 switch (result_location.policy()) { 652 switch (result_location.policy()) {
708 case Location::kAny: 653 case Location::kAny:
709 case Location::kPrefersRegister: 654 case Location::kPrefersRegister:
710 case Location::kRequiresRegister: 655 case Location::kRequiresRegister:
711 result_location = Location::RegisterLocation( 656 result_location = Location::RegisterLocation(
712 AllocateFreeRegister(blocked_registers)); 657 AllocateFreeRegister(blocked_registers));
713 break; 658 break;
714 case Location::kSameAsFirstInput: 659 case Location::kSameAsFirstInput:
715 result_location = locs->in(0); 660 result_location = locs->in(0);
716 break; 661 break;
717 } 662 }
718 locs->set_out(result_location); 663 locs->set_out(result_location);
719 } 664 }
720
721 if (result_location.IsRegister()) {
722 SpillRegister(result_location.reg());
723 }
724 } 665 }
725 666
726 667
727 void FrameRegisterAllocator::Pop(Register dst, Value* val) {
728 if (is_ssa_) return;
729
730 if (!stack_.is_empty()) {
731 ASSERT(keep_values_in_registers_);
732 Register src = stack_.Last();
733 ASSERT(val->AsUse()->definition() == registers_[src]);
734 stack_.RemoveLast();
735 registers_[src] = NULL;
736 compiler()->assembler()->MoveRegister(dst, src);
737 } else {
738 compiler()->assembler()->PopRegister(dst);
739 }
740 }
741
742
743 void FrameRegisterAllocator::Push(Register reg, BindInstr* val) {
744 if (is_ssa_) return;
745
746 ASSERT(registers_[reg] == NULL);
747 if (keep_values_in_registers_) {
748 registers_[reg] = val;
749 stack_.Add(reg);
750 } else {
751 compiler()->assembler()->PushRegister(reg);
752 }
753 }
754
755
756 void FrameRegisterAllocator::Spill() {
757 if (is_ssa_) return;
758
759 for (int i = 0; i < stack_.length(); i++) {
760 Register r = stack_[i];
761 registers_[r] = NULL;
762 compiler()->assembler()->PushRegister(r);
763 }
764 stack_.Clear();
765 }
766
767
768 void FrameRegisterAllocator::SpillInDeoptStub(DeoptimizationStub* stub) {
769 if (is_ssa_) return;
770
771 for (int i = 0; i < stack_.length(); i++) {
772 stub->Push(stack_[i]);
773 }
774 }
775
776
777 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler) 668 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler)
778 : compiler_(compiler), moves_(32) {} 669 : compiler_(compiler), moves_(32) {}
779 670
780 671
781 void ParallelMoveResolver::EmitNativeCode(ParallelMoveInstr* parallel_move) { 672 void ParallelMoveResolver::EmitNativeCode(ParallelMoveInstr* parallel_move) {
782 ASSERT(moves_.is_empty()); 673 ASSERT(moves_.is_empty());
783 // Build up a worklist of moves. 674 // Build up a worklist of moves.
784 BuildInitialMoveList(parallel_move); 675 BuildInitialMoveList(parallel_move);
785 676
786 for (int i = 0; i < moves_.length(); ++i) { 677 for (int i = 0; i < moves_.length(); ++i) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 return; 767 return;
877 } 768 }
878 } 769 }
879 770
880 // This move is not blocked. 771 // This move is not blocked.
881 EmitMove(index); 772 EmitMove(index);
882 } 773 }
883 774
884 775
885 } // namespace dart 776 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698