LCOV - code coverage report
Current view: top level - src/compiler - raw-machine-assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 326 383 85.1 %
Date: 2019-01-20 Functions: 45 57 78.9 %

          Line data    Source code
       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/compiler/node-properties.h"
       8             : #include "src/compiler/pipeline.h"
       9             : #include "src/compiler/scheduler.h"
      10             : #include "src/heap/factory-inl.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : namespace compiler {
      15             : 
      16      296381 : RawMachineAssembler::RawMachineAssembler(
      17      853938 :     Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
      18             :     MachineRepresentation word, MachineOperatorBuilder::Flags flags,
      19             :     MachineOperatorBuilder::AlignmentRequirements alignment_requirements,
      20     1446700 :     PoisoningMitigationLevel poisoning_level)
      21             :     : isolate_(isolate),
      22             :       graph_(graph),
      23      296381 :       schedule_(new (zone()) Schedule(zone())),
      24             :       machine_(zone(), word, flags, alignment_requirements),
      25             :       common_(zone()),
      26             :       simplified_(zone()),
      27             :       call_descriptor_(call_descriptor),
      28             :       target_parameter_(nullptr),
      29             :       parameters_(parameter_count(), zone()),
      30      296381 :       current_block_(schedule()->start()),
      31     1778286 :       poisoning_level_(poisoning_level) {
      32      296381 :   int param_count = static_cast<int>(parameter_count());
      33             :   // Add an extra input for the JSFunction parameter to the start node.
      34      296381 :   graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
      35      296381 :   if (call_descriptor->IsJSFunctionCall()) {
      36             :     target_parameter_ = AddNode(
      37       40278 :         common()->Parameter(Linkage::kJSCallClosureParamIndex), graph->start());
      38             :   }
      39     1411495 :   for (size_t i = 0; i < parameter_count(); ++i) {
      40      557557 :     parameters_[i] =
      41     1115114 :         AddNode(common()->Parameter(static_cast<int>(i)), graph->start());
      42             :   }
      43      296381 :   graph->SetEnd(graph->NewNode(common_.End(0)));
      44      296381 : }
      45             : 
      46           0 : Node* RawMachineAssembler::NullConstant() {
      47           0 :   return HeapConstant(isolate()->factory()->null_value());
      48             : }
      49             : 
      50           5 : Node* RawMachineAssembler::UndefinedConstant() {
      51           5 :   return HeapConstant(isolate()->factory()->undefined_value());
      52             : }
      53             : 
      54           0 : Node* RawMachineAssembler::RelocatableIntPtrConstant(intptr_t value,
      55             :                                                      RelocInfo::Mode rmode) {
      56             :   return kSystemPointerSize == 8
      57             :              ? RelocatableInt64Constant(value, rmode)
      58           0 :              : RelocatableInt32Constant(static_cast<int>(value), rmode);
      59             : }
      60             : 
      61       63021 : Node* RawMachineAssembler::OptimizedAllocate(Node* size,
      62             :                                              PretenureFlag pretenure) {
      63      126042 :   return AddNode(simplified()->AllocateRaw(Type::Any(), pretenure), size);
      64             : }
      65             : 
      66      226857 : Schedule* RawMachineAssembler::Export() {
      67             :   // Compute the correct codegen order.
      68             :   DCHECK(schedule_->rpo_order()->empty());
      69      226857 :   if (FLAG_trace_turbo_scheduler) {
      70           0 :     PrintF("--- RAW SCHEDULE -------------------------------------------\n");
      71           0 :     StdoutStream{} << *schedule_;
      72             :   }
      73      226857 :   schedule_->EnsureCFGWellFormedness();
      74      453714 :   Scheduler::ComputeSpecialRPO(zone(), schedule_);
      75      226857 :   schedule_->PropagateDeferredMark();
      76      226857 :   if (FLAG_trace_turbo_scheduler) {
      77           0 :     PrintF("--- EDGE SPLIT AND PROPAGATED DEFERRED SCHEDULE ------------\n");
      78           0 :     StdoutStream{} << *schedule_;
      79             :   }
      80             :   // Invalidate RawMachineAssembler.
      81      226857 :   Schedule* schedule = schedule_;
      82      226857 :   schedule_ = nullptr;
      83      226857 :   return schedule;
      84             : }
      85             : 
      86      133830 : Graph* RawMachineAssembler::ExportForOptimization() {
      87             :   // Compute the correct codegen order.
      88             :   DCHECK(schedule_->rpo_order()->empty());
      89       66915 :   if (FLAG_trace_turbo_scheduler) {
      90           0 :     PrintF("--- RAW SCHEDULE -------------------------------------------\n");
      91           0 :     StdoutStream{} << *schedule_;
      92             :   }
      93       66915 :   schedule_->EnsureCFGWellFormedness();
      94      133830 :   Scheduler::ComputeSpecialRPO(zone(), schedule_);
      95       66915 :   if (FLAG_trace_turbo_scheduler) {
      96           0 :     PrintF("--- SCHEDULE BEFORE GRAPH CREATION -------------------------\n");
      97           0 :     StdoutStream{} << *schedule_;
      98             :   }
      99       66915 :   MakeReschedulable();
     100             :   // Invalidate RawMachineAssembler.
     101       66915 :   schedule_ = nullptr;
     102       66915 :   return graph();
     103             : }
     104             : 
     105     2054014 : void RawMachineAssembler::MakeReschedulable() {
     106    12446126 :   std::vector<Node*> block_final_control(schedule_->all_blocks_.size());
     107      133830 :   std::vector<Node*> block_final_effect(schedule_->all_blocks_.size());
     108             : 
     109             :   struct LoopHeader {
     110             :     BasicBlock* block;
     111             :     Node* loop_node;
     112             :     Node* effect_phi;
     113             :   };
     114             :   std::vector<LoopHeader> loop_headers;
     115             : 
     116             :   // These are hoisted outside of the loop to avoid re-allocation.
     117             :   std::vector<Node*> merge_inputs;
     118             :   std::vector<Node*> effect_phi_inputs;
     119             : 
     120    24691512 :   for (BasicBlock* block : *schedule_->rpo_order()) {
     121             :     Node* current_control;
     122             :     Node* current_effect;
     123    12312296 :     if (block == schedule_->start()) {
     124       66915 :       current_control = current_effect = graph()->start();
     125     6089233 :     } else if (block == schedule_->end()) {
     126      484402 :       for (size_t i = 0; i < block->PredecessorCount(); ++i) {
     127             :         NodeProperties::MergeControlToEnd(
     128      417492 :             graph(), common(), block->PredecessorAt(i)->control_input());
     129             :       }
     130     6022323 :     } else if (block->IsLoopHeader()) {
     131             :       // The graph()->start() inputs are just placeholders until we computed the
     132             :       // real back-edges and re-structure the control flow so the loop has
     133             :       // exactly two predecessors.
     134             :       current_control = graph()->NewNode(common()->Loop(2), graph()->start(),
     135      195036 :                                          graph()->start());
     136             :       current_effect =
     137             :           graph()->NewNode(common()->EffectPhi(2), graph()->start(),
     138      195036 :                            graph()->start(), current_control);
     139             : 
     140             :       Node* terminate = graph()->NewNode(common()->Terminate(), current_effect,
     141       97518 :                                          current_control);
     142       97518 :       NodeProperties::MergeControlToEnd(graph(), common(), terminate);
     143             :       loop_headers.push_back(
     144      195036 :           LoopHeader{block, current_control, current_effect});
     145     5924805 :     } else if (block->PredecessorCount() == 1) {
     146             :       BasicBlock* predecessor = block->PredecessorAt(0);
     147             :       DCHECK_LT(predecessor->rpo_number(), block->rpo_number());
     148    10723280 :       current_effect = block_final_effect[predecessor->id().ToSize()];
     149    10723280 :       current_control = block_final_control[predecessor->id().ToSize()];
     150             :     } else {
     151             :       // Create control merge nodes and effect phis for all predecessor blocks.
     152             :       merge_inputs.clear();
     153             :       effect_phi_inputs.clear();
     154      563165 :       int predecessor_count = static_cast<int>(block->PredecessorCount());
     155     2218139 :       for (int i = 0; i < predecessor_count; ++i) {
     156     1654974 :         BasicBlock* predecessor = block->PredecessorAt(i);
     157             :         DCHECK_LT(predecessor->rpo_number(), block->rpo_number());
     158     3309948 :         merge_inputs.push_back(block_final_control[predecessor->id().ToSize()]);
     159             :         effect_phi_inputs.push_back(
     160     3309948 :             block_final_effect[predecessor->id().ToSize()]);
     161             :       }
     162             :       current_control = graph()->NewNode(common()->Merge(predecessor_count),
     163      563165 :                                          static_cast<int>(merge_inputs.size()),
     164     1126330 :                                          merge_inputs.data());
     165      563165 :       effect_phi_inputs.push_back(current_control);
     166             :       current_effect = graph()->NewNode(
     167             :           common()->EffectPhi(predecessor_count),
     168     1689495 :           static_cast<int>(effect_phi_inputs.size()), effect_phi_inputs.data());
     169             :     }
     170             : 
     171    74529724 :     auto update_current_control_and_effect = [&](Node* node) {
     172             :       bool existing_effect_and_control =
     173    34620010 :           IrOpcode::IsIfProjectionOpcode(node->opcode()) ||
     174             :           IrOpcode::IsPhiOpcode(node->opcode());
     175    37264862 :       if (node->op()->EffectInputCount() > 0) {
     176             :         DCHECK_EQ(1, node->op()->EffectInputCount());
     177     3386446 :         if (existing_effect_and_control) {
     178       12360 :           NodeProperties::ReplaceEffectInput(node, current_effect);
     179             :         } else {
     180     8054474 :           node->AppendInput(graph()->zone(), current_effect);
     181             :         }
     182             :       }
     183    37264862 :       if (node->op()->ControlInputCount() > 0) {
     184             :         DCHECK_EQ(1, node->op()->ControlInputCount());
     185     7937053 :         if (existing_effect_and_control) {
     186     3256665 :           NodeProperties::ReplaceControlInput(node, current_control);
     187             :         } else {
     188     9360776 :           node->AppendInput(graph()->zone(), current_control);
     189             :         }
     190             :       }
     191    37264862 :       if (node->op()->EffectOutputCount() > 0) {
     192             :         DCHECK_EQ(1, node->op()->EffectOutputCount());
     193     3177700 :         current_effect = node;
     194             :       }
     195    37264862 :       if (node->op()->ControlOutputCount() > 0) {
     196     4462374 :         current_control = node;
     197             :       }
     198    24788579 :     };
     199             : 
     200    29448897 :     for (Node* node : *block) {
     201    17136601 :       update_current_control_and_effect(node);
     202             :     }
     203     6156148 :     if (block->deferred()) MarkControlDeferred(current_control);
     204             : 
     205     6156148 :     if (Node* block_terminator = block->control_input()) {
     206     1495830 :       update_current_control_and_effect(block_terminator);
     207             :     }
     208             : 
     209    12312296 :     block_final_effect[block->id().ToSize()] = current_effect;
     210    12312296 :     block_final_control[block->id().ToSize()] = current_control;
     211             :   }
     212             : 
     213             :   // Fix-up loop backedges and re-structure control flow so that loop nodes have
     214             :   // exactly two control predecessors.
     215      231348 :   for (const LoopHeader& loop_header : loop_headers) {
     216       97518 :     BasicBlock* block = loop_header.block;
     217             :     std::vector<BasicBlock*> loop_entries;
     218             :     std::vector<BasicBlock*> loop_backedges;
     219      638328 :     for (size_t i = 0; i < block->PredecessorCount(); ++i) {
     220      221646 :       BasicBlock* predecessor = block->PredecessorAt(i);
     221      221646 :       if (block->LoopContains(predecessor)) {
     222      123848 :         loop_backedges.push_back(predecessor);
     223             :       } else {
     224             :         DCHECK(loop_backedges.empty());
     225       97798 :         loop_entries.push_back(predecessor);
     226             :       }
     227             :     }
     228             :     DCHECK(!loop_entries.empty());
     229             :     DCHECK(!loop_backedges.empty());
     230             : 
     231      195036 :     int entrance_count = static_cast<int>(loop_entries.size());
     232      195036 :     int backedge_count = static_cast<int>(loop_backedges.size());
     233             :     Node* control_loop_entry = CreateNodeFromPredecessors(
     234      195036 :         loop_entries, block_final_control, common()->Merge(entrance_count), {});
     235             :     Node* control_backedge =
     236             :         CreateNodeFromPredecessors(loop_backedges, block_final_control,
     237      195036 :                                    common()->Merge(backedge_count), {});
     238             :     Node* effect_loop_entry = CreateNodeFromPredecessors(
     239             :         loop_entries, block_final_effect, common()->EffectPhi(entrance_count),
     240      292554 :         {control_loop_entry});
     241             :     Node* effect_backedge = CreateNodeFromPredecessors(
     242             :         loop_backedges, block_final_effect, common()->EffectPhi(backedge_count),
     243      292554 :         {control_backedge});
     244             : 
     245       97518 :     loop_header.loop_node->ReplaceInput(0, control_loop_entry);
     246       97518 :     loop_header.loop_node->ReplaceInput(1, control_backedge);
     247       97518 :     loop_header.effect_phi->ReplaceInput(0, effect_loop_entry);
     248       97518 :     loop_header.effect_phi->ReplaceInput(1, effect_backedge);
     249             : 
     250      987028 :     for (Node* node : *block) {
     251      791992 :       if (node->opcode() == IrOpcode::kPhi) {
     252      159409 :         MakePhiBinary(node, static_cast<int>(loop_entries.size()),
     253      159409 :                       control_loop_entry, control_backedge);
     254             :       }
     255             :     }
     256             :   }
     257       66915 : }
     258             : 
     259      390072 : Node* RawMachineAssembler::CreateNodeFromPredecessors(
     260      390072 :     const std::vector<BasicBlock*>& predecessors,
     261      443292 :     const std::vector<Node*>& sidetable, const Operator* op,
     262       27908 :     const std::vector<Node*>& additional_inputs) {
     263      390072 :   if (predecessors.size() == 1) {
     264      724328 :     return sidetable[predecessors.front()->id().ToSize()];
     265             :   }
     266             :   std::vector<Node*> inputs;
     267      136944 :   for (BasicBlock* predecessor : predecessors) {
     268       81128 :     inputs.push_back(sidetable[predecessor->id().ToSize()]);
     269             :   }
     270       69770 :   for (Node* additional_input : additional_inputs) {
     271       13954 :     inputs.push_back(additional_input);
     272             :   }
     273       83724 :   return graph()->NewNode(op, static_cast<int>(inputs.size()), inputs.data());
     274             : }
     275             : 
     276      159409 : void RawMachineAssembler::MakePhiBinary(Node* phi, int split_point,
     277             :                                         Node* left_control,
     278       31268 :                                         Node* right_control) {
     279      159409 :   int value_count = phi->op()->ValueInputCount();
     280      318818 :   if (value_count == 2) return;
     281             :   DCHECK_LT(split_point, value_count);
     282             :   DCHECK_GT(split_point, 0);
     283             : 
     284       31100 :   MachineRepresentation rep = PhiRepresentationOf(phi->op());
     285             :   int left_input_count = split_point;
     286       31100 :   int right_input_count = value_count - split_point;
     287             : 
     288             :   Node* left_input;
     289       31100 :   if (left_input_count == 1) {
     290       30484 :     left_input = NodeProperties::GetValueInput(phi, 0);
     291             :   } else {
     292             :     std::vector<Node*> inputs;
     293        1848 :     for (int i = 0; i < left_input_count; ++i) {
     294        2464 :       inputs.push_back(NodeProperties::GetValueInput(phi, i));
     295             :     }
     296         616 :     inputs.push_back(left_control);
     297             :     left_input =
     298             :         graph()->NewNode(common()->Phi(rep, static_cast<int>(left_input_count)),
     299        1848 :                          static_cast<int>(inputs.size()), inputs.data());
     300             :   }
     301             : 
     302             :   Node* right_input;
     303       31100 :   if (right_input_count == 1) {
     304         448 :     right_input = NodeProperties::GetValueInput(phi, split_point);
     305             :   } else {
     306             :     std::vector<Node*> inputs;
     307      127180 :     for (int i = split_point; i < value_count; ++i) {
     308      193056 :       inputs.push_back(NodeProperties::GetValueInput(phi, i));
     309             :     }
     310       30652 :     inputs.push_back(right_control);
     311             :     right_input = graph()->NewNode(
     312             :         common()->Phi(rep, static_cast<int>(right_input_count)),
     313       91956 :         static_cast<int>(inputs.size()), inputs.data());
     314             :   }
     315             : 
     316       31100 :   Node* control = NodeProperties::GetControlInput(phi);
     317       31100 :   phi->TrimInputCount(3);
     318       31100 :   phi->ReplaceInput(0, left_input);
     319       31100 :   phi->ReplaceInput(1, right_input);
     320       31100 :   phi->ReplaceInput(2, control);
     321       31100 :   NodeProperties::ChangeOp(phi, common()->Phi(rep, 2));
     322             : }
     323             : 
     324     1390826 : void RawMachineAssembler::MarkControlDeferred(Node* control_node) {
     325             :   BranchHint new_branch_hint;
     326      361553 :   Node* responsible_branch = nullptr;
     327     1448826 :   while (responsible_branch == nullptr) {
     328      618523 :     switch (control_node->opcode()) {
     329             :       case IrOpcode::kIfException:
     330             :         // IfException projections are deferred by default.
     331             :         return;
     332             :       case IrOpcode::kIfSuccess:
     333         896 :         control_node = NodeProperties::GetControlInput(control_node);
     334         896 :         continue;
     335             :       case IrOpcode::kIfValue: {
     336         952 :         IfValueParameters parameters = IfValueParametersOf(control_node->op());
     337         952 :         if (parameters.hint() != BranchHint::kFalse) {
     338             :           NodeProperties::ChangeOp(
     339             :               control_node, common()->IfValue(parameters.value(),
     340             :                                               parameters.comparison_order(),
     341         952 :                                               BranchHint::kFalse));
     342             :         }
     343             :         return;
     344             :       }
     345             :       case IrOpcode::kIfDefault:
     346        6888 :         if (BranchHintOf(control_node->op()) != BranchHint::kFalse) {
     347             :           NodeProperties::ChangeOp(control_node,
     348        6888 :                                    common()->IfDefault(BranchHint::kFalse));
     349             :         }
     350             :         return;
     351             :       case IrOpcode::kIfTrue: {
     352      212025 :         Node* branch = NodeProperties::GetControlInput(control_node);
     353      212025 :         BranchHint hint = BranchOperatorInfoOf(branch->op()).hint;
     354      212025 :         if (hint == BranchHint::kTrue) {
     355             :           // The other possibility is also deferred, so the responsible branch
     356             :           // has to be before.
     357        7504 :           control_node = NodeProperties::GetControlInput(branch);
     358        7504 :           continue;
     359             :         }
     360             :         new_branch_hint = BranchHint::kFalse;
     361             :         responsible_branch = branch;
     362             :         break;
     363             :       }
     364             :       case IrOpcode::kIfFalse: {
     365      162581 :         Node* branch = NodeProperties::GetControlInput(control_node);
     366      162581 :         BranchHint hint = BranchOperatorInfoOf(branch->op()).hint;
     367      162581 :         if (hint == BranchHint::kFalse) {
     368             :           // The other possibility is also deferred, so the responsible branch
     369             :           // has to be before.
     370        5549 :           control_node = NodeProperties::GetControlInput(branch);
     371        5549 :           continue;
     372             :         }
     373             :         new_branch_hint = BranchHint::kTrue;
     374             :         responsible_branch = branch;
     375             :         break;
     376             :       }
     377             :       case IrOpcode::kMerge:
     378      853219 :         for (int i = 0; i < control_node->op()->ControlInputCount(); ++i) {
     379      246113 :           MarkControlDeferred(NodeProperties::GetControlInput(control_node, i));
     380             :         }
     381             :         return;
     382             :       case IrOpcode::kLoop:
     383           0 :         control_node = NodeProperties::GetControlInput(control_node, 0);
     384           0 :         continue;
     385             :       case IrOpcode::kBranch:
     386             :       case IrOpcode::kSwitch:
     387           0 :         UNREACHABLE();
     388             :       case IrOpcode::kStart:
     389             :         return;
     390             :       default:
     391             :         DCHECK_EQ(1, control_node->op()->ControlInputCount());
     392      135824 :         control_node = NodeProperties::GetControlInput(control_node);
     393      135824 :         continue;
     394             :     }
     395             :   }
     396             : 
     397      361553 :   BranchOperatorInfo info = BranchOperatorInfoOf(responsible_branch->op());
     398      361553 :   if (info.hint == new_branch_hint) return;
     399             :   NodeProperties::ChangeOp(
     400             :       responsible_branch,
     401      360601 :       common()->Branch(new_branch_hint, info.is_safety_check));
     402             : }
     403             : 
     404         224 : Node* RawMachineAssembler::TargetParameter() {
     405             :   DCHECK_NOT_NULL(target_parameter_);
     406         224 :   return target_parameter_;
     407             : }
     408             : 
     409      372424 : Node* RawMachineAssembler::Parameter(size_t index) {
     410             :   DCHECK_LT(index, parameter_count());
     411      744848 :   return parameters_[index];
     412             : }
     413             : 
     414             : 
     415     3855446 : void RawMachineAssembler::Goto(RawMachineLabel* label) {
     416             :   DCHECK(current_block_ != schedule()->end());
     417     1927723 :   schedule()->AddGoto(CurrentBlock(), Use(label));
     418     1927723 :   current_block_ = nullptr;
     419     1927723 : }
     420             : 
     421             : 
     422     1276671 : void RawMachineAssembler::Branch(Node* condition, RawMachineLabel* true_val,
     423     6383355 :                                  RawMachineLabel* false_val) {
     424             :   DCHECK(current_block_ != schedule()->end());
     425             :   Node* branch = MakeNode(
     426             :       common()->Branch(BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck), 1,
     427     2553342 :       &condition);
     428     1276671 :   BasicBlock* true_block = schedule()->NewBasicBlock();
     429     1276671 :   BasicBlock* false_block = schedule()->NewBasicBlock();
     430     2553342 :   schedule()->AddBranch(CurrentBlock(), branch, true_block, false_block);
     431             : 
     432     2553342 :   true_block->AddNode(MakeNode(common()->IfTrue(), 1, &branch));
     433     1276671 :   schedule()->AddGoto(true_block, Use(true_val));
     434             : 
     435     2553342 :   false_block->AddNode(MakeNode(common()->IfFalse(), 1, &branch));
     436     1276671 :   schedule()->AddGoto(false_block, Use(false_val));
     437             : 
     438     1276671 :   current_block_ = nullptr;
     439     1276671 : }
     440             : 
     441       12360 : void RawMachineAssembler::Continuations(Node* call, RawMachineLabel* if_success,
     442       12360 :                                         RawMachineLabel* if_exception) {
     443             :   DCHECK_NOT_NULL(schedule_);
     444             :   DCHECK_NOT_NULL(current_block_);
     445       12360 :   schedule()->AddCall(CurrentBlock(), call, Use(if_success), Use(if_exception));
     446       12360 :   current_block_ = nullptr;
     447       12360 : }
     448             : 
     449        9962 : void RawMachineAssembler::Switch(Node* index, RawMachineLabel* default_label,
     450             :                                  const int32_t* case_values,
     451             :                                  RawMachineLabel** case_labels,
     452      382694 :                                  size_t case_count) {
     453             :   DCHECK_NE(schedule()->end(), current_block_);
     454        9962 :   size_t succ_count = case_count + 1;
     455        9962 :   Node* switch_node = MakeNode(common()->Switch(succ_count), 1, &index);
     456             :   BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count);
     457       93183 :   for (size_t index = 0; index < case_count; ++index) {
     458       83221 :     int32_t case_value = case_values[index];
     459       83221 :     BasicBlock* case_block = schedule()->NewBasicBlock();
     460             :     Node* case_node =
     461       83221 :         graph()->NewNode(common()->IfValue(case_value), switch_node);
     462       83221 :     schedule()->AddNode(case_block, case_node);
     463      166442 :     schedule()->AddGoto(case_block, Use(case_labels[index]));
     464       83221 :     succ_blocks[index] = case_block;
     465             :   }
     466        9962 :   BasicBlock* default_block = schedule()->NewBasicBlock();
     467        9962 :   Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node);
     468        9962 :   schedule()->AddNode(default_block, default_node);
     469        9962 :   schedule()->AddGoto(default_block, Use(default_label));
     470        9962 :   succ_blocks[case_count] = default_block;
     471        9962 :   schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count);
     472        9962 :   current_block_ = nullptr;
     473        9962 : }
     474             : 
     475      599602 : void RawMachineAssembler::Return(Node* value) {
     476      299801 :   Node* values[] = {Int32Constant(0), value};
     477      299801 :   Node* ret = MakeNode(common()->Return(1), 2, values);
     478      299801 :   schedule()->AddReturn(CurrentBlock(), ret);
     479      299801 :   current_block_ = nullptr;
     480      299801 : }
     481             : 
     482           0 : void RawMachineAssembler::Return(Node* v1, Node* v2) {
     483           0 :   Node* values[] = {Int32Constant(0), v1, v2};
     484           0 :   Node* ret = MakeNode(common()->Return(2), 3, values);
     485           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     486           0 :   current_block_ = nullptr;
     487           0 : }
     488             : 
     489           0 : void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) {
     490           0 :   Node* values[] = {Int32Constant(0), v1, v2, v3};
     491           0 :   Node* ret = MakeNode(common()->Return(3), 4, values);
     492           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     493           0 :   current_block_ = nullptr;
     494           0 : }
     495             : 
     496           0 : void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3, Node* v4) {
     497           0 :   Node* values[] = {Int32Constant(0), v1, v2, v3, v4};
     498           0 :   Node* ret = MakeNode(common()->Return(4), 5, values);
     499           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     500           0 :   current_block_ = nullptr;
     501           0 : }
     502             : 
     503        1882 : void RawMachineAssembler::Return(int count, Node* vs[]) {
     504             :   typedef Node* Node_ptr;
     505         941 :   Node** values = new Node_ptr[count + 1];
     506         941 :   values[0] = Int32Constant(0);
     507         941 :   for (int i = 0; i < count; ++i) values[i + 1] = vs[i];
     508         941 :   Node* ret = MakeNode(common()->Return(count), count + 1, values);
     509         941 :   schedule()->AddReturn(CurrentBlock(), ret);
     510         941 :   current_block_ = nullptr;
     511         941 :   delete[] values;
     512         941 : }
     513             : 
     514       39260 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* value) {
     515       19630 :   Node* values[] = {pop, value};
     516       19630 :   Node* ret = MakeNode(common()->Return(1), 2, values);
     517       19630 :   schedule()->AddReturn(CurrentBlock(), ret);
     518       19630 :   current_block_ = nullptr;
     519       19630 : }
     520             : 
     521           0 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2) {
     522           0 :   Node* values[] = {pop, v1, v2};
     523           0 :   Node* ret = MakeNode(common()->Return(2), 3, values);
     524           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     525           0 :   current_block_ = nullptr;
     526           0 : }
     527             : 
     528           0 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2,
     529           0 :                                        Node* v3) {
     530           0 :   Node* values[] = {pop, v1, v2, v3};
     531           0 :   Node* ret = MakeNode(common()->Return(3), 4, values);
     532           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     533           0 :   current_block_ = nullptr;
     534           0 : }
     535             : 
     536           0 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3,
     537           0 :                                        Node* v4) {
     538           0 :   Node* values[] = {pop, v1, v2, v3, v4};
     539           0 :   Node* ret = MakeNode(common()->Return(4), 5, values);
     540           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     541           0 :   current_block_ = nullptr;
     542           0 : }
     543             : 
     544         525 : void RawMachineAssembler::DebugAbort(Node* message) {
     545         525 :   AddNode(machine()->DebugAbort(), message);
     546         525 : }
     547             : 
     548      134758 : void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); }
     549             : 
     550      128262 : void RawMachineAssembler::Unreachable() {
     551       64131 :   Node* ret = MakeNode(common()->Throw(), 0, nullptr);
     552       64131 :   schedule()->AddThrow(CurrentBlock(), ret);
     553       64131 :   current_block_ = nullptr;
     554       64131 : }
     555             : 
     556           5 : void RawMachineAssembler::Comment(std::string msg) {
     557           5 :   size_t length = msg.length() + 1;
     558             :   char* zone_buffer = zone()->NewArray<char>(length);
     559             :   MemCopy(zone_buffer, msg.c_str(), length);
     560           5 :   AddNode(machine()->Comment(zone_buffer));
     561           5 : }
     562             : 
     563      285027 : Node* RawMachineAssembler::CallN(CallDescriptor* call_descriptor,
     564             :                                  int input_count, Node* const* inputs) {
     565             :   DCHECK(!call_descriptor->NeedsFrameState());
     566             :   // +1 is for target.
     567             :   DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 1);
     568      285027 :   return AddNode(common()->Call(call_descriptor), input_count, inputs);
     569             : }
     570             : 
     571           3 : Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* call_descriptor,
     572             :                                                int input_count,
     573             :                                                Node* const* inputs) {
     574             :   DCHECK(call_descriptor->NeedsFrameState());
     575             :   // +2 is for target and frame state.
     576             :   DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 2);
     577           3 :   return AddNode(common()->Call(call_descriptor), input_count, inputs);
     578             : }
     579             : 
     580       62822 : Node* RawMachineAssembler::TailCallN(CallDescriptor* call_descriptor,
     581       62822 :                                      int input_count, Node* const* inputs) {
     582             :   // +1 is for target.
     583             :   DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 1);
     584             :   Node* tail_call =
     585       62822 :       MakeNode(common()->TailCall(call_descriptor), input_count, inputs);
     586       62822 :   schedule()->AddTailCall(CurrentBlock(), tail_call);
     587       62822 :   current_block_ = nullptr;
     588       62822 :   return tail_call;
     589             : }
     590             : 
     591           5 : Node* RawMachineAssembler::CallCFunction0(MachineType return_type,
     592             :                                           Node* function) {
     593             :   MachineSignature::Builder builder(zone(), 1, 0);
     594             :   builder.AddReturn(return_type);
     595             :   auto call_descriptor =
     596          10 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     597             : 
     598          10 :   return AddNode(common()->Call(call_descriptor), function);
     599             : }
     600             : 
     601             : 
     602         634 : Node* RawMachineAssembler::CallCFunction1(MachineType return_type,
     603             :                                           MachineType arg0_type, Node* function,
     604             :                                           Node* arg0) {
     605             :   MachineSignature::Builder builder(zone(), 1, 1);
     606             :   builder.AddReturn(return_type);
     607             :   builder.AddParam(arg0_type);
     608             :   auto call_descriptor =
     609        1268 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     610             : 
     611        1268 :   return AddNode(common()->Call(call_descriptor), function, arg0);
     612             : }
     613             : 
     614         224 : Node* RawMachineAssembler::CallCFunction1WithCallerSavedRegisters(
     615             :     MachineType return_type, MachineType arg0_type, Node* function, Node* arg0,
     616             :     SaveFPRegsMode mode) {
     617             :   MachineSignature::Builder builder(zone(), 1, 1);
     618             :   builder.AddReturn(return_type);
     619             :   builder.AddParam(arg0_type);
     620             :   auto call_descriptor =
     621         448 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     622             : 
     623             :   call_descriptor->set_save_fp_mode(mode);
     624             : 
     625             :   return AddNode(common()->CallWithCallerSavedRegisters(call_descriptor),
     626         448 :                  function, arg0);
     627             : }
     628             : 
     629        4500 : Node* RawMachineAssembler::CallCFunction2(MachineType return_type,
     630             :                                           MachineType arg0_type,
     631             :                                           MachineType arg1_type, Node* function,
     632             :                                           Node* arg0, Node* arg1) {
     633             :   MachineSignature::Builder builder(zone(), 1, 2);
     634             :   builder.AddReturn(return_type);
     635             :   builder.AddParam(arg0_type);
     636             :   builder.AddParam(arg1_type);
     637             :   auto call_descriptor =
     638        9000 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     639             : 
     640        9000 :   return AddNode(common()->Call(call_descriptor), function, arg0, arg1);
     641             : }
     642             : 
     643        6326 : Node* RawMachineAssembler::CallCFunction3(MachineType return_type,
     644             :                                           MachineType arg0_type,
     645             :                                           MachineType arg1_type,
     646             :                                           MachineType arg2_type, Node* function,
     647             :                                           Node* arg0, Node* arg1, Node* arg2) {
     648             :   MachineSignature::Builder builder(zone(), 1, 3);
     649             :   builder.AddReturn(return_type);
     650             :   builder.AddParam(arg0_type);
     651             :   builder.AddParam(arg1_type);
     652             :   builder.AddParam(arg2_type);
     653             :   auto call_descriptor =
     654       12652 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     655             : 
     656       12652 :   return AddNode(common()->Call(call_descriptor), function, arg0, arg1, arg2);
     657             : }
     658             : 
     659         117 : Node* RawMachineAssembler::CallCFunction3WithCallerSavedRegisters(
     660             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     661             :     MachineType arg2_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
     662             :     SaveFPRegsMode mode) {
     663             :   MachineSignature::Builder builder(zone(), 1, 3);
     664             :   builder.AddReturn(return_type);
     665             :   builder.AddParam(arg0_type);
     666             :   builder.AddParam(arg1_type);
     667             :   builder.AddParam(arg2_type);
     668             :   auto call_descriptor =
     669         234 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     670             : 
     671             :   call_descriptor->set_save_fp_mode(mode);
     672             : 
     673             :   return AddNode(common()->CallWithCallerSavedRegisters(call_descriptor),
     674         234 :                  function, arg0, arg1, arg2);
     675             : }
     676             : 
     677         112 : Node* RawMachineAssembler::CallCFunction4(
     678             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     679             :     MachineType arg2_type, MachineType arg3_type, Node* function, Node* arg0,
     680             :     Node* arg1, Node* arg2, Node* arg3) {
     681             :   MachineSignature::Builder builder(zone(), 1, 4);
     682             :   builder.AddReturn(return_type);
     683             :   builder.AddParam(arg0_type);
     684             :   builder.AddParam(arg1_type);
     685             :   builder.AddParam(arg2_type);
     686             :   builder.AddParam(arg3_type);
     687             :   auto call_descriptor =
     688         224 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     689             : 
     690             :   return AddNode(common()->Call(call_descriptor), function, arg0, arg1, arg2,
     691         224 :                  arg3);
     692             : }
     693             : 
     694         280 : Node* RawMachineAssembler::CallCFunction5(
     695             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     696             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     697             :     Node* function, Node* arg0, Node* arg1, Node* arg2, Node* arg3,
     698             :     Node* arg4) {
     699             :   MachineSignature::Builder builder(zone(), 1, 5);
     700             :   builder.AddReturn(return_type);
     701             :   builder.AddParam(arg0_type);
     702             :   builder.AddParam(arg1_type);
     703             :   builder.AddParam(arg2_type);
     704             :   builder.AddParam(arg3_type);
     705             :   builder.AddParam(arg4_type);
     706             :   auto call_descriptor =
     707         560 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     708             : 
     709             :   return AddNode(common()->Call(call_descriptor), function, arg0, arg1, arg2,
     710         560 :                  arg3, arg4);
     711             : }
     712             : 
     713         672 : Node* RawMachineAssembler::CallCFunction6(
     714             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     715             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     716             :     MachineType arg5_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
     717             :     Node* arg3, Node* arg4, Node* arg5) {
     718             :   MachineSignature::Builder builder(zone(), 1, 6);
     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             :   auto call_descriptor =
     727        1344 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     728             : 
     729             :   return AddNode(common()->Call(call_descriptor), function, arg0, arg1, arg2,
     730        1344 :                  arg3, arg4, arg5);
     731             : }
     732             : 
     733           5 : Node* RawMachineAssembler::CallCFunction8(
     734             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     735             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     736             :     MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
     737             :     Node* function, Node* arg0, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
     738             :     Node* arg5, Node* arg6, Node* arg7) {
     739             :   MachineSignature::Builder builder(zone(), 1, 8);
     740             :   builder.AddReturn(return_type);
     741             :   builder.AddParam(arg0_type);
     742             :   builder.AddParam(arg1_type);
     743             :   builder.AddParam(arg2_type);
     744             :   builder.AddParam(arg3_type);
     745             :   builder.AddParam(arg4_type);
     746             :   builder.AddParam(arg5_type);
     747             :   builder.AddParam(arg6_type);
     748             :   builder.AddParam(arg7_type);
     749           5 :   Node* args[] = {function, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
     750             :   auto call_descriptor =
     751          10 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     752           5 :   return AddNode(common()->Call(call_descriptor), arraysize(args), args);
     753             : }
     754             : 
     755         570 : Node* RawMachineAssembler::CallCFunction9(
     756             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     757             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     758             :     MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
     759             :     MachineType arg8_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
     760             :     Node* arg3, Node* arg4, Node* arg5, Node* arg6, Node* arg7, Node* arg8) {
     761             :   MachineSignature::Builder builder(zone(), 1, 9);
     762             :   builder.AddReturn(return_type);
     763             :   builder.AddParam(arg0_type);
     764             :   builder.AddParam(arg1_type);
     765             :   builder.AddParam(arg2_type);
     766             :   builder.AddParam(arg3_type);
     767             :   builder.AddParam(arg4_type);
     768             :   builder.AddParam(arg5_type);
     769             :   builder.AddParam(arg6_type);
     770             :   builder.AddParam(arg7_type);
     771             :   builder.AddParam(arg8_type);
     772             :   Node* args[] = {function, arg0, arg1, arg2, arg3,
     773         570 :                   arg4,     arg5, arg6, arg7, arg8};
     774             :   auto call_descriptor =
     775        1140 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     776         570 :   return AddNode(common()->Call(call_descriptor), arraysize(args), args);
     777             : }
     778             : 
     779           0 : BasicBlock* RawMachineAssembler::Use(RawMachineLabel* label) {
     780     4598968 :   label->used_ = true;
     781           0 :   return EnsureBlock(label);
     782             : }
     783             : 
     784     3380264 : BasicBlock* RawMachineAssembler::EnsureBlock(RawMachineLabel* label) {
     785     7979232 :   if (label->block_ == nullptr) {
     786     3380264 :     label->block_ = schedule()->NewBasicBlock();
     787             :   }
     788     7979232 :   return label->block_;
     789             : }
     790             : 
     791     3380264 : void RawMachineAssembler::Bind(RawMachineLabel* label) {
     792             :   DCHECK_NULL(current_block_);
     793             :   DCHECK(!label->bound_);
     794     3380264 :   label->bound_ = true;
     795     3380264 :   current_block_ = EnsureBlock(label);
     796     3380264 :   current_block_->set_deferred(label->deferred_);
     797     3380264 : }
     798             : 
     799             : #if DEBUG
     800             : void RawMachineAssembler::Bind(RawMachineLabel* label,
     801             :                                AssemblerDebugInfo info) {
     802             :   if (current_block_ != nullptr) {
     803             :     std::stringstream str;
     804             :     str << "Binding label without closing previous block:"
     805             :         << "\n#    label:          " << info
     806             :         << "\n#    previous block: " << *current_block_;
     807             :     FATAL("%s", str.str().c_str());
     808             :   }
     809             :   Bind(label);
     810             :   current_block_->set_debug_info(info);
     811             : }
     812             : 
     813             : void RawMachineAssembler::PrintCurrentBlock(std::ostream& os) {
     814             :   os << CurrentBlock();
     815             : }
     816             : 
     817             : void RawMachineAssembler::SetInitialDebugInformation(
     818             :     AssemblerDebugInfo debug_info) {
     819             :   CurrentBlock()->set_debug_info(debug_info);
     820             : }
     821             : #endif  // DEBUG
     822             : 
     823        2184 : bool RawMachineAssembler::InsideBlock() { return current_block_ != nullptr; }
     824             : 
     825           0 : BasicBlock* RawMachineAssembler::CurrentBlock() {
     826             :   DCHECK(current_block_);
     827    24043822 :   return current_block_;
     828             : }
     829             : 
     830     3988219 : Node* RawMachineAssembler::Phi(MachineRepresentation rep, int input_count,
     831     3988219 :                                Node* const* inputs) {
     832     3988219 :   Node** buffer = new (zone()->New(sizeof(Node*) * (input_count + 1)))
     833     3988219 :       Node*[input_count + 1];
     834     3988219 :   std::copy(inputs, inputs + input_count, buffer);
     835     7976438 :   buffer[input_count] = graph()->start();
     836     3988219 :   return AddNode(common()->Phi(rep, input_count), input_count + 1, buffer);
     837             : }
     838             : 
     839      284557 : void RawMachineAssembler::AppendPhiInput(Node* phi, Node* new_input) {
     840             :   const Operator* op = phi->op();
     841      284557 :   const Operator* new_op = common()->ResizeMergeOrPhi(op, phi->InputCount());
     842      569114 :   phi->InsertInput(zone(), phi->InputCount() - 1, new_input);
     843      284557 :   NodeProperties::ChangeOp(phi, new_op);
     844      284557 : }
     845             : 
     846    20369781 : Node* RawMachineAssembler::AddNode(const Operator* op, int input_count,
     847    20369781 :                                    Node* const* inputs) {
     848             :   DCHECK_NOT_NULL(schedule_);
     849             :   DCHECK_NOT_NULL(current_block_);
     850             :   Node* node = MakeNode(op, input_count, inputs);
     851    20369781 :   schedule()->AddNode(CurrentBlock(), node);
     852    20369781 :   return node;
     853             : }
     854             : 
     855           0 : Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
     856    24657081 :                                     Node* const* inputs) {
     857             :   // The raw machine assembler nodes do not have effect and control inputs,
     858             :   // so we disable checking input counts here.
     859    24657081 :   return graph()->NewNodeUnchecked(op, input_count, inputs);
     860             : }
     861             : 
     862     3485240 : RawMachineLabel::~RawMachineLabel() {
     863             : #if DEBUG
     864             :   if (bound_ == used_) return;
     865             :   std::stringstream str;
     866             :   if (bound_) {
     867             :     str << "A label has been bound but it's not used."
     868             :         << "\n#    label: " << *block_;
     869             :   } else {
     870             :     str << "A label has been used but it's not bound.";
     871             :   }
     872             :   FATAL("%s", str.str().c_str());
     873             : #endif  // DEBUG
     874     3485240 : }
     875             : 
     876             : }  // namespace compiler
     877             : }  // namespace internal
     878      183867 : }  // namespace v8

Generated by: LCOV version 1.10