1// 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/raw-machine-assembler.h"
6
7#include "src/code-factory.h"
8#include "src/compiler/node-properties.h"
9#include "src/compiler/pipeline.h"
10#include "src/compiler/scheduler.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
16RawMachineAssembler::RawMachineAssembler(
17    Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
18    MachineRepresentation word, MachineOperatorBuilder::Flags flags,
19    MachineOperatorBuilder::AlignmentRequirements alignment_requirements)
20    : isolate_(isolate),
21      graph_(graph),
22      schedule_(new (zone()) Schedule(zone())),
23      machine_(zone(), word, flags, alignment_requirements),
24      common_(zone()),
25      call_descriptor_(call_descriptor),
26      parameters_(parameter_count(), zone()),
27      current_block_(schedule()->start()) {
28  int param_count = static_cast<int>(parameter_count());
29  // Add an extra input for the JSFunction parameter to the start node.
30  graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
31  for (size_t i = 0; i < parameter_count(); ++i) {
32    parameters_[i] =
33        AddNode(common()->Parameter(static_cast<int>(i)), graph->start());
34  }
35  graph->SetEnd(graph->NewNode(common_.End(0)));
36}
37
38Node* RawMachineAssembler::RelocatableIntPtrConstant(intptr_t value,
39                                                     RelocInfo::Mode rmode) {
40  return kPointerSize == 8
41             ? RelocatableInt64Constant(value, rmode)
42             : RelocatableInt32Constant(static_cast<int>(value), rmode);
43}
44
45Schedule* RawMachineAssembler::Export() {
46  // Compute the correct codegen order.
47  DCHECK(schedule_->rpo_order()->empty());
48  OFStream os(stdout);
49  if (FLAG_trace_turbo_scheduler) {
50    PrintF("--- RAW SCHEDULE -------------------------------------------\n");
51    os << *schedule_;
52  }
53  schedule_->EnsureCFGWellFormedness();
54  schedule_->PropagateDeferredMark();
55  if (FLAG_trace_turbo_scheduler) {
56    PrintF("--- EDGE SPLIT AND PROPAGATED DEFERRED SCHEDULE ------------\n");
57    os << *schedule_;
58  }
59  Scheduler::ComputeSpecialRPO(zone(), schedule_);
60  // Invalidate RawMachineAssembler.
61  Schedule* schedule = schedule_;
62  schedule_ = nullptr;
63  return schedule;
64}
65
66
67Node* RawMachineAssembler::Parameter(size_t index) {
68  DCHECK(index < parameter_count());
69  return parameters_[index];
70}
71
72
73void RawMachineAssembler::Goto(RawMachineLabel* label) {
74  DCHECK(current_block_ != schedule()->end());
75  schedule()->AddGoto(CurrentBlock(), Use(label));
76  current_block_ = nullptr;
77}
78
79
80void RawMachineAssembler::Branch(Node* condition, RawMachineLabel* true_val,
81                                 RawMachineLabel* false_val) {
82  DCHECK(current_block_ != schedule()->end());
83  Node* branch = MakeNode(common()->Branch(), 1, &condition);
84  schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val));
85  current_block_ = nullptr;
86}
87
88void RawMachineAssembler::Continuations(Node* call, RawMachineLabel* if_success,
89                                        RawMachineLabel* if_exception) {
90  DCHECK_NOT_NULL(schedule_);
91  DCHECK_NOT_NULL(current_block_);
92  schedule()->AddCall(CurrentBlock(), call, Use(if_success), Use(if_exception));
93  current_block_ = nullptr;
94}
95
96void RawMachineAssembler::Switch(Node* index, RawMachineLabel* default_label,
97                                 const int32_t* case_values,
98                                 RawMachineLabel** case_labels,
99                                 size_t case_count) {
100  DCHECK_NE(schedule()->end(), current_block_);
101  size_t succ_count = case_count + 1;
102  Node* switch_node = AddNode(common()->Switch(succ_count), index);
103  BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count);
104  for (size_t index = 0; index < case_count; ++index) {
105    int32_t case_value = case_values[index];
106    BasicBlock* case_block = schedule()->NewBasicBlock();
107    Node* case_node =
108        graph()->NewNode(common()->IfValue(case_value), switch_node);
109    schedule()->AddNode(case_block, case_node);
110    schedule()->AddGoto(case_block, Use(case_labels[index]));
111    succ_blocks[index] = case_block;
112  }
113  BasicBlock* default_block = schedule()->NewBasicBlock();
114  Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node);
115  schedule()->AddNode(default_block, default_node);
116  schedule()->AddGoto(default_block, Use(default_label));
117  succ_blocks[case_count] = default_block;
118  schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count);
119  current_block_ = nullptr;
120}
121
122void RawMachineAssembler::Return(Node* value) {
123  Node* values[] = {Int32Constant(0), value};
124  Node* ret = MakeNode(common()->Return(1), 2, values);
125  schedule()->AddReturn(CurrentBlock(), ret);
126  current_block_ = nullptr;
127}
128
129
130void RawMachineAssembler::Return(Node* v1, Node* v2) {
131  Node* values[] = {Int32Constant(0), v1, v2};
132  Node* ret = MakeNode(common()->Return(2), 3, values);
133  schedule()->AddReturn(CurrentBlock(), ret);
134  current_block_ = nullptr;
135}
136
137
138void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) {
139  Node* values[] = {Int32Constant(0), v1, v2, v3};
140  Node* ret = MakeNode(common()->Return(3), 4, values);
141  schedule()->AddReturn(CurrentBlock(), ret);
142  current_block_ = nullptr;
143}
144
145void RawMachineAssembler::PopAndReturn(Node* pop, Node* value) {
146  Node* values[] = {pop, value};
147  Node* ret = MakeNode(common()->Return(1), 2, values);
148  schedule()->AddReturn(CurrentBlock(), ret);
149  current_block_ = nullptr;
150}
151
152void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2) {
153  Node* values[] = {pop, v1, v2};
154  Node* ret = MakeNode(common()->Return(2), 3, values);
155  schedule()->AddReturn(CurrentBlock(), ret);
156  current_block_ = nullptr;
157}
158
159void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2,
160                                       Node* v3) {
161  Node* values[] = {pop, v1, v2, v3};
162  Node* ret = MakeNode(common()->Return(3), 4, values);
163  schedule()->AddReturn(CurrentBlock(), ret);
164  current_block_ = nullptr;
165}
166
167void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); }
168
169void RawMachineAssembler::Comment(const char* msg) {
170  AddNode(machine()->Comment(msg));
171}
172
173Node* RawMachineAssembler::CallN(CallDescriptor* desc, Node* function,
174                                 Node** args) {
175  int param_count = static_cast<int>(desc->ParameterCount());
176  int input_count = param_count + 1;
177  Node** buffer = zone()->NewArray<Node*>(input_count);
178  int index = 0;
179  buffer[index++] = function;
180  for (int i = 0; i < param_count; i++) {
181    buffer[index++] = args[i];
182  }
183  return AddNode(common()->Call(desc), input_count, buffer);
184}
185
186
187Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* desc,
188                                               Node* function, Node** args,
189                                               Node* frame_state) {
190  DCHECK(desc->NeedsFrameState());
191  int param_count = static_cast<int>(desc->ParameterCount());
192  int input_count = param_count + 2;
193  Node** buffer = zone()->NewArray<Node*>(input_count);
194  int index = 0;
195  buffer[index++] = function;
196  for (int i = 0; i < param_count; i++) {
197    buffer[index++] = args[i];
198  }
199  buffer[index++] = frame_state;
200  return AddNode(common()->Call(desc), input_count, buffer);
201}
202
203Node* RawMachineAssembler::CallRuntime0(Runtime::FunctionId function,
204                                        Node* context) {
205  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
206      zone(), function, 0, Operator::kNoProperties, CallDescriptor::kNoFlags);
207  int return_count = static_cast<int>(descriptor->ReturnCount());
208
209  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
210  Node* ref = AddNode(
211      common()->ExternalConstant(ExternalReference(function, isolate())));
212  Node* arity = Int32Constant(0);
213
214  return AddNode(common()->Call(descriptor), centry, ref, arity, context);
215}
216
217Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function,
218                                        Node* arg1, Node* context) {
219  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
220      zone(), function, 1, Operator::kNoProperties, CallDescriptor::kNoFlags);
221  int return_count = static_cast<int>(descriptor->ReturnCount());
222
223  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
224  Node* ref = AddNode(
225      common()->ExternalConstant(ExternalReference(function, isolate())));
226  Node* arity = Int32Constant(1);
227
228  return AddNode(common()->Call(descriptor), centry, arg1, ref, arity, context);
229}
230
231
232Node* RawMachineAssembler::CallRuntime2(Runtime::FunctionId function,
233                                        Node* arg1, Node* arg2, Node* context) {
234  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
235      zone(), function, 2, Operator::kNoProperties, CallDescriptor::kNoFlags);
236  int return_count = static_cast<int>(descriptor->ReturnCount());
237
238  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
239  Node* ref = AddNode(
240      common()->ExternalConstant(ExternalReference(function, isolate())));
241  Node* arity = Int32Constant(2);
242
243  return AddNode(common()->Call(descriptor), centry, arg1, arg2, ref, arity,
244                 context);
245}
246
247Node* RawMachineAssembler::CallRuntime3(Runtime::FunctionId function,
248                                        Node* arg1, Node* arg2, Node* arg3,
249                                        Node* context) {
250  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
251      zone(), function, 3, Operator::kNoProperties, CallDescriptor::kNoFlags);
252  int return_count = static_cast<int>(descriptor->ReturnCount());
253
254  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
255  Node* ref = AddNode(
256      common()->ExternalConstant(ExternalReference(function, isolate())));
257  Node* arity = Int32Constant(3);
258
259  return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, ref,
260                 arity, context);
261}
262
263Node* RawMachineAssembler::CallRuntime4(Runtime::FunctionId function,
264                                        Node* arg1, Node* arg2, Node* arg3,
265                                        Node* arg4, Node* context) {
266  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
267      zone(), function, 4, Operator::kNoProperties, CallDescriptor::kNoFlags);
268  int return_count = static_cast<int>(descriptor->ReturnCount());
269
270  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
271  Node* ref = AddNode(
272      common()->ExternalConstant(ExternalReference(function, isolate())));
273  Node* arity = Int32Constant(4);
274
275  return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, arg4,
276                 ref, arity, context);
277}
278
279Node* RawMachineAssembler::CallRuntime5(Runtime::FunctionId function,
280                                        Node* arg1, Node* arg2, Node* arg3,
281                                        Node* arg4, Node* arg5, Node* context) {
282  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
283      zone(), function, 5, Operator::kNoProperties, CallDescriptor::kNoFlags);
284  int return_count = static_cast<int>(descriptor->ReturnCount());
285
286  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
287  Node* ref = AddNode(
288      common()->ExternalConstant(ExternalReference(function, isolate())));
289  Node* arity = Int32Constant(5);
290
291  return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, arg4,
292                 arg5, ref, arity, context);
293}
294
295Node* RawMachineAssembler::TailCallN(CallDescriptor* desc, Node* function,
296                                     Node** args) {
297  int param_count = static_cast<int>(desc->ParameterCount());
298  int input_count = param_count + 1;
299  Node** buffer = zone()->NewArray<Node*>(input_count);
300  int index = 0;
301  buffer[index++] = function;
302  for (int i = 0; i < param_count; i++) {
303    buffer[index++] = args[i];
304  }
305  Node* tail_call = MakeNode(common()->TailCall(desc), input_count, buffer);
306  schedule()->AddTailCall(CurrentBlock(), tail_call);
307  current_block_ = nullptr;
308  return tail_call;
309}
310
311Node* RawMachineAssembler::TailCallRuntime0(Runtime::FunctionId function,
312                                            Node* context) {
313  const int kArity = 0;
314  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
315      zone(), function, kArity, Operator::kNoProperties,
316      CallDescriptor::kSupportsTailCalls);
317  int return_count = static_cast<int>(desc->ReturnCount());
318
319  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
320  Node* ref = AddNode(
321      common()->ExternalConstant(ExternalReference(function, isolate())));
322  Node* arity = Int32Constant(kArity);
323
324  Node* nodes[] = {centry, ref, arity, context};
325  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
326
327  schedule()->AddTailCall(CurrentBlock(), tail_call);
328  current_block_ = nullptr;
329  return tail_call;
330}
331
332Node* RawMachineAssembler::TailCallRuntime1(Runtime::FunctionId function,
333                                            Node* arg1, Node* context) {
334  const int kArity = 1;
335  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
336      zone(), function, kArity, Operator::kNoProperties,
337      CallDescriptor::kSupportsTailCalls);
338  int return_count = static_cast<int>(desc->ReturnCount());
339
340  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
341  Node* ref = AddNode(
342      common()->ExternalConstant(ExternalReference(function, isolate())));
343  Node* arity = Int32Constant(kArity);
344
345  Node* nodes[] = {centry, arg1, ref, arity, context};
346  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
347
348  schedule()->AddTailCall(CurrentBlock(), tail_call);
349  current_block_ = nullptr;
350  return tail_call;
351}
352
353
354Node* RawMachineAssembler::TailCallRuntime2(Runtime::FunctionId function,
355                                            Node* arg1, Node* arg2,
356                                            Node* context) {
357  const int kArity = 2;
358  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
359      zone(), function, kArity, Operator::kNoProperties,
360      CallDescriptor::kSupportsTailCalls);
361  int return_count = static_cast<int>(desc->ReturnCount());
362
363  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
364  Node* ref = AddNode(
365      common()->ExternalConstant(ExternalReference(function, isolate())));
366  Node* arity = Int32Constant(kArity);
367
368  Node* nodes[] = {centry, arg1, arg2, ref, arity, context};
369  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
370
371  schedule()->AddTailCall(CurrentBlock(), tail_call);
372  current_block_ = nullptr;
373  return tail_call;
374}
375
376Node* RawMachineAssembler::TailCallRuntime3(Runtime::FunctionId function,
377                                            Node* arg1, Node* arg2, Node* arg3,
378                                            Node* context) {
379  const int kArity = 3;
380  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
381      zone(), function, kArity, Operator::kNoProperties,
382      CallDescriptor::kSupportsTailCalls);
383  int return_count = static_cast<int>(desc->ReturnCount());
384
385  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
386  Node* ref = AddNode(
387      common()->ExternalConstant(ExternalReference(function, isolate())));
388  Node* arity = Int32Constant(kArity);
389
390  Node* nodes[] = {centry, arg1, arg2, arg3, ref, arity, context};
391  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
392
393  schedule()->AddTailCall(CurrentBlock(), tail_call);
394  current_block_ = nullptr;
395  return tail_call;
396}
397
398Node* RawMachineAssembler::TailCallRuntime4(Runtime::FunctionId function,
399                                            Node* arg1, Node* arg2, Node* arg3,
400                                            Node* arg4, Node* context) {
401  const int kArity = 4;
402  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
403      zone(), function, kArity, Operator::kNoProperties,
404      CallDescriptor::kSupportsTailCalls);
405  int return_count = static_cast<int>(desc->ReturnCount());
406
407  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
408  Node* ref = AddNode(
409      common()->ExternalConstant(ExternalReference(function, isolate())));
410  Node* arity = Int32Constant(kArity);
411
412  Node* nodes[] = {centry, arg1, arg2, arg3, arg4, ref, arity, context};
413  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
414
415  schedule()->AddTailCall(CurrentBlock(), tail_call);
416  current_block_ = nullptr;
417  return tail_call;
418}
419
420Node* RawMachineAssembler::TailCallRuntime5(Runtime::FunctionId function,
421                                            Node* arg1, Node* arg2, Node* arg3,
422                                            Node* arg4, Node* arg5,
423                                            Node* context) {
424  const int kArity = 5;
425  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
426      zone(), function, kArity, Operator::kNoProperties,
427      CallDescriptor::kSupportsTailCalls);
428  int return_count = static_cast<int>(desc->ReturnCount());
429
430  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
431  Node* ref = AddNode(
432      common()->ExternalConstant(ExternalReference(function, isolate())));
433  Node* arity = Int32Constant(kArity);
434
435  Node* nodes[] = {centry, arg1, arg2, arg3, arg4, arg5, ref, arity, context};
436  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
437
438  schedule()->AddTailCall(CurrentBlock(), tail_call);
439  current_block_ = nullptr;
440  return tail_call;
441}
442
443Node* RawMachineAssembler::TailCallRuntime6(Runtime::FunctionId function,
444                                            Node* arg1, Node* arg2, Node* arg3,
445                                            Node* arg4, Node* arg5, Node* arg6,
446                                            Node* context) {
447  const int kArity = 6;
448  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
449      zone(), function, kArity, Operator::kNoProperties,
450      CallDescriptor::kSupportsTailCalls);
451  int return_count = static_cast<int>(desc->ReturnCount());
452
453  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
454  Node* ref = AddNode(
455      common()->ExternalConstant(ExternalReference(function, isolate())));
456  Node* arity = Int32Constant(kArity);
457
458  Node* nodes[] = {centry, arg1, arg2, arg3,  arg4,
459                   arg5,   arg6, ref,  arity, context};
460  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
461
462  schedule()->AddTailCall(CurrentBlock(), tail_call);
463  current_block_ = nullptr;
464  return tail_call;
465}
466
467Node* RawMachineAssembler::CallCFunction0(MachineType return_type,
468                                          Node* function) {
469  MachineSignature::Builder builder(zone(), 1, 0);
470  builder.AddReturn(return_type);
471  const CallDescriptor* descriptor =
472      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
473
474  return AddNode(common()->Call(descriptor), function);
475}
476
477
478Node* RawMachineAssembler::CallCFunction1(MachineType return_type,
479                                          MachineType arg0_type, Node* function,
480                                          Node* arg0) {
481  MachineSignature::Builder builder(zone(), 1, 1);
482  builder.AddReturn(return_type);
483  builder.AddParam(arg0_type);
484  const CallDescriptor* descriptor =
485      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
486
487  return AddNode(common()->Call(descriptor), function, arg0);
488}
489
490
491Node* RawMachineAssembler::CallCFunction2(MachineType return_type,
492                                          MachineType arg0_type,
493                                          MachineType arg1_type, Node* function,
494                                          Node* arg0, Node* arg1) {
495  MachineSignature::Builder builder(zone(), 1, 2);
496  builder.AddReturn(return_type);
497  builder.AddParam(arg0_type);
498  builder.AddParam(arg1_type);
499  const CallDescriptor* descriptor =
500      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
501
502  return AddNode(common()->Call(descriptor), function, arg0, arg1);
503}
504
505
506Node* RawMachineAssembler::CallCFunction8(
507    MachineType return_type, MachineType arg0_type, MachineType arg1_type,
508    MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
509    MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
510    Node* function, Node* arg0, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
511    Node* arg5, Node* arg6, Node* arg7) {
512  MachineSignature::Builder builder(zone(), 1, 8);
513  builder.AddReturn(return_type);
514  builder.AddParam(arg0_type);
515  builder.AddParam(arg1_type);
516  builder.AddParam(arg2_type);
517  builder.AddParam(arg3_type);
518  builder.AddParam(arg4_type);
519  builder.AddParam(arg5_type);
520  builder.AddParam(arg6_type);
521  builder.AddParam(arg7_type);
522  Node* args[] = {function, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
523  const CallDescriptor* descriptor =
524      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
525  return AddNode(common()->Call(descriptor), arraysize(args), args);
526}
527
528
529void RawMachineAssembler::Bind(RawMachineLabel* label) {
530  DCHECK(current_block_ == nullptr);
531  DCHECK(!label->bound_);
532  label->bound_ = true;
533  current_block_ = EnsureBlock(label);
534  current_block_->set_deferred(label->deferred_);
535}
536
537
538BasicBlock* RawMachineAssembler::Use(RawMachineLabel* label) {
539  label->used_ = true;
540  return EnsureBlock(label);
541}
542
543
544BasicBlock* RawMachineAssembler::EnsureBlock(RawMachineLabel* label) {
545  if (label->block_ == nullptr) label->block_ = schedule()->NewBasicBlock();
546  return label->block_;
547}
548
549
550BasicBlock* RawMachineAssembler::CurrentBlock() {
551  DCHECK(current_block_);
552  return current_block_;
553}
554
555Node* RawMachineAssembler::Phi(MachineRepresentation rep, int input_count,
556                               Node* const* inputs) {
557  Node** buffer = new (zone()->New(sizeof(Node*) * (input_count + 1)))
558      Node*[input_count + 1];
559  std::copy(inputs, inputs + input_count, buffer);
560  buffer[input_count] = graph()->start();
561  return AddNode(common()->Phi(rep, input_count), input_count + 1, buffer);
562}
563
564void RawMachineAssembler::AppendPhiInput(Node* phi, Node* new_input) {
565  const Operator* op = phi->op();
566  const Operator* new_op = common()->ResizeMergeOrPhi(op, phi->InputCount());
567  phi->InsertInput(zone(), phi->InputCount() - 1, new_input);
568  NodeProperties::ChangeOp(phi, new_op);
569}
570
571Node* RawMachineAssembler::AddNode(const Operator* op, int input_count,
572                                   Node* const* inputs) {
573  DCHECK_NOT_NULL(schedule_);
574  DCHECK_NOT_NULL(current_block_);
575  Node* node = MakeNode(op, input_count, inputs);
576  schedule()->AddNode(CurrentBlock(), node);
577  return node;
578}
579
580Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
581                                    Node* const* inputs) {
582  // The raw machine assembler nodes do not have effect and control inputs,
583  // so we disable checking input counts here.
584  return graph()->NewNodeUnchecked(op, input_count, inputs);
585}
586
587RawMachineLabel::~RawMachineLabel() { DCHECK(bound_ || !used_); }
588
589}  // namespace compiler
590}  // namespace internal
591}  // namespace v8
592