blob: d172ed18588edda1aacd78df77df753ca53d80cf [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/instruction-selector.h"
6
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include <limits>
8
9#include "src/base/adapters.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/compiler/instruction-selector-impl.h"
11#include "src/compiler/node-matchers.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "src/compiler/pipeline.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/compiler/schedule.h"
14#include "src/compiler/state-values-utils.h"
15#include "src/deoptimizer.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016
17namespace v8 {
18namespace internal {
19namespace compiler {
20
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021InstructionSelector::InstructionSelector(
22 Zone* zone, size_t node_count, Linkage* linkage,
23 InstructionSequence* sequence, Schedule* schedule,
Ben Murdoch097c5b22016-05-18 11:27:45 +010024 SourcePositionTable* source_positions, Frame* frame,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025 SourcePositionMode source_position_mode, Features features)
26 : zone_(zone),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027 linkage_(linkage),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028 sequence_(sequence),
29 source_positions_(source_positions),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030 source_position_mode_(source_position_mode),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031 features_(features),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032 schedule_(schedule),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000033 current_block_(nullptr),
34 instructions_(zone),
35 defined_(node_count, false, zone),
36 used_(node_count, false, zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +010037 effect_level_(node_count, 0, zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 virtual_registers_(node_count,
39 InstructionOperand::kInvalidVirtualRegister, zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +010040 scheduler_(nullptr),
41 frame_(frame) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 instructions_.reserve(node_count);
43}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044
45
46void InstructionSelector::SelectInstructions() {
47 // Mark the inputs of all phis in loop headers as used.
48 BasicBlockVector* blocks = schedule()->rpo_order();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049 for (auto const block : *blocks) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000050 if (!block->IsLoopHeader()) continue;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 DCHECK_LE(2u, block->PredecessorCount());
52 for (Node* const phi : *block) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053 if (phi->opcode() != IrOpcode::kPhi) continue;
54
55 // Mark all inputs as used.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056 for (Node* const input : phi->inputs()) {
57 MarkAsUsed(input);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 }
59 }
60 }
61
62 // Visit each basic block in post order.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063 for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064 VisitBlock(*i);
65 }
66
67 // Schedule the selected instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 if (FLAG_turbo_instruction_scheduling &&
69 InstructionScheduler::SchedulerSupported()) {
70 scheduler_ = new (zone()) InstructionScheduler(zone(), sequence());
71 }
72
73 for (auto const block : *blocks) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040074 InstructionBlock* instruction_block =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -040076 size_t end = instruction_block->code_end();
77 size_t start = instruction_block->code_start();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078 DCHECK_LE(end, start);
79 StartBlock(RpoNumber::FromInt(block->rpo_number()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080 while (start-- > end) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081 AddInstruction(instructions_[start]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083 EndBlock(RpoNumber::FromInt(block->rpo_number()));
84 }
Ben Murdochda12d292016-06-02 14:46:10 +010085#if DEBUG
86 sequence()->ValidateSSA();
87#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088}
89
90
91void InstructionSelector::StartBlock(RpoNumber rpo) {
92 if (FLAG_turbo_instruction_scheduling &&
93 InstructionScheduler::SchedulerSupported()) {
94 DCHECK_NOT_NULL(scheduler_);
95 scheduler_->StartBlock(rpo);
96 } else {
97 sequence()->StartBlock(rpo);
98 }
99}
100
101
102void InstructionSelector::EndBlock(RpoNumber rpo) {
103 if (FLAG_turbo_instruction_scheduling &&
104 InstructionScheduler::SchedulerSupported()) {
105 DCHECK_NOT_NULL(scheduler_);
106 scheduler_->EndBlock(rpo);
107 } else {
108 sequence()->EndBlock(rpo);
109 }
110}
111
112
113void InstructionSelector::AddInstruction(Instruction* instr) {
114 if (FLAG_turbo_instruction_scheduling &&
115 InstructionScheduler::SchedulerSupported()) {
116 DCHECK_NOT_NULL(scheduler_);
117 scheduler_->AddInstruction(instr);
118 } else {
119 sequence()->AddInstruction(instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 }
121}
122
123
124Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 InstructionOperand output,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126 size_t temp_count,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127 InstructionOperand* temps) {
128 size_t output_count = output.IsInvalid() ? 0 : 1;
129 return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130}
131
132
133Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 InstructionOperand output,
135 InstructionOperand a, size_t temp_count,
136 InstructionOperand* temps) {
137 size_t output_count = output.IsInvalid() ? 0 : 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
139}
140
141
142Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000143 InstructionOperand output,
144 InstructionOperand a,
145 InstructionOperand b, size_t temp_count,
146 InstructionOperand* temps) {
147 size_t output_count = output.IsInvalid() ? 0 : 1;
148 InstructionOperand inputs[] = {a, b};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 size_t input_count = arraysize(inputs);
150 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
151 temps);
152}
153
154
155Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 InstructionOperand output,
157 InstructionOperand a,
158 InstructionOperand b,
159 InstructionOperand c, size_t temp_count,
160 InstructionOperand* temps) {
161 size_t output_count = output.IsInvalid() ? 0 : 1;
162 InstructionOperand inputs[] = {a, b, c};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163 size_t input_count = arraysize(inputs);
164 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
165 temps);
166}
167
168
169Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000170 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
171 InstructionOperand b, InstructionOperand c, InstructionOperand d,
172 size_t temp_count, InstructionOperand* temps) {
173 size_t output_count = output.IsInvalid() ? 0 : 1;
174 InstructionOperand inputs[] = {a, b, c, d};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 size_t input_count = arraysize(inputs);
176 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
177 temps);
178}
179
180
181Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
183 InstructionOperand b, InstructionOperand c, InstructionOperand d,
184 InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
185 size_t output_count = output.IsInvalid() ? 0 : 1;
186 InstructionOperand inputs[] = {a, b, c, d, e};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400187 size_t input_count = arraysize(inputs);
188 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
189 temps);
190}
191
192
193Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000194 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
195 InstructionOperand b, InstructionOperand c, InstructionOperand d,
196 InstructionOperand e, InstructionOperand f, size_t temp_count,
197 InstructionOperand* temps) {
198 size_t output_count = output.IsInvalid() ? 0 : 1;
199 InstructionOperand inputs[] = {a, b, c, d, e, f};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400200 size_t input_count = arraysize(inputs);
201 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
202 temps);
203}
204
205
206Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
208 size_t input_count, InstructionOperand* inputs, size_t temp_count,
209 InstructionOperand* temps) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210 Instruction* instr =
211 Instruction::New(instruction_zone(), opcode, output_count, outputs,
212 input_count, inputs, temp_count, temps);
213 return Emit(instr);
214}
215
216
217Instruction* InstructionSelector::Emit(Instruction* instr) {
218 instructions_.push_back(instr);
219 return instr;
220}
221
222
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223bool InstructionSelector::CanCover(Node* user, Node* node) const {
Ben Murdochda12d292016-06-02 14:46:10 +0100224 // 1. Both {user} and {node} must be in the same basic block.
225 if (schedule()->block(node) != schedule()->block(user)) {
226 return false;
227 }
228 // 2. Pure {node}s must be owned by the {user}.
229 if (node->op()->HasProperty(Operator::kPure)) {
230 return node->OwnedBy(user);
231 }
232 // 3. Impure {node}s must match the effect level of {user}.
233 if (GetEffectLevel(node) != GetEffectLevel(user)) {
234 return false;
235 }
236 // 4. Only {node} must have value edges pointing to {user}.
237 for (Edge const edge : node->use_edges()) {
238 if (edge.from() != user && NodeProperties::IsValueEdge(edge)) {
239 return false;
240 }
241 }
242 return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243}
244
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400245int InstructionSelector::GetVirtualRegister(const Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 DCHECK_NOT_NULL(node);
247 size_t const id = node->id();
248 DCHECK_LT(id, virtual_registers_.size());
249 int virtual_register = virtual_registers_[id];
250 if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
251 virtual_register = sequence()->NextVirtualRegister();
252 virtual_registers_[id] = virtual_register;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400253 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000254 return virtual_register;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400255}
256
257
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting()
259 const {
260 std::map<NodeId, int> virtual_registers;
261 for (size_t n = 0; n < virtual_registers_.size(); ++n) {
262 if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) {
263 NodeId const id = static_cast<NodeId>(n);
264 virtual_registers.insert(std::make_pair(id, virtual_registers_[n]));
265 }
266 }
267 return virtual_registers;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400268}
269
270
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271bool InstructionSelector::IsDefined(Node* node) const {
272 DCHECK_NOT_NULL(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000273 size_t const id = node->id();
274 DCHECK_LT(id, defined_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000275 return defined_[id];
276}
277
278
279void InstructionSelector::MarkAsDefined(Node* node) {
280 DCHECK_NOT_NULL(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000281 size_t const id = node->id();
282 DCHECK_LT(id, defined_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000283 defined_[id] = true;
284}
285
286
287bool InstructionSelector::IsUsed(Node* node) const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000288 DCHECK_NOT_NULL(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000289 if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000290 size_t const id = node->id();
291 DCHECK_LT(id, used_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292 return used_[id];
293}
294
295
296void InstructionSelector::MarkAsUsed(Node* node) {
297 DCHECK_NOT_NULL(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298 size_t const id = node->id();
299 DCHECK_LT(id, used_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300 used_[id] = true;
301}
302
Ben Murdoch097c5b22016-05-18 11:27:45 +0100303int InstructionSelector::GetEffectLevel(Node* node) const {
304 DCHECK_NOT_NULL(node);
305 size_t const id = node->id();
306 DCHECK_LT(id, effect_level_.size());
307 return effect_level_[id];
308}
309
310void InstructionSelector::SetEffectLevel(Node* node, int effect_level) {
311 DCHECK_NOT_NULL(node);
312 size_t const id = node->id();
313 DCHECK_LT(id, effect_level_.size());
314 effect_level_[id] = effect_level;
315}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000317void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
318 const InstructionOperand& op) {
319 UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
320 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000321}
322
323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
325 Node* node) {
326 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000327}
328
329
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330namespace {
331
332enum class FrameStateInputKind { kAny, kStackSlot };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000333
334
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
336 FrameStateInputKind kind) {
337 switch (input->opcode()) {
338 case IrOpcode::kInt32Constant:
339 case IrOpcode::kNumberConstant:
340 case IrOpcode::kFloat32Constant:
341 case IrOpcode::kFloat64Constant:
342 case IrOpcode::kHeapConstant:
343 return g->UseImmediate(input);
344 case IrOpcode::kObjectState:
345 UNREACHABLE();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400346 break;
347 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000348 switch (kind) {
349 case FrameStateInputKind::kStackSlot:
350 return g->UseUniqueSlot(input);
351 case FrameStateInputKind::kAny:
352 return g->UseAny(input);
353 }
354 }
355 UNREACHABLE();
356 return InstructionOperand();
357}
358
359
360class StateObjectDeduplicator {
361 public:
362 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
363 static const size_t kNotDuplicated = SIZE_MAX;
364
365 size_t GetObjectId(Node* node) {
366 for (size_t i = 0; i < objects_.size(); ++i) {
367 if (objects_[i] == node) {
368 return i;
369 }
370 }
371 return kNotDuplicated;
372 }
373
374 size_t InsertObject(Node* node) {
375 size_t id = objects_.size();
376 objects_.push_back(node);
377 return id;
378 }
379
380 private:
381 ZoneVector<Node*> objects_;
382};
383
384
385// Returns the number of instruction operands added to inputs.
386size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor,
387 InstructionOperandVector* inputs,
388 OperandGenerator* g,
389 StateObjectDeduplicator* deduplicator,
390 Node* input, MachineType type,
391 FrameStateInputKind kind, Zone* zone) {
392 switch (input->opcode()) {
393 case IrOpcode::kObjectState: {
394 size_t id = deduplicator->GetObjectId(input);
395 if (id == StateObjectDeduplicator::kNotDuplicated) {
396 size_t entries = 0;
397 id = deduplicator->InsertObject(input);
398 descriptor->fields().push_back(
399 StateValueDescriptor::Recursive(zone, id));
400 StateValueDescriptor* new_desc = &descriptor->fields().back();
401 for (Edge edge : input->input_edges()) {
402 entries += AddOperandToStateValueDescriptor(
403 new_desc, inputs, g, deduplicator, edge.to(),
404 MachineType::AnyTagged(), kind, zone);
405 }
406 return entries;
407 } else {
408 // Crankshaft counts duplicate objects for the running id, so we have
409 // to push the input again.
410 deduplicator->InsertObject(input);
411 descriptor->fields().push_back(
412 StateValueDescriptor::Duplicate(zone, id));
413 return 0;
414 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400415 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416 }
417 default: {
418 inputs->push_back(OperandForDeopt(g, input, kind));
419 descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type));
420 return 1;
421 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400422 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000423}
424
425
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426// Returns the number of instruction operands added to inputs.
427size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor,
428 Node* state, OperandGenerator* g,
429 StateObjectDeduplicator* deduplicator,
430 InstructionOperandVector* inputs,
431 FrameStateInputKind kind, Zone* zone) {
432 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
433
434 size_t entries = 0;
435 size_t initial_size = inputs->size();
436 USE(initial_size); // initial_size is only used for debug.
437
438 if (descriptor->outer_state()) {
439 entries += AddInputsToFrameStateDescriptor(
440 descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
441 g, deduplicator, inputs, kind, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443
444 Node* parameters = state->InputAt(kFrameStateParametersInput);
445 Node* locals = state->InputAt(kFrameStateLocalsInput);
446 Node* stack = state->InputAt(kFrameStateStackInput);
447 Node* context = state->InputAt(kFrameStateContextInput);
448 Node* function = state->InputAt(kFrameStateFunctionInput);
449
450 DCHECK_EQ(descriptor->parameters_count(),
451 StateValuesAccess(parameters).size());
452 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
453 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
454
455 StateValueDescriptor* values_descriptor =
456 descriptor->GetStateValueDescriptor();
457 entries += AddOperandToStateValueDescriptor(
458 values_descriptor, inputs, g, deduplicator, function,
459 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
460 for (StateValuesAccess::TypedNode input_node :
461 StateValuesAccess(parameters)) {
462 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
463 deduplicator, input_node.node,
464 input_node.type, kind, zone);
465 }
466 if (descriptor->HasContext()) {
467 entries += AddOperandToStateValueDescriptor(
468 values_descriptor, inputs, g, deduplicator, context,
469 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
470 }
471 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
472 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
473 deduplicator, input_node.node,
474 input_node.type, kind, zone);
475 }
476 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
477 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
478 deduplicator, input_node.node,
479 input_node.type, kind, zone);
480 }
481 DCHECK_EQ(initial_size + entries, inputs->size());
482 return entries;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000483}
484
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000485} // namespace
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000486
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000487
488// An internal helper class for generating the operands to calls.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000489// TODO(bmeurer): Get rid of the CallBuffer business and make
490// InstructionSelector::VisitCall platform independent instead.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491struct CallBuffer {
492 CallBuffer(Zone* zone, const CallDescriptor* descriptor,
493 FrameStateDescriptor* frame_state)
494 : descriptor(descriptor),
495 frame_state_descriptor(frame_state),
496 output_nodes(zone),
497 outputs(zone),
498 instruction_args(zone),
499 pushed_nodes(zone) {
500 output_nodes.reserve(descriptor->ReturnCount());
501 outputs.reserve(descriptor->ReturnCount());
502 pushed_nodes.reserve(input_count());
503 instruction_args.reserve(input_count() + frame_state_value_count());
504 }
505
506
507 const CallDescriptor* descriptor;
508 FrameStateDescriptor* frame_state_descriptor;
509 NodeVector output_nodes;
510 InstructionOperandVector outputs;
511 InstructionOperandVector instruction_args;
512 ZoneVector<PushParameter> pushed_nodes;
513
514 size_t input_count() const { return descriptor->InputCount(); }
515
516 size_t frame_state_count() const { return descriptor->FrameStateCount(); }
517
518 size_t frame_state_value_count() const {
519 return (frame_state_descriptor == nullptr)
520 ? 0
521 : (frame_state_descriptor->GetTotalSize() +
522 1); // Include deopt id.
523 }
524};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000525
526
527// TODO(bmeurer): Get rid of the CallBuffer business and make
528// InstructionSelector::VisitCall platform independent instead.
529void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000530 CallBufferFlags flags,
531 int stack_param_delta) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000533 DCHECK_LE(call->op()->ValueOutputCount(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400534 static_cast<int>(buffer->descriptor->ReturnCount()));
535 DCHECK_EQ(
536 call->op()->ValueInputCount(),
537 static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000538
539 if (buffer->descriptor->ReturnCount() > 0) {
540 // Collect the projections that represent multiple outputs from this call.
541 if (buffer->descriptor->ReturnCount() == 1) {
542 buffer->output_nodes.push_back(call);
543 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000544 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr);
545 for (auto use : call->uses()) {
546 if (use->opcode() != IrOpcode::kProjection) continue;
547 size_t const index = ProjectionIndexOf(use->op());
548 DCHECK_LT(index, buffer->output_nodes.size());
549 DCHECK(!buffer->output_nodes[index]);
550 buffer->output_nodes[index] = use;
551 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000552 }
553
554 // Filter out the outputs that aren't live because no projection uses them.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400555 size_t outputs_needed_by_framestate =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 buffer->frame_state_descriptor == nullptr
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400557 ? 0
558 : buffer->frame_state_descriptor->state_combine()
559 .ConsumedOutputCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000560 for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000561 bool output_is_live = buffer->output_nodes[i] != nullptr ||
562 i < outputs_needed_by_framestate;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400563 if (output_is_live) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000564 MachineType type =
565 buffer->descriptor->GetReturnType(static_cast<int>(i));
566 LinkageLocation location =
567 buffer->descriptor->GetReturnLocation(static_cast<int>(i));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400568
569 Node* output = buffer->output_nodes[i];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000570 InstructionOperand op =
571 output == nullptr
572 ? g.TempLocation(location, type.representation())
573 : g.DefineAsLocation(output, location, type.representation());
574 MarkAsRepresentation(type.representation(), op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400575
576 buffer->outputs.push_back(op);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000577 }
578 }
579 }
580
581 // The first argument is always the callee code.
582 Node* callee = call->InputAt(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000583 bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
584 bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000585 switch (buffer->descriptor->kind()) {
586 case CallDescriptor::kCallCodeObject:
587 buffer->instruction_args.push_back(
588 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
589 ? g.UseImmediate(callee)
590 : g.UseRegister(callee));
591 break;
592 case CallDescriptor::kCallAddress:
593 buffer->instruction_args.push_back(
594 (call_address_immediate &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000595 callee->opcode() == IrOpcode::kExternalConstant)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000596 ? g.UseImmediate(callee)
597 : g.UseRegister(callee));
598 break;
599 case CallDescriptor::kCallJSFunction:
600 buffer->instruction_args.push_back(
601 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 buffer->descriptor->GetInputType(0).representation()));
603 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000604 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000605 DCHECK_EQ(1u, buffer->instruction_args.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000606
607 // If the call needs a frame state, we insert the state information as
608 // follows (n is the number of value inputs to the frame state):
609 // arg 1 : deoptimization id.
610 // arg 2 - arg (n + 1) : value inputs to the frame state.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000611 size_t frame_state_entries = 0;
612 USE(frame_state_entries); // frame_state_entries is only used for debug.
613 if (buffer->frame_state_descriptor != nullptr) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100614 Node* frame_state =
615 call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
616
617 // If it was a syntactic tail call we need to drop the current frame and
Ben Murdochda12d292016-06-02 14:46:10 +0100618 // all the frames on top of it that are either an arguments adaptor frame
619 // or a tail caller frame.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100620 if (buffer->descriptor->SupportsTailCalls()) {
621 frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
622 buffer->frame_state_descriptor =
623 buffer->frame_state_descriptor->outer_state();
Ben Murdochda12d292016-06-02 14:46:10 +0100624 while (buffer->frame_state_descriptor != nullptr &&
625 (buffer->frame_state_descriptor->type() ==
626 FrameStateType::kArgumentsAdaptor ||
627 buffer->frame_state_descriptor->type() ==
628 FrameStateType::kTailCallerFunction)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100629 frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
630 buffer->frame_state_descriptor =
631 buffer->frame_state_descriptor->outer_state();
632 }
633 }
634
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000635 InstructionSequence::StateId state_id =
636 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
637 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
638
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000639 StateObjectDeduplicator deduplicator(instruction_zone());
640
641 frame_state_entries =
642 1 + AddInputsToFrameStateDescriptor(
643 buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
644 &buffer->instruction_args, FrameStateInputKind::kStackSlot,
645 instruction_zone());
646
647 DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000649
650 size_t input_count = static_cast<size_t>(buffer->input_count());
651
652 // Split the arguments into pushed_nodes and instruction_args. Pushed
653 // arguments require an explicit push instruction before the call and do
654 // not appear as arguments to the call. Everything else ends up
655 // as an InstructionOperand argument to the call.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400656 auto iter(call->inputs().begin());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657 size_t pushed_count = 0;
658 bool call_tail = (flags & kCallTail) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000659 for (size_t index = 0; index < input_count; ++iter, ++index) {
660 DCHECK(iter != call->inputs().end());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000661 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
662 if (index == 0) continue; // The first argument (callee) is already done.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663
664 LinkageLocation location = buffer->descriptor->GetInputLocation(index);
665 if (call_tail) {
666 location = LinkageLocation::ConvertToTailCallerLocation(
667 location, stack_param_delta);
668 }
669 InstructionOperand op =
670 g.UseLocation(*iter, location,
671 buffer->descriptor->GetInputType(index).representation());
672 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
673 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000674 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000675 buffer->pushed_nodes.resize(stack_index + 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000677 PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
678 buffer->pushed_nodes[stack_index] = parameter;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 pushed_count++;
680 } else {
681 buffer->instruction_args.push_back(op);
682 }
683 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000684 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
685 frame_state_entries);
686 if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail &&
687 stack_param_delta != 0) {
688 // For tail calls that change the size of their parameter list and keep
689 // their return address on the stack, move the return address to just above
690 // the parameters.
691 LinkageLocation saved_return_location =
692 LinkageLocation::ForSavedCallerReturnAddress();
693 InstructionOperand return_address =
694 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
695 saved_return_location, stack_param_delta),
696 saved_return_location);
697 buffer->instruction_args.push_back(return_address);
698 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000699}
700
701
702void InstructionSelector::VisitBlock(BasicBlock* block) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000703 DCHECK(!current_block_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000704 current_block_ = block;
705 int current_block_end = static_cast<int>(instructions_.size());
706
Ben Murdoch097c5b22016-05-18 11:27:45 +0100707 int effect_level = 0;
708 for (Node* const node : *block) {
709 if (node->opcode() == IrOpcode::kStore ||
710 node->opcode() == IrOpcode::kCheckedStore ||
711 node->opcode() == IrOpcode::kCall) {
712 ++effect_level;
713 }
714 SetEffectLevel(node, effect_level);
715 }
716
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717 // Generate code for the block control "top down", but schedule the code
718 // "bottom up".
719 VisitControl(block);
720 std::reverse(instructions_.begin() + current_block_end, instructions_.end());
721
722 // Visit code in reverse control flow order, because architecture-specific
723 // matching may cover more than one node at a time.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000724 for (auto node : base::Reversed(*block)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000725 // Skip nodes that are unused or already defined.
726 if (!IsUsed(node) || IsDefined(node)) continue;
727 // Generate code for this node "top down", but schedule the code "bottom
728 // up".
729 size_t current_node_end = instructions_.size();
730 VisitNode(node);
731 std::reverse(instructions_.begin() + current_node_end, instructions_.end());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000732 if (instructions_.size() == current_node_end) continue;
733 // Mark source position on first instruction emitted.
734 SourcePosition source_position = source_positions_->GetSourcePosition(node);
735 if (source_position.IsKnown() &&
736 (source_position_mode_ == kAllSourcePositions ||
737 node->opcode() == IrOpcode::kCall)) {
738 sequence()->SetSourcePosition(instructions_[current_node_end],
739 source_position);
740 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000741 }
742
743 // We're done with the block.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400744 InstructionBlock* instruction_block =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000745 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400746 instruction_block->set_code_start(static_cast<int>(instructions_.size()));
747 instruction_block->set_code_end(current_block_end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000748
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000749 current_block_ = nullptr;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000750}
751
752
753void InstructionSelector::VisitControl(BasicBlock* block) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000754#ifdef DEBUG
755 // SSA deconstruction requires targets of branches not to have phis.
756 // Edge split form guarantees this property, but is more strict.
757 if (block->SuccessorCount() > 1) {
758 for (BasicBlock* const successor : block->successors()) {
759 for (Node* const node : *successor) {
760 CHECK(!IrOpcode::IsPhiOpcode(node->opcode()));
761 }
762 }
763 }
764#endif
765
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400766 Node* input = block->control_input();
767 switch (block->control()) {
768 case BasicBlock::kGoto:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000769 return VisitGoto(block->SuccessorAt(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000770 case BasicBlock::kCall: {
771 DCHECK_EQ(IrOpcode::kCall, input->opcode());
772 BasicBlock* success = block->SuccessorAt(0);
773 BasicBlock* exception = block->SuccessorAt(1);
774 return VisitCall(input, exception), VisitGoto(success);
775 }
776 case BasicBlock::kTailCall: {
777 DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
778 return VisitTailCall(input);
779 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400780 case BasicBlock::kBranch: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000781 DCHECK_EQ(IrOpcode::kBranch, input->opcode());
782 BasicBlock* tbranch = block->SuccessorAt(0);
783 BasicBlock* fbranch = block->SuccessorAt(1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000784 if (tbranch == fbranch) return VisitGoto(tbranch);
785 return VisitBranch(input, tbranch, fbranch);
786 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000787 case BasicBlock::kSwitch: {
788 DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
789 SwitchInfo sw;
790 // Last successor must be Default.
791 sw.default_branch = block->successors().back();
792 DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode());
793 // All other successors must be cases.
794 sw.case_count = block->SuccessorCount() - 1;
795 sw.case_branches = &block->successors().front();
796 // Determine case values and their min/max.
797 sw.case_values = zone()->NewArray<int32_t>(sw.case_count);
798 sw.min_value = std::numeric_limits<int32_t>::max();
799 sw.max_value = std::numeric_limits<int32_t>::min();
800 for (size_t index = 0; index < sw.case_count; ++index) {
801 BasicBlock* branch = sw.case_branches[index];
802 int32_t value = OpParameter<int32_t>(branch->front()->op());
803 sw.case_values[index] = value;
804 if (sw.min_value > value) sw.min_value = value;
805 if (sw.max_value < value) sw.max_value = value;
806 }
807 DCHECK_LE(sw.min_value, sw.max_value);
808 // Note that {value_range} can be 0 if {min_value} is -2^31 and
809 // {max_value}
810 // is 2^31-1, so don't assume that it's non-zero below.
811 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) -
812 bit_cast<uint32_t>(sw.min_value);
813 return VisitSwitch(input, sw);
814 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400815 case BasicBlock::kReturn: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000816 DCHECK_EQ(IrOpcode::kReturn, input->opcode());
817 return VisitReturn(input);
818 }
819 case BasicBlock::kDeoptimize: {
820 DeoptimizeKind kind = DeoptimizeKindOf(input->op());
821 Node* value = input->InputAt(0);
822 return VisitDeoptimize(kind, value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000823 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400824 case BasicBlock::kThrow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000825 DCHECK_EQ(IrOpcode::kThrow, input->opcode());
826 return VisitThrow(input->InputAt(0));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400827 case BasicBlock::kNone: {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100828 // Exit block doesn't have control.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000829 DCHECK_NULL(input);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830 break;
831 }
832 default:
833 UNREACHABLE();
834 break;
835 }
836}
837
838
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000839void InstructionSelector::VisitNode(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400840 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
841 switch (node->opcode()) {
842 case IrOpcode::kStart:
843 case IrOpcode::kLoop:
844 case IrOpcode::kEnd:
845 case IrOpcode::kBranch:
846 case IrOpcode::kIfTrue:
847 case IrOpcode::kIfFalse:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000848 case IrOpcode::kIfSuccess:
849 case IrOpcode::kSwitch:
850 case IrOpcode::kIfValue:
851 case IrOpcode::kIfDefault:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400852 case IrOpcode::kEffectPhi:
853 case IrOpcode::kMerge:
854 case IrOpcode::kTerminate:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855 case IrOpcode::kBeginRegion:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000856 // No code needed for these graph artifacts.
857 return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000858 case IrOpcode::kIfException:
859 return MarkAsReference(node), VisitIfException(node);
860 case IrOpcode::kFinishRegion:
861 return MarkAsReference(node), VisitFinishRegion(node);
862 case IrOpcode::kGuard:
863 return MarkAsReference(node), VisitGuard(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864 case IrOpcode::kParameter: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 MachineType type =
866 linkage()->GetParameterType(ParameterIndexOf(node->op()));
867 MarkAsRepresentation(type.representation(), node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868 return VisitParameter(node);
869 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000870 case IrOpcode::kOsrValue:
871 return MarkAsReference(node), VisitOsrValue(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000872 case IrOpcode::kPhi: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000873 MachineRepresentation rep = PhiRepresentationOf(node->op());
874 MarkAsRepresentation(rep, node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000875 return VisitPhi(node);
876 }
877 case IrOpcode::kProjection:
878 return VisitProjection(node);
879 case IrOpcode::kInt32Constant:
880 case IrOpcode::kInt64Constant:
881 case IrOpcode::kExternalConstant:
882 return VisitConstant(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400883 case IrOpcode::kFloat32Constant:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000884 return MarkAsFloat32(node), VisitConstant(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000885 case IrOpcode::kFloat64Constant:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 return MarkAsFloat64(node), VisitConstant(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887 case IrOpcode::kHeapConstant:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000888 return MarkAsReference(node), VisitConstant(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000889 case IrOpcode::kNumberConstant: {
890 double value = OpParameter<double>(node);
891 if (!IsSmiDouble(value)) MarkAsReference(node);
892 return VisitConstant(node);
893 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000894 case IrOpcode::kCall:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400895 return VisitCall(node);
Ben Murdochda12d292016-06-02 14:46:10 +0100896 case IrOpcode::kDeoptimizeIf:
897 return VisitDeoptimizeIf(node);
898 case IrOpcode::kDeoptimizeUnless:
899 return VisitDeoptimizeUnless(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000900 case IrOpcode::kFrameState:
901 case IrOpcode::kStateValues:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000902 case IrOpcode::kObjectState:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000903 return;
904 case IrOpcode::kLoad: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000905 LoadRepresentation type = LoadRepresentationOf(node->op());
906 MarkAsRepresentation(type.representation(), node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 return VisitLoad(node);
908 }
909 case IrOpcode::kStore:
910 return VisitStore(node);
911 case IrOpcode::kWord32And:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000912 return MarkAsWord32(node), VisitWord32And(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000913 case IrOpcode::kWord32Or:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000914 return MarkAsWord32(node), VisitWord32Or(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000915 case IrOpcode::kWord32Xor:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000916 return MarkAsWord32(node), VisitWord32Xor(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000917 case IrOpcode::kWord32Shl:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 return MarkAsWord32(node), VisitWord32Shl(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000919 case IrOpcode::kWord32Shr:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000920 return MarkAsWord32(node), VisitWord32Shr(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000921 case IrOpcode::kWord32Sar:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000922 return MarkAsWord32(node), VisitWord32Sar(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000923 case IrOpcode::kWord32Ror:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 return MarkAsWord32(node), VisitWord32Ror(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000925 case IrOpcode::kWord32Equal:
926 return VisitWord32Equal(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927 case IrOpcode::kWord32Clz:
928 return MarkAsWord32(node), VisitWord32Clz(node);
929 case IrOpcode::kWord32Ctz:
930 return MarkAsWord32(node), VisitWord32Ctz(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100931 case IrOpcode::kWord32ReverseBits:
932 return MarkAsWord32(node), VisitWord32ReverseBits(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933 case IrOpcode::kWord32Popcnt:
934 return MarkAsWord32(node), VisitWord32Popcnt(node);
935 case IrOpcode::kWord64Popcnt:
936 return MarkAsWord32(node), VisitWord64Popcnt(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937 case IrOpcode::kWord64And:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000938 return MarkAsWord64(node), VisitWord64And(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000939 case IrOpcode::kWord64Or:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940 return MarkAsWord64(node), VisitWord64Or(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000941 case IrOpcode::kWord64Xor:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000942 return MarkAsWord64(node), VisitWord64Xor(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000943 case IrOpcode::kWord64Shl:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944 return MarkAsWord64(node), VisitWord64Shl(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000945 case IrOpcode::kWord64Shr:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000946 return MarkAsWord64(node), VisitWord64Shr(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947 case IrOpcode::kWord64Sar:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000948 return MarkAsWord64(node), VisitWord64Sar(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000949 case IrOpcode::kWord64Ror:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 return MarkAsWord64(node), VisitWord64Ror(node);
951 case IrOpcode::kWord64Clz:
952 return MarkAsWord64(node), VisitWord64Clz(node);
953 case IrOpcode::kWord64Ctz:
954 return MarkAsWord64(node), VisitWord64Ctz(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100955 case IrOpcode::kWord64ReverseBits:
956 return MarkAsWord64(node), VisitWord64ReverseBits(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000957 case IrOpcode::kWord64Equal:
958 return VisitWord64Equal(node);
959 case IrOpcode::kInt32Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000960 return MarkAsWord32(node), VisitInt32Add(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000961 case IrOpcode::kInt32AddWithOverflow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000962 return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000963 case IrOpcode::kInt32Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000964 return MarkAsWord32(node), VisitInt32Sub(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000965 case IrOpcode::kInt32SubWithOverflow:
966 return VisitInt32SubWithOverflow(node);
967 case IrOpcode::kInt32Mul:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000968 return MarkAsWord32(node), VisitInt32Mul(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400969 case IrOpcode::kInt32MulHigh:
970 return VisitInt32MulHigh(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000971 case IrOpcode::kInt32Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000972 return MarkAsWord32(node), VisitInt32Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000973 case IrOpcode::kInt32Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000974 return MarkAsWord32(node), VisitInt32Mod(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000975 case IrOpcode::kInt32LessThan:
976 return VisitInt32LessThan(node);
977 case IrOpcode::kInt32LessThanOrEqual:
978 return VisitInt32LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400979 case IrOpcode::kUint32Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000980 return MarkAsWord32(node), VisitUint32Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000981 case IrOpcode::kUint32LessThan:
982 return VisitUint32LessThan(node);
983 case IrOpcode::kUint32LessThanOrEqual:
984 return VisitUint32LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400985 case IrOpcode::kUint32Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000986 return MarkAsWord32(node), VisitUint32Mod(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400987 case IrOpcode::kUint32MulHigh:
988 return VisitUint32MulHigh(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000989 case IrOpcode::kInt64Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000990 return MarkAsWord64(node), VisitInt64Add(node);
991 case IrOpcode::kInt64AddWithOverflow:
992 return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000993 case IrOpcode::kInt64Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000994 return MarkAsWord64(node), VisitInt64Sub(node);
995 case IrOpcode::kInt64SubWithOverflow:
996 return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000997 case IrOpcode::kInt64Mul:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000998 return MarkAsWord64(node), VisitInt64Mul(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999 case IrOpcode::kInt64Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001000 return MarkAsWord64(node), VisitInt64Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001001 case IrOpcode::kInt64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001002 return MarkAsWord64(node), VisitInt64Mod(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001003 case IrOpcode::kInt64LessThan:
1004 return VisitInt64LessThan(node);
1005 case IrOpcode::kInt64LessThanOrEqual:
1006 return VisitInt64LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001007 case IrOpcode::kUint64Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001008 return MarkAsWord64(node), VisitUint64Div(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001009 case IrOpcode::kUint64LessThan:
1010 return VisitUint64LessThan(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001011 case IrOpcode::kUint64LessThanOrEqual:
1012 return VisitUint64LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001013 case IrOpcode::kUint64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001014 return MarkAsWord64(node), VisitUint64Mod(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001015 case IrOpcode::kChangeFloat32ToFloat64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001016 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001017 case IrOpcode::kChangeInt32ToFloat64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001018 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001019 case IrOpcode::kChangeUint32ToFloat64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001020 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001021 case IrOpcode::kChangeFloat64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001022 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001023 case IrOpcode::kChangeFloat64ToUint32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001024 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
Ben Murdochda12d292016-06-02 14:46:10 +01001025 case IrOpcode::kTruncateFloat64ToUint32:
1026 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001027 case IrOpcode::kTruncateFloat32ToInt32:
1028 return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node);
1029 case IrOpcode::kTruncateFloat32ToUint32:
1030 return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001031 case IrOpcode::kTryTruncateFloat32ToInt64:
1032 return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
1033 case IrOpcode::kTryTruncateFloat64ToInt64:
1034 return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
1035 case IrOpcode::kTryTruncateFloat32ToUint64:
1036 return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
1037 case IrOpcode::kTryTruncateFloat64ToUint64:
1038 return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001039 case IrOpcode::kChangeInt32ToInt64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001040 return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041 case IrOpcode::kChangeUint32ToUint64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001042 return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001043 case IrOpcode::kTruncateFloat64ToFloat32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001044 return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001045 case IrOpcode::kTruncateFloat64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001046 return MarkAsWord32(node), VisitTruncateFloat64ToInt32(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001047 case IrOpcode::kTruncateInt64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001048 return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
1049 case IrOpcode::kRoundInt64ToFloat32:
1050 return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001051 case IrOpcode::kRoundInt32ToFloat32:
1052 return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001053 case IrOpcode::kRoundInt64ToFloat64:
1054 return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
1055 case IrOpcode::kBitcastFloat32ToInt32:
1056 return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001057 case IrOpcode::kRoundUint32ToFloat32:
1058 return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001059 case IrOpcode::kRoundUint64ToFloat32:
1060 return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
1061 case IrOpcode::kRoundUint64ToFloat64:
1062 return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
1063 case IrOpcode::kBitcastFloat64ToInt64:
1064 return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
1065 case IrOpcode::kBitcastInt32ToFloat32:
1066 return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
1067 case IrOpcode::kBitcastInt64ToFloat64:
1068 return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
1069 case IrOpcode::kFloat32Add:
1070 return MarkAsFloat32(node), VisitFloat32Add(node);
1071 case IrOpcode::kFloat32Sub:
1072 return MarkAsFloat32(node), VisitFloat32Sub(node);
1073 case IrOpcode::kFloat32Mul:
1074 return MarkAsFloat32(node), VisitFloat32Mul(node);
1075 case IrOpcode::kFloat32Div:
1076 return MarkAsFloat32(node), VisitFloat32Div(node);
1077 case IrOpcode::kFloat32Min:
1078 return MarkAsFloat32(node), VisitFloat32Min(node);
1079 case IrOpcode::kFloat32Max:
1080 return MarkAsFloat32(node), VisitFloat32Max(node);
1081 case IrOpcode::kFloat32Abs:
1082 return MarkAsFloat32(node), VisitFloat32Abs(node);
1083 case IrOpcode::kFloat32Sqrt:
1084 return MarkAsFloat32(node), VisitFloat32Sqrt(node);
1085 case IrOpcode::kFloat32Equal:
1086 return VisitFloat32Equal(node);
1087 case IrOpcode::kFloat32LessThan:
1088 return VisitFloat32LessThan(node);
1089 case IrOpcode::kFloat32LessThanOrEqual:
1090 return VisitFloat32LessThanOrEqual(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001091 case IrOpcode::kFloat64Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001092 return MarkAsFloat64(node), VisitFloat64Add(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001093 case IrOpcode::kFloat64Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001094 return MarkAsFloat64(node), VisitFloat64Sub(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001095 case IrOpcode::kFloat64Mul:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001096 return MarkAsFloat64(node), VisitFloat64Mul(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001097 case IrOpcode::kFloat64Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001098 return MarkAsFloat64(node), VisitFloat64Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001099 case IrOpcode::kFloat64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001100 return MarkAsFloat64(node), VisitFloat64Mod(node);
1101 case IrOpcode::kFloat64Min:
1102 return MarkAsFloat64(node), VisitFloat64Min(node);
1103 case IrOpcode::kFloat64Max:
1104 return MarkAsFloat64(node), VisitFloat64Max(node);
1105 case IrOpcode::kFloat64Abs:
1106 return MarkAsFloat64(node), VisitFloat64Abs(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107 case IrOpcode::kFloat64Sqrt:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001108 return MarkAsFloat64(node), VisitFloat64Sqrt(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001109 case IrOpcode::kFloat64Equal:
1110 return VisitFloat64Equal(node);
1111 case IrOpcode::kFloat64LessThan:
1112 return VisitFloat64LessThan(node);
1113 case IrOpcode::kFloat64LessThanOrEqual:
1114 return VisitFloat64LessThanOrEqual(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001115 case IrOpcode::kFloat32RoundDown:
1116 return MarkAsFloat32(node), VisitFloat32RoundDown(node);
1117 case IrOpcode::kFloat64RoundDown:
1118 return MarkAsFloat64(node), VisitFloat64RoundDown(node);
1119 case IrOpcode::kFloat32RoundUp:
1120 return MarkAsFloat32(node), VisitFloat32RoundUp(node);
1121 case IrOpcode::kFloat64RoundUp:
1122 return MarkAsFloat64(node), VisitFloat64RoundUp(node);
1123 case IrOpcode::kFloat32RoundTruncate:
1124 return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001125 case IrOpcode::kFloat64RoundTruncate:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001126 return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001127 case IrOpcode::kFloat64RoundTiesAway:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001128 return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
1129 case IrOpcode::kFloat32RoundTiesEven:
1130 return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
1131 case IrOpcode::kFloat64RoundTiesEven:
1132 return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
1133 case IrOpcode::kFloat64ExtractLowWord32:
1134 return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
1135 case IrOpcode::kFloat64ExtractHighWord32:
1136 return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
1137 case IrOpcode::kFloat64InsertLowWord32:
1138 return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
1139 case IrOpcode::kFloat64InsertHighWord32:
1140 return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001141 case IrOpcode::kStackSlot:
1142 return VisitStackSlot(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001143 case IrOpcode::kLoadStackPointer:
1144 return VisitLoadStackPointer(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001145 case IrOpcode::kLoadFramePointer:
1146 return VisitLoadFramePointer(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001147 case IrOpcode::kLoadParentFramePointer:
1148 return VisitLoadParentFramePointer(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001149 case IrOpcode::kCheckedLoad: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001150 MachineRepresentation rep =
1151 CheckedLoadRepresentationOf(node->op()).representation();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001152 MarkAsRepresentation(rep, node);
1153 return VisitCheckedLoad(node);
1154 }
1155 case IrOpcode::kCheckedStore:
1156 return VisitCheckedStore(node);
Ben Murdochda12d292016-06-02 14:46:10 +01001157 case IrOpcode::kInt32PairAdd:
1158 MarkAsWord32(NodeProperties::FindProjection(node, 0));
1159 MarkAsWord32(NodeProperties::FindProjection(node, 1));
1160 return VisitInt32PairAdd(node);
1161 case IrOpcode::kInt32PairSub:
1162 MarkAsWord32(NodeProperties::FindProjection(node, 0));
1163 MarkAsWord32(NodeProperties::FindProjection(node, 1));
1164 return VisitInt32PairSub(node);
1165 case IrOpcode::kInt32PairMul:
1166 MarkAsWord32(NodeProperties::FindProjection(node, 0));
1167 MarkAsWord32(NodeProperties::FindProjection(node, 1));
1168 return VisitInt32PairMul(node);
1169 case IrOpcode::kWord32PairShl:
1170 MarkAsWord32(NodeProperties::FindProjection(node, 0));
1171 MarkAsWord32(NodeProperties::FindProjection(node, 1));
1172 return VisitWord32PairShl(node);
1173 case IrOpcode::kWord32PairShr:
1174 MarkAsWord32(NodeProperties::FindProjection(node, 0));
1175 MarkAsWord32(NodeProperties::FindProjection(node, 1));
1176 return VisitWord32PairShr(node);
1177 case IrOpcode::kWord32PairSar:
1178 MarkAsWord32(NodeProperties::FindProjection(node, 0));
1179 MarkAsWord32(NodeProperties::FindProjection(node, 1));
1180 return VisitWord32PairSar(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001181 default:
1182 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
1183 node->opcode(), node->op()->mnemonic(), node->id());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001184 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001185 }
1186}
1187
1188
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001189void InstructionSelector::VisitLoadStackPointer(Node* node) {
1190 OperandGenerator g(this);
1191 Emit(kArchStackPointer, g.DefineAsRegister(node));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001192}
1193
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001194
1195void InstructionSelector::VisitLoadFramePointer(Node* node) {
1196 OperandGenerator g(this);
1197 Emit(kArchFramePointer, g.DefineAsRegister(node));
1198}
1199
Ben Murdoch097c5b22016-05-18 11:27:45 +01001200void InstructionSelector::VisitLoadParentFramePointer(Node* node) {
1201 OperandGenerator g(this);
1202 Emit(kArchParentFramePointer, g.DefineAsRegister(node));
1203}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204
1205void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw,
1206 InstructionOperand& index_operand) {
1207 OperandGenerator g(this);
1208 size_t input_count = 2 + sw.value_range;
1209 auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1210 inputs[0] = index_operand;
1211 InstructionOperand default_operand = g.Label(sw.default_branch);
1212 std::fill(&inputs[1], &inputs[input_count], default_operand);
1213 for (size_t index = 0; index < sw.case_count; ++index) {
1214 size_t value = sw.case_values[index] - sw.min_value;
1215 BasicBlock* branch = sw.case_branches[index];
1216 DCHECK_LE(0u, value);
1217 DCHECK_LT(value + 2, input_count);
1218 inputs[value + 2] = g.Label(branch);
1219 }
1220 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1221}
1222
1223
1224void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
1225 InstructionOperand& value_operand) {
1226 OperandGenerator g(this);
1227 size_t input_count = 2 + sw.case_count * 2;
1228 auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1229 inputs[0] = value_operand;
1230 inputs[1] = g.Label(sw.default_branch);
1231 for (size_t index = 0; index < sw.case_count; ++index) {
1232 int32_t value = sw.case_values[index];
1233 BasicBlock* branch = sw.case_branches[index];
1234 inputs[index * 2 + 2 + 0] = g.TempImmediate(value);
1235 inputs[index * 2 + 2 + 1] = g.Label(branch);
1236 }
1237 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1238}
1239
Ben Murdoch097c5b22016-05-18 11:27:45 +01001240void InstructionSelector::VisitStackSlot(Node* node) {
1241 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op()));
1242 int slot = frame_->AllocateSpillSlot(size);
1243 OperandGenerator g(this);
1244
1245 Emit(kArchStackSlot, g.DefineAsRegister(node),
1246 sequence()->AddImmediate(Constant(slot)), 0, nullptr);
1247}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001248
1249// 32 bit targets do not implement the following instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001250#if V8_TARGET_ARCH_32_BIT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001251
1252void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
1253
1254
1255void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
1256
1257
1258void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
1259
1260
1261void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
1262
1263
1264void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
1265
1266
1267void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
1268
1269
1270void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
1271
1272
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001273void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
1274
1275
1276void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
1277
1278
Ben Murdoch097c5b22016-05-18 11:27:45 +01001279void InstructionSelector::VisitWord64ReverseBits(Node* node) {
1280 UNIMPLEMENTED();
1281}
1282
1283
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001284void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
1285
1286
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001287void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
1288
1289
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001290void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
1291
1292
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001293void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
1294 UNIMPLEMENTED();
1295}
1296
1297
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001298void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
1299
1300
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001301void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
1302 UNIMPLEMENTED();
1303}
1304
1305
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001306void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
1307
1308
1309void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
1310
1311
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001312void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
1313
1314
1315void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
1316 UNIMPLEMENTED();
1317}
1318
1319
1320void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001321
1322
1323void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
1324
1325
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001326void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
1327
1328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001329void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
1330 UNIMPLEMENTED();
1331}
1332
1333
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001334void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001335
1336
1337void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
1338 UNIMPLEMENTED();
1339}
1340
1341
1342void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
1343 UNIMPLEMENTED();
1344}
1345
1346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001347void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
1348 UNIMPLEMENTED();
1349}
1350
1351
1352void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
1353 UNIMPLEMENTED();
1354}
1355
1356
1357void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
1358 UNIMPLEMENTED();
1359}
1360
1361
1362void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
1363 UNIMPLEMENTED();
1364}
1365
1366
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001367void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
1368 UNIMPLEMENTED();
1369}
1370
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001371
1372void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
1373 UNIMPLEMENTED();
1374}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001375
1376
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001377void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
1378 UNIMPLEMENTED();
1379}
1380
1381
1382void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
1383 UNIMPLEMENTED();
1384}
1385
1386
1387void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
1388 UNIMPLEMENTED();
1389}
1390
1391
1392void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
1393 UNIMPLEMENTED();
1394}
1395
1396
1397void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
1398 UNIMPLEMENTED();
1399}
1400
1401#endif // V8_TARGET_ARCH_32_BIT
1402
Ben Murdochda12d292016-06-02 14:46:10 +01001403// 64 bit targets do not implement the following instructions.
1404#if V8_TARGET_ARCH_64_BIT
1405void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
1406
1407void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); }
1408
1409void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); }
1410
1411void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); }
1412
1413void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); }
1414
1415void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); }
1416#endif // V8_TARGET_ARCH_64_BIT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001417
1418void InstructionSelector::VisitFinishRegion(Node* node) {
1419 OperandGenerator g(this);
1420 Node* value = node->InputAt(0);
1421 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1422}
1423
1424
1425void InstructionSelector::VisitGuard(Node* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001426 OperandGenerator g(this);
1427 Node* value = node->InputAt(0);
1428 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1429}
1430
1431
1432void InstructionSelector::VisitParameter(Node* node) {
1433 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001434 int index = ParameterIndexOf(node->op());
1435 InstructionOperand op =
1436 linkage()->ParameterHasSecondaryLocation(index)
1437 ? g.DefineAsDualLocation(
1438 node, linkage()->GetParameterLocation(index),
1439 linkage()->GetParameterSecondaryLocation(index))
1440 : g.DefineAsLocation(
1441 node, linkage()->GetParameterLocation(index),
1442 linkage()->GetParameterType(index).representation());
1443
1444 Emit(kArchNop, op);
1445}
1446
1447
1448void InstructionSelector::VisitIfException(Node* node) {
1449 OperandGenerator g(this);
1450 Node* call = node->InputAt(1);
1451 DCHECK_EQ(IrOpcode::kCall, call->opcode());
1452 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(call);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001453 Emit(kArchNop,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001454 g.DefineAsLocation(node, descriptor->GetReturnLocation(0),
1455 descriptor->GetReturnType(0).representation()));
1456}
1457
1458
1459void InstructionSelector::VisitOsrValue(Node* node) {
1460 OperandGenerator g(this);
1461 int index = OpParameter<int>(node);
1462 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index),
1463 MachineRepresentation::kTagged));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001464}
1465
1466
1467void InstructionSelector::VisitPhi(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001468 const int input_count = node->op()->ValueInputCount();
1469 PhiInstruction* phi = new (instruction_zone())
1470 PhiInstruction(instruction_zone(), GetVirtualRegister(node),
1471 static_cast<size_t>(input_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001472 sequence()
1473 ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
1474 ->AddPhi(phi);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001475 for (int i = 0; i < input_count; ++i) {
1476 Node* const input = node->InputAt(i);
1477 MarkAsUsed(input);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001478 phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001479 }
1480}
1481
1482
1483void InstructionSelector::VisitProjection(Node* node) {
1484 OperandGenerator g(this);
1485 Node* value = node->InputAt(0);
1486 switch (value->opcode()) {
1487 case IrOpcode::kInt32AddWithOverflow:
1488 case IrOpcode::kInt32SubWithOverflow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001489 case IrOpcode::kInt64AddWithOverflow:
1490 case IrOpcode::kInt64SubWithOverflow:
1491 case IrOpcode::kTryTruncateFloat32ToInt64:
1492 case IrOpcode::kTryTruncateFloat64ToInt64:
1493 case IrOpcode::kTryTruncateFloat32ToUint64:
1494 case IrOpcode::kTryTruncateFloat64ToUint64:
Ben Murdochda12d292016-06-02 14:46:10 +01001495 case IrOpcode::kInt32PairAdd:
1496 case IrOpcode::kInt32PairSub:
1497 case IrOpcode::kInt32PairMul:
1498 case IrOpcode::kWord32PairShl:
1499 case IrOpcode::kWord32PairShr:
1500 case IrOpcode::kWord32PairSar:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001501 if (ProjectionIndexOf(node->op()) == 0u) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001502 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1503 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001504 DCHECK(ProjectionIndexOf(node->op()) == 1u);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001505 MarkAsUsed(value);
1506 }
1507 break;
1508 default:
1509 break;
1510 }
1511}
1512
1513
1514void InstructionSelector::VisitConstant(Node* node) {
1515 // We must emit a NOP here because every live range needs a defining
1516 // instruction in the register allocator.
1517 OperandGenerator g(this);
1518 Emit(kArchNop, g.DefineAsConstant(node));
1519}
1520
1521
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001522void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001523 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001524 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
1525
1526 FrameStateDescriptor* frame_state_descriptor = nullptr;
1527 if (descriptor->NeedsFrameState()) {
1528 frame_state_descriptor = GetFrameStateDescriptor(
1529 node->InputAt(static_cast<int>(descriptor->InputCount())));
1530 }
1531
1532 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
1533
1534 // Compute InstructionOperands for inputs and outputs.
1535 // TODO(turbofan): on some architectures it's probably better to use
1536 // the code object in a register if there are multiple uses of it.
1537 // Improve constant pool and the heuristics in the register allocator
1538 // for where to emit constants.
1539 CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
1540 InitializeCallBuffer(node, &buffer, call_buffer_flags);
1541
1542 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
1543
1544 // Pass label of exception handler block.
1545 CallDescriptor::Flags flags = descriptor->flags();
1546 if (handler) {
1547 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
1548 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front());
1549 if (hint == IfExceptionHint::kLocallyCaught) {
1550 flags |= CallDescriptor::kHasLocalCatchHandler;
1551 }
1552 flags |= CallDescriptor::kHasExceptionHandler;
1553 buffer.instruction_args.push_back(g.Label(handler));
1554 }
1555
Ben Murdochda12d292016-06-02 14:46:10 +01001556 bool from_native_stack = linkage()->GetIncomingDescriptor()->UseNativeStack();
1557 bool to_native_stack = descriptor->UseNativeStack();
1558 if (from_native_stack != to_native_stack) {
1559 // (arm64 only) Mismatch in the use of stack pointers. One or the other
1560 // has to be restored manually by the code generator.
1561 flags |= to_native_stack ? CallDescriptor::kRestoreJSSP
1562 : CallDescriptor::kRestoreCSP;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001563 }
1564
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001565 // Select the appropriate opcode based on the call type.
1566 InstructionCode opcode = kArchNop;
1567 switch (descriptor->kind()) {
1568 case CallDescriptor::kCallAddress:
1569 opcode =
1570 kArchCallCFunction |
1571 MiscField::encode(static_cast<int>(descriptor->CParameterCount()));
1572 break;
1573 case CallDescriptor::kCallCodeObject:
1574 opcode = kArchCallCodeObject | MiscField::encode(flags);
1575 break;
1576 case CallDescriptor::kCallJSFunction:
1577 opcode = kArchCallJSFunction | MiscField::encode(flags);
1578 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001579 }
1580
1581 // Emit the call instruction.
1582 size_t const output_count = buffer.outputs.size();
1583 auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
1584 Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
1585 &buffer.instruction_args.front())
1586 ->MarkAsCall();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001587}
1588
1589
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001590void InstructionSelector::VisitTailCall(Node* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001591 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001592 CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node);
1593 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls);
1594 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite);
1595 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall);
1596
1597 // TODO(turbofan): Relax restriction for stack parameters.
1598
1599 int stack_param_delta = 0;
1600 if (linkage()->GetIncomingDescriptor()->CanTailCall(node,
1601 &stack_param_delta)) {
1602 CallBuffer buffer(zone(), descriptor, nullptr);
1603
1604 // Compute InstructionOperands for inputs and outputs.
1605 CallBufferFlags flags(kCallCodeImmediate | kCallTail);
1606 if (IsTailCallAddressImmediate()) {
1607 flags |= kCallAddressImmediate;
1608 }
1609 InitializeCallBuffer(node, &buffer, flags, stack_param_delta);
1610
1611 // Select the appropriate opcode based on the call type.
1612 InstructionCode opcode;
Ben Murdochda12d292016-06-02 14:46:10 +01001613 InstructionOperandVector temps(zone());
1614 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
1615 switch (descriptor->kind()) {
1616 case CallDescriptor::kCallCodeObject:
1617 opcode = kArchTailCallCodeObjectFromJSFunction;
1618 break;
1619 case CallDescriptor::kCallJSFunction:
1620 opcode = kArchTailCallJSFunctionFromJSFunction;
1621 break;
1622 default:
1623 UNREACHABLE();
1624 return;
1625 }
1626 int temps_count = GetTempsCountForTailCallFromJSFunction();
1627 for (int i = 0; i < temps_count; i++) {
1628 temps.push_back(g.TempRegister());
1629 }
1630 } else {
1631 switch (descriptor->kind()) {
1632 case CallDescriptor::kCallCodeObject:
1633 opcode = kArchTailCallCodeObject;
1634 break;
1635 case CallDescriptor::kCallJSFunction:
1636 opcode = kArchTailCallJSFunction;
1637 break;
1638 default:
1639 UNREACHABLE();
1640 return;
1641 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001642 }
1643 opcode |= MiscField::encode(descriptor->flags());
1644
1645 buffer.instruction_args.push_back(g.TempImmediate(stack_param_delta));
1646
1647 Emit(kArchPrepareTailCall, g.NoOutput(),
1648 g.TempImmediate(stack_param_delta));
1649
1650 // Emit the tailcall instruction.
1651 Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
Ben Murdochda12d292016-06-02 14:46:10 +01001652 &buffer.instruction_args.front(), temps.size(),
1653 temps.empty() ? nullptr : &temps.front());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001654 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001655 FrameStateDescriptor* frame_state_descriptor =
1656 descriptor->NeedsFrameState()
1657 ? GetFrameStateDescriptor(
1658 node->InputAt(static_cast<int>(descriptor->InputCount())))
1659 : nullptr;
1660
1661 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
1662
1663 // Compute InstructionOperands for inputs and outputs.
1664 CallBufferFlags flags = kCallCodeImmediate;
1665 if (IsTailCallAddressImmediate()) {
1666 flags |= kCallAddressImmediate;
1667 }
1668 InitializeCallBuffer(node, &buffer, flags);
1669
1670 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
1671
1672 // Select the appropriate opcode based on the call type.
1673 InstructionCode opcode;
1674 switch (descriptor->kind()) {
1675 case CallDescriptor::kCallCodeObject:
1676 opcode = kArchCallCodeObject;
1677 break;
1678 case CallDescriptor::kCallJSFunction:
1679 opcode = kArchCallJSFunction;
1680 break;
1681 default:
1682 UNREACHABLE();
1683 return;
1684 }
1685 opcode |= MiscField::encode(descriptor->flags());
1686
1687 // Emit the call instruction.
1688 size_t output_count = buffer.outputs.size();
1689 auto* outputs = &buffer.outputs.front();
1690 Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
1691 &buffer.instruction_args.front())
1692 ->MarkAsCall();
1693 Emit(kArchRet, 0, nullptr, output_count, outputs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001694 }
1695}
1696
1697
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001698void InstructionSelector::VisitGoto(BasicBlock* target) {
1699 // jump to the next block.
1700 OperandGenerator g(this);
1701 Emit(kArchJmp, g.NoOutput(), g.Label(target));
1702}
1703
1704
1705void InstructionSelector::VisitReturn(Node* ret) {
1706 OperandGenerator g(this);
1707 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) {
1708 Emit(kArchRet, g.NoOutput());
1709 } else {
1710 const int ret_count = ret->op()->ValueInputCount();
1711 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count);
1712 for (int i = 0; i < ret_count; ++i) {
1713 value_locations[i] =
1714 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i),
1715 linkage()->GetReturnType(i).representation());
1716 }
1717 Emit(kArchRet, 0, nullptr, ret_count, value_locations);
1718 }
1719}
1720
Ben Murdochda12d292016-06-02 14:46:10 +01001721Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode,
1722 InstructionOperand output,
1723 InstructionOperand a,
1724 InstructionOperand b,
1725 Node* frame_state) {
1726 size_t output_count = output.IsInvalid() ? 0 : 1;
1727 InstructionOperand inputs[] = {a, b};
1728 size_t input_count = arraysize(inputs);
1729 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
1730 frame_state);
1731}
1732
1733Instruction* InstructionSelector::EmitDeoptimize(
1734 InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
1735 size_t input_count, InstructionOperand* inputs, Node* frame_state) {
1736 OperandGenerator g(this);
1737 FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
1738 InstructionOperandVector args(instruction_zone());
1739 args.reserve(input_count + 1 + descriptor->GetTotalSize());
1740 for (size_t i = 0; i < input_count; ++i) {
1741 args.push_back(inputs[i]);
1742 }
1743 opcode |= MiscField::encode(static_cast<int>(input_count));
1744 InstructionSequence::StateId const state_id =
1745 sequence()->AddFrameStateDescriptor(descriptor);
1746 args.push_back(g.TempImmediate(state_id.ToInt()));
1747 StateObjectDeduplicator deduplicator(instruction_zone());
1748 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
1749 &args, FrameStateInputKind::kAny,
1750 instruction_zone());
1751 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0,
1752 nullptr);
1753}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001754
1755void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001756 InstructionCode opcode = kArchDeoptimize;
1757 switch (kind) {
1758 case DeoptimizeKind::kEager:
1759 opcode |= MiscField::encode(Deoptimizer::EAGER);
1760 break;
1761 case DeoptimizeKind::kSoft:
1762 opcode |= MiscField::encode(Deoptimizer::SOFT);
1763 break;
1764 }
Ben Murdochda12d292016-06-02 14:46:10 +01001765 EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001766}
1767
1768
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001769void InstructionSelector::VisitThrow(Node* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001770 OperandGenerator g(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001771 Emit(kArchThrowTerminator, g.NoOutput());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001772}
1773
1774
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001775FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
1776 Node* state) {
1777 DCHECK(state->opcode() == IrOpcode::kFrameState);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001778 DCHECK_EQ(kFrameStateInputCount, state->InputCount());
1779 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001780
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001781 int parameters = static_cast<int>(
1782 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size());
1783 int locals = static_cast<int>(
1784 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size());
1785 int stack = static_cast<int>(
1786 StateValuesAccess(state->InputAt(kFrameStateStackInput)).size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001787
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001788 DCHECK_EQ(parameters, state_info.parameter_count());
1789 DCHECK_EQ(locals, state_info.local_count());
1790
1791 FrameStateDescriptor* outer_state = nullptr;
1792 Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001793 if (outer_node->opcode() == IrOpcode::kFrameState) {
1794 outer_state = GetFrameStateDescriptor(outer_node);
1795 }
1796
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001797 return new (instruction_zone()) FrameStateDescriptor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001798 instruction_zone(), state_info.type(), state_info.bailout_id(),
1799 state_info.state_combine(), parameters, locals, stack,
1800 state_info.shared_info(), outer_state);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001801}
1802
1803
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001804} // namespace compiler
1805} // namespace internal
1806} // namespace v8