5 #include "src/compiler/raw-machine-assembler.h" 7 #include "src/compiler/node-properties.h" 8 #include "src/compiler/pipeline.h" 9 #include "src/compiler/scheduler.h" 10 #include "src/heap/factory-inl.h" 16 RawMachineAssembler::RawMachineAssembler(
17 Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
18 MachineRepresentation word, MachineOperatorBuilder::Flags flags,
19 MachineOperatorBuilder::AlignmentRequirements alignment_requirements,
20 PoisoningMitigationLevel poisoning_level)
23 schedule_(new (zone()) Schedule(zone())),
24 machine_(zone(), word, flags, alignment_requirements),
26 call_descriptor_(call_descriptor),
27 target_parameter_(nullptr),
28 parameters_(parameter_count(), zone()),
29 current_block_(schedule()->start()),
30 poisoning_level_(poisoning_level) {
31 int param_count =
static_cast<int>(parameter_count());
33 graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
34 if (call_descriptor->IsJSFunctionCall()) {
35 target_parameter_ = AddNode(
36 common()->Parameter(Linkage::kJSCallClosureParamIndex), graph->start());
38 for (
size_t i = 0;
i < parameter_count(); ++
i) {
40 AddNode(common()->Parameter(static_cast<int>(
i)), graph->start());
42 graph->SetEnd(graph->NewNode(common_.End(0)));
45 Node* RawMachineAssembler::NullConstant() {
46 return HeapConstant(isolate()->factory()->null_value());
49 Node* RawMachineAssembler::UndefinedConstant() {
50 return HeapConstant(isolate()->factory()->undefined_value());
53 Node* RawMachineAssembler::RelocatableIntPtrConstant(intptr_t value,
54 RelocInfo::Mode rmode) {
55 return kPointerSize == 8
56 ? RelocatableInt64Constant(value, rmode)
57 : RelocatableInt32Constant(static_cast<
int>(value), rmode);
60 Schedule* RawMachineAssembler::Export() {
62 DCHECK(schedule_->rpo_order()->empty());
63 if (FLAG_trace_turbo_scheduler) {
64 PrintF(
"--- RAW SCHEDULE -------------------------------------------\n");
65 StdoutStream{} << *schedule_;
67 schedule_->EnsureCFGWellFormedness();
68 Scheduler::ComputeSpecialRPO(zone(), schedule_);
69 schedule_->PropagateDeferredMark();
70 if (FLAG_trace_turbo_scheduler) {
71 PrintF(
"--- EDGE SPLIT AND PROPAGATED DEFERRED SCHEDULE ------------\n");
72 StdoutStream{} << *schedule_;
75 Schedule* schedule = schedule_;
80 Graph* RawMachineAssembler::ExportForOptimization() {
82 DCHECK(schedule_->rpo_order()->empty());
83 if (FLAG_trace_turbo_scheduler) {
84 PrintF(
"--- RAW SCHEDULE -------------------------------------------\n");
85 StdoutStream{} << *schedule_;
87 schedule_->EnsureCFGWellFormedness();
88 Scheduler::ComputeSpecialRPO(zone(), schedule_);
89 if (FLAG_trace_turbo_scheduler) {
90 PrintF(
"--- SCHEDULE BEFORE GRAPH CREATION -------------------------\n");
91 StdoutStream{} << *schedule_;
99 void RawMachineAssembler::MakeReschedulable() {
100 std::vector<Node*> block_final_control(schedule_->all_blocks_.size());
101 std::vector<Node*> block_final_effect(schedule_->all_blocks_.size());
108 std::vector<LoopHeader> loop_headers;
111 std::vector<Node*> merge_inputs;
112 std::vector<Node*> effect_phi_inputs;
114 for (BasicBlock* block : *schedule_->rpo_order()) {
115 Node* current_control;
116 Node* current_effect;
117 if (block == schedule_->start()) {
118 current_control = current_effect = graph()->start();
119 }
else if (block == schedule_->end()) {
120 for (
size_t i = 0;
i < block->PredecessorCount(); ++
i) {
121 NodeProperties::MergeControlToEnd(
122 graph(), common(), block->PredecessorAt(
i)->control_input());
124 }
else if (block->IsLoopHeader()) {
128 current_control = graph()->NewNode(common()->Loop(2), graph()->start(),
131 graph()->NewNode(common()->EffectPhi(2), graph()->start(),
132 graph()->start(), current_control);
134 Node* terminate = graph()->NewNode(common()->Terminate(), current_effect,
136 NodeProperties::MergeControlToEnd(graph(), common(), terminate);
137 loop_headers.push_back(
138 LoopHeader{block, current_control, current_effect});
139 }
else if (block->PredecessorCount() == 1) {
140 BasicBlock* predecessor = block->PredecessorAt(0);
141 DCHECK_LT(predecessor->rpo_number(), block->rpo_number());
142 current_effect = block_final_effect[predecessor->id().ToSize()];
143 current_control = block_final_control[predecessor->id().ToSize()];
146 merge_inputs.clear();
147 effect_phi_inputs.clear();
148 int predecessor_count =
static_cast<int>(block->PredecessorCount());
149 for (
int i = 0;
i < predecessor_count; ++
i) {
150 BasicBlock* predecessor = block->PredecessorAt(
i);
151 DCHECK_LT(predecessor->rpo_number(), block->rpo_number());
152 merge_inputs.push_back(block_final_control[predecessor->id().ToSize()]);
153 effect_phi_inputs.push_back(
154 block_final_effect[predecessor->id().ToSize()]);
156 current_control = graph()->NewNode(common()->Merge(predecessor_count),
157 static_cast<int>(merge_inputs.size()),
158 merge_inputs.data());
159 effect_phi_inputs.push_back(current_control);
160 current_effect = graph()->NewNode(
161 common()->EffectPhi(predecessor_count),
162 static_cast<int>(effect_phi_inputs.size()), effect_phi_inputs.data());
165 auto update_current_control_and_effect = [&](Node* node) {
166 bool existing_effect_and_control =
167 IrOpcode::IsIfProjectionOpcode(node->opcode()) ||
168 IrOpcode::IsPhiOpcode(node->opcode());
169 if (node->op()->EffectInputCount() > 0) {
170 DCHECK_EQ(1, node->op()->EffectInputCount());
171 if (existing_effect_and_control) {
172 NodeProperties::ReplaceEffectInput(node, current_effect);
174 node->AppendInput(graph()->zone(), current_effect);
177 if (node->op()->ControlInputCount() > 0) {
178 DCHECK_EQ(1, node->op()->ControlInputCount());
179 if (existing_effect_and_control) {
180 NodeProperties::ReplaceControlInput(node, current_control);
182 node->AppendInput(graph()->zone(), current_control);
185 if (node->op()->EffectOutputCount() > 0) {
186 DCHECK_EQ(1, node->op()->EffectOutputCount());
187 current_effect = node;
189 if (node->op()->ControlOutputCount() > 0) {
190 current_control = node;
194 for (Node* node : *block) {
195 update_current_control_and_effect(node);
197 if (block->deferred()) MarkControlDeferred(current_control);
199 if (Node* block_terminator = block->control_input()) {
200 update_current_control_and_effect(block_terminator);
203 block_final_effect[block->id().ToSize()] = current_effect;
204 block_final_control[block->id().ToSize()] = current_control;
209 for (
const LoopHeader& loop_header : loop_headers) {
210 BasicBlock* block = loop_header.block;
211 std::vector<BasicBlock*> loop_entries;
212 std::vector<BasicBlock*> loop_backedges;
213 for (
size_t i = 0;
i < block->PredecessorCount(); ++
i) {
214 BasicBlock* predecessor = block->PredecessorAt(
i);
215 if (block->LoopContains(predecessor)) {
216 loop_backedges.push_back(predecessor);
218 DCHECK(loop_backedges.empty());
219 loop_entries.push_back(predecessor);
222 DCHECK(!loop_entries.empty());
223 DCHECK(!loop_backedges.empty());
225 int entrance_count =
static_cast<int>(loop_entries.size());
226 int backedge_count =
static_cast<int>(loop_backedges.size());
227 Node* control_loop_entry = CreateNodeFromPredecessors(
228 loop_entries, block_final_control, common()->Merge(entrance_count), {});
229 Node* control_backedge =
230 CreateNodeFromPredecessors(loop_backedges, block_final_control,
231 common()->Merge(backedge_count), {});
232 Node* effect_loop_entry = CreateNodeFromPredecessors(
233 loop_entries, block_final_effect, common()->EffectPhi(entrance_count),
234 {control_loop_entry});
235 Node* effect_backedge = CreateNodeFromPredecessors(
236 loop_backedges, block_final_effect, common()->EffectPhi(backedge_count),
239 loop_header.loop_node->ReplaceInput(0, control_loop_entry);
240 loop_header.loop_node->ReplaceInput(1, control_backedge);
241 loop_header.effect_phi->ReplaceInput(0, effect_loop_entry);
242 loop_header.effect_phi->ReplaceInput(1, effect_backedge);
244 for (Node* node : *block) {
245 if (node->opcode() == IrOpcode::kPhi) {
246 MakePhiBinary(node, static_cast<int>(loop_entries.size()),
247 control_loop_entry, control_backedge);
253 Node* RawMachineAssembler::CreateNodeFromPredecessors(
254 const std::vector<BasicBlock*>& predecessors,
255 const std::vector<Node*>& sidetable,
const Operator* op,
256 const std::vector<Node*>& additional_inputs) {
257 if (predecessors.size() == 1) {
258 return sidetable[predecessors.front()->id().ToSize()];
260 std::vector<Node*> inputs;
261 for (BasicBlock* predecessor : predecessors) {
262 inputs.push_back(sidetable[predecessor->id().ToSize()]);
264 for (Node* additional_input : additional_inputs) {
265 inputs.push_back(additional_input);
267 return graph()->NewNode(op, static_cast<int>(inputs.size()), inputs.data());
270 void RawMachineAssembler::MakePhiBinary(Node* phi,
int split_point,
272 Node* right_control) {
273 int value_count = phi->op()->ValueInputCount();
274 if (value_count == 2)
return;
275 DCHECK_LT(split_point, value_count);
276 DCHECK_GT(split_point, 0);
278 MachineRepresentation rep = PhiRepresentationOf(phi->op());
279 int left_input_count = split_point;
280 int right_input_count = value_count - split_point;
283 if (left_input_count == 1) {
284 left_input = NodeProperties::GetValueInput(phi, 0);
286 std::vector<Node*> inputs;
287 for (
int i = 0;
i < left_input_count; ++
i) {
288 inputs.push_back(NodeProperties::GetValueInput(phi,
i));
290 inputs.push_back(left_control);
292 graph()->NewNode(common()->Phi(rep, static_cast<int>(left_input_count)),
293 static_cast<int>(inputs.size()), inputs.data());
297 if (right_input_count == 1) {
298 right_input = NodeProperties::GetValueInput(phi, split_point);
300 std::vector<Node*> inputs;
301 for (
int i = split_point;
i < value_count; ++
i) {
302 inputs.push_back(NodeProperties::GetValueInput(phi,
i));
304 inputs.push_back(right_control);
305 right_input = graph()->NewNode(
306 common()->Phi(rep, static_cast<int>(right_input_count)),
307 static_cast<int>(inputs.size()), inputs.data());
310 Node* control = NodeProperties::GetControlInput(phi);
311 phi->TrimInputCount(3);
312 phi->ReplaceInput(0, left_input);
313 phi->ReplaceInput(1, right_input);
314 phi->ReplaceInput(2, control);
315 NodeProperties::ChangeOp(phi, common()->Phi(rep, 2));
318 void RawMachineAssembler::MarkControlDeferred(Node* control_node) {
319 BranchHint new_branch_hint;
320 Node* responsible_branch =
nullptr;
321 while (responsible_branch ==
nullptr) {
322 switch (control_node->opcode()) {
323 case IrOpcode::kIfException:
326 case IrOpcode::kIfSuccess:
327 control_node = NodeProperties::GetControlInput(control_node);
329 case IrOpcode::kIfValue:
330 case IrOpcode::kIfDefault:
333 case IrOpcode::kIfTrue: {
334 Node* branch = NodeProperties::GetControlInput(control_node);
335 BranchHint hint = BranchOperatorInfoOf(branch->op()).hint;
336 if (hint == BranchHint::kTrue) {
339 control_node = NodeProperties::GetControlInput(branch);
342 new_branch_hint = BranchHint::kFalse;
343 responsible_branch = branch;
346 case IrOpcode::kIfFalse: {
347 Node* branch = NodeProperties::GetControlInput(control_node);
348 BranchHint hint = BranchOperatorInfoOf(branch->op()).hint;
349 if (hint == BranchHint::kFalse) {
352 control_node = NodeProperties::GetControlInput(branch);
355 new_branch_hint = BranchHint::kTrue;
356 responsible_branch = branch;
359 case IrOpcode::kMerge:
360 for (
int i = 0;
i < control_node->op()->ControlInputCount(); ++
i) {
361 MarkControlDeferred(NodeProperties::GetControlInput(control_node,
i));
364 case IrOpcode::kLoop:
365 control_node = NodeProperties::GetControlInput(control_node, 0);
367 case IrOpcode::kBranch:
368 case IrOpcode::kSwitch:
370 case IrOpcode::kStart:
373 DCHECK_EQ(1, control_node->op()->ControlInputCount());
374 control_node = NodeProperties::GetControlInput(control_node);
379 BranchOperatorInfo info = BranchOperatorInfoOf(responsible_branch->op());
380 if (info.hint == new_branch_hint)
return;
381 NodeProperties::ChangeOp(
383 common()->Branch(new_branch_hint, info.is_safety_check));
386 Node* RawMachineAssembler::TargetParameter() {
387 DCHECK_NOT_NULL(target_parameter_);
388 return target_parameter_;
391 Node* RawMachineAssembler::Parameter(
size_t index) {
392 DCHECK(index < parameter_count());
393 return parameters_[index];
397 void RawMachineAssembler::Goto(RawMachineLabel* label) {
398 DCHECK(current_block_ != schedule()->end());
399 schedule()->AddGoto(CurrentBlock(), Use(label));
400 current_block_ =
nullptr;
404 void RawMachineAssembler::Branch(Node* condition, RawMachineLabel* true_val,
405 RawMachineLabel* false_val) {
406 DCHECK(current_block_ != schedule()->end());
407 Node* branch = MakeNode(
408 common()->Branch(BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck), 1,
410 BasicBlock* true_block = schedule()->NewBasicBlock();
411 BasicBlock* false_block = schedule()->NewBasicBlock();
412 schedule()->AddBranch(CurrentBlock(), branch, true_block, false_block);
414 true_block->AddNode(MakeNode(common()->IfTrue(), 1, &branch));
415 schedule()->AddGoto(true_block, Use(true_val));
417 false_block->AddNode(MakeNode(common()->IfFalse(), 1, &branch));
418 schedule()->AddGoto(false_block, Use(false_val));
420 current_block_ =
nullptr;
423 void RawMachineAssembler::Continuations(Node* call, RawMachineLabel* if_success,
424 RawMachineLabel* if_exception) {
425 DCHECK_NOT_NULL(schedule_);
426 DCHECK_NOT_NULL(current_block_);
427 schedule()->AddCall(CurrentBlock(), call, Use(if_success), Use(if_exception));
428 current_block_ =
nullptr;
431 void RawMachineAssembler::Switch(Node* index, RawMachineLabel* default_label,
432 const int32_t* case_values,
433 RawMachineLabel** case_labels,
435 DCHECK_NE(schedule()->end(), current_block_);
436 size_t succ_count = case_count + 1;
437 Node* switch_node = MakeNode(common()->Switch(succ_count), 1, &index);
438 BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count);
439 for (
size_t index = 0; index < case_count; ++index) {
440 int32_t case_value = case_values[index];
441 BasicBlock* case_block = schedule()->NewBasicBlock();
443 graph()->NewNode(common()->IfValue(case_value), switch_node);
444 schedule()->AddNode(case_block, case_node);
445 schedule()->AddGoto(case_block, Use(case_labels[index]));
446 succ_blocks[index] = case_block;
448 BasicBlock* default_block = schedule()->NewBasicBlock();
449 Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node);
450 schedule()->AddNode(default_block, default_node);
451 schedule()->AddGoto(default_block, Use(default_label));
452 succ_blocks[case_count] = default_block;
453 schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count);
454 current_block_ =
nullptr;
457 void RawMachineAssembler::Return(Node* value) {
458 Node* values[] = {Int32Constant(0), value};
459 Node* ret = MakeNode(common()->Return(1), 2, values);
460 schedule()->AddReturn(CurrentBlock(), ret);
461 current_block_ =
nullptr;
464 void RawMachineAssembler::Return(Node* v1, Node* v2) {
465 Node* values[] = {Int32Constant(0), v1, v2};
466 Node* ret = MakeNode(common()->Return(2), 3, values);
467 schedule()->AddReturn(CurrentBlock(), ret);
468 current_block_ =
nullptr;
471 void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) {
472 Node* values[] = {Int32Constant(0), v1, v2, v3};
473 Node* ret = MakeNode(common()->Return(3), 4, values);
474 schedule()->AddReturn(CurrentBlock(), ret);
475 current_block_ =
nullptr;
478 void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3, Node* v4) {
479 Node* values[] = {Int32Constant(0), v1, v2, v3, v4};
480 Node* ret = MakeNode(common()->Return(4), 5, values);
481 schedule()->AddReturn(CurrentBlock(), ret);
482 current_block_ =
nullptr;
485 void RawMachineAssembler::Return(
int count, Node* vs[]) {
486 typedef Node* Node_ptr;
487 Node** values =
new Node_ptr[count + 1];
488 values[0] = Int32Constant(0);
489 for (
int i = 0;
i < count; ++
i) values[
i + 1] = vs[
i];
490 Node* ret = MakeNode(common()->Return(count), count + 1, values);
491 schedule()->AddReturn(CurrentBlock(), ret);
492 current_block_ =
nullptr;
496 void RawMachineAssembler::PopAndReturn(Node* pop, Node* value) {
497 Node* values[] = {pop, value};
498 Node* ret = MakeNode(common()->Return(1), 2, values);
499 schedule()->AddReturn(CurrentBlock(), ret);
500 current_block_ =
nullptr;
503 void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2) {
504 Node* values[] = {pop, v1, v2};
505 Node* ret = MakeNode(common()->Return(2), 3, values);
506 schedule()->AddReturn(CurrentBlock(), ret);
507 current_block_ =
nullptr;
510 void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2,
512 Node* values[] = {pop, v1, v2, v3};
513 Node* ret = MakeNode(common()->Return(3), 4, values);
514 schedule()->AddReturn(CurrentBlock(), ret);
515 current_block_ =
nullptr;
518 void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3,
520 Node* values[] = {pop, v1, v2, v3, v4};
521 Node* ret = MakeNode(common()->Return(4), 5, values);
522 schedule()->AddReturn(CurrentBlock(), ret);
523 current_block_ =
nullptr;
526 void RawMachineAssembler::DebugAbort(Node* message) {
527 AddNode(machine()->DebugAbort(), message);
530 void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); }
532 void RawMachineAssembler::Unreachable() {
533 Node* ret = MakeNode(common()->Throw(), 0,
nullptr);
534 schedule()->AddThrow(CurrentBlock(), ret);
535 current_block_ =
nullptr;
538 void RawMachineAssembler::Comment(
const char* msg) {
539 AddNode(machine()->Comment(msg));
542 Node* RawMachineAssembler::CallN(CallDescriptor* call_descriptor,
543 int input_count, Node*
const* inputs) {
544 DCHECK(!call_descriptor->NeedsFrameState());
546 DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 1);
547 return AddNode(common()->Call(call_descriptor), input_count, inputs);
550 Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* call_descriptor,
552 Node*
const* inputs) {
553 DCHECK(call_descriptor->NeedsFrameState());
555 DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 2);
556 return AddNode(common()->Call(call_descriptor), input_count, inputs);
559 Node* RawMachineAssembler::TailCallN(CallDescriptor* call_descriptor,
560 int input_count, Node*
const* inputs) {
562 DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 1);
564 MakeNode(common()->TailCall(call_descriptor), input_count, inputs);
565 schedule()->AddTailCall(CurrentBlock(), tail_call);
566 current_block_ =
nullptr;
570 Node* RawMachineAssembler::CallCFunction0(MachineType return_type,
572 MachineSignature::Builder builder(zone(), 1, 0);
573 builder.AddReturn(return_type);
574 auto call_descriptor =
575 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
577 return AddNode(common()->Call(call_descriptor),
function);
581 Node* RawMachineAssembler::CallCFunction1(MachineType return_type,
582 MachineType arg0_type, Node*
function,
584 MachineSignature::Builder builder(zone(), 1, 1);
585 builder.AddReturn(return_type);
586 builder.AddParam(arg0_type);
587 auto call_descriptor =
588 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
590 return AddNode(common()->Call(call_descriptor),
function, arg0);
593 Node* RawMachineAssembler::CallCFunction1WithCallerSavedRegisters(
594 MachineType return_type, MachineType arg0_type, Node*
function, Node* arg0,
595 SaveFPRegsMode mode) {
596 MachineSignature::Builder builder(zone(), 1, 1);
597 builder.AddReturn(return_type);
598 builder.AddParam(arg0_type);
599 auto call_descriptor =
600 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
602 call_descriptor->set_save_fp_mode(mode);
604 return AddNode(common()->CallWithCallerSavedRegisters(call_descriptor),
608 Node* RawMachineAssembler::CallCFunction2(MachineType return_type,
609 MachineType arg0_type,
610 MachineType arg1_type, Node*
function,
611 Node* arg0, Node* arg1) {
612 MachineSignature::Builder builder(zone(), 1, 2);
613 builder.AddReturn(return_type);
614 builder.AddParam(arg0_type);
615 builder.AddParam(arg1_type);
616 auto call_descriptor =
617 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
619 return AddNode(common()->Call(call_descriptor),
function, arg0, arg1);
622 Node* RawMachineAssembler::CallCFunction3(MachineType return_type,
623 MachineType arg0_type,
624 MachineType arg1_type,
625 MachineType arg2_type, Node*
function,
626 Node* arg0, Node* arg1, Node* arg2) {
627 MachineSignature::Builder builder(zone(), 1, 3);
628 builder.AddReturn(return_type);
629 builder.AddParam(arg0_type);
630 builder.AddParam(arg1_type);
631 builder.AddParam(arg2_type);
632 auto call_descriptor =
633 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
635 return AddNode(common()->Call(call_descriptor),
function, arg0, arg1, arg2);
638 Node* RawMachineAssembler::CallCFunction3WithCallerSavedRegisters(
639 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
640 MachineType arg2_type, Node*
function, Node* arg0, Node* arg1, Node* arg2,
641 SaveFPRegsMode mode) {
642 MachineSignature::Builder builder(zone(), 1, 3);
643 builder.AddReturn(return_type);
644 builder.AddParam(arg0_type);
645 builder.AddParam(arg1_type);
646 builder.AddParam(arg2_type);
647 auto call_descriptor =
648 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
650 call_descriptor->set_save_fp_mode(mode);
652 return AddNode(common()->CallWithCallerSavedRegisters(call_descriptor),
653 function, arg0, arg1, arg2);
656 Node* RawMachineAssembler::CallCFunction4(
657 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
658 MachineType arg2_type, MachineType arg3_type, Node*
function, Node* arg0,
659 Node* arg1, Node* arg2, Node* arg3) {
660 MachineSignature::Builder builder(zone(), 1, 4);
661 builder.AddReturn(return_type);
662 builder.AddParam(arg0_type);
663 builder.AddParam(arg1_type);
664 builder.AddParam(arg2_type);
665 builder.AddParam(arg3_type);
666 auto call_descriptor =
667 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
669 return AddNode(common()->Call(call_descriptor),
function, arg0, arg1, arg2,
673 Node* RawMachineAssembler::CallCFunction5(
674 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
675 MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
676 Node*
function, Node* arg0, Node* arg1, Node* arg2, Node* arg3,
678 MachineSignature::Builder builder(zone(), 1, 5);
679 builder.AddReturn(return_type);
680 builder.AddParam(arg0_type);
681 builder.AddParam(arg1_type);
682 builder.AddParam(arg2_type);
683 builder.AddParam(arg3_type);
684 builder.AddParam(arg4_type);
685 auto call_descriptor =
686 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
688 return AddNode(common()->Call(call_descriptor),
function, arg0, arg1, arg2,
692 Node* RawMachineAssembler::CallCFunction6(
693 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
694 MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
695 MachineType arg5_type, Node*
function, Node* arg0, Node* arg1, Node* arg2,
696 Node* arg3, Node* arg4, Node* arg5) {
697 MachineSignature::Builder builder(zone(), 1, 6);
698 builder.AddReturn(return_type);
699 builder.AddParam(arg0_type);
700 builder.AddParam(arg1_type);
701 builder.AddParam(arg2_type);
702 builder.AddParam(arg3_type);
703 builder.AddParam(arg4_type);
704 builder.AddParam(arg5_type);
705 auto call_descriptor =
706 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
708 return AddNode(common()->Call(call_descriptor),
function, arg0, arg1, arg2,
712 Node* RawMachineAssembler::CallCFunction8(
713 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
714 MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
715 MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
716 Node*
function, Node* arg0, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
717 Node* arg5, Node* arg6, Node* arg7) {
718 MachineSignature::Builder builder(zone(), 1, 8);
719 builder.AddReturn(return_type);
720 builder.AddParam(arg0_type);
721 builder.AddParam(arg1_type);
722 builder.AddParam(arg2_type);
723 builder.AddParam(arg3_type);
724 builder.AddParam(arg4_type);
725 builder.AddParam(arg5_type);
726 builder.AddParam(arg6_type);
727 builder.AddParam(arg7_type);
728 Node* args[] = {
function, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
729 auto call_descriptor =
730 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
731 return AddNode(common()->Call(call_descriptor), arraysize(args), args);
734 Node* RawMachineAssembler::CallCFunction9(
735 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
736 MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
737 MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
738 MachineType arg8_type, Node*
function, Node* arg0, Node* arg1, Node* arg2,
739 Node* arg3, Node* arg4, Node* arg5, Node* arg6, Node* arg7, Node* arg8) {
740 MachineSignature::Builder builder(zone(), 1, 9);
741 builder.AddReturn(return_type);
742 builder.AddParam(arg0_type);
743 builder.AddParam(arg1_type);
744 builder.AddParam(arg2_type);
745 builder.AddParam(arg3_type);
746 builder.AddParam(arg4_type);
747 builder.AddParam(arg5_type);
748 builder.AddParam(arg6_type);
749 builder.AddParam(arg7_type);
750 builder.AddParam(arg8_type);
751 Node* args[] = {
function, arg0, arg1, arg2, arg3,
752 arg4, arg5, arg6, arg7, arg8};
753 auto call_descriptor =
754 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
755 return AddNode(common()->Call(call_descriptor), arraysize(args), args);
758 BasicBlock* RawMachineAssembler::Use(RawMachineLabel* label) {
760 return EnsureBlock(label);
763 BasicBlock* RawMachineAssembler::EnsureBlock(RawMachineLabel* label) {
764 if (label->block_ ==
nullptr) {
765 label->block_ = schedule()->NewBasicBlock();
767 return label->block_;
770 void RawMachineAssembler::Bind(RawMachineLabel* label) {
771 DCHECK_NULL(current_block_);
772 DCHECK(!label->bound_);
773 label->bound_ =
true;
774 current_block_ = EnsureBlock(label);
775 current_block_->set_deferred(label->deferred_);
779 void RawMachineAssembler::Bind(RawMachineLabel* label,
780 AssemblerDebugInfo info) {
781 if (current_block_ !=
nullptr) {
782 std::stringstream str;
783 str <<
"Binding label without closing previous block:" 784 <<
"\n# label: " << info
785 <<
"\n# previous block: " << *current_block_;
786 FATAL(
"%s", str.str().c_str());
789 current_block_->set_debug_info(info);
792 void RawMachineAssembler::PrintCurrentBlock(std::ostream& os) {
793 os << CurrentBlock();
796 void RawMachineAssembler::SetInitialDebugInformation(
797 AssemblerDebugInfo debug_info) {
798 CurrentBlock()->set_debug_info(debug_info);
802 bool RawMachineAssembler::InsideBlock() {
return current_block_ !=
nullptr; }
804 BasicBlock* RawMachineAssembler::CurrentBlock() {
805 DCHECK(current_block_);
806 return current_block_;
809 Node* RawMachineAssembler::Phi(MachineRepresentation rep,
int input_count,
810 Node*
const* inputs) {
811 Node** buffer =
new (zone()->New(
sizeof(Node*) * (input_count + 1)))
812 Node*[input_count + 1];
813 std::copy(inputs, inputs + input_count, buffer);
814 buffer[input_count] = graph()->start();
815 return AddNode(common()->Phi(rep, input_count), input_count + 1, buffer);
818 void RawMachineAssembler::AppendPhiInput(Node* phi, Node* new_input) {
819 const Operator* op = phi->op();
820 const Operator* new_op = common()->ResizeMergeOrPhi(op, phi->InputCount());
821 phi->InsertInput(zone(), phi->InputCount() - 1, new_input);
822 NodeProperties::ChangeOp(phi, new_op);
825 Node* RawMachineAssembler::AddNode(
const Operator* op,
int input_count,
826 Node*
const* inputs) {
827 DCHECK_NOT_NULL(schedule_);
828 DCHECK_NOT_NULL(current_block_);
829 Node* node = MakeNode(op, input_count, inputs);
830 schedule()->AddNode(CurrentBlock(), node);
834 Node* RawMachineAssembler::MakeNode(
const Operator* op,
int input_count,
835 Node*
const* inputs) {
838 return graph()->NewNodeUnchecked(op, input_count, inputs);
841 RawMachineLabel::~RawMachineLabel() {
843 if (bound_ == used_)
return;
844 std::stringstream str;
846 str <<
"A label has been bound but it's not used." 847 <<
"\n# label: " << *block_;
849 str <<
"A label has been used but it's not bound.";
851 FATAL(
"%s", str.str().c_str());