18640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 28640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 38640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// found in the LICENSE file. 48640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 5ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#include "src/compiler/instruction-selector-unittest.h" 68640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 79aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org#include "src/compiler/compiler-test-utils.h" 85e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/flags.h" 95e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 108640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgnamespace v8 { 118640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgnamespace internal { 128640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgnamespace compiler { 138640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 14e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgnamespace { 15e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 16e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgtypedef RawMachineAssembler::Label MLabel; 17e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 18e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} // namespace 19e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 20e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgInstructionSelectorTest::InstructionSelectorTest() : rng_(FLAG_random_seed) {} 225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 249aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgInstructionSelectorTest::~InstructionSelectorTest() {} 259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 269aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgInstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build( 288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org InstructionSelector::Features features, 298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org InstructionSelectorTest::StreamBuilderMode mode) { 308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Schedule* schedule = Export(); 315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (FLAG_trace_turbo) { 325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org OFStream out(stdout); 335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org out << "=== Schedule before instruction selection ===" << endl << *schedule; 345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } 358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_NE(0, graph()->NodeCount()); 368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CompilationInfo info(test_->isolate(), test_->zone()); 378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Linkage linkage(&info, call_descriptor()); 388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org InstructionSequence sequence(&linkage, graph(), schedule); 398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org SourcePositionTable source_position_table(graph()); 408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org InstructionSelector selector(&sequence, &source_position_table, features); 418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org selector.SelectInstructions(); 428640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (FLAG_trace_turbo) { 438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org OFStream out(stdout); 445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org out << "=== Code sequence after instruction selection ===" << endl 458640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org << sequence; 468640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 478640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Stream s; 48e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org std::set<int> virtual_registers; 498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org for (InstructionSequence::const_iterator i = sequence.begin(); 508640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org i != sequence.end(); ++i) { 518640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Instruction* instr = *i; 528640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (instr->opcode() < 0) continue; 538640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (mode == kTargetInstructions) { 548640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org switch (instr->arch_opcode()) { 558640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#define CASE(Name) \ 568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org case k##Name: \ 578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org break; 588640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TARGET_ARCH_OPCODE_LIST(CASE) 598640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#undef CASE 608640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org default: 618640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org continue; 628640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 638640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 645fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org if (mode == kAllExceptNopInstructions && instr->arch_opcode() == kArchNop) { 655fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org continue; 665fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org } 678640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org for (size_t i = 0; i < instr->OutputCount(); ++i) { 688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org InstructionOperand* output = instr->OutputAt(i); 698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_NE(InstructionOperand::IMMEDIATE, output->kind()); 708640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (output->IsConstant()) { 718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org s.constants_.insert(std::make_pair( 728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org output->index(), sequence.GetConstant(output->index()))); 73e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org virtual_registers.insert(output->index()); 74e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org } else if (output->IsUnallocated()) { 75e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org virtual_registers.insert( 76e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org UnallocatedOperand::cast(output)->virtual_register()); 778640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 788640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 798640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org for (size_t i = 0; i < instr->InputCount(); ++i) { 808640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org InstructionOperand* input = instr->InputAt(i); 818640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_NE(InstructionOperand::CONSTANT, input->kind()); 828640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (input->IsImmediate()) { 838640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org s.immediates_.insert(std::make_pair( 848640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org input->index(), sequence.GetImmediate(input->index()))); 85e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org } else if (input->IsUnallocated()) { 86e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org virtual_registers.insert( 87e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org UnallocatedOperand::cast(input)->virtual_register()); 888640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 898640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 908640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org s.instructions_.push_back(instr); 918640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 92e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org for (std::set<int>::const_iterator i = virtual_registers.begin(); 93e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org i != virtual_registers.end(); ++i) { 94e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org int virtual_register = *i; 95e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org if (sequence.IsDouble(virtual_register)) { 96e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_FALSE(sequence.IsReference(virtual_register)); 97e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org s.doubles_.insert(virtual_register); 98e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org } 99e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org if (sequence.IsReference(virtual_register)) { 100e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_FALSE(sequence.IsDouble(virtual_register)); 101e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org s.references_.insert(virtual_register); 102e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org } 103e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org } 104ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org for (int i = 0; i < sequence.GetFrameStateDescriptorCount(); i++) { 105ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org s.deoptimization_entries_.push_back(sequence.GetFrameStateDescriptor( 106ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org InstructionSequence::StateId::FromInt(i))); 1075fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org } 1088640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org return s; 1098640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} 1108640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1118640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1127dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// ----------------------------------------------------------------------------- 1137dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// Return. 1147dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1157dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ReturnParameter) { 1175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org StreamBuilder m(this, kMachInt32, kMachInt32); 1188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org m.Return(m.Parameter(0)); 1198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Stream s = m.Build(kAllInstructions); 1208640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ASSERT_EQ(2U, s.size()); 1218640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(kArchNop, s[0]->arch_opcode()); 1228640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ASSERT_EQ(1U, s[0]->OutputCount()); 1238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(kArchRet, s[1]->arch_opcode()); 1248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(1U, s[1]->InputCount()); 1258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} 1268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ReturnZero) { 1295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org StreamBuilder m(this, kMachInt32); 1308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org m.Return(m.Int32Constant(0)); 1318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Stream s = m.Build(kAllInstructions); 1328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ASSERT_EQ(2U, s.size()); 1338640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(kArchNop, s[0]->arch_opcode()); 1348640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ASSERT_EQ(1U, s[0]->OutputCount()); 1358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); 1368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0))); 1378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(kArchRet, s[1]->arch_opcode()); 1388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org EXPECT_EQ(1U, s[1]->InputCount()); 1398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} 1408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1417dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1427dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// ----------------------------------------------------------------------------- 1437dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// Conversions. 1447dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1457dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1467dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) { 1477dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org StreamBuilder m(this, kMachInt32, kMachFloat64); 1487dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org m.Return(m.TruncateFloat64ToInt32(m.Parameter(0))); 1497dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org Stream s = m.Build(kAllInstructions); 1507dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org ASSERT_EQ(3U, s.size()); 1517dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org EXPECT_EQ(kArchNop, s[0]->arch_opcode()); 1527dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode()); 1537dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org EXPECT_EQ(1U, s[1]->InputCount()); 1547dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org EXPECT_EQ(1U, s[1]->OutputCount()); 1557dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org EXPECT_EQ(kArchRet, s[2]->arch_opcode()); 1567dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org} 1577dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 158e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 159e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// ----------------------------------------------------------------------------- 160e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// Parameters. 161e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 162e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 163e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, DoubleParameter) { 164e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org StreamBuilder m(this, kMachFloat64, kMachFloat64); 165e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param = m.Parameter(0); 166e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Return(param); 167e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s = m.Build(kAllInstructions); 168e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_TRUE(s.IsDouble(param->id())); 169e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} 170e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 171e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 172e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) { 173e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged); 174e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param = m.Parameter(0); 175e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Return(param); 176e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s = m.Build(kAllInstructions); 177e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_TRUE(s.IsReference(param->id())); 178e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} 179e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 180e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 181e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// ----------------------------------------------------------------------------- 182e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// Finish. 183e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 184e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 18542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, Finish) { 1869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged); 187e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param = m.Parameter(0); 188e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* finish = m.NewNode(m.common()->Finish(1), param, m.graph()->start()); 189e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Return(finish); 190e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s = m.Build(kAllInstructions); 191e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_EQ(3U, s.size()); 192e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(kArchNop, s[0]->arch_opcode()); 193e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_EQ(1U, s[0]->OutputCount()); 194e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_TRUE(s[0]->Output()->IsUnallocated()); 195fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org EXPECT_EQ(param->id(), s.ToVreg(s[0]->Output())); 196e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(kArchNop, s[1]->arch_opcode()); 197e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_EQ(1U, s[1]->InputCount()); 198e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_TRUE(s[1]->InputAt(0)->IsUnallocated()); 199fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org EXPECT_EQ(param->id(), s.ToVreg(s[1]->InputAt(0))); 200e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_EQ(1U, s[1]->OutputCount()); 201e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_TRUE(s[1]->Output()->IsUnallocated()); 202e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_TRUE(UnallocatedOperand::cast(s[1]->Output())->HasSameAsInputPolicy()); 203fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org EXPECT_EQ(finish->id(), s.ToVreg(s[1]->Output())); 20442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org EXPECT_TRUE(s.IsReference(finish->id())); 205e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} 206e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 207e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 208e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// ----------------------------------------------------------------------------- 2099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org// Phi. 210e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 211e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 212e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgtypedef InstructionSelectorTestWithParam<MachineType> 213e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org InstructionSelectorPhiTest; 214e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 215e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 21642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgTARGET_TEST_P(InstructionSelectorPhiTest, Doubleness) { 217e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org const MachineType type = GetParam(); 218e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org StreamBuilder m(this, type, type, type); 219e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param0 = m.Parameter(0); 220e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param1 = m.Parameter(1); 221e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org MLabel a, b, c; 222e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Branch(m.Int32Constant(0), &a, &b); 223e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Bind(&a); 224e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Goto(&c); 225e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Bind(&b); 226e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Goto(&c); 227e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Bind(&c); 22842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Node* phi = m.Phi(type, param0, param1); 229e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Return(phi); 230e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s = m.Build(kAllInstructions); 231e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(s.IsDouble(phi->id()), s.IsDouble(param0->id())); 232e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(s.IsDouble(phi->id()), s.IsDouble(param1->id())); 233e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} 234e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 235e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 23642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgTARGET_TEST_P(InstructionSelectorPhiTest, Referenceness) { 237e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org const MachineType type = GetParam(); 238e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org StreamBuilder m(this, type, type, type); 239e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param0 = m.Parameter(0); 240e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* param1 = m.Parameter(1); 241e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org MLabel a, b, c; 242e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Branch(m.Int32Constant(1), &a, &b); 243e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Bind(&a); 244e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Goto(&c); 245e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Bind(&b); 246e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Goto(&c); 247e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Bind(&c); 24842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Node* phi = m.Phi(type, param0, param1); 249e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m.Return(phi); 250e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s = m.Build(kAllInstructions); 251e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(s.IsReference(phi->id()), s.IsReference(param0->id())); 252e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(s.IsReference(phi->id()), s.IsReference(param1->id())); 253e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} 254e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 255e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 256e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorPhiTest, 257e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ::testing::Values(kMachFloat64, kMachInt8, kMachUint8, 258e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org kMachInt16, kMachUint16, kMachInt32, 259e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org kMachUint32, kMachInt64, kMachUint64, 260e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org kMachPtr, kMachAnyTagged)); 261e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 262e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 263e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// ----------------------------------------------------------------------------- 264e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// ValueEffect. 265e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 266e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 267e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ValueEffect) { 268e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org StreamBuilder m1(this, kMachInt32, kMachPtr); 269e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* p1 = m1.Parameter(0); 270e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m1.Return(m1.Load(kMachInt32, p1, m1.Int32Constant(0))); 271e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s1 = m1.Build(kAllInstructions); 272e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org StreamBuilder m2(this, kMachInt32, kMachPtr); 273e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Node* p2 = m2.Parameter(0); 274e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m2.Return(m2.NewNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0), 275e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org m2.NewNode(m2.common()->ValueEffect(1), p2))); 276e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Stream s2 = m2.Build(kAllInstructions); 277e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_LE(3U, s1.size()); 278e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org ASSERT_EQ(s1.size(), s2.size()); 279e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org TRACED_FORRANGE(size_t, i, 0, s1.size() - 1) { 280e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org const Instruction* i1 = s1[i]; 281e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org const Instruction* i2 = s2[i]; 282e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(i1->arch_opcode(), i2->arch_opcode()); 283e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(i1->InputCount(), i2->InputCount()); 284e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org EXPECT_EQ(i1->OutputCount(), i2->OutputCount()); 285e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org } 286e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org} 287e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org 2885fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 2895fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org// ----------------------------------------------------------------------------- 2905fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org// Calls with deoptimization. 291d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { 2929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, 2939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org kMachAnyTagged); 2945fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 2955fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org BailoutId bailout_id(42); 2965fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 2975fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* function_node = m.Parameter(0); 2985fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* receiver = m.Parameter(1); 2999aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* context = m.Parameter(2); 3005fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3015fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1)); 3025fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* locals = m.NewNode(m.common()->StateValues(0)); 3035fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* stack = m.NewNode(m.common()->StateValues(0)); 304ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Node* context_dummy = m.Int32Constant(0); 3055fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 306a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Node* state_node = m.NewNode( 307a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org m.common()->FrameState(JS_FRAME, bailout_id, kPushOutput), parameters, 308a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org locals, stack, context_dummy, m.UndefinedConstant()); 3099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* call = m.CallJS0(function_node, receiver, context, state_node); 310ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org m.Return(call); 3115fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3125fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Stream s = m.Build(kAllExceptNopInstructions); 3135fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3145fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Skip until kArchCallJSFunction. 3155fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org size_t index = 0; 3165fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org for (; index < s.size() && s[index]->arch_opcode() != kArchCallJSFunction; 3175fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org index++) { 3185fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org } 319ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org // Now we should have two instructions: call and return. 320ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org ASSERT_EQ(index + 2, s.size()); 3215fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3225fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode()); 3235fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); 324ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 325ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org // TODO(jarin) Check deoptimization table. 3265fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org} 3275fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3285fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 329d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) { 3305fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, 3315fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org kMachAnyTagged); 3325fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3335fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org BailoutId bailout_id_before(42); 3345fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3355fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Some arguments for the call node. 3365fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* function_node = m.Parameter(0); 3375fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* receiver = m.Parameter(1); 3385fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* context = m.Int32Constant(1); // Context is ignored. 3395fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3405fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Build frame state for the state before the call. 3415fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); 3425fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44)); 3435fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45)); 3449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 345ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Node* context_sentinel = m.Int32Constant(0); 3469aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* frame_state_before = m.NewNode( 347a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org m.common()->FrameState(JS_FRAME, bailout_id_before, kPushOutput), 348a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org parameters, locals, stack, context_sentinel, m.UndefinedConstant()); 3495fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3505fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Build the call. 351ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Node* call = m.CallFunctionStub0(function_node, receiver, context, 352ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org frame_state_before, CALL_AS_METHOD); 3535fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3545fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org m.Return(call); 3555fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3565fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org Stream s = m.Build(kAllExceptNopInstructions); 3575fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3585fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Skip until kArchCallJSFunction. 3595fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org size_t index = 0; 3605fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject; 3615fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org index++) { 3625fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org } 363ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org // Now we should have two instructions: call, return. 364ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org ASSERT_EQ(index + 2, s.size()); 3655fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3665fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Check the call instruction 3675fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org const Instruction* call_instr = s[index++]; 3685fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode()); 3695fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org size_t num_operands = 3705fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 1 + // Code object. 3715fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 1 + 372ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 4 + // Frame state deopt id + one input for each value in frame state. 3735fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 1 + // Function. 374ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 1; // Context. 3755fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org ASSERT_EQ(num_operands, call_instr->InputCount()); 3765fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3775fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Code object. 3785fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate()); 3795fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3805fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Deoptimization id. 3815fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); 382ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org FrameStateDescriptor* desc_before = 383ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org s.GetFrameStateDescriptor(deopt_id_before); 3845fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); 385ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org EXPECT_EQ(kPushOutput, desc_before->state_combine()); 386a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EXPECT_EQ(1u, desc_before->parameters_count()); 387a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EXPECT_EQ(1u, desc_before->locals_count()); 388a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EXPECT_EQ(1u, desc_before->stack_count()); 3895fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2))); 390ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3))); 391ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(4))); 392ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(5))); 3935fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3945fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Function. 395ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(6))); 3965fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org // Context. 397ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org EXPECT_EQ(context->id(), s.ToVreg(call_instr->InputAt(7))); 3985fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 3995fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); 4005fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 4015fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org EXPECT_EQ(index, s.size()); 4025fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org} 4035fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org 4049aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4059aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, 4069aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org CallFunctionStubDeoptRecursiveFrameState) { 4079aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, 4089aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org kMachAnyTagged); 4099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4109aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org BailoutId bailout_id_before(42); 4119aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org BailoutId bailout_id_parent(62); 4129aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4139aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Some arguments for the call node. 4149aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* function_node = m.Parameter(0); 4159aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* receiver = m.Parameter(1); 4169aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* context = m.Int32Constant(66); 4179aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4189aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Build frame state for the state before the call. 4199aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(63)); 4209aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64)); 4219aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65)); 422a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Node* frame_state_parent = m.NewNode( 423a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org m.common()->FrameState(JS_FRAME, bailout_id_parent, kIgnoreOutput), 424a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org parameters, locals, stack, context, m.UndefinedConstant()); 4259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4269aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* context2 = m.Int32Constant(46); 4279aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* parameters2 = 4289aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); 4299aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* locals2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44)); 4309aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* stack2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45)); 431a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Node* frame_state_before = m.NewNode( 432a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org m.common()->FrameState(JS_FRAME, bailout_id_before, kPushOutput), 433a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org parameters2, locals2, stack2, context2, frame_state_parent); 4349aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4359aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Build the call. 4369aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* call = m.CallFunctionStub0(function_node, receiver, context2, 4379aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org frame_state_before, CALL_AS_METHOD); 4389aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4399aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m.Return(call); 4409aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4419aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Stream s = m.Build(kAllExceptNopInstructions); 4429aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4439aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Skip until kArchCallJSFunction. 4449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org size_t index = 0; 4459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject; 4469aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org index++) { 4479aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 4489aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Now we should have three instructions: call, return. 4499aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(index + 2, s.size()); 4509aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4519aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Check the call instruction 4529aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org const Instruction* call_instr = s[index++]; 4539aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode()); 4549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org size_t num_operands = 4559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 1 + // Code object. 4569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 1 + // Frame state deopt id 4579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4 + // One input for each value in frame state + context. 4589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4 + // One input for each value in the parent frame state + context. 4599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 1 + // Function. 4609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 1; // Context. 4619aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(num_operands, call_instr->InputCount()); 4629aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Code object. 4639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate()); 4649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Deoptimization id. 4669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); 4679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org FrameStateDescriptor* desc_before = 4689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org s.GetFrameStateDescriptor(deopt_id_before); 4699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); 470a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EXPECT_EQ(1u, desc_before->parameters_count()); 471a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EXPECT_EQ(1u, desc_before->locals_count()); 472a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EXPECT_EQ(1u, desc_before->stack_count()); 4739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2))); 4749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Context: 4759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3))); 4769aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4))); 4779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5))); 4789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Values from parent environment should follow. 4799aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6))); 4809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7))); 4819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(8))); 4829aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(9))); 4839aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4849aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Function. 4859aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(10))); 4869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Context. 4879aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(context2->id(), s.ToVreg(call_instr->InputAt(11))); 4889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Continuation. 4899aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4909aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); 4919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org EXPECT_EQ(index, s.size()); 4929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org} 4939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 4948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} // namespace compiler 4958640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} // namespace internal 4968640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} // namespace v8 497