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

Side by Side Diff: src/compiler/register-allocator-verifier.cc

Issue 713803002: [turbofan] add register assignment verifier (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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 | « src/compiler/register-allocator-verifier.h ('k') | tools/gyp/v8.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/compiler/instruction.h"
6 #include "src/compiler/register-allocator-verifier.h"
7
8 namespace v8 {
9 namespace internal {
10 namespace compiler {
11
12 static size_t OperandCount(const Instruction* instr) {
13 return instr->InputCount() + instr->OutputCount() + instr->TempCount();
14 }
15
16
17 RegisterAllocatorVerifier::RegisterAllocatorVerifier(
18 Zone* zone, const InstructionSequence* sequence)
19 : sequence_(sequence), constraints_(zone) {
20 constraints_.reserve(sequence->instructions().size());
21 for (const auto* instr : sequence->instructions()) {
22 const size_t operand_count = OperandCount(instr);
23 auto* op_constraints =
24 zone->NewArray<OperandConstraint>(static_cast<int>(operand_count));
25 // Construct OperandConstraints for all InstructionOperands, eliminating
26 // kSameAsFirst along the way.
27 size_t count = 0;
28 for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
29 BuildConstraint(instr->InputAt(i), &op_constraints[count]);
30 CHECK_NE(kSameAsFirst, op_constraints[count].type_);
31 }
32 for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) {
33 BuildConstraint(instr->OutputAt(i), &op_constraints[count]);
34 if (op_constraints[count].type_ == kSameAsFirst) {
35 CHECK(instr->InputCount() > 0);
36 op_constraints[count] = op_constraints[0];
37 }
38 }
39 for (size_t i = 0; i < instr->TempCount(); ++i, ++count) {
40 BuildConstraint(instr->TempAt(i), &op_constraints[count]);
41 CHECK_NE(kSameAsFirst, op_constraints[count].type_);
42 }
43 // All gaps should be totally unallocated at this point.
44 if (instr->IsGapMoves()) {
45 const auto* gap = GapInstruction::cast(instr);
46 for (int i = GapInstruction::FIRST_INNER_POSITION;
47 i <= GapInstruction::LAST_INNER_POSITION; i++) {
48 GapInstruction::InnerPosition inner_pos =
49 static_cast<GapInstruction::InnerPosition>(i);
50 CHECK_EQ(NULL, gap->GetParallelMove(inner_pos));
51 }
52 }
53 InstructionConstraint instr_constraint = {instr, operand_count,
54 op_constraints};
55 constraints()->push_back(instr_constraint);
56 }
57 }
58
59
60 void RegisterAllocatorVerifier::VerifyAssignment() {
61 CHECK(sequence()->instructions().size() == constraints()->size());
62 auto instr_it = sequence()->begin();
63 for (const auto& instr_constraint : *constraints()) {
64 const auto* instr = instr_constraint.instruction_;
65 const size_t operand_count = instr_constraint.operand_constaints_size_;
66 const auto* op_constraints = instr_constraint.operand_constraints_;
67 CHECK_EQ(instr, *instr_it);
68 CHECK(operand_count == OperandCount(instr));
69 size_t count = 0;
70 for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
71 CheckConstraint(instr->InputAt(i), &op_constraints[count]);
72 }
73 for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) {
74 CheckConstraint(instr->OutputAt(i), &op_constraints[count]);
75 }
76 for (size_t i = 0; i < instr->TempCount(); ++i, ++count) {
77 CheckConstraint(instr->TempAt(i), &op_constraints[count]);
78 }
79 ++instr_it;
80 }
81 }
82
83
84 void RegisterAllocatorVerifier::BuildConstraint(const InstructionOperand* op,
85 OperandConstraint* constraint) {
86 constraint->value_ = kMinInt;
87 if (op->IsConstant()) {
88 constraint->type_ = kConstant;
89 constraint->value_ = ConstantOperand::cast(op)->index();
90 } else if (op->IsImmediate()) {
91 constraint->type_ = kImmediate;
92 constraint->value_ = ImmediateOperand::cast(op)->index();
93 } else {
94 CHECK(op->IsUnallocated());
95 const auto* unallocated = UnallocatedOperand::cast(op);
96 int vreg = unallocated->virtual_register();
97 if (unallocated->basic_policy() == UnallocatedOperand::FIXED_SLOT) {
98 constraint->type_ = kFixedSlot;
99 constraint->value_ = unallocated->fixed_slot_index();
100 } else {
101 switch (unallocated->extended_policy()) {
102 case UnallocatedOperand::ANY:
103 CHECK(false);
Jarin 2014/11/10 11:24:59 What is wrong with the ANY constraint?
dcarney 2014/11/10 11:27:17 it's only used for phi gap moves, not as an instru
104 break;
105 case UnallocatedOperand::NONE:
106 if (sequence()->IsDouble(vreg)) {
107 constraint->type_ = kNoneDouble;
108 } else {
109 constraint->type_ = kNone;
110 }
111 break;
112 case UnallocatedOperand::FIXED_REGISTER:
113 constraint->type_ = kFixedRegister;
114 constraint->value_ = unallocated->fixed_register_index();
115 break;
116 case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
117 constraint->type_ = kFixedDoubleRegister;
118 constraint->value_ = unallocated->fixed_register_index();
119 break;
120 case UnallocatedOperand::MUST_HAVE_REGISTER:
121 if (sequence()->IsDouble(vreg)) {
122 constraint->type_ = kDoubleRegister;
123 } else {
124 constraint->type_ = kRegister;
125 }
126 break;
127 case UnallocatedOperand::SAME_AS_FIRST_INPUT:
128 constraint->type_ = kSameAsFirst;
129 break;
130 }
131 }
132 }
133 }
134
135
136 void RegisterAllocatorVerifier::CheckConstraint(
137 const InstructionOperand* op, const OperandConstraint* constraint) {
138 switch (constraint->type_) {
139 case kConstant:
140 CHECK(op->IsConstant());
141 CHECK_EQ(op->index(), constraint->value_);
142 return;
143 case kImmediate:
144 CHECK(op->IsImmediate());
145 CHECK_EQ(op->index(), constraint->value_);
146 return;
147 case kRegister:
148 CHECK(op->IsRegister());
149 return;
150 case kFixedRegister:
151 CHECK(op->IsRegister());
152 CHECK_EQ(op->index(), constraint->value_);
153 return;
154 case kDoubleRegister:
155 CHECK(op->IsDoubleRegister());
156 return;
157 case kFixedDoubleRegister:
158 CHECK(op->IsDoubleRegister());
159 CHECK_EQ(op->index(), constraint->value_);
160 return;
161 case kFixedSlot:
162 CHECK(op->IsStackSlot());
163 CHECK_EQ(op->index(), constraint->value_);
164 return;
165 case kNone:
166 CHECK(op->IsRegister() || op->IsStackSlot());
167 return;
168 case kNoneDouble:
169 CHECK(op->IsDoubleRegister() || op->IsDoubleStackSlot());
170 return;
171 case kSameAsFirst:
172 CHECK(false);
173 return;
174 }
175 }
176
177 } // namespace compiler
178 } // namespace internal
179 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator-verifier.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698