Home | History | Annotate | Download | only in compiler
      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/instruction-selector.h"
      6 
      7 #include "src/compiler/instruction-selector-impl.h"
      8 #include "src/compiler/node-matchers.h"
      9 #include "src/compiler/node-properties-inl.h"
     10 #include "src/compiler/pipeline.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 namespace compiler {
     15 
     16 InstructionSelector::InstructionSelector(InstructionSequence* sequence,
     17                                          SourcePositionTable* source_positions,
     18                                          Features features)
     19     : zone_(sequence->isolate()),
     20       sequence_(sequence),
     21       source_positions_(source_positions),
     22       features_(features),
     23       current_block_(NULL),
     24       instructions_(zone()),
     25       defined_(graph()->NodeCount(), false, zone()),
     26       used_(graph()->NodeCount(), false, zone()) {}
     27 
     28 
     29 void InstructionSelector::SelectInstructions() {
     30   // Mark the inputs of all phis in loop headers as used.
     31   BasicBlockVector* blocks = schedule()->rpo_order();
     32   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
     33     BasicBlock* block = *i;
     34     if (!block->IsLoopHeader()) continue;
     35     DCHECK_NE(0, block->PredecessorCount());
     36     DCHECK_NE(1, block->PredecessorCount());
     37     for (BasicBlock::const_iterator j = block->begin(); j != block->end();
     38          ++j) {
     39       Node* phi = *j;
     40       if (phi->opcode() != IrOpcode::kPhi) continue;
     41 
     42       // Mark all inputs as used.
     43       Node::Inputs inputs = phi->inputs();
     44       for (InputIter k = inputs.begin(); k != inputs.end(); ++k) {
     45         MarkAsUsed(*k);
     46       }
     47     }
     48   }
     49 
     50   // Visit each basic block in post order.
     51   for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) {
     52     VisitBlock(*i);
     53   }
     54 
     55   // Schedule the selected instructions.
     56   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
     57     BasicBlock* block = *i;
     58     size_t end = block->code_end_;
     59     size_t start = block->code_start_;
     60     sequence()->StartBlock(block);
     61     while (start-- > end) {
     62       sequence()->AddInstruction(instructions_[start], block);
     63     }
     64     sequence()->EndBlock(block);
     65   }
     66 }
     67 
     68 
     69 Instruction* InstructionSelector::Emit(InstructionCode opcode,
     70                                        InstructionOperand* output,
     71                                        size_t temp_count,
     72                                        InstructionOperand** temps) {
     73   size_t output_count = output == NULL ? 0 : 1;
     74   return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps);
     75 }
     76 
     77 
     78 Instruction* InstructionSelector::Emit(InstructionCode opcode,
     79                                        InstructionOperand* output,
     80                                        InstructionOperand* a, size_t temp_count,
     81                                        InstructionOperand** temps) {
     82   size_t output_count = output == NULL ? 0 : 1;
     83   return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
     84 }
     85 
     86 
     87 Instruction* InstructionSelector::Emit(InstructionCode opcode,
     88                                        InstructionOperand* output,
     89                                        InstructionOperand* a,
     90                                        InstructionOperand* b, size_t temp_count,
     91                                        InstructionOperand** temps) {
     92   size_t output_count = output == NULL ? 0 : 1;
     93   InstructionOperand* inputs[] = {a, b};
     94   size_t input_count = arraysize(inputs);
     95   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
     96               temps);
     97 }
     98 
     99 
    100 Instruction* InstructionSelector::Emit(InstructionCode opcode,
    101                                        InstructionOperand* output,
    102                                        InstructionOperand* a,
    103                                        InstructionOperand* b,
    104                                        InstructionOperand* c, size_t temp_count,
    105                                        InstructionOperand** temps) {
    106   size_t output_count = output == NULL ? 0 : 1;
    107   InstructionOperand* inputs[] = {a, b, c};
    108   size_t input_count = arraysize(inputs);
    109   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
    110               temps);
    111 }
    112 
    113 
    114 Instruction* InstructionSelector::Emit(
    115     InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
    116     InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
    117     size_t temp_count, InstructionOperand** temps) {
    118   size_t output_count = output == NULL ? 0 : 1;
    119   InstructionOperand* inputs[] = {a, b, c, d};
    120   size_t input_count = arraysize(inputs);
    121   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
    122               temps);
    123 }
    124 
    125 
    126 Instruction* InstructionSelector::Emit(
    127     InstructionCode opcode, size_t output_count, InstructionOperand** outputs,
    128     size_t input_count, InstructionOperand** inputs, size_t temp_count,
    129     InstructionOperand** temps) {
    130   Instruction* instr =
    131       Instruction::New(instruction_zone(), opcode, output_count, outputs,
    132                        input_count, inputs, temp_count, temps);
    133   return Emit(instr);
    134 }
    135 
    136 
    137 Instruction* InstructionSelector::Emit(Instruction* instr) {
    138   instructions_.push_back(instr);
    139   return instr;
    140 }
    141 
    142 
    143 bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
    144   return block->rpo_number_ == (current_block_->rpo_number_ + 1) &&
    145          block->deferred_ == current_block_->deferred_;
    146 }
    147 
    148 
    149 bool InstructionSelector::CanCover(Node* user, Node* node) const {
    150   return node->OwnedBy(user) &&
    151          schedule()->block(node) == schedule()->block(user);
    152 }
    153 
    154 
    155 bool InstructionSelector::IsDefined(Node* node) const {
    156   DCHECK_NOT_NULL(node);
    157   NodeId id = node->id();
    158   DCHECK(id >= 0);
    159   DCHECK(id < static_cast<NodeId>(defined_.size()));
    160   return defined_[id];
    161 }
    162 
    163 
    164 void InstructionSelector::MarkAsDefined(Node* node) {
    165   DCHECK_NOT_NULL(node);
    166   NodeId id = node->id();
    167   DCHECK(id >= 0);
    168   DCHECK(id < static_cast<NodeId>(defined_.size()));
    169   defined_[id] = true;
    170 }
    171 
    172 
    173 bool InstructionSelector::IsUsed(Node* node) const {
    174   if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
    175   NodeId id = node->id();
    176   DCHECK(id >= 0);
    177   DCHECK(id < static_cast<NodeId>(used_.size()));
    178   return used_[id];
    179 }
    180 
    181 
    182 void InstructionSelector::MarkAsUsed(Node* node) {
    183   DCHECK_NOT_NULL(node);
    184   NodeId id = node->id();
    185   DCHECK(id >= 0);
    186   DCHECK(id < static_cast<NodeId>(used_.size()));
    187   used_[id] = true;
    188 }
    189 
    190 
    191 bool InstructionSelector::IsDouble(const Node* node) const {
    192   DCHECK_NOT_NULL(node);
    193   return sequence()->IsDouble(node->id());
    194 }
    195 
    196 
    197 void InstructionSelector::MarkAsDouble(Node* node) {
    198   DCHECK_NOT_NULL(node);
    199   DCHECK(!IsReference(node));
    200   sequence()->MarkAsDouble(node->id());
    201 }
    202 
    203 
    204 bool InstructionSelector::IsReference(const Node* node) const {
    205   DCHECK_NOT_NULL(node);
    206   return sequence()->IsReference(node->id());
    207 }
    208 
    209 
    210 void InstructionSelector::MarkAsReference(Node* node) {
    211   DCHECK_NOT_NULL(node);
    212   DCHECK(!IsDouble(node));
    213   sequence()->MarkAsReference(node->id());
    214 }
    215 
    216 
    217 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
    218   DCHECK_NOT_NULL(node);
    219   switch (RepresentationOf(rep)) {
    220     case kRepFloat32:
    221     case kRepFloat64:
    222       MarkAsDouble(node);
    223       break;
    224     case kRepTagged:
    225       MarkAsReference(node);
    226       break;
    227     default:
    228       break;
    229   }
    230 }
    231 
    232 
    233 // TODO(bmeurer): Get rid of the CallBuffer business and make
    234 // InstructionSelector::VisitCall platform independent instead.
    235 CallBuffer::CallBuffer(Zone* zone, CallDescriptor* d,
    236                        FrameStateDescriptor* frame_desc)
    237     : descriptor(d),
    238       frame_state_descriptor(frame_desc),
    239       output_nodes(zone),
    240       outputs(zone),
    241       instruction_args(zone),
    242       pushed_nodes(zone) {
    243   output_nodes.reserve(d->ReturnCount());
    244   outputs.reserve(d->ReturnCount());
    245   pushed_nodes.reserve(input_count());
    246   instruction_args.reserve(input_count() + frame_state_value_count());
    247 }
    248 
    249 
    250 // TODO(bmeurer): Get rid of the CallBuffer business and make
    251 // InstructionSelector::VisitCall platform independent instead.
    252 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
    253                                                bool call_code_immediate,
    254                                                bool call_address_immediate) {
    255   OperandGenerator g(this);
    256   DCHECK_EQ(call->op()->OutputCount(), buffer->descriptor->ReturnCount());
    257   DCHECK_EQ(OperatorProperties::GetValueInputCount(call->op()),
    258             buffer->input_count() + buffer->frame_state_count());
    259 
    260   if (buffer->descriptor->ReturnCount() > 0) {
    261     // Collect the projections that represent multiple outputs from this call.
    262     if (buffer->descriptor->ReturnCount() == 1) {
    263       buffer->output_nodes.push_back(call);
    264     } else {
    265       buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL);
    266       call->CollectProjections(&buffer->output_nodes);
    267     }
    268 
    269     // Filter out the outputs that aren't live because no projection uses them.
    270     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
    271       if (buffer->output_nodes[i] != NULL) {
    272         Node* output = buffer->output_nodes[i];
    273         MachineType type =
    274             buffer->descriptor->GetReturnType(static_cast<int>(i));
    275         LinkageLocation location =
    276             buffer->descriptor->GetReturnLocation(static_cast<int>(i));
    277         MarkAsRepresentation(type, output);
    278         buffer->outputs.push_back(g.DefineAsLocation(output, location, type));
    279       }
    280     }
    281   }
    282 
    283   // The first argument is always the callee code.
    284   Node* callee = call->InputAt(0);
    285   switch (buffer->descriptor->kind()) {
    286     case CallDescriptor::kCallCodeObject:
    287       buffer->instruction_args.push_back(
    288           (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
    289               ? g.UseImmediate(callee)
    290               : g.UseRegister(callee));
    291       break;
    292     case CallDescriptor::kCallAddress:
    293       buffer->instruction_args.push_back(
    294           (call_address_immediate &&
    295            (callee->opcode() == IrOpcode::kInt32Constant ||
    296             callee->opcode() == IrOpcode::kInt64Constant))
    297               ? g.UseImmediate(callee)
    298               : g.UseRegister(callee));
    299       break;
    300     case CallDescriptor::kCallJSFunction:
    301       buffer->instruction_args.push_back(
    302           g.UseLocation(callee, buffer->descriptor->GetInputLocation(0),
    303                         buffer->descriptor->GetInputType(0)));
    304       break;
    305   }
    306   DCHECK_EQ(1, buffer->instruction_args.size());
    307 
    308   // If the call needs a frame state, we insert the state information as
    309   // follows (n is the number of value inputs to the frame state):
    310   // arg 1               : deoptimization id.
    311   // arg 2 - arg (n + 1) : value inputs to the frame state.
    312   if (buffer->frame_state_descriptor != NULL) {
    313     InstructionSequence::StateId state_id =
    314         sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
    315     buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
    316 
    317     Node* frame_state =
    318         call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
    319     AddFrameStateInputs(frame_state, &buffer->instruction_args,
    320                         buffer->frame_state_descriptor);
    321   }
    322   DCHECK(1 + buffer->frame_state_value_count() ==
    323          buffer->instruction_args.size());
    324 
    325   size_t input_count = static_cast<size_t>(buffer->input_count());
    326 
    327   // Split the arguments into pushed_nodes and instruction_args. Pushed
    328   // arguments require an explicit push instruction before the call and do
    329   // not appear as arguments to the call. Everything else ends up
    330   // as an InstructionOperand argument to the call.
    331   InputIter iter(call->inputs().begin());
    332   int pushed_count = 0;
    333   for (size_t index = 0; index < input_count; ++iter, ++index) {
    334     DCHECK(iter != call->inputs().end());
    335     DCHECK(index == static_cast<size_t>(iter.index()));
    336     DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
    337     if (index == 0) continue;  // The first argument (callee) is already done.
    338     InstructionOperand* op =
    339         g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index),
    340                       buffer->descriptor->GetInputType(index));
    341     if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) {
    342       int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1;
    343       if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
    344         buffer->pushed_nodes.resize(stack_index + 1, NULL);
    345       }
    346       DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]);
    347       buffer->pushed_nodes[stack_index] = *iter;
    348       pushed_count++;
    349     } else {
    350       buffer->instruction_args.push_back(op);
    351     }
    352   }
    353   CHECK_EQ(pushed_count, static_cast<int>(buffer->pushed_nodes.size()));
    354   DCHECK(static_cast<size_t>(input_count) ==
    355          (buffer->instruction_args.size() + buffer->pushed_nodes.size() -
    356           buffer->frame_state_value_count()));
    357 }
    358 
    359 
    360 void InstructionSelector::VisitBlock(BasicBlock* block) {
    361   DCHECK_EQ(NULL, current_block_);
    362   current_block_ = block;
    363   int current_block_end = static_cast<int>(instructions_.size());
    364 
    365   // Generate code for the block control "top down", but schedule the code
    366   // "bottom up".
    367   VisitControl(block);
    368   std::reverse(instructions_.begin() + current_block_end, instructions_.end());
    369 
    370   // Visit code in reverse control flow order, because architecture-specific
    371   // matching may cover more than one node at a time.
    372   for (BasicBlock::reverse_iterator i = block->rbegin(); i != block->rend();
    373        ++i) {
    374     Node* node = *i;
    375     // Skip nodes that are unused or already defined.
    376     if (!IsUsed(node) || IsDefined(node)) continue;
    377     // Generate code for this node "top down", but schedule the code "bottom
    378     // up".
    379     size_t current_node_end = instructions_.size();
    380     VisitNode(node);
    381     std::reverse(instructions_.begin() + current_node_end, instructions_.end());
    382   }
    383 
    384   // We're done with the block.
    385   // TODO(bmeurer): We should not mutate the schedule.
    386   block->code_end_ = current_block_end;
    387   block->code_start_ = static_cast<int>(instructions_.size());
    388 
    389   current_block_ = NULL;
    390 }
    391 
    392 
    393 static inline void CheckNoPhis(const BasicBlock* block) {
    394 #ifdef DEBUG
    395   // Branch targets should not have phis.
    396   for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) {
    397     const Node* node = *i;
    398     CHECK_NE(IrOpcode::kPhi, node->opcode());
    399   }
    400 #endif
    401 }
    402 
    403 
    404 void InstructionSelector::VisitControl(BasicBlock* block) {
    405   Node* input = block->control_input_;
    406   switch (block->control_) {
    407     case BasicBlockData::kGoto:
    408       return VisitGoto(block->SuccessorAt(0));
    409     case BasicBlockData::kBranch: {
    410       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
    411       BasicBlock* tbranch = block->SuccessorAt(0);
    412       BasicBlock* fbranch = block->SuccessorAt(1);
    413       // SSA deconstruction requires targets of branches not to have phis.
    414       // Edge split form guarantees this property, but is more strict.
    415       CheckNoPhis(tbranch);
    416       CheckNoPhis(fbranch);
    417       if (tbranch == fbranch) return VisitGoto(tbranch);
    418       return VisitBranch(input, tbranch, fbranch);
    419     }
    420     case BasicBlockData::kReturn: {
    421       // If the result itself is a return, return its input.
    422       Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
    423                         ? input->InputAt(0)
    424                         : input;
    425       return VisitReturn(value);
    426     }
    427     case BasicBlockData::kThrow:
    428       return VisitThrow(input);
    429     case BasicBlockData::kNone: {
    430       // TODO(titzer): exit block doesn't have control.
    431       DCHECK(input == NULL);
    432       break;
    433     }
    434     default:
    435       UNREACHABLE();
    436       break;
    437   }
    438 }
    439 
    440 
    441 void InstructionSelector::VisitNode(Node* node) {
    442   DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
    443   SourcePosition source_position = source_positions_->GetSourcePosition(node);
    444   if (!source_position.IsUnknown()) {
    445     DCHECK(!source_position.IsInvalid());
    446     if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) {
    447       Emit(SourcePositionInstruction::New(instruction_zone(), source_position));
    448     }
    449   }
    450   switch (node->opcode()) {
    451     case IrOpcode::kStart:
    452     case IrOpcode::kLoop:
    453     case IrOpcode::kEnd:
    454     case IrOpcode::kBranch:
    455     case IrOpcode::kIfTrue:
    456     case IrOpcode::kIfFalse:
    457     case IrOpcode::kEffectPhi:
    458     case IrOpcode::kMerge:
    459       // No code needed for these graph artifacts.
    460       return;
    461     case IrOpcode::kFinish:
    462       return MarkAsReference(node), VisitFinish(node);
    463     case IrOpcode::kParameter: {
    464       MachineType type = linkage()->GetParameterType(OpParameter<int>(node));
    465       MarkAsRepresentation(type, node);
    466       return VisitParameter(node);
    467     }
    468     case IrOpcode::kPhi: {
    469       MachineType type = OpParameter<MachineType>(node);
    470       MarkAsRepresentation(type, node);
    471       return VisitPhi(node);
    472     }
    473     case IrOpcode::kProjection:
    474       return VisitProjection(node);
    475     case IrOpcode::kInt32Constant:
    476     case IrOpcode::kInt64Constant:
    477     case IrOpcode::kExternalConstant:
    478       return VisitConstant(node);
    479     case IrOpcode::kFloat64Constant:
    480       return MarkAsDouble(node), VisitConstant(node);
    481     case IrOpcode::kHeapConstant:
    482     case IrOpcode::kNumberConstant:
    483       // TODO(turbofan): only mark non-smis as references.
    484       return MarkAsReference(node), VisitConstant(node);
    485     case IrOpcode::kCall:
    486       return VisitCall(node, NULL, NULL);
    487     case IrOpcode::kFrameState:
    488     case IrOpcode::kStateValues:
    489       return;
    490     case IrOpcode::kLoad: {
    491       LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
    492       MarkAsRepresentation(rep, node);
    493       return VisitLoad(node);
    494     }
    495     case IrOpcode::kStore:
    496       return VisitStore(node);
    497     case IrOpcode::kWord32And:
    498       return VisitWord32And(node);
    499     case IrOpcode::kWord32Or:
    500       return VisitWord32Or(node);
    501     case IrOpcode::kWord32Xor:
    502       return VisitWord32Xor(node);
    503     case IrOpcode::kWord32Shl:
    504       return VisitWord32Shl(node);
    505     case IrOpcode::kWord32Shr:
    506       return VisitWord32Shr(node);
    507     case IrOpcode::kWord32Sar:
    508       return VisitWord32Sar(node);
    509     case IrOpcode::kWord32Ror:
    510       return VisitWord32Ror(node);
    511     case IrOpcode::kWord32Equal:
    512       return VisitWord32Equal(node);
    513     case IrOpcode::kWord64And:
    514       return VisitWord64And(node);
    515     case IrOpcode::kWord64Or:
    516       return VisitWord64Or(node);
    517     case IrOpcode::kWord64Xor:
    518       return VisitWord64Xor(node);
    519     case IrOpcode::kWord64Shl:
    520       return VisitWord64Shl(node);
    521     case IrOpcode::kWord64Shr:
    522       return VisitWord64Shr(node);
    523     case IrOpcode::kWord64Sar:
    524       return VisitWord64Sar(node);
    525     case IrOpcode::kWord64Ror:
    526       return VisitWord64Ror(node);
    527     case IrOpcode::kWord64Equal:
    528       return VisitWord64Equal(node);
    529     case IrOpcode::kInt32Add:
    530       return VisitInt32Add(node);
    531     case IrOpcode::kInt32AddWithOverflow:
    532       return VisitInt32AddWithOverflow(node);
    533     case IrOpcode::kInt32Sub:
    534       return VisitInt32Sub(node);
    535     case IrOpcode::kInt32SubWithOverflow:
    536       return VisitInt32SubWithOverflow(node);
    537     case IrOpcode::kInt32Mul:
    538       return VisitInt32Mul(node);
    539     case IrOpcode::kInt32Div:
    540       return VisitInt32Div(node);
    541     case IrOpcode::kInt32UDiv:
    542       return VisitInt32UDiv(node);
    543     case IrOpcode::kInt32Mod:
    544       return VisitInt32Mod(node);
    545     case IrOpcode::kInt32UMod:
    546       return VisitInt32UMod(node);
    547     case IrOpcode::kInt32LessThan:
    548       return VisitInt32LessThan(node);
    549     case IrOpcode::kInt32LessThanOrEqual:
    550       return VisitInt32LessThanOrEqual(node);
    551     case IrOpcode::kUint32LessThan:
    552       return VisitUint32LessThan(node);
    553     case IrOpcode::kUint32LessThanOrEqual:
    554       return VisitUint32LessThanOrEqual(node);
    555     case IrOpcode::kInt64Add:
    556       return VisitInt64Add(node);
    557     case IrOpcode::kInt64Sub:
    558       return VisitInt64Sub(node);
    559     case IrOpcode::kInt64Mul:
    560       return VisitInt64Mul(node);
    561     case IrOpcode::kInt64Div:
    562       return VisitInt64Div(node);
    563     case IrOpcode::kInt64UDiv:
    564       return VisitInt64UDiv(node);
    565     case IrOpcode::kInt64Mod:
    566       return VisitInt64Mod(node);
    567     case IrOpcode::kInt64UMod:
    568       return VisitInt64UMod(node);
    569     case IrOpcode::kInt64LessThan:
    570       return VisitInt64LessThan(node);
    571     case IrOpcode::kInt64LessThanOrEqual:
    572       return VisitInt64LessThanOrEqual(node);
    573     case IrOpcode::kChangeInt32ToFloat64:
    574       return MarkAsDouble(node), VisitChangeInt32ToFloat64(node);
    575     case IrOpcode::kChangeUint32ToFloat64:
    576       return MarkAsDouble(node), VisitChangeUint32ToFloat64(node);
    577     case IrOpcode::kChangeFloat64ToInt32:
    578       return VisitChangeFloat64ToInt32(node);
    579     case IrOpcode::kChangeFloat64ToUint32:
    580       return VisitChangeFloat64ToUint32(node);
    581     case IrOpcode::kChangeInt32ToInt64:
    582       return VisitChangeInt32ToInt64(node);
    583     case IrOpcode::kChangeUint32ToUint64:
    584       return VisitChangeUint32ToUint64(node);
    585     case IrOpcode::kTruncateFloat64ToInt32:
    586       return VisitTruncateFloat64ToInt32(node);
    587     case IrOpcode::kTruncateInt64ToInt32:
    588       return VisitTruncateInt64ToInt32(node);
    589     case IrOpcode::kFloat64Add:
    590       return MarkAsDouble(node), VisitFloat64Add(node);
    591     case IrOpcode::kFloat64Sub:
    592       return MarkAsDouble(node), VisitFloat64Sub(node);
    593     case IrOpcode::kFloat64Mul:
    594       return MarkAsDouble(node), VisitFloat64Mul(node);
    595     case IrOpcode::kFloat64Div:
    596       return MarkAsDouble(node), VisitFloat64Div(node);
    597     case IrOpcode::kFloat64Mod:
    598       return MarkAsDouble(node), VisitFloat64Mod(node);
    599     case IrOpcode::kFloat64Sqrt:
    600       return MarkAsDouble(node), VisitFloat64Sqrt(node);
    601     case IrOpcode::kFloat64Equal:
    602       return VisitFloat64Equal(node);
    603     case IrOpcode::kFloat64LessThan:
    604       return VisitFloat64LessThan(node);
    605     case IrOpcode::kFloat64LessThanOrEqual:
    606       return VisitFloat64LessThanOrEqual(node);
    607     default:
    608       V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
    609                node->opcode(), node->op()->mnemonic(), node->id());
    610   }
    611 }
    612 
    613 
    614 #if V8_TURBOFAN_BACKEND
    615 
    616 void InstructionSelector::VisitWord32Equal(Node* node) {
    617   FlagsContinuation cont(kEqual, node);
    618   Int32BinopMatcher m(node);
    619   if (m.right().Is(0)) {
    620     return VisitWord32Test(m.left().node(), &cont);
    621   }
    622   VisitWord32Compare(node, &cont);
    623 }
    624 
    625 
    626 void InstructionSelector::VisitInt32LessThan(Node* node) {
    627   FlagsContinuation cont(kSignedLessThan, node);
    628   VisitWord32Compare(node, &cont);
    629 }
    630 
    631 
    632 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
    633   FlagsContinuation cont(kSignedLessThanOrEqual, node);
    634   VisitWord32Compare(node, &cont);
    635 }
    636 
    637 
    638 void InstructionSelector::VisitUint32LessThan(Node* node) {
    639   FlagsContinuation cont(kUnsignedLessThan, node);
    640   VisitWord32Compare(node, &cont);
    641 }
    642 
    643 
    644 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
    645   FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
    646   VisitWord32Compare(node, &cont);
    647 }
    648 
    649 
    650 void InstructionSelector::VisitWord64Equal(Node* node) {
    651   FlagsContinuation cont(kEqual, node);
    652   Int64BinopMatcher m(node);
    653   if (m.right().Is(0)) {
    654     return VisitWord64Test(m.left().node(), &cont);
    655   }
    656   VisitWord64Compare(node, &cont);
    657 }
    658 
    659 
    660 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
    661   if (Node* ovf = node->FindProjection(1)) {
    662     FlagsContinuation cont(kOverflow, ovf);
    663     return VisitInt32AddWithOverflow(node, &cont);
    664   }
    665   FlagsContinuation cont;
    666   VisitInt32AddWithOverflow(node, &cont);
    667 }
    668 
    669 
    670 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
    671   if (Node* ovf = node->FindProjection(1)) {
    672     FlagsContinuation cont(kOverflow, ovf);
    673     return VisitInt32SubWithOverflow(node, &cont);
    674   }
    675   FlagsContinuation cont;
    676   VisitInt32SubWithOverflow(node, &cont);
    677 }
    678 
    679 
    680 void InstructionSelector::VisitInt64LessThan(Node* node) {
    681   FlagsContinuation cont(kSignedLessThan, node);
    682   VisitWord64Compare(node, &cont);
    683 }
    684 
    685 
    686 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
    687   FlagsContinuation cont(kSignedLessThanOrEqual, node);
    688   VisitWord64Compare(node, &cont);
    689 }
    690 
    691 
    692 void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
    693   OperandGenerator g(this);
    694   Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
    695        g.UseRegister(node->InputAt(0)));
    696 }
    697 
    698 
    699 void InstructionSelector::VisitFloat64Equal(Node* node) {
    700   FlagsContinuation cont(kUnorderedEqual, node);
    701   VisitFloat64Compare(node, &cont);
    702 }
    703 
    704 
    705 void InstructionSelector::VisitFloat64LessThan(Node* node) {
    706   FlagsContinuation cont(kUnorderedLessThan, node);
    707   VisitFloat64Compare(node, &cont);
    708 }
    709 
    710 
    711 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
    712   FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
    713   VisitFloat64Compare(node, &cont);
    714 }
    715 
    716 #endif  // V8_TURBOFAN_BACKEND
    717 
    718 // 32 bit targets do not implement the following instructions.
    719 #if V8_TARGET_ARCH_32_BIT && V8_TURBOFAN_BACKEND
    720 
    721 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
    722 
    723 
    724 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
    725 
    726 
    727 void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
    728 
    729 
    730 void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
    731 
    732 
    733 void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
    734 
    735 
    736 void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
    737 
    738 
    739 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
    740 
    741 
    742 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
    743 
    744 
    745 void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
    746 
    747 
    748 void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
    749 
    750 
    751 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
    752 
    753 
    754 void InstructionSelector::VisitInt64UDiv(Node* node) { UNIMPLEMENTED(); }
    755 
    756 
    757 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
    758 
    759 
    760 void InstructionSelector::VisitInt64UMod(Node* node) { UNIMPLEMENTED(); }
    761 
    762 
    763 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
    764   UNIMPLEMENTED();
    765 }
    766 
    767 
    768 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
    769   UNIMPLEMENTED();
    770 }
    771 
    772 
    773 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
    774   UNIMPLEMENTED();
    775 }
    776 
    777 #endif  // V8_TARGET_ARCH_32_BIT && V8_TURBOFAN_BACKEND
    778 
    779 
    780 // 32-bit targets and unsupported architectures need dummy implementations of
    781 // selected 64-bit ops.
    782 #if V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_BACKEND
    783 
    784 void InstructionSelector::VisitWord64Test(Node* node, FlagsContinuation* cont) {
    785   UNIMPLEMENTED();
    786 }
    787 
    788 
    789 void InstructionSelector::VisitWord64Compare(Node* node,
    790                                              FlagsContinuation* cont) {
    791   UNIMPLEMENTED();
    792 }
    793 
    794 #endif  // V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_BACKEND
    795 
    796 
    797 void InstructionSelector::VisitFinish(Node* node) {
    798   OperandGenerator g(this);
    799   Node* value = node->InputAt(0);
    800   Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
    801 }
    802 
    803 
    804 void InstructionSelector::VisitParameter(Node* node) {
    805   OperandGenerator g(this);
    806   int index = OpParameter<int>(node);
    807   Emit(kArchNop,
    808        g.DefineAsLocation(node, linkage()->GetParameterLocation(index),
    809                           linkage()->GetParameterType(index)));
    810 }
    811 
    812 
    813 void InstructionSelector::VisitPhi(Node* node) {
    814   // TODO(bmeurer): Emit a PhiInstruction here.
    815   for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
    816     MarkAsUsed(*i);
    817   }
    818 }
    819 
    820 
    821 void InstructionSelector::VisitProjection(Node* node) {
    822   OperandGenerator g(this);
    823   Node* value = node->InputAt(0);
    824   switch (value->opcode()) {
    825     case IrOpcode::kInt32AddWithOverflow:
    826     case IrOpcode::kInt32SubWithOverflow:
    827       if (OpParameter<size_t>(node) == 0) {
    828         Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
    829       } else {
    830         DCHECK(OpParameter<size_t>(node) == 1u);
    831         MarkAsUsed(value);
    832       }
    833       break;
    834     default:
    835       break;
    836   }
    837 }
    838 
    839 
    840 void InstructionSelector::VisitConstant(Node* node) {
    841   // We must emit a NOP here because every live range needs a defining
    842   // instruction in the register allocator.
    843   OperandGenerator g(this);
    844   Emit(kArchNop, g.DefineAsConstant(node));
    845 }
    846 
    847 
    848 void InstructionSelector::VisitGoto(BasicBlock* target) {
    849   if (IsNextInAssemblyOrder(target)) {
    850     // fall through to the next block.
    851     Emit(kArchNop, NULL)->MarkAsControl();
    852   } else {
    853     // jump to the next block.
    854     OperandGenerator g(this);
    855     Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl();
    856   }
    857 }
    858 
    859 
    860 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
    861                                       BasicBlock* fbranch) {
    862   OperandGenerator g(this);
    863   Node* user = branch;
    864   Node* value = branch->InputAt(0);
    865 
    866   FlagsContinuation cont(kNotEqual, tbranch, fbranch);
    867 
    868   // If we can fall through to the true block, invert the branch.
    869   if (IsNextInAssemblyOrder(tbranch)) {
    870     cont.Negate();
    871     cont.SwapBlocks();
    872   }
    873 
    874   // Try to combine with comparisons against 0 by simply inverting the branch.
    875   while (CanCover(user, value)) {
    876     if (value->opcode() == IrOpcode::kWord32Equal) {
    877       Int32BinopMatcher m(value);
    878       if (m.right().Is(0)) {
    879         user = value;
    880         value = m.left().node();
    881         cont.Negate();
    882       } else {
    883         break;
    884       }
    885     } else if (value->opcode() == IrOpcode::kWord64Equal) {
    886       Int64BinopMatcher m(value);
    887       if (m.right().Is(0)) {
    888         user = value;
    889         value = m.left().node();
    890         cont.Negate();
    891       } else {
    892         break;
    893       }
    894     } else {
    895       break;
    896     }
    897   }
    898 
    899   // Try to combine the branch with a comparison.
    900   if (CanCover(user, value)) {
    901     switch (value->opcode()) {
    902       case IrOpcode::kWord32Equal:
    903         cont.OverwriteAndNegateIfEqual(kEqual);
    904         return VisitWord32Compare(value, &cont);
    905       case IrOpcode::kInt32LessThan:
    906         cont.OverwriteAndNegateIfEqual(kSignedLessThan);
    907         return VisitWord32Compare(value, &cont);
    908       case IrOpcode::kInt32LessThanOrEqual:
    909         cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
    910         return VisitWord32Compare(value, &cont);
    911       case IrOpcode::kUint32LessThan:
    912         cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
    913         return VisitWord32Compare(value, &cont);
    914       case IrOpcode::kUint32LessThanOrEqual:
    915         cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
    916         return VisitWord32Compare(value, &cont);
    917       case IrOpcode::kWord64Equal:
    918         cont.OverwriteAndNegateIfEqual(kEqual);
    919         return VisitWord64Compare(value, &cont);
    920       case IrOpcode::kInt64LessThan:
    921         cont.OverwriteAndNegateIfEqual(kSignedLessThan);
    922         return VisitWord64Compare(value, &cont);
    923       case IrOpcode::kInt64LessThanOrEqual:
    924         cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
    925         return VisitWord64Compare(value, &cont);
    926       case IrOpcode::kFloat64Equal:
    927         cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
    928         return VisitFloat64Compare(value, &cont);
    929       case IrOpcode::kFloat64LessThan:
    930         cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
    931         return VisitFloat64Compare(value, &cont);
    932       case IrOpcode::kFloat64LessThanOrEqual:
    933         cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
    934         return VisitFloat64Compare(value, &cont);
    935       case IrOpcode::kProjection:
    936         // Check if this is the overflow output projection of an
    937         // <Operation>WithOverflow node.
    938         if (OpParameter<size_t>(value) == 1u) {
    939           // We cannot combine the <Operation>WithOverflow with this branch
    940           // unless the 0th projection (the use of the actual value of the
    941           // <Operation> is either NULL, which means there's no use of the
    942           // actual value, or was already defined, which means it is scheduled
    943           // *AFTER* this branch).
    944           Node* node = value->InputAt(0);
    945           Node* result = node->FindProjection(0);
    946           if (result == NULL || IsDefined(result)) {
    947             switch (node->opcode()) {
    948               case IrOpcode::kInt32AddWithOverflow:
    949                 cont.OverwriteAndNegateIfEqual(kOverflow);
    950                 return VisitInt32AddWithOverflow(node, &cont);
    951               case IrOpcode::kInt32SubWithOverflow:
    952                 cont.OverwriteAndNegateIfEqual(kOverflow);
    953                 return VisitInt32SubWithOverflow(node, &cont);
    954               default:
    955                 break;
    956             }
    957           }
    958         }
    959         break;
    960       default:
    961         break;
    962     }
    963   }
    964 
    965   // Branch could not be combined with a compare, emit compare against 0.
    966   VisitWord32Test(value, &cont);
    967 }
    968 
    969 
    970 void InstructionSelector::VisitReturn(Node* value) {
    971   OperandGenerator g(this);
    972   if (value != NULL) {
    973     Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(),
    974                                        linkage()->GetReturnType()));
    975   } else {
    976     Emit(kArchRet, NULL);
    977   }
    978 }
    979 
    980 
    981 void InstructionSelector::VisitThrow(Node* value) {
    982   UNIMPLEMENTED();  // TODO(titzer)
    983 }
    984 
    985 
    986 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
    987     Node* state) {
    988   DCHECK(state->opcode() == IrOpcode::kFrameState);
    989   DCHECK_EQ(5, state->InputCount());
    990   FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state);
    991   int parameters = OpParameter<int>(state->InputAt(0));
    992   int locals = OpParameter<int>(state->InputAt(1));
    993   int stack = OpParameter<int>(state->InputAt(2));
    994 
    995   FrameStateDescriptor* outer_state = NULL;
    996   Node* outer_node = state->InputAt(4);
    997   if (outer_node->opcode() == IrOpcode::kFrameState) {
    998     outer_state = GetFrameStateDescriptor(outer_node);
    999   }
   1000 
   1001   return new (instruction_zone())
   1002       FrameStateDescriptor(state_info, parameters, locals, stack, outer_state);
   1003 }
   1004 
   1005 
   1006 static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) {
   1007   switch (input->opcode()) {
   1008     case IrOpcode::kInt32Constant:
   1009     case IrOpcode::kNumberConstant:
   1010     case IrOpcode::kFloat64Constant:
   1011     case IrOpcode::kHeapConstant:
   1012       return g->UseImmediate(input);
   1013     default:
   1014       return g->UseUnique(input);
   1015   }
   1016 }
   1017 
   1018 
   1019 void InstructionSelector::AddFrameStateInputs(
   1020     Node* state, InstructionOperandVector* inputs,
   1021     FrameStateDescriptor* descriptor) {
   1022   DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
   1023 
   1024   if (descriptor->outer_state() != NULL) {
   1025     AddFrameStateInputs(state->InputAt(4), inputs, descriptor->outer_state());
   1026   }
   1027 
   1028   Node* parameters = state->InputAt(0);
   1029   Node* locals = state->InputAt(1);
   1030   Node* stack = state->InputAt(2);
   1031   Node* context = state->InputAt(3);
   1032 
   1033   DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode());
   1034   DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode());
   1035   DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode());
   1036 
   1037   DCHECK_EQ(descriptor->parameters_count(), parameters->InputCount());
   1038   DCHECK_EQ(descriptor->locals_count(), locals->InputCount());
   1039   DCHECK_EQ(descriptor->stack_count(), stack->InputCount());
   1040 
   1041   OperandGenerator g(this);
   1042   for (int i = 0; i < static_cast<int>(descriptor->parameters_count()); i++) {
   1043     inputs->push_back(UseOrImmediate(&g, parameters->InputAt(i)));
   1044   }
   1045   if (descriptor->HasContext()) {
   1046     inputs->push_back(UseOrImmediate(&g, context));
   1047   }
   1048   for (int i = 0; i < static_cast<int>(descriptor->locals_count()); i++) {
   1049     inputs->push_back(UseOrImmediate(&g, locals->InputAt(i)));
   1050   }
   1051   for (int i = 0; i < static_cast<int>(descriptor->stack_count()); i++) {
   1052     inputs->push_back(UseOrImmediate(&g, stack->InputAt(i)));
   1053   }
   1054 }
   1055 
   1056 
   1057 #if !V8_TURBOFAN_BACKEND
   1058 
   1059 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \
   1060   void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); }
   1061 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR)
   1062 #undef DECLARE_UNIMPLEMENTED_SELECTOR
   1063 
   1064 
   1065 void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
   1066                                                     FlagsContinuation* cont) {
   1067   UNIMPLEMENTED();
   1068 }
   1069 
   1070 
   1071 void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
   1072                                                     FlagsContinuation* cont) {
   1073   UNIMPLEMENTED();
   1074 }
   1075 
   1076 
   1077 void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
   1078   UNIMPLEMENTED();
   1079 }
   1080 
   1081 
   1082 void InstructionSelector::VisitWord32Compare(Node* node,
   1083                                              FlagsContinuation* cont) {
   1084   UNIMPLEMENTED();
   1085 }
   1086 
   1087 
   1088 void InstructionSelector::VisitFloat64Compare(Node* node,
   1089                                               FlagsContinuation* cont) {
   1090   UNIMPLEMENTED();
   1091 }
   1092 
   1093 
   1094 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   1095                                     BasicBlock* deoptimization) {}
   1096 
   1097 #endif  // !V8_TURBOFAN_BACKEND
   1098 
   1099 }  // namespace compiler
   1100 }  // namespace internal
   1101 }  // namespace v8
   1102