Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(333)

Side by Side Diff: test/unittests/compiler/register-allocator-unittest.cc

Issue 683133005: [turbofan] initial framework for unittesting of register allocator (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/unittests/compiler/instruction-selector-unittest.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/base/utils/random-number-generator.h"
6 #include "src/compiler/register-allocator.h"
7 #include "test/unittests/test-utils.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
14 typedef BasicBlock::RpoNumber Rpo;
15
16 namespace {
17
18 static const char* general_register_names_[kMaxGeneralRegisters];
19 static const char* double_register_names_[kMaxDoubleRegisters];
20 static char register_names_[10 * (kMaxGeneralRegisters + kMaxDoubleRegisters)];
21
22
23 static const char* GeneralRegisterName(int allocation_index) {
24 return general_register_names_[allocation_index];
25 }
26
27
28 static const char* DoubleRegisterName(int allocation_index) {
29 return double_register_names_[allocation_index];
30 }
31
32
33 static void InitializeRegisterNames() {
34 char* loc = register_names_;
35 for (int i = 0; i < kMaxGeneralRegisters; ++i) {
36 general_register_names_[i] = loc;
37 loc += base::OS::SNPrintF(loc, 100, "gp_%d", i);
38 *loc++ = 0;
39 }
40 for (int i = 0; i < kMaxDoubleRegisters; ++i) {
41 double_register_names_[i] = loc;
42 loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1;
43 *loc++ = 0;
44 }
45 }
46
47 } // namespace
48
49
50 // TODO(dcarney): fake opcodes.
51 // TODO(dcarney): fix printing of sequence w.r.t fake opcodes and registers.
52 class RegisterAllocatorTest : public TestWithZone {
53 public:
54 static const int kDefaultNRegs = 4;
55
56 RegisterAllocatorTest()
57 : basic_blocks_(zone()),
58 instruction_blocks_(zone()),
59 current_block_(NULL) {
60 InitializeRegisterNames();
61 config_.num_general_registers_ = kDefaultNRegs;
62 config_.num_double_registers_ = kDefaultNRegs;
63 config_.num_aliased_double_registers_ = kDefaultNRegs;
64 config_.GeneralRegisterName = GeneralRegisterName;
65 config_.DoubleRegisterName = DoubleRegisterName;
66 }
67
68 Frame* frame() {
69 if (frame_.is_empty()) {
70 frame_.Reset(new Frame());
71 }
72 return frame_.get();
73 }
74
75 InstructionSequence* sequence() {
76 if (sequence_.is_empty()) {
77 sequence_.Reset(new InstructionSequence(zone(), &instruction_blocks_));
78 }
79 return sequence_.get();
80 }
81
82 RegisterAllocator* allocator() {
83 if (allocator_.is_empty()) {
84 allocator_.Reset(
85 new RegisterAllocator(config_, zone(), frame(), sequence()));
86 }
87 return allocator_.get();
88 }
89
90 InstructionBlock* StartBlock(Rpo loop_header = Rpo::Invalid(),
91 Rpo loop_end = Rpo::Invalid()) {
92 CHECK(current_block_ == NULL);
93 BasicBlock::Id block_id =
94 BasicBlock::Id::FromSize(instruction_blocks_.size());
95 BasicBlock* basic_block = new (zone()) BasicBlock(zone(), block_id);
96 basic_block->set_rpo_number(block_id.ToInt());
97 basic_block->set_ao_number(block_id.ToInt());
98 if (loop_header.IsValid()) {
99 basic_block->set_loop_depth(1);
100 basic_block->set_loop_header(basic_blocks_[loop_header.ToSize()]);
101 basic_block->set_loop_end(loop_end.ToInt());
102 }
103 InstructionBlock* instruction_block =
104 new (zone()) InstructionBlock(zone(), basic_block);
105 basic_blocks_.push_back(basic_block);
106 instruction_blocks_.push_back(instruction_block);
107 current_block_ = instruction_block;
108 sequence()->StartBlock(basic_block);
109 return instruction_block;
110 }
111
112 void EndBlock() {
113 CHECK(current_block_ != NULL);
114 sequence()->EndBlock(basic_blocks_[current_block_->rpo_number().ToSize()]);
115 current_block_ = NULL;
116 }
117
118 void Allocate() {
119 if (FLAG_trace_alloc) {
120 OFStream os(stdout);
121 os << "Before: " << std::endl << *sequence() << std::endl;
122 }
123 allocator()->Allocate();
124 if (FLAG_trace_alloc) {
125 OFStream os(stdout);
126 os << "After: " << std::endl << *sequence() << std::endl;
127 }
128 }
129
130 int NewReg() { return sequence()->NextVirtualRegister(); }
131
132 int Parameter() {
133 // TODO(dcarney): assert parameters before other instructions.
134 int vreg = NewReg();
135 InstructionOperand* outputs[1]{
136 Unallocated(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
137 sequence()->AddInstruction(
138 Instruction::New(zone(), kArchNop, 1, outputs, 0, NULL, 0, NULL));
139 return vreg;
140 }
141
142 void Return(int vreg) {
143 InstructionOperand* inputs[1]{
144 Unallocated(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
145 sequence()->AddInstruction(
146 Instruction::New(zone(), kArchNop, 0, NULL, 1, inputs, 0, NULL));
147 }
148
149 Instruction* Emit(int output_vreg, int input_vreg_0, int input_vreg_1) {
150 InstructionOperand* outputs[1]{
151 Unallocated(UnallocatedOperand::MUST_HAVE_REGISTER, output_vreg)};
152 InstructionOperand* inputs[2]{
153 Unallocated(UnallocatedOperand::MUST_HAVE_REGISTER, input_vreg_0),
154 Unallocated(UnallocatedOperand::MUST_HAVE_REGISTER, input_vreg_1)};
155 Instruction* instruction =
156 Instruction::New(zone(), kArchNop, 1, outputs, 2, inputs, 0, NULL);
157 sequence()->AddInstruction(instruction);
158 return instruction;
159 }
160
161 private:
162 InstructionOperand* Unallocated(UnallocatedOperand::ExtendedPolicy policy,
163 int vreg) {
164 UnallocatedOperand* op =
165 new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER);
166 op->set_virtual_register(vreg);
167 return op;
168 }
169
170 RegisterAllocator::Config config_;
171 ZoneVector<BasicBlock*> basic_blocks_;
172 InstructionBlocks instruction_blocks_;
173 InstructionBlock* current_block_;
174 SmartPointer<Frame> frame_;
175 SmartPointer<RegisterAllocator> allocator_;
176 SmartPointer<InstructionSequence> sequence_;
177 };
178
179
180 TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) {
181 StartBlock();
182 int a_reg = Parameter();
183 int b_reg = Parameter();
184 int c_reg = NewReg();
185 Instruction* res = Emit(c_reg, a_reg, b_reg);
186 Return(c_reg);
187 EndBlock();
188
189 Allocate();
190
191 ASSERT_TRUE(res->OutputAt(0)->IsRegister());
192 }
193
194 } // namespace compiler
195 } // namespace internal
196 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/instruction-selector-unittest.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698