Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler_x64.cc |
| diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc |
| index 0b846fa3547541f68c7f9dd7fc36c05142214b34..95e50a83a454e13223017607d17749e7744b1c29 100644 |
| --- a/runtime/vm/flow_graph_compiler_x64.cc |
| +++ b/runtime/vm/flow_graph_compiler_x64.cc |
| @@ -32,6 +32,11 @@ DECLARE_FLAG(bool, report_usage_count); |
| DECLARE_FLAG(bool, code_comments); |
| +static Register ToRegister(Location loc) { |
| + return RegisterLocation::Cast(loc).reg(); |
| +} |
| + |
| + |
| FlowGraphCompiler::FlowGraphCompiler( |
| Assembler* assembler, |
| const ParsedFunction& parsed_function, |
| @@ -546,22 +551,37 @@ void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { |
| } |
| +LocationSummary* StrictCompareComp::MakeLocationSummary() { |
|
srdjan
2012/05/18 18:00:14
In unoptimizing compiler this is the same for all
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Preallocating and reusing proves to be hard becaus
srdjan
2012/05/21 16:05:22
Valid points, good suggestion. Let's not do anythi
|
| + LocationSummary* summary = new LocationSummary(2); |
| + summary->SetInputLocationAt( |
| + 0, UnallocatedLocation(UnallocatedLocation::REGISTER)); |
| + summary->SetInputLocationAt( |
| + 1, UnallocatedLocation(UnallocatedLocation::REGISTER)); |
|
srdjan
2012/05/18 18:00:14
Too verbose.
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
introduced a helper function and shortened method
|
| + summary->set_result_location( |
| + UnallocatedLocation(UnallocatedLocation::SAME_AS_FIRST_INPUT)); |
| + return summary; |
|
srdjan
2012/05/18 18:00:14
As you said, this does not belong here. Maybe in a
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
moved to intermediate_language_x64.cc
|
| +} |
| + |
| + |
| void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { |
| const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| - LoadValue(RDX, comp->right()); |
| - LoadValue(RAX, comp->left()); |
| - __ cmpq(RAX, RDX); |
| + |
| + Register left = ToRegister(comp->GetLocationSummary()->InputLocationAt(0)); |
| + Register right = ToRegister(comp->GetLocationSummary()->InputLocationAt(1)); |
| + Register result = ToRegister(comp->GetLocationSummary()->result_location()); |
|
srdjan
2012/05/18 18:00:14
Too verbose, maybe:
comp->locs()->in(0)->AsRegiste
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Done.
|
| + |
| + __ cmpq(left, right); |
| Label load_true, done; |
| if (comp->kind() == Token::kEQ_STRICT) { |
| __ j(EQUAL, &load_true, Assembler::kNearJump); |
| } else { |
| __ j(NOT_EQUAL, &load_true, Assembler::kNearJump); |
| } |
| - __ LoadObject(RAX, bool_false); |
| + __ LoadObject(result, bool_false); |
| __ jmp(&done, Assembler::kNearJump); |
| __ Bind(&load_true); |
| - __ LoadObject(RAX, bool_true); |
| + __ LoadObject(result, bool_true); |
| __ Bind(&done); |
| } |
| @@ -1122,6 +1142,73 @@ void FlowGraphCompiler::VisitCatchEntry(CatchEntryComp* comp) { |
| } |
| +static Register AllocateFreeRegister(bool* blocked_registers) { |
|
srdjan
2012/05/18 18:00:14
I would rather use BitVector or GrowableArray sinc
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
both are zone allocated which seems unnecessary ex
|
| + for (int regno = 0; regno < kNumberOfCpuRegisters; regno++) { |
| + if (!blocked_registers[regno]) { |
| + blocked_registers[regno] = true; |
| + return static_cast<Register>(regno); |
|
srdjan
2012/05/18 18:00:14
The register allocation needs also to move out of
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Moved simple register allocator into LocationSumma
|
| + } |
| + } |
| + UNREACHABLE(); |
| + return kNoRegister; |
| +} |
| + |
| + |
| +static void AllocateRegisters(LocationSummary* summary) { |
| + bool blocked_registers[kNumberOfCpuRegisters] = { false }; |
| + |
| + for (intptr_t i = 0; i < summary->InputLocationsCount(); i++) { |
| + Location loc = summary->InputLocationAt(i); |
| + if (loc.kind() == Location::REGISTER) { |
| + ASSERT(!blocked_registers[ToRegister(loc)]); |
| + blocked_registers[loc.value()] = true; |
| + } |
| + } |
| + |
| + for (intptr_t i = 0; i < summary->InputLocationsCount(); i++) { |
| + Location loc = summary->InputLocationAt(i); |
| + if (loc.kind() == Location::UNALLOCATED) { |
| + ASSERT(UnallocatedLocation::Cast(loc).policy() == |
| + UnallocatedLocation::REGISTER); |
| + summary->SetInputLocationAt(i, RegisterLocation( |
| + AllocateFreeRegister(blocked_registers))); |
| + } |
| + } |
| + |
| + Location result_location = summary->result_location(); |
| + if (result_location.kind() == Location::UNALLOCATED) { |
| + switch (UnallocatedLocation::Cast(result_location).policy()) { |
| + case UnallocatedLocation::REGISTER: |
| + result_location = RegisterLocation( |
| + AllocateFreeRegister(blocked_registers)); |
| + break; |
| + case UnallocatedLocation::SAME_AS_FIRST_INPUT: |
| + result_location = summary->InputLocationAt(0); |
| + break; |
| + } |
| + summary->set_result_location(result_location); |
| + } |
| +} |
| + |
| + |
| +void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { |
| + LocationSummary* summary = instr->GetLocationSummary(); |
| + |
| + // Check if current instruction has any special location requirements. |
| + if (summary == NULL) return; |
| + |
| + AllocateRegisters(summary); |
| + |
| + // Load instruction inputs into allocated registers. |
| + for (intptr_t i = summary->InputLocationsCount() - 1; i >= 0; i--) { |
| + Location loc = summary->InputLocationAt(i); |
| + if (loc.kind() == Location::REGISTER) { |
| + __ popq(ToRegister(loc)); |
| + } |
| + } |
| +} |
| + |
| + |
| void FlowGraphCompiler::VisitBlocks() { |
| for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| __ Comment("B%d", i); |
| @@ -1131,6 +1218,7 @@ void FlowGraphCompiler::VisitBlocks() { |
| // Compile all successors until an exit, branch, or a block entry. |
| while ((instr != NULL) && !instr->IsBlockEntry()) { |
| if (FLAG_code_comments) EmitComment(instr); |
| + EmitInstructionPrologue(instr); |
| instr = instr->Accept(this); |
| } |
| @@ -1182,7 +1270,14 @@ void FlowGraphCompiler::VisitDo(DoInstr* instr) { |
| void FlowGraphCompiler::VisitBind(BindInstr* instr) { |
| instr->computation()->Accept(this); |
| - __ pushq(RAX); |
| + |
| + if (instr->GetLocationSummary() == NULL) { |
| + // If instruction does not have special location requirements |
| + // then it returns result in register RAX. |
| + __ pushq(RAX); |
| + } else { |
| + __ pushq(ToRegister(instr->GetLocationSummary()->result_location())); |
| + } |
| } |