LCOV - code coverage report
Current view: top level - src/compiler - raw-machine-assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 332 389 85.3 %
Date: 2019-02-19 Functions: 46 58 79.3 %

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

Generated by: LCOV version 1.10