Chromium Code Reviews| Index: src/compiler/instruction-selector.cc |
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc |
| index 7fd67e6d1c4610ed66e32063428b1a881af3f8b2..58a73d0a35140292b26d13d043175fd23bbd9f63 100644 |
| --- a/src/compiler/instruction-selector.cc |
| +++ b/src/compiler/instruction-selector.cc |
| @@ -1889,15 +1889,15 @@ void InstructionSelector::VisitTailCall(Node* node) { |
| DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); |
| CallDescriptor* caller = linkage()->GetIncomingDescriptor(); |
| - if (caller->CanTailCall(node)) { |
| - const CallDescriptor* callee = CallDescriptorOf(node->op()); |
| - int stack_param_delta = callee->GetStackParameterDelta(caller); |
| - CallBuffer buffer(zone(), descriptor, nullptr); |
| - |
| - // Compute InstructionOperands for inputs and outputs. |
| - CallBufferFlags flags(kCallCodeImmediate | kCallTail); |
| - if (IsTailCallAddressImmediate()) { |
| - flags |= kCallAddressImmediate; |
| + DCHECK(caller->CanTailCall(node)); |
| + const CallDescriptor* callee = CallDescriptorOf(node->op()); |
| + int stack_param_delta = callee->GetStackParameterDelta(caller); |
| + CallBuffer buffer(zone(), descriptor, nullptr); |
| + |
| + // Compute InstructionOperands for inputs and outputs. |
| + CallBufferFlags flags(kCallCodeImmediate | kCallTail); |
| + if (IsTailCallAddressImmediate()) { |
| + flags |= kCallAddressImmediate; |
| } |
|
Michael Starzinger
2016/10/28 14:12:14
nit: Indentation of the rest of the function off,
danno
2016/10/31 10:06:39
Done.
|
| InitializeCallBuffer(node, &buffer, flags, stack_param_delta); |
| @@ -1949,49 +1949,6 @@ void InstructionSelector::VisitTailCall(Node* node) { |
| Emit(opcode, 0, nullptr, buffer.instruction_args.size(), |
| &buffer.instruction_args.front(), temps.size(), |
| temps.empty() ? nullptr : &temps.front()); |
| - } else { |
| - FrameStateDescriptor* frame_state_descriptor = |
| - descriptor->NeedsFrameState() |
| - ? GetFrameStateDescriptor( |
| - node->InputAt(static_cast<int>(descriptor->InputCount()))) |
| - : nullptr; |
| - |
| - CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
| - |
| - // Compute InstructionOperands for inputs and outputs. |
| - CallBufferFlags flags = kCallCodeImmediate; |
| - if (IsTailCallAddressImmediate()) { |
| - flags |= kCallAddressImmediate; |
| - } |
| - InitializeCallBuffer(node, &buffer, flags); |
| - |
| - EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node); |
| - |
| - // Select the appropriate opcode based on the call type. |
| - InstructionCode opcode; |
| - switch (descriptor->kind()) { |
| - case CallDescriptor::kCallCodeObject: |
| - opcode = kArchCallCodeObject; |
| - break; |
| - case CallDescriptor::kCallJSFunction: |
| - opcode = kArchCallJSFunction; |
| - break; |
| - default: |
| - UNREACHABLE(); |
| - return; |
| - } |
| - opcode |= MiscField::encode(descriptor->flags()); |
| - |
| - // Emit the call instruction. |
| - size_t output_count = buffer.outputs.size(); |
| - auto* outputs = &buffer.outputs.front(); |
| - Instruction* call_instr = |
| - Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
| - &buffer.instruction_args.front()); |
| - if (instruction_selection_failed()) return; |
| - call_instr->MarkAsCall(); |
| - Emit(kArchRet, 0, nullptr, output_count, outputs); |
| - } |
| } |
| @@ -2001,20 +1958,22 @@ void InstructionSelector::VisitGoto(BasicBlock* target) { |
| Emit(kArchJmp, g.NoOutput(), g.Label(target)); |
| } |
| - |
| void InstructionSelector::VisitReturn(Node* ret) { |
| OperandGenerator g(this); |
| - if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) { |
| - Emit(kArchRet, g.NoOutput()); |
| - } else { |
| - const int ret_count = ret->op()->ValueInputCount(); |
| - auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); |
| - for (int i = 0; i < ret_count; ++i) { |
| - value_locations[i] = |
| - g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i)); |
| - } |
| - Emit(kArchRet, 0, nullptr, ret_count, value_locations); |
| + const int ret_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0 |
|
Michael Starzinger
2016/10/28 14:12:14
nit: s/ret_count/input_count/ because the semantic
danno
2016/10/31 10:06:39
Done.
|
| + ? 1 |
| + : ret->op()->ValueInputCount(); |
| + DCHECK_GE(ret_count, 1); |
| + auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); |
| + Node* pop_count = ret->InputAt(0); |
| + value_locations[0] = pop_count->opcode() == IrOpcode::kInt32Constant |
|
Michael Starzinger
2016/10/28 14:12:14
nit: Can we use g.CanBeImmediate here?
danno
2016/10/31 10:06:39
Unfortunately, no. IFAICT, CanBeImmediate is platf
Michael Starzinger
2016/10/31 10:23:19
Acknowledged. Nah, I thought it would be "an easy"
|
| + ? g.UseImmediate(pop_count) |
| + : g.UseRegister(pop_count); |
| + for (int i = 1; i < ret_count; ++i) { |
| + value_locations[i] = |
| + g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1)); |
| } |
| + Emit(kArchRet, 0, nullptr, ret_count, value_locations); |
| } |
| Instruction* InstructionSelector::EmitDeoptimize( |