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 #ifndef V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
      6 #define V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
      7 
      8 #include <deque>
      9 #include <set>
     10 
     11 #include "src/compiler/instruction-selector.h"
     12 #include "src/compiler/raw-machine-assembler.h"
     13 #include "src/ostreams.h"
     14 #include "test/cctest/cctest.h"
     15 
     16 namespace v8 {
     17 namespace internal {
     18 namespace compiler {
     19 
     20 typedef std::set<int> VirtualRegisterSet;
     21 
     22 enum InstructionSelectorTesterMode { kTargetMode, kInternalMode };
     23 
     24 class InstructionSelectorTester : public HandleAndZoneScope,
     25                                   public RawMachineAssembler {
     26  public:
     27   enum Mode { kTargetMode, kInternalMode };
     28 
     29   static const int kParameterCount = 3;
     30   static MachineType* BuildParameterArray(Zone* zone) {
     31     MachineType* array = zone->NewArray<MachineType>(kParameterCount);
     32     for (int i = 0; i < kParameterCount; ++i) {
     33       array[i] = kMachInt32;
     34     }
     35     return array;
     36   }
     37 
     38   InstructionSelectorTester()
     39       : RawMachineAssembler(
     40             new (main_zone()) Graph(main_zone()),
     41             new (main_zone()) MachineCallDescriptorBuilder(
     42                 kMachInt32, kParameterCount, BuildParameterArray(main_zone())),
     43             kMachPtr) {}
     44 
     45   void SelectInstructions(CpuFeature feature) {
     46     SelectInstructions(InstructionSelector::Features(feature));
     47   }
     48 
     49   void SelectInstructions(CpuFeature feature1, CpuFeature feature2) {
     50     SelectInstructions(InstructionSelector::Features(feature1, feature2));
     51   }
     52 
     53   void SelectInstructions(Mode mode = kTargetMode) {
     54     SelectInstructions(InstructionSelector::Features(), mode);
     55   }
     56 
     57   void SelectInstructions(InstructionSelector::Features features,
     58                           Mode mode = kTargetMode) {
     59     OFStream out(stdout);
     60     Schedule* schedule = Export();
     61     CHECK_NE(0, graph()->NodeCount());
     62     CompilationInfo info(main_isolate(), main_zone());
     63     Linkage linkage(&info, call_descriptor());
     64     InstructionSequence sequence(&linkage, graph(), schedule);
     65     SourcePositionTable source_positions(graph());
     66     InstructionSelector selector(&sequence, &source_positions, features);
     67     selector.SelectInstructions();
     68     out << "--- Code sequence after instruction selection --- " << endl
     69         << sequence;
     70     for (InstructionSequence::const_iterator i = sequence.begin();
     71          i != sequence.end(); ++i) {
     72       Instruction* instr = *i;
     73       if (instr->opcode() < 0) continue;
     74       if (mode == kTargetMode) {
     75         switch (ArchOpcodeField::decode(instr->opcode())) {
     76 #define CASE(Name) \
     77   case k##Name:    \
     78     break;
     79           TARGET_ARCH_OPCODE_LIST(CASE)
     80 #undef CASE
     81           default:
     82             continue;
     83         }
     84       }
     85       code.push_back(instr);
     86     }
     87     for (int vreg = 0; vreg < sequence.VirtualRegisterCount(); ++vreg) {
     88       if (sequence.IsDouble(vreg)) {
     89         CHECK(!sequence.IsReference(vreg));
     90         doubles.insert(vreg);
     91       }
     92       if (sequence.IsReference(vreg)) {
     93         CHECK(!sequence.IsDouble(vreg));
     94         references.insert(vreg);
     95       }
     96     }
     97     immediates.assign(sequence.immediates().begin(),
     98                       sequence.immediates().end());
     99   }
    100 
    101   int32_t ToInt32(const InstructionOperand* operand) const {
    102     size_t i = operand->index();
    103     CHECK(i < immediates.size());
    104     CHECK_EQ(InstructionOperand::IMMEDIATE, operand->kind());
    105     return immediates[i].ToInt32();
    106   }
    107 
    108   std::deque<Instruction*> code;
    109   VirtualRegisterSet doubles;
    110   VirtualRegisterSet references;
    111   std::deque<Constant> immediates;
    112 };
    113 
    114 
    115 static inline void CheckSameVreg(InstructionOperand* exp,
    116                                  InstructionOperand* val) {
    117   CHECK_EQ(InstructionOperand::UNALLOCATED, exp->kind());
    118   CHECK_EQ(InstructionOperand::UNALLOCATED, val->kind());
    119   CHECK_EQ(UnallocatedOperand::cast(exp)->virtual_register(),
    120            UnallocatedOperand::cast(val)->virtual_register());
    121 }
    122 
    123 }  // namespace compiler
    124 }  // namespace internal
    125 }  // namespace v8
    126 
    127 #endif  // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
    128