blob: 0f27e50dc9cfcb68f0e527894eedada42257da96 [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 }
85}
86
87
88void InstructionSelector::StartBlock(RpoNumber rpo) {
89 if (FLAG_turbo_instruction_scheduling &&
90 InstructionScheduler::SchedulerSupported()) {
91 DCHECK_NOT_NULL(scheduler_);
92 scheduler_->StartBlock(rpo);
93 } else {
94 sequence()->StartBlock(rpo);
95 }
96}
97
98
99void InstructionSelector::EndBlock(RpoNumber rpo) {
100 if (FLAG_turbo_instruction_scheduling &&
101 InstructionScheduler::SchedulerSupported()) {
102 DCHECK_NOT_NULL(scheduler_);
103 scheduler_->EndBlock(rpo);
104 } else {
105 sequence()->EndBlock(rpo);
106 }
107}
108
109
110void InstructionSelector::AddInstruction(Instruction* instr) {
111 if (FLAG_turbo_instruction_scheduling &&
112 InstructionScheduler::SchedulerSupported()) {
113 DCHECK_NOT_NULL(scheduler_);
114 scheduler_->AddInstruction(instr);
115 } else {
116 sequence()->AddInstruction(instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 }
118}
119
120
121Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 InstructionOperand output,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 size_t temp_count,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 InstructionOperand* temps) {
125 size_t output_count = output.IsInvalid() ? 0 : 1;
126 return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127}
128
129
130Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131 InstructionOperand output,
132 InstructionOperand a, size_t temp_count,
133 InstructionOperand* temps) {
134 size_t output_count = output.IsInvalid() ? 0 : 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
136}
137
138
139Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000140 InstructionOperand output,
141 InstructionOperand a,
142 InstructionOperand b, size_t temp_count,
143 InstructionOperand* temps) {
144 size_t output_count = output.IsInvalid() ? 0 : 1;
145 InstructionOperand inputs[] = {a, b};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146 size_t input_count = arraysize(inputs);
147 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
148 temps);
149}
150
151
152Instruction* InstructionSelector::Emit(InstructionCode opcode,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153 InstructionOperand output,
154 InstructionOperand a,
155 InstructionOperand b,
156 InstructionOperand c, size_t temp_count,
157 InstructionOperand* temps) {
158 size_t output_count = output.IsInvalid() ? 0 : 1;
159 InstructionOperand inputs[] = {a, b, c};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000160 size_t input_count = arraysize(inputs);
161 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
162 temps);
163}
164
165
166Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
168 InstructionOperand b, InstructionOperand c, InstructionOperand d,
169 size_t temp_count, InstructionOperand* temps) {
170 size_t output_count = output.IsInvalid() ? 0 : 1;
171 InstructionOperand inputs[] = {a, b, c, d};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 size_t input_count = arraysize(inputs);
173 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
174 temps);
175}
176
177
178Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
180 InstructionOperand b, InstructionOperand c, InstructionOperand d,
181 InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
182 size_t output_count = output.IsInvalid() ? 0 : 1;
183 InstructionOperand inputs[] = {a, b, c, d, e};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400184 size_t input_count = arraysize(inputs);
185 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
186 temps);
187}
188
189
190Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
192 InstructionOperand b, InstructionOperand c, InstructionOperand d,
193 InstructionOperand e, InstructionOperand f, size_t temp_count,
194 InstructionOperand* temps) {
195 size_t output_count = output.IsInvalid() ? 0 : 1;
196 InstructionOperand inputs[] = {a, b, c, d, e, f};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 size_t input_count = arraysize(inputs);
198 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
199 temps);
200}
201
202
203Instruction* InstructionSelector::Emit(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204 InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
205 size_t input_count, InstructionOperand* inputs, size_t temp_count,
206 InstructionOperand* temps) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000207 Instruction* instr =
208 Instruction::New(instruction_zone(), opcode, output_count, outputs,
209 input_count, inputs, temp_count, temps);
210 return Emit(instr);
211}
212
213
214Instruction* InstructionSelector::Emit(Instruction* instr) {
215 instructions_.push_back(instr);
216 return instr;
217}
218
219
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220bool InstructionSelector::CanCover(Node* user, Node* node) const {
221 return node->OwnedBy(user) &&
Ben Murdoch097c5b22016-05-18 11:27:45 +0100222 schedule()->block(node) == schedule()->block(user) &&
223 (node->op()->HasProperty(Operator::kPure) ||
224 GetEffectLevel(node) == GetEffectLevel(user));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225}
226
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400227int InstructionSelector::GetVirtualRegister(const Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 DCHECK_NOT_NULL(node);
229 size_t const id = node->id();
230 DCHECK_LT(id, virtual_registers_.size());
231 int virtual_register = virtual_registers_[id];
232 if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
233 virtual_register = sequence()->NextVirtualRegister();
234 virtual_registers_[id] = virtual_register;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400235 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236 return virtual_register;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400237}
238
239
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000240const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting()
241 const {
242 std::map<NodeId, int> virtual_registers;
243 for (size_t n = 0; n < virtual_registers_.size(); ++n) {
244 if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) {
245 NodeId const id = static_cast<NodeId>(n);
246 virtual_registers.insert(std::make_pair(id, virtual_registers_[n]));
247 }
248 }
249 return virtual_registers;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400250}
251
252
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253bool InstructionSelector::IsDefined(Node* node) const {
254 DCHECK_NOT_NULL(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255 size_t const id = node->id();
256 DCHECK_LT(id, defined_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 return defined_[id];
258}
259
260
261void InstructionSelector::MarkAsDefined(Node* node) {
262 DCHECK_NOT_NULL(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000263 size_t const id = node->id();
264 DCHECK_LT(id, defined_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265 defined_[id] = true;
266}
267
268
269bool InstructionSelector::IsUsed(Node* node) const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 DCHECK_NOT_NULL(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 size_t const id = node->id();
273 DCHECK_LT(id, used_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274 return used_[id];
275}
276
277
278void InstructionSelector::MarkAsUsed(Node* node) {
279 DCHECK_NOT_NULL(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280 size_t const id = node->id();
281 DCHECK_LT(id, used_.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000282 used_[id] = true;
283}
284
Ben Murdoch097c5b22016-05-18 11:27:45 +0100285int InstructionSelector::GetEffectLevel(Node* node) const {
286 DCHECK_NOT_NULL(node);
287 size_t const id = node->id();
288 DCHECK_LT(id, effect_level_.size());
289 return effect_level_[id];
290}
291
292void InstructionSelector::SetEffectLevel(Node* node, int effect_level) {
293 DCHECK_NOT_NULL(node);
294 size_t const id = node->id();
295 DCHECK_LT(id, effect_level_.size());
296 effect_level_[id] = effect_level;
297}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000299void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
300 const InstructionOperand& op) {
301 UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
302 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000303}
304
305
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000306void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
307 Node* node) {
308 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309}
310
311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312namespace {
313
314enum class FrameStateInputKind { kAny, kStackSlot };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000315
316
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000317InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
318 FrameStateInputKind kind) {
319 switch (input->opcode()) {
320 case IrOpcode::kInt32Constant:
321 case IrOpcode::kNumberConstant:
322 case IrOpcode::kFloat32Constant:
323 case IrOpcode::kFloat64Constant:
324 case IrOpcode::kHeapConstant:
325 return g->UseImmediate(input);
326 case IrOpcode::kObjectState:
327 UNREACHABLE();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400328 break;
329 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 switch (kind) {
331 case FrameStateInputKind::kStackSlot:
332 return g->UseUniqueSlot(input);
333 case FrameStateInputKind::kAny:
334 return g->UseAny(input);
335 }
336 }
337 UNREACHABLE();
338 return InstructionOperand();
339}
340
341
342class StateObjectDeduplicator {
343 public:
344 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
345 static const size_t kNotDuplicated = SIZE_MAX;
346
347 size_t GetObjectId(Node* node) {
348 for (size_t i = 0; i < objects_.size(); ++i) {
349 if (objects_[i] == node) {
350 return i;
351 }
352 }
353 return kNotDuplicated;
354 }
355
356 size_t InsertObject(Node* node) {
357 size_t id = objects_.size();
358 objects_.push_back(node);
359 return id;
360 }
361
362 private:
363 ZoneVector<Node*> objects_;
364};
365
366
367// Returns the number of instruction operands added to inputs.
368size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor,
369 InstructionOperandVector* inputs,
370 OperandGenerator* g,
371 StateObjectDeduplicator* deduplicator,
372 Node* input, MachineType type,
373 FrameStateInputKind kind, Zone* zone) {
374 switch (input->opcode()) {
375 case IrOpcode::kObjectState: {
376 size_t id = deduplicator->GetObjectId(input);
377 if (id == StateObjectDeduplicator::kNotDuplicated) {
378 size_t entries = 0;
379 id = deduplicator->InsertObject(input);
380 descriptor->fields().push_back(
381 StateValueDescriptor::Recursive(zone, id));
382 StateValueDescriptor* new_desc = &descriptor->fields().back();
383 for (Edge edge : input->input_edges()) {
384 entries += AddOperandToStateValueDescriptor(
385 new_desc, inputs, g, deduplicator, edge.to(),
386 MachineType::AnyTagged(), kind, zone);
387 }
388 return entries;
389 } else {
390 // Crankshaft counts duplicate objects for the running id, so we have
391 // to push the input again.
392 deduplicator->InsertObject(input);
393 descriptor->fields().push_back(
394 StateValueDescriptor::Duplicate(zone, id));
395 return 0;
396 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400397 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000398 }
399 default: {
400 inputs->push_back(OperandForDeopt(g, input, kind));
401 descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type));
402 return 1;
403 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400404 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000405}
406
407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000408// Returns the number of instruction operands added to inputs.
409size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor,
410 Node* state, OperandGenerator* g,
411 StateObjectDeduplicator* deduplicator,
412 InstructionOperandVector* inputs,
413 FrameStateInputKind kind, Zone* zone) {
414 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
415
416 size_t entries = 0;
417 size_t initial_size = inputs->size();
418 USE(initial_size); // initial_size is only used for debug.
419
420 if (descriptor->outer_state()) {
421 entries += AddInputsToFrameStateDescriptor(
422 descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
423 g, deduplicator, inputs, kind, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000424 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425
426 Node* parameters = state->InputAt(kFrameStateParametersInput);
427 Node* locals = state->InputAt(kFrameStateLocalsInput);
428 Node* stack = state->InputAt(kFrameStateStackInput);
429 Node* context = state->InputAt(kFrameStateContextInput);
430 Node* function = state->InputAt(kFrameStateFunctionInput);
431
432 DCHECK_EQ(descriptor->parameters_count(),
433 StateValuesAccess(parameters).size());
434 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
435 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
436
437 StateValueDescriptor* values_descriptor =
438 descriptor->GetStateValueDescriptor();
439 entries += AddOperandToStateValueDescriptor(
440 values_descriptor, inputs, g, deduplicator, function,
441 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
442 for (StateValuesAccess::TypedNode input_node :
443 StateValuesAccess(parameters)) {
444 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
445 deduplicator, input_node.node,
446 input_node.type, kind, zone);
447 }
448 if (descriptor->HasContext()) {
449 entries += AddOperandToStateValueDescriptor(
450 values_descriptor, inputs, g, deduplicator, context,
451 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
452 }
453 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
454 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
455 deduplicator, input_node.node,
456 input_node.type, kind, zone);
457 }
458 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
459 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
460 deduplicator, input_node.node,
461 input_node.type, kind, zone);
462 }
463 DCHECK_EQ(initial_size + entries, inputs->size());
464 return entries;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000465}
466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467} // namespace
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000468
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000469
470// An internal helper class for generating the operands to calls.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000471// TODO(bmeurer): Get rid of the CallBuffer business and make
472// InstructionSelector::VisitCall platform independent instead.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000473struct CallBuffer {
474 CallBuffer(Zone* zone, const CallDescriptor* descriptor,
475 FrameStateDescriptor* frame_state)
476 : descriptor(descriptor),
477 frame_state_descriptor(frame_state),
478 output_nodes(zone),
479 outputs(zone),
480 instruction_args(zone),
481 pushed_nodes(zone) {
482 output_nodes.reserve(descriptor->ReturnCount());
483 outputs.reserve(descriptor->ReturnCount());
484 pushed_nodes.reserve(input_count());
485 instruction_args.reserve(input_count() + frame_state_value_count());
486 }
487
488
489 const CallDescriptor* descriptor;
490 FrameStateDescriptor* frame_state_descriptor;
491 NodeVector output_nodes;
492 InstructionOperandVector outputs;
493 InstructionOperandVector instruction_args;
494 ZoneVector<PushParameter> pushed_nodes;
495
496 size_t input_count() const { return descriptor->InputCount(); }
497
498 size_t frame_state_count() const { return descriptor->FrameStateCount(); }
499
500 size_t frame_state_value_count() const {
501 return (frame_state_descriptor == nullptr)
502 ? 0
503 : (frame_state_descriptor->GetTotalSize() +
504 1); // Include deopt id.
505 }
506};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000507
508
509// TODO(bmeurer): Get rid of the CallBuffer business and make
510// InstructionSelector::VisitCall platform independent instead.
511void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512 CallBufferFlags flags,
513 int stack_param_delta) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000515 DCHECK_LE(call->op()->ValueOutputCount(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400516 static_cast<int>(buffer->descriptor->ReturnCount()));
517 DCHECK_EQ(
518 call->op()->ValueInputCount(),
519 static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000520
521 if (buffer->descriptor->ReturnCount() > 0) {
522 // Collect the projections that represent multiple outputs from this call.
523 if (buffer->descriptor->ReturnCount() == 1) {
524 buffer->output_nodes.push_back(call);
525 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000526 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr);
527 for (auto use : call->uses()) {
528 if (use->opcode() != IrOpcode::kProjection) continue;
529 size_t const index = ProjectionIndexOf(use->op());
530 DCHECK_LT(index, buffer->output_nodes.size());
531 DCHECK(!buffer->output_nodes[index]);
532 buffer->output_nodes[index] = use;
533 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000534 }
535
536 // Filter out the outputs that aren't live because no projection uses them.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400537 size_t outputs_needed_by_framestate =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000538 buffer->frame_state_descriptor == nullptr
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400539 ? 0
540 : buffer->frame_state_descriptor->state_combine()
541 .ConsumedOutputCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000542 for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000543 bool output_is_live = buffer->output_nodes[i] != nullptr ||
544 i < outputs_needed_by_framestate;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400545 if (output_is_live) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000546 MachineType type =
547 buffer->descriptor->GetReturnType(static_cast<int>(i));
548 LinkageLocation location =
549 buffer->descriptor->GetReturnLocation(static_cast<int>(i));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400550
551 Node* output = buffer->output_nodes[i];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000552 InstructionOperand op =
553 output == nullptr
554 ? g.TempLocation(location, type.representation())
555 : g.DefineAsLocation(output, location, type.representation());
556 MarkAsRepresentation(type.representation(), op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400557
558 buffer->outputs.push_back(op);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000559 }
560 }
561 }
562
563 // The first argument is always the callee code.
564 Node* callee = call->InputAt(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
566 bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000567 switch (buffer->descriptor->kind()) {
568 case CallDescriptor::kCallCodeObject:
569 buffer->instruction_args.push_back(
570 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
571 ? g.UseImmediate(callee)
572 : g.UseRegister(callee));
573 break;
574 case CallDescriptor::kCallAddress:
575 buffer->instruction_args.push_back(
576 (call_address_immediate &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000577 callee->opcode() == IrOpcode::kExternalConstant)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000578 ? g.UseImmediate(callee)
579 : g.UseRegister(callee));
580 break;
581 case CallDescriptor::kCallJSFunction:
582 buffer->instruction_args.push_back(
583 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000584 buffer->descriptor->GetInputType(0).representation()));
585 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587 DCHECK_EQ(1u, buffer->instruction_args.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000588
589 // If the call needs a frame state, we insert the state information as
590 // follows (n is the number of value inputs to the frame state):
591 // arg 1 : deoptimization id.
592 // arg 2 - arg (n + 1) : value inputs to the frame state.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000593 size_t frame_state_entries = 0;
594 USE(frame_state_entries); // frame_state_entries is only used for debug.
595 if (buffer->frame_state_descriptor != nullptr) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100596 Node* frame_state =
597 call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
598
599 // If it was a syntactic tail call we need to drop the current frame and
600 // an arguments adaptor frame on top of it (if the latter is present).
601 if (buffer->descriptor->SupportsTailCalls()) {
602 frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
603 buffer->frame_state_descriptor =
604 buffer->frame_state_descriptor->outer_state();
605
606 if (buffer->frame_state_descriptor != nullptr &&
607 buffer->frame_state_descriptor->type() ==
608 FrameStateType::kArgumentsAdaptor) {
609 frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
610 buffer->frame_state_descriptor =
611 buffer->frame_state_descriptor->outer_state();
612 }
613 }
614
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000615 InstructionSequence::StateId state_id =
616 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
617 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
618
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000619 StateObjectDeduplicator deduplicator(instruction_zone());
620
621 frame_state_entries =
622 1 + AddInputsToFrameStateDescriptor(
623 buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
624 &buffer->instruction_args, FrameStateInputKind::kStackSlot,
625 instruction_zone());
626
627 DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000628 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000629
630 size_t input_count = static_cast<size_t>(buffer->input_count());
631
632 // Split the arguments into pushed_nodes and instruction_args. Pushed
633 // arguments require an explicit push instruction before the call and do
634 // not appear as arguments to the call. Everything else ends up
635 // as an InstructionOperand argument to the call.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400636 auto iter(call->inputs().begin());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000637 size_t pushed_count = 0;
638 bool call_tail = (flags & kCallTail) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000639 for (size_t index = 0; index < input_count; ++iter, ++index) {
640 DCHECK(iter != call->inputs().end());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000641 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
642 if (index == 0) continue; // The first argument (callee) is already done.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000643
644 LinkageLocation location = buffer->descriptor->GetInputLocation(index);
645 if (call_tail) {
646 location = LinkageLocation::ConvertToTailCallerLocation(
647 location, stack_param_delta);
648 }
649 InstructionOperand op =
650 g.UseLocation(*iter, location,
651 buffer->descriptor->GetInputType(index).representation());
652 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
653 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000654 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000655 buffer->pushed_nodes.resize(stack_index + 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000656 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657 PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
658 buffer->pushed_nodes[stack_index] = parameter;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000659 pushed_count++;
660 } else {
661 buffer->instruction_args.push_back(op);
662 }
663 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000664 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
665 frame_state_entries);
666 if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail &&
667 stack_param_delta != 0) {
668 // For tail calls that change the size of their parameter list and keep
669 // their return address on the stack, move the return address to just above
670 // the parameters.
671 LinkageLocation saved_return_location =
672 LinkageLocation::ForSavedCallerReturnAddress();
673 InstructionOperand return_address =
674 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
675 saved_return_location, stack_param_delta),
676 saved_return_location);
677 buffer->instruction_args.push_back(return_address);
678 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679}
680
681
682void InstructionSelector::VisitBlock(BasicBlock* block) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000683 DCHECK(!current_block_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684 current_block_ = block;
685 int current_block_end = static_cast<int>(instructions_.size());
686
Ben Murdoch097c5b22016-05-18 11:27:45 +0100687 int effect_level = 0;
688 for (Node* const node : *block) {
689 if (node->opcode() == IrOpcode::kStore ||
690 node->opcode() == IrOpcode::kCheckedStore ||
691 node->opcode() == IrOpcode::kCall) {
692 ++effect_level;
693 }
694 SetEffectLevel(node, effect_level);
695 }
696
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000697 // Generate code for the block control "top down", but schedule the code
698 // "bottom up".
699 VisitControl(block);
700 std::reverse(instructions_.begin() + current_block_end, instructions_.end());
701
702 // Visit code in reverse control flow order, because architecture-specific
703 // matching may cover more than one node at a time.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 for (auto node : base::Reversed(*block)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000705 // Skip nodes that are unused or already defined.
706 if (!IsUsed(node) || IsDefined(node)) continue;
707 // Generate code for this node "top down", but schedule the code "bottom
708 // up".
709 size_t current_node_end = instructions_.size();
710 VisitNode(node);
711 std::reverse(instructions_.begin() + current_node_end, instructions_.end());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000712 if (instructions_.size() == current_node_end) continue;
713 // Mark source position on first instruction emitted.
714 SourcePosition source_position = source_positions_->GetSourcePosition(node);
715 if (source_position.IsKnown() &&
716 (source_position_mode_ == kAllSourcePositions ||
717 node->opcode() == IrOpcode::kCall)) {
718 sequence()->SetSourcePosition(instructions_[current_node_end],
719 source_position);
720 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000721 }
722
723 // We're done with the block.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400724 InstructionBlock* instruction_block =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400726 instruction_block->set_code_start(static_cast<int>(instructions_.size()));
727 instruction_block->set_code_end(current_block_end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000728
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729 current_block_ = nullptr;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000730}
731
732
733void InstructionSelector::VisitControl(BasicBlock* block) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734#ifdef DEBUG
735 // SSA deconstruction requires targets of branches not to have phis.
736 // Edge split form guarantees this property, but is more strict.
737 if (block->SuccessorCount() > 1) {
738 for (BasicBlock* const successor : block->successors()) {
739 for (Node* const node : *successor) {
740 CHECK(!IrOpcode::IsPhiOpcode(node->opcode()));
741 }
742 }
743 }
744#endif
745
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400746 Node* input = block->control_input();
747 switch (block->control()) {
748 case BasicBlock::kGoto:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749 return VisitGoto(block->SuccessorAt(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000750 case BasicBlock::kCall: {
751 DCHECK_EQ(IrOpcode::kCall, input->opcode());
752 BasicBlock* success = block->SuccessorAt(0);
753 BasicBlock* exception = block->SuccessorAt(1);
754 return VisitCall(input, exception), VisitGoto(success);
755 }
756 case BasicBlock::kTailCall: {
757 DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
758 return VisitTailCall(input);
759 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400760 case BasicBlock::kBranch: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000761 DCHECK_EQ(IrOpcode::kBranch, input->opcode());
762 BasicBlock* tbranch = block->SuccessorAt(0);
763 BasicBlock* fbranch = block->SuccessorAt(1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000764 if (tbranch == fbranch) return VisitGoto(tbranch);
765 return VisitBranch(input, tbranch, fbranch);
766 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000767 case BasicBlock::kSwitch: {
768 DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
769 SwitchInfo sw;
770 // Last successor must be Default.
771 sw.default_branch = block->successors().back();
772 DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode());
773 // All other successors must be cases.
774 sw.case_count = block->SuccessorCount() - 1;
775 sw.case_branches = &block->successors().front();
776 // Determine case values and their min/max.
777 sw.case_values = zone()->NewArray<int32_t>(sw.case_count);
778 sw.min_value = std::numeric_limits<int32_t>::max();
779 sw.max_value = std::numeric_limits<int32_t>::min();
780 for (size_t index = 0; index < sw.case_count; ++index) {
781 BasicBlock* branch = sw.case_branches[index];
782 int32_t value = OpParameter<int32_t>(branch->front()->op());
783 sw.case_values[index] = value;
784 if (sw.min_value > value) sw.min_value = value;
785 if (sw.max_value < value) sw.max_value = value;
786 }
787 DCHECK_LE(sw.min_value, sw.max_value);
788 // Note that {value_range} can be 0 if {min_value} is -2^31 and
789 // {max_value}
790 // is 2^31-1, so don't assume that it's non-zero below.
791 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) -
792 bit_cast<uint32_t>(sw.min_value);
793 return VisitSwitch(input, sw);
794 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400795 case BasicBlock::kReturn: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796 DCHECK_EQ(IrOpcode::kReturn, input->opcode());
797 return VisitReturn(input);
798 }
799 case BasicBlock::kDeoptimize: {
800 DeoptimizeKind kind = DeoptimizeKindOf(input->op());
801 Node* value = input->InputAt(0);
802 return VisitDeoptimize(kind, value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000803 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400804 case BasicBlock::kThrow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805 DCHECK_EQ(IrOpcode::kThrow, input->opcode());
806 return VisitThrow(input->InputAt(0));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400807 case BasicBlock::kNone: {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100808 // Exit block doesn't have control.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000809 DCHECK_NULL(input);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000810 break;
811 }
812 default:
813 UNREACHABLE();
814 break;
815 }
816}
817
818
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000819void InstructionSelector::VisitNode(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400820 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
821 switch (node->opcode()) {
822 case IrOpcode::kStart:
823 case IrOpcode::kLoop:
824 case IrOpcode::kEnd:
825 case IrOpcode::kBranch:
826 case IrOpcode::kIfTrue:
827 case IrOpcode::kIfFalse:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000828 case IrOpcode::kIfSuccess:
829 case IrOpcode::kSwitch:
830 case IrOpcode::kIfValue:
831 case IrOpcode::kIfDefault:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400832 case IrOpcode::kEffectPhi:
833 case IrOpcode::kMerge:
834 case IrOpcode::kTerminate:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000835 case IrOpcode::kBeginRegion:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000836 // No code needed for these graph artifacts.
837 return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000838 case IrOpcode::kIfException:
839 return MarkAsReference(node), VisitIfException(node);
840 case IrOpcode::kFinishRegion:
841 return MarkAsReference(node), VisitFinishRegion(node);
842 case IrOpcode::kGuard:
843 return MarkAsReference(node), VisitGuard(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000844 case IrOpcode::kParameter: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000845 MachineType type =
846 linkage()->GetParameterType(ParameterIndexOf(node->op()));
847 MarkAsRepresentation(type.representation(), node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000848 return VisitParameter(node);
849 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000850 case IrOpcode::kOsrValue:
851 return MarkAsReference(node), VisitOsrValue(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000852 case IrOpcode::kPhi: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000853 MachineRepresentation rep = PhiRepresentationOf(node->op());
854 MarkAsRepresentation(rep, node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000855 return VisitPhi(node);
856 }
857 case IrOpcode::kProjection:
858 return VisitProjection(node);
859 case IrOpcode::kInt32Constant:
860 case IrOpcode::kInt64Constant:
861 case IrOpcode::kExternalConstant:
862 return VisitConstant(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400863 case IrOpcode::kFloat32Constant:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000864 return MarkAsFloat32(node), VisitConstant(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000865 case IrOpcode::kFloat64Constant:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000866 return MarkAsFloat64(node), VisitConstant(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 case IrOpcode::kHeapConstant:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868 return MarkAsReference(node), VisitConstant(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869 case IrOpcode::kNumberConstant: {
870 double value = OpParameter<double>(node);
871 if (!IsSmiDouble(value)) MarkAsReference(node);
872 return VisitConstant(node);
873 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000874 case IrOpcode::kCall:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400875 return VisitCall(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000876 case IrOpcode::kFrameState:
877 case IrOpcode::kStateValues:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000878 case IrOpcode::kObjectState:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000879 return;
880 case IrOpcode::kLoad: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000881 LoadRepresentation type = LoadRepresentationOf(node->op());
882 MarkAsRepresentation(type.representation(), node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883 return VisitLoad(node);
884 }
885 case IrOpcode::kStore:
886 return VisitStore(node);
887 case IrOpcode::kWord32And:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000888 return MarkAsWord32(node), VisitWord32And(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000889 case IrOpcode::kWord32Or:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 return MarkAsWord32(node), VisitWord32Or(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891 case IrOpcode::kWord32Xor:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000892 return MarkAsWord32(node), VisitWord32Xor(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000893 case IrOpcode::kWord32Shl:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000894 return MarkAsWord32(node), VisitWord32Shl(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000895 case IrOpcode::kWord32Shr:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000896 return MarkAsWord32(node), VisitWord32Shr(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000897 case IrOpcode::kWord32Sar:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 return MarkAsWord32(node), VisitWord32Sar(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000899 case IrOpcode::kWord32Ror:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000900 return MarkAsWord32(node), VisitWord32Ror(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000901 case IrOpcode::kWord32Equal:
902 return VisitWord32Equal(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000903 case IrOpcode::kWord32Clz:
904 return MarkAsWord32(node), VisitWord32Clz(node);
905 case IrOpcode::kWord32Ctz:
906 return MarkAsWord32(node), VisitWord32Ctz(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100907 case IrOpcode::kWord32ReverseBits:
908 return MarkAsWord32(node), VisitWord32ReverseBits(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000909 case IrOpcode::kWord32Popcnt:
910 return MarkAsWord32(node), VisitWord32Popcnt(node);
911 case IrOpcode::kWord64Popcnt:
912 return MarkAsWord32(node), VisitWord64Popcnt(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000913 case IrOpcode::kWord64And:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000914 return MarkAsWord64(node), VisitWord64And(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000915 case IrOpcode::kWord64Or:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000916 return MarkAsWord64(node), VisitWord64Or(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000917 case IrOpcode::kWord64Xor:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 return MarkAsWord64(node), VisitWord64Xor(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000919 case IrOpcode::kWord64Shl:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000920 return MarkAsWord64(node), VisitWord64Shl(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000921 case IrOpcode::kWord64Shr:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000922 return MarkAsWord64(node), VisitWord64Shr(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000923 case IrOpcode::kWord64Sar:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 return MarkAsWord64(node), VisitWord64Sar(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000925 case IrOpcode::kWord64Ror:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000926 return MarkAsWord64(node), VisitWord64Ror(node);
927 case IrOpcode::kWord64Clz:
928 return MarkAsWord64(node), VisitWord64Clz(node);
929 case IrOpcode::kWord64Ctz:
930 return MarkAsWord64(node), VisitWord64Ctz(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100931 case IrOpcode::kWord64ReverseBits:
932 return MarkAsWord64(node), VisitWord64ReverseBits(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000933 case IrOpcode::kWord64Equal:
934 return VisitWord64Equal(node);
935 case IrOpcode::kInt32Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000936 return MarkAsWord32(node), VisitInt32Add(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937 case IrOpcode::kInt32AddWithOverflow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000938 return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000939 case IrOpcode::kInt32Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940 return MarkAsWord32(node), VisitInt32Sub(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000941 case IrOpcode::kInt32SubWithOverflow:
942 return VisitInt32SubWithOverflow(node);
943 case IrOpcode::kInt32Mul:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944 return MarkAsWord32(node), VisitInt32Mul(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400945 case IrOpcode::kInt32MulHigh:
946 return VisitInt32MulHigh(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947 case IrOpcode::kInt32Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000948 return MarkAsWord32(node), VisitInt32Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000949 case IrOpcode::kInt32Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 return MarkAsWord32(node), VisitInt32Mod(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951 case IrOpcode::kInt32LessThan:
952 return VisitInt32LessThan(node);
953 case IrOpcode::kInt32LessThanOrEqual:
954 return VisitInt32LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400955 case IrOpcode::kUint32Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000956 return MarkAsWord32(node), VisitUint32Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000957 case IrOpcode::kUint32LessThan:
958 return VisitUint32LessThan(node);
959 case IrOpcode::kUint32LessThanOrEqual:
960 return VisitUint32LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400961 case IrOpcode::kUint32Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000962 return MarkAsWord32(node), VisitUint32Mod(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400963 case IrOpcode::kUint32MulHigh:
964 return VisitUint32MulHigh(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000965 case IrOpcode::kInt64Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 return MarkAsWord64(node), VisitInt64Add(node);
967 case IrOpcode::kInt64AddWithOverflow:
968 return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000969 case IrOpcode::kInt64Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000970 return MarkAsWord64(node), VisitInt64Sub(node);
971 case IrOpcode::kInt64SubWithOverflow:
972 return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000973 case IrOpcode::kInt64Mul:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000974 return MarkAsWord64(node), VisitInt64Mul(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000975 case IrOpcode::kInt64Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000976 return MarkAsWord64(node), VisitInt64Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000977 case IrOpcode::kInt64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000978 return MarkAsWord64(node), VisitInt64Mod(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000979 case IrOpcode::kInt64LessThan:
980 return VisitInt64LessThan(node);
981 case IrOpcode::kInt64LessThanOrEqual:
982 return VisitInt64LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400983 case IrOpcode::kUint64Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984 return MarkAsWord64(node), VisitUint64Div(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400985 case IrOpcode::kUint64LessThan:
986 return VisitUint64LessThan(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000987 case IrOpcode::kUint64LessThanOrEqual:
988 return VisitUint64LessThanOrEqual(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400989 case IrOpcode::kUint64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000990 return MarkAsWord64(node), VisitUint64Mod(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400991 case IrOpcode::kChangeFloat32ToFloat64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000992 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000993 case IrOpcode::kChangeInt32ToFloat64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000994 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000995 case IrOpcode::kChangeUint32ToFloat64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000996 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000997 case IrOpcode::kChangeFloat64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000998 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999 case IrOpcode::kChangeFloat64ToUint32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001000 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001001 case IrOpcode::kTruncateFloat32ToInt32:
1002 return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node);
1003 case IrOpcode::kTruncateFloat32ToUint32:
1004 return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001005 case IrOpcode::kTryTruncateFloat32ToInt64:
1006 return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
1007 case IrOpcode::kTryTruncateFloat64ToInt64:
1008 return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
1009 case IrOpcode::kTryTruncateFloat32ToUint64:
1010 return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
1011 case IrOpcode::kTryTruncateFloat64ToUint64:
1012 return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013 case IrOpcode::kChangeInt32ToInt64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001014 return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001015 case IrOpcode::kChangeUint32ToUint64:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001016 return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001017 case IrOpcode::kTruncateFloat64ToFloat32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001018 return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001019 case IrOpcode::kTruncateFloat64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001020 return MarkAsWord32(node), VisitTruncateFloat64ToInt32(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001021 case IrOpcode::kTruncateInt64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001022 return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
1023 case IrOpcode::kRoundInt64ToFloat32:
1024 return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001025 case IrOpcode::kRoundInt32ToFloat32:
1026 return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001027 case IrOpcode::kRoundInt64ToFloat64:
1028 return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
1029 case IrOpcode::kBitcastFloat32ToInt32:
1030 return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001031 case IrOpcode::kRoundUint32ToFloat32:
1032 return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001033 case IrOpcode::kRoundUint64ToFloat32:
1034 return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
1035 case IrOpcode::kRoundUint64ToFloat64:
1036 return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
1037 case IrOpcode::kBitcastFloat64ToInt64:
1038 return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
1039 case IrOpcode::kBitcastInt32ToFloat32:
1040 return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
1041 case IrOpcode::kBitcastInt64ToFloat64:
1042 return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
1043 case IrOpcode::kFloat32Add:
1044 return MarkAsFloat32(node), VisitFloat32Add(node);
1045 case IrOpcode::kFloat32Sub:
1046 return MarkAsFloat32(node), VisitFloat32Sub(node);
1047 case IrOpcode::kFloat32Mul:
1048 return MarkAsFloat32(node), VisitFloat32Mul(node);
1049 case IrOpcode::kFloat32Div:
1050 return MarkAsFloat32(node), VisitFloat32Div(node);
1051 case IrOpcode::kFloat32Min:
1052 return MarkAsFloat32(node), VisitFloat32Min(node);
1053 case IrOpcode::kFloat32Max:
1054 return MarkAsFloat32(node), VisitFloat32Max(node);
1055 case IrOpcode::kFloat32Abs:
1056 return MarkAsFloat32(node), VisitFloat32Abs(node);
1057 case IrOpcode::kFloat32Sqrt:
1058 return MarkAsFloat32(node), VisitFloat32Sqrt(node);
1059 case IrOpcode::kFloat32Equal:
1060 return VisitFloat32Equal(node);
1061 case IrOpcode::kFloat32LessThan:
1062 return VisitFloat32LessThan(node);
1063 case IrOpcode::kFloat32LessThanOrEqual:
1064 return VisitFloat32LessThanOrEqual(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001065 case IrOpcode::kFloat64Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001066 return MarkAsFloat64(node), VisitFloat64Add(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001067 case IrOpcode::kFloat64Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001068 return MarkAsFloat64(node), VisitFloat64Sub(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001069 case IrOpcode::kFloat64Mul:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 return MarkAsFloat64(node), VisitFloat64Mul(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071 case IrOpcode::kFloat64Div:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001072 return MarkAsFloat64(node), VisitFloat64Div(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001073 case IrOpcode::kFloat64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001074 return MarkAsFloat64(node), VisitFloat64Mod(node);
1075 case IrOpcode::kFloat64Min:
1076 return MarkAsFloat64(node), VisitFloat64Min(node);
1077 case IrOpcode::kFloat64Max:
1078 return MarkAsFloat64(node), VisitFloat64Max(node);
1079 case IrOpcode::kFloat64Abs:
1080 return MarkAsFloat64(node), VisitFloat64Abs(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001081 case IrOpcode::kFloat64Sqrt:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001082 return MarkAsFloat64(node), VisitFloat64Sqrt(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001083 case IrOpcode::kFloat64Equal:
1084 return VisitFloat64Equal(node);
1085 case IrOpcode::kFloat64LessThan:
1086 return VisitFloat64LessThan(node);
1087 case IrOpcode::kFloat64LessThanOrEqual:
1088 return VisitFloat64LessThanOrEqual(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001089 case IrOpcode::kFloat32RoundDown:
1090 return MarkAsFloat32(node), VisitFloat32RoundDown(node);
1091 case IrOpcode::kFloat64RoundDown:
1092 return MarkAsFloat64(node), VisitFloat64RoundDown(node);
1093 case IrOpcode::kFloat32RoundUp:
1094 return MarkAsFloat32(node), VisitFloat32RoundUp(node);
1095 case IrOpcode::kFloat64RoundUp:
1096 return MarkAsFloat64(node), VisitFloat64RoundUp(node);
1097 case IrOpcode::kFloat32RoundTruncate:
1098 return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001099 case IrOpcode::kFloat64RoundTruncate:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001100 return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001101 case IrOpcode::kFloat64RoundTiesAway:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001102 return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
1103 case IrOpcode::kFloat32RoundTiesEven:
1104 return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
1105 case IrOpcode::kFloat64RoundTiesEven:
1106 return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
1107 case IrOpcode::kFloat64ExtractLowWord32:
1108 return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
1109 case IrOpcode::kFloat64ExtractHighWord32:
1110 return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
1111 case IrOpcode::kFloat64InsertLowWord32:
1112 return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
1113 case IrOpcode::kFloat64InsertHighWord32:
1114 return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001115 case IrOpcode::kStackSlot:
1116 return VisitStackSlot(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001117 case IrOpcode::kLoadStackPointer:
1118 return VisitLoadStackPointer(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001119 case IrOpcode::kLoadFramePointer:
1120 return VisitLoadFramePointer(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001121 case IrOpcode::kLoadParentFramePointer:
1122 return VisitLoadParentFramePointer(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001123 case IrOpcode::kCheckedLoad: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001124 MachineRepresentation rep =
1125 CheckedLoadRepresentationOf(node->op()).representation();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001126 MarkAsRepresentation(rep, node);
1127 return VisitCheckedLoad(node);
1128 }
1129 case IrOpcode::kCheckedStore:
1130 return VisitCheckedStore(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001131 default:
1132 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
1133 node->opcode(), node->op()->mnemonic(), node->id());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001134 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001135 }
1136}
1137
1138
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001139void InstructionSelector::VisitLoadStackPointer(Node* node) {
1140 OperandGenerator g(this);
1141 Emit(kArchStackPointer, g.DefineAsRegister(node));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001142}
1143
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001144
1145void InstructionSelector::VisitLoadFramePointer(Node* node) {
1146 OperandGenerator g(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001147 frame_->MarkNeedsFrame();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001148 Emit(kArchFramePointer, g.DefineAsRegister(node));
1149}
1150
Ben Murdoch097c5b22016-05-18 11:27:45 +01001151void InstructionSelector::VisitLoadParentFramePointer(Node* node) {
1152 OperandGenerator g(this);
1153 Emit(kArchParentFramePointer, g.DefineAsRegister(node));
1154}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001155
1156void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw,
1157 InstructionOperand& index_operand) {
1158 OperandGenerator g(this);
1159 size_t input_count = 2 + sw.value_range;
1160 auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1161 inputs[0] = index_operand;
1162 InstructionOperand default_operand = g.Label(sw.default_branch);
1163 std::fill(&inputs[1], &inputs[input_count], default_operand);
1164 for (size_t index = 0; index < sw.case_count; ++index) {
1165 size_t value = sw.case_values[index] - sw.min_value;
1166 BasicBlock* branch = sw.case_branches[index];
1167 DCHECK_LE(0u, value);
1168 DCHECK_LT(value + 2, input_count);
1169 inputs[value + 2] = g.Label(branch);
1170 }
1171 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1172}
1173
1174
1175void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
1176 InstructionOperand& value_operand) {
1177 OperandGenerator g(this);
1178 size_t input_count = 2 + sw.case_count * 2;
1179 auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1180 inputs[0] = value_operand;
1181 inputs[1] = g.Label(sw.default_branch);
1182 for (size_t index = 0; index < sw.case_count; ++index) {
1183 int32_t value = sw.case_values[index];
1184 BasicBlock* branch = sw.case_branches[index];
1185 inputs[index * 2 + 2 + 0] = g.TempImmediate(value);
1186 inputs[index * 2 + 2 + 1] = g.Label(branch);
1187 }
1188 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1189}
1190
Ben Murdoch097c5b22016-05-18 11:27:45 +01001191void InstructionSelector::VisitStackSlot(Node* node) {
1192 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op()));
1193 int slot = frame_->AllocateSpillSlot(size);
1194 OperandGenerator g(this);
1195
1196 Emit(kArchStackSlot, g.DefineAsRegister(node),
1197 sequence()->AddImmediate(Constant(slot)), 0, nullptr);
1198}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001199
1200// 32 bit targets do not implement the following instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001201#if V8_TARGET_ARCH_32_BIT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001202
1203void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
1204
1205
1206void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
1207
1208
1209void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
1210
1211
1212void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
1213
1214
1215void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
1216
1217
1218void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
1219
1220
1221void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
1222
1223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
1225
1226
1227void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
1228
1229
Ben Murdoch097c5b22016-05-18 11:27:45 +01001230void InstructionSelector::VisitWord64ReverseBits(Node* node) {
1231 UNIMPLEMENTED();
1232}
1233
1234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001235void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
1236
1237
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001238void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
1239
1240
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001241void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
1242
1243
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001244void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
1245 UNIMPLEMENTED();
1246}
1247
1248
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001249void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
1250
1251
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001252void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
1253 UNIMPLEMENTED();
1254}
1255
1256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001257void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
1258
1259
1260void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
1261
1262
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001263void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
1264
1265
1266void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
1267 UNIMPLEMENTED();
1268}
1269
1270
1271void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001272
1273
1274void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
1275
1276
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001277void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
1278
1279
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001280void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
1281 UNIMPLEMENTED();
1282}
1283
1284
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001285void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001286
1287
1288void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
1289 UNIMPLEMENTED();
1290}
1291
1292
1293void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
1294 UNIMPLEMENTED();
1295}
1296
1297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001298void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
1299 UNIMPLEMENTED();
1300}
1301
1302
1303void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
1304 UNIMPLEMENTED();
1305}
1306
1307
1308void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
1309 UNIMPLEMENTED();
1310}
1311
1312
1313void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
1314 UNIMPLEMENTED();
1315}
1316
1317
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001318void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
1319 UNIMPLEMENTED();
1320}
1321
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001322
1323void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
1324 UNIMPLEMENTED();
1325}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001326
1327
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001328void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
1329 UNIMPLEMENTED();
1330}
1331
1332
1333void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
1334 UNIMPLEMENTED();
1335}
1336
1337
1338void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
1339 UNIMPLEMENTED();
1340}
1341
1342
1343void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
1344 UNIMPLEMENTED();
1345}
1346
1347
1348void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
1349 UNIMPLEMENTED();
1350}
1351
1352#endif // V8_TARGET_ARCH_32_BIT
1353
1354
1355void InstructionSelector::VisitFinishRegion(Node* node) {
1356 OperandGenerator g(this);
1357 Node* value = node->InputAt(0);
1358 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1359}
1360
1361
1362void InstructionSelector::VisitGuard(Node* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001363 OperandGenerator g(this);
1364 Node* value = node->InputAt(0);
1365 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1366}
1367
1368
1369void InstructionSelector::VisitParameter(Node* node) {
1370 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001371 int index = ParameterIndexOf(node->op());
1372 InstructionOperand op =
1373 linkage()->ParameterHasSecondaryLocation(index)
1374 ? g.DefineAsDualLocation(
1375 node, linkage()->GetParameterLocation(index),
1376 linkage()->GetParameterSecondaryLocation(index))
1377 : g.DefineAsLocation(
1378 node, linkage()->GetParameterLocation(index),
1379 linkage()->GetParameterType(index).representation());
1380
1381 Emit(kArchNop, op);
1382}
1383
1384
1385void InstructionSelector::VisitIfException(Node* node) {
1386 OperandGenerator g(this);
1387 Node* call = node->InputAt(1);
1388 DCHECK_EQ(IrOpcode::kCall, call->opcode());
1389 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(call);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001390 Emit(kArchNop,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001391 g.DefineAsLocation(node, descriptor->GetReturnLocation(0),
1392 descriptor->GetReturnType(0).representation()));
1393}
1394
1395
1396void InstructionSelector::VisitOsrValue(Node* node) {
1397 OperandGenerator g(this);
1398 int index = OpParameter<int>(node);
1399 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index),
1400 MachineRepresentation::kTagged));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001401}
1402
1403
1404void InstructionSelector::VisitPhi(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001405 const int input_count = node->op()->ValueInputCount();
1406 PhiInstruction* phi = new (instruction_zone())
1407 PhiInstruction(instruction_zone(), GetVirtualRegister(node),
1408 static_cast<size_t>(input_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001409 sequence()
1410 ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
1411 ->AddPhi(phi);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001412 for (int i = 0; i < input_count; ++i) {
1413 Node* const input = node->InputAt(i);
1414 MarkAsUsed(input);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001415 phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001416 }
1417}
1418
1419
1420void InstructionSelector::VisitProjection(Node* node) {
1421 OperandGenerator g(this);
1422 Node* value = node->InputAt(0);
1423 switch (value->opcode()) {
1424 case IrOpcode::kInt32AddWithOverflow:
1425 case IrOpcode::kInt32SubWithOverflow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001426 case IrOpcode::kInt64AddWithOverflow:
1427 case IrOpcode::kInt64SubWithOverflow:
1428 case IrOpcode::kTryTruncateFloat32ToInt64:
1429 case IrOpcode::kTryTruncateFloat64ToInt64:
1430 case IrOpcode::kTryTruncateFloat32ToUint64:
1431 case IrOpcode::kTryTruncateFloat64ToUint64:
1432 if (ProjectionIndexOf(node->op()) == 0u) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001433 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1434 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001435 DCHECK(ProjectionIndexOf(node->op()) == 1u);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001436 MarkAsUsed(value);
1437 }
1438 break;
1439 default:
1440 break;
1441 }
1442}
1443
1444
1445void InstructionSelector::VisitConstant(Node* node) {
1446 // We must emit a NOP here because every live range needs a defining
1447 // instruction in the register allocator.
1448 OperandGenerator g(this);
1449 Emit(kArchNop, g.DefineAsConstant(node));
1450}
1451
1452
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001453void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001454 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001455 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
1456
1457 FrameStateDescriptor* frame_state_descriptor = nullptr;
1458 if (descriptor->NeedsFrameState()) {
1459 frame_state_descriptor = GetFrameStateDescriptor(
1460 node->InputAt(static_cast<int>(descriptor->InputCount())));
1461 }
1462
1463 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
1464
1465 // Compute InstructionOperands for inputs and outputs.
1466 // TODO(turbofan): on some architectures it's probably better to use
1467 // the code object in a register if there are multiple uses of it.
1468 // Improve constant pool and the heuristics in the register allocator
1469 // for where to emit constants.
1470 CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
1471 InitializeCallBuffer(node, &buffer, call_buffer_flags);
1472
1473 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
1474
1475 // Pass label of exception handler block.
1476 CallDescriptor::Flags flags = descriptor->flags();
1477 if (handler) {
1478 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
1479 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front());
1480 if (hint == IfExceptionHint::kLocallyCaught) {
1481 flags |= CallDescriptor::kHasLocalCatchHandler;
1482 }
1483 flags |= CallDescriptor::kHasExceptionHandler;
1484 buffer.instruction_args.push_back(g.Label(handler));
1485 }
1486
Ben Murdoch097c5b22016-05-18 11:27:45 +01001487 // (arm64 only) caller uses JSSP but callee might destroy it.
1488 if (descriptor->UseNativeStack() &&
1489 !linkage()->GetIncomingDescriptor()->UseNativeStack()) {
1490 flags |= CallDescriptor::kRestoreJSSP;
1491 }
1492
1493
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001494 // Select the appropriate opcode based on the call type.
1495 InstructionCode opcode = kArchNop;
1496 switch (descriptor->kind()) {
1497 case CallDescriptor::kCallAddress:
1498 opcode =
1499 kArchCallCFunction |
1500 MiscField::encode(static_cast<int>(descriptor->CParameterCount()));
1501 break;
1502 case CallDescriptor::kCallCodeObject:
1503 opcode = kArchCallCodeObject | MiscField::encode(flags);
1504 break;
1505 case CallDescriptor::kCallJSFunction:
1506 opcode = kArchCallJSFunction | MiscField::encode(flags);
1507 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001508 }
1509
1510 // Emit the call instruction.
1511 size_t const output_count = buffer.outputs.size();
1512 auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
1513 Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
1514 &buffer.instruction_args.front())
1515 ->MarkAsCall();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001516}
1517
1518
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001519void InstructionSelector::VisitTailCall(Node* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001520 OperandGenerator g(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001521 CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node);
1522 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls);
1523 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite);
1524 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall);
1525
1526 // TODO(turbofan): Relax restriction for stack parameters.
1527
1528 int stack_param_delta = 0;
1529 if (linkage()->GetIncomingDescriptor()->CanTailCall(node,
1530 &stack_param_delta)) {
1531 CallBuffer buffer(zone(), descriptor, nullptr);
1532
1533 // Compute InstructionOperands for inputs and outputs.
1534 CallBufferFlags flags(kCallCodeImmediate | kCallTail);
1535 if (IsTailCallAddressImmediate()) {
1536 flags |= kCallAddressImmediate;
1537 }
1538 InitializeCallBuffer(node, &buffer, flags, stack_param_delta);
1539
1540 // Select the appropriate opcode based on the call type.
1541 InstructionCode opcode;
1542 switch (descriptor->kind()) {
1543 case CallDescriptor::kCallCodeObject:
1544 opcode = kArchTailCallCodeObject;
1545 break;
1546 case CallDescriptor::kCallJSFunction:
1547 opcode = kArchTailCallJSFunction;
1548 break;
1549 default:
1550 UNREACHABLE();
1551 return;
1552 }
1553 opcode |= MiscField::encode(descriptor->flags());
1554
1555 buffer.instruction_args.push_back(g.TempImmediate(stack_param_delta));
1556
1557 Emit(kArchPrepareTailCall, g.NoOutput(),
1558 g.TempImmediate(stack_param_delta));
1559
1560 // Emit the tailcall instruction.
1561 Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
1562 &buffer.instruction_args.front());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001563 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001564 FrameStateDescriptor* frame_state_descriptor =
1565 descriptor->NeedsFrameState()
1566 ? GetFrameStateDescriptor(
1567 node->InputAt(static_cast<int>(descriptor->InputCount())))
1568 : nullptr;
1569
1570 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
1571
1572 // Compute InstructionOperands for inputs and outputs.
1573 CallBufferFlags flags = kCallCodeImmediate;
1574 if (IsTailCallAddressImmediate()) {
1575 flags |= kCallAddressImmediate;
1576 }
1577 InitializeCallBuffer(node, &buffer, flags);
1578
1579 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
1580
1581 // Select the appropriate opcode based on the call type.
1582 InstructionCode opcode;
1583 switch (descriptor->kind()) {
1584 case CallDescriptor::kCallCodeObject:
1585 opcode = kArchCallCodeObject;
1586 break;
1587 case CallDescriptor::kCallJSFunction:
1588 opcode = kArchCallJSFunction;
1589 break;
1590 default:
1591 UNREACHABLE();
1592 return;
1593 }
1594 opcode |= MiscField::encode(descriptor->flags());
1595
1596 // Emit the call instruction.
1597 size_t output_count = buffer.outputs.size();
1598 auto* outputs = &buffer.outputs.front();
1599 Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
1600 &buffer.instruction_args.front())
1601 ->MarkAsCall();
1602 Emit(kArchRet, 0, nullptr, output_count, outputs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001603 }
1604}
1605
1606
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001607void InstructionSelector::VisitGoto(BasicBlock* target) {
1608 // jump to the next block.
1609 OperandGenerator g(this);
1610 Emit(kArchJmp, g.NoOutput(), g.Label(target));
1611}
1612
1613
1614void InstructionSelector::VisitReturn(Node* ret) {
1615 OperandGenerator g(this);
1616 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) {
1617 Emit(kArchRet, g.NoOutput());
1618 } else {
1619 const int ret_count = ret->op()->ValueInputCount();
1620 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count);
1621 for (int i = 0; i < ret_count; ++i) {
1622 value_locations[i] =
1623 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i),
1624 linkage()->GetReturnType(i).representation());
1625 }
1626 Emit(kArchRet, 0, nullptr, ret_count, value_locations);
1627 }
1628}
1629
1630
1631void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) {
1632 OperandGenerator g(this);
1633
1634 FrameStateDescriptor* desc = GetFrameStateDescriptor(value);
1635
1636 InstructionOperandVector args(instruction_zone());
1637 args.reserve(desc->GetTotalSize() + 1); // Include deopt id.
1638
1639 InstructionSequence::StateId state_id =
1640 sequence()->AddFrameStateDescriptor(desc);
1641 args.push_back(g.TempImmediate(state_id.ToInt()));
1642
1643 StateObjectDeduplicator deduplicator(instruction_zone());
1644
1645 AddInputsToFrameStateDescriptor(desc, value, &g, &deduplicator, &args,
1646 FrameStateInputKind::kAny,
1647 instruction_zone());
1648
1649 InstructionCode opcode = kArchDeoptimize;
1650 switch (kind) {
1651 case DeoptimizeKind::kEager:
1652 opcode |= MiscField::encode(Deoptimizer::EAGER);
1653 break;
1654 case DeoptimizeKind::kSoft:
1655 opcode |= MiscField::encode(Deoptimizer::SOFT);
1656 break;
1657 }
1658 Emit(opcode, 0, nullptr, args.size(), &args.front(), 0, nullptr);
1659}
1660
1661
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001662void InstructionSelector::VisitThrow(Node* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001663 OperandGenerator g(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001664 Emit(kArchThrowTerminator, g.NoOutput());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001665}
1666
1667
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001668FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
1669 Node* state) {
1670 DCHECK(state->opcode() == IrOpcode::kFrameState);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001671 DCHECK_EQ(kFrameStateInputCount, state->InputCount());
1672 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001673
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001674 int parameters = static_cast<int>(
1675 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size());
1676 int locals = static_cast<int>(
1677 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size());
1678 int stack = static_cast<int>(
1679 StateValuesAccess(state->InputAt(kFrameStateStackInput)).size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001680
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001681 DCHECK_EQ(parameters, state_info.parameter_count());
1682 DCHECK_EQ(locals, state_info.local_count());
1683
1684 FrameStateDescriptor* outer_state = nullptr;
1685 Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001686 if (outer_node->opcode() == IrOpcode::kFrameState) {
1687 outer_state = GetFrameStateDescriptor(outer_node);
1688 }
1689
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001690 return new (instruction_zone()) FrameStateDescriptor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 instruction_zone(), state_info.type(), state_info.bailout_id(),
1692 state_info.state_combine(), parameters, locals, stack,
1693 state_info.shared_info(), outer_state);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001694}
1695
1696
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001697} // namespace compiler
1698} // namespace internal
1699} // namespace v8