OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ |
6 #define V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ | 6 #define V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ |
7 | 7 |
8 #include "src/compiler/instruction.h" | 8 #include "src/compiler/instruction.h" |
9 #include "src/compiler/instruction-selector.h" | 9 #include "src/compiler/instruction-selector.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 Register::ToAllocationIndex(reg))); | 41 Register::ToAllocationIndex(reg))); |
42 } | 42 } |
43 | 43 |
44 InstructionOperand* DefineAsFixedDouble(Node* node, DoubleRegister reg) { | 44 InstructionOperand* DefineAsFixedDouble(Node* node, DoubleRegister reg) { |
45 return Define(node, new (zone()) | 45 return Define(node, new (zone()) |
46 UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, | 46 UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, |
47 DoubleRegister::ToAllocationIndex(reg))); | 47 DoubleRegister::ToAllocationIndex(reg))); |
48 } | 48 } |
49 | 49 |
50 InstructionOperand* DefineAsConstant(Node* node) { | 50 InstructionOperand* DefineAsConstant(Node* node) { |
| 51 selector()->MarkAsDefined(node); |
51 sequence()->AddConstant(node->id(), ToConstant(node)); | 52 sequence()->AddConstant(node->id(), ToConstant(node)); |
52 return ConstantOperand::Create(node->id(), zone()); | 53 return ConstantOperand::Create(node->id(), zone()); |
53 } | 54 } |
54 | 55 |
55 InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location) { | 56 InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location) { |
56 return Define(node, ToUnallocatedOperand(location)); | 57 return Define(node, ToUnallocatedOperand(location)); |
57 } | 58 } |
58 | 59 |
59 InstructionOperand* Use(Node* node) { | 60 InstructionOperand* Use(Node* node) { |
60 return Use(node, | 61 return Use(node, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 break; | 173 break; |
173 } | 174 } |
174 UNREACHABLE(); | 175 UNREACHABLE(); |
175 return Constant(static_cast<int32_t>(0)); | 176 return Constant(static_cast<int32_t>(0)); |
176 } | 177 } |
177 | 178 |
178 UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) { | 179 UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) { |
179 ASSERT_NOT_NULL(node); | 180 ASSERT_NOT_NULL(node); |
180 ASSERT_NOT_NULL(operand); | 181 ASSERT_NOT_NULL(operand); |
181 operand->set_virtual_register(node->id()); | 182 operand->set_virtual_register(node->id()); |
| 183 selector()->MarkAsDefined(node); |
182 return operand; | 184 return operand; |
183 } | 185 } |
184 | 186 |
185 UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) { | 187 UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) { |
186 selector_->MarkAsUsed(node); | 188 ASSERT_NOT_NULL(node); |
187 return Define(node, operand); | 189 ASSERT_NOT_NULL(operand); |
| 190 operand->set_virtual_register(node->id()); |
| 191 selector()->MarkAsUsed(node); |
| 192 return operand; |
188 } | 193 } |
189 | 194 |
190 UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location) { | 195 UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location) { |
191 if (location.location_ == LinkageLocation::ANY_REGISTER) { | 196 if (location.location_ == LinkageLocation::ANY_REGISTER) { |
192 return new (zone()) | 197 return new (zone()) |
193 UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER); | 198 UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER); |
194 } | 199 } |
195 if (location.location_ < 0) { | 200 if (location.location_ < 0) { |
196 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, | 201 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, |
197 location.location_); | 202 location.location_); |
(...skipping 10 matching lines...) Expand all Loading... |
208 }; | 213 }; |
209 | 214 |
210 | 215 |
211 // The flags continuation is a way to combine a branch or a materialization | 216 // The flags continuation is a way to combine a branch or a materialization |
212 // of a boolean value with an instruction that sets the flags register. | 217 // of a boolean value with an instruction that sets the flags register. |
213 // The whole instruction is treated as a unit by the register allocator, and | 218 // The whole instruction is treated as a unit by the register allocator, and |
214 // thus no spills or moves can be introduced between the flags-setting | 219 // thus no spills or moves can be introduced between the flags-setting |
215 // instruction and the branch or set it should be combined with. | 220 // instruction and the branch or set it should be combined with. |
216 class FlagsContinuation V8_FINAL { | 221 class FlagsContinuation V8_FINAL { |
217 public: | 222 public: |
| 223 FlagsContinuation() : mode_(kFlags_none) {} |
| 224 |
218 // Creates a new flags continuation from the given condition and true/false | 225 // Creates a new flags continuation from the given condition and true/false |
219 // blocks. | 226 // blocks. |
220 FlagsContinuation(FlagsCondition condition, BasicBlock* true_block, | 227 FlagsContinuation(FlagsCondition condition, BasicBlock* true_block, |
221 BasicBlock* false_block) | 228 BasicBlock* false_block) |
222 : mode_(kFlags_branch), | 229 : mode_(kFlags_branch), |
223 condition_(condition), | 230 condition_(condition), |
224 true_block_(true_block), | 231 true_block_(true_block), |
225 false_block_(false_block) { | 232 false_block_(false_block) { |
226 ASSERT_NOT_NULL(true_block); | 233 ASSERT_NOT_NULL(true_block); |
227 ASSERT_NOT_NULL(false_block); | 234 ASSERT_NOT_NULL(false_block); |
228 } | 235 } |
229 | 236 |
230 // Creates a new flags continuation from the given condition and result node. | 237 // Creates a new flags continuation from the given condition and result node. |
231 FlagsContinuation(FlagsCondition condition, Node* result) | 238 FlagsContinuation(FlagsCondition condition, Node* result) |
232 : mode_(kFlags_set), condition_(condition), result_(result) { | 239 : mode_(kFlags_set), condition_(condition), result_(result) { |
233 ASSERT_NOT_NULL(result); | 240 ASSERT_NOT_NULL(result); |
234 } | 241 } |
235 | 242 |
236 bool IsNone() const { return mode_ == kFlags_none; } | 243 bool IsNone() const { return mode_ == kFlags_none; } |
237 bool IsBranch() const { return mode_ == kFlags_branch; } | 244 bool IsBranch() const { return mode_ == kFlags_branch; } |
238 bool IsSet() const { return mode_ == kFlags_set; } | 245 bool IsSet() const { return mode_ == kFlags_set; } |
239 FlagsCondition condition() const { return condition_; } | 246 FlagsCondition condition() const { |
| 247 ASSERT(!IsNone()); |
| 248 return condition_; |
| 249 } |
240 Node* result() const { | 250 Node* result() const { |
241 ASSERT(IsSet()); | 251 ASSERT(IsSet()); |
242 return result_; | 252 return result_; |
243 } | 253 } |
244 BasicBlock* true_block() const { | 254 BasicBlock* true_block() const { |
245 ASSERT(IsBranch()); | 255 ASSERT(IsBranch()); |
246 return true_block_; | 256 return true_block_; |
247 } | 257 } |
248 BasicBlock* false_block() const { | 258 BasicBlock* false_block() const { |
249 ASSERT(IsBranch()); | 259 ASSERT(IsBranch()); |
250 return false_block_; | 260 return false_block_; |
251 } | 261 } |
252 | 262 |
253 void Negate() { condition_ = static_cast<FlagsCondition>(condition_ ^ 1); } | 263 void Negate() { |
| 264 ASSERT(!IsNone()); |
| 265 condition_ = static_cast<FlagsCondition>(condition_ ^ 1); |
| 266 } |
254 | 267 |
255 void Commute() { | 268 void Commute() { |
| 269 ASSERT(!IsNone()); |
256 switch (condition_) { | 270 switch (condition_) { |
257 case kEqual: | 271 case kEqual: |
258 case kNotEqual: | 272 case kNotEqual: |
259 case kOverflow: | 273 case kOverflow: |
260 case kNotOverflow: | 274 case kNotOverflow: |
261 return; | 275 return; |
262 case kSignedLessThan: | 276 case kSignedLessThan: |
263 condition_ = kSignedGreaterThan; | 277 condition_ = kSignedGreaterThan; |
264 return; | 278 return; |
265 case kSignedGreaterThanOrEqual: | 279 case kSignedGreaterThanOrEqual: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 void OverwriteAndNegateIfEqual(FlagsCondition condition) { | 319 void OverwriteAndNegateIfEqual(FlagsCondition condition) { |
306 bool negate = condition_ == kEqual; | 320 bool negate = condition_ == kEqual; |
307 condition_ = condition; | 321 condition_ = condition; |
308 if (negate) Negate(); | 322 if (negate) Negate(); |
309 } | 323 } |
310 | 324 |
311 void SwapBlocks() { std::swap(true_block_, false_block_); } | 325 void SwapBlocks() { std::swap(true_block_, false_block_); } |
312 | 326 |
313 // Encodes this flags continuation into the given opcode. | 327 // Encodes this flags continuation into the given opcode. |
314 InstructionCode Encode(InstructionCode opcode) { | 328 InstructionCode Encode(InstructionCode opcode) { |
315 return opcode | FlagsModeField::encode(mode_) | | 329 opcode |= FlagsModeField::encode(mode_); |
316 FlagsConditionField::encode(condition_); | 330 if (mode_ != kFlags_none) { |
| 331 opcode |= FlagsConditionField::encode(condition_); |
| 332 } |
| 333 return opcode; |
317 } | 334 } |
318 | 335 |
319 private: | 336 private: |
320 FlagsMode mode_; | 337 FlagsMode mode_; |
321 FlagsCondition condition_; | 338 FlagsCondition condition_; |
322 Node* result_; // Only valid if mode_ == kFlags_set. | 339 Node* result_; // Only valid if mode_ == kFlags_set. |
323 BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch. | 340 BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch. |
324 BasicBlock* false_block_; // Only valid if mode_ == kFlags_branch. | 341 BasicBlock* false_block_; // Only valid if mode_ == kFlags_branch. |
325 }; | 342 }; |
326 | 343 |
(...skipping 18 matching lines...) Expand all Loading... |
345 int control_count() { return descriptor->CanLazilyDeoptimize() ? 2 : 0; } | 362 int control_count() { return descriptor->CanLazilyDeoptimize() ? 2 : 0; } |
346 | 363 |
347 int fixed_and_control_count() { return fixed_count + control_count(); } | 364 int fixed_and_control_count() { return fixed_count + control_count(); } |
348 }; | 365 }; |
349 | 366 |
350 } // namespace compiler | 367 } // namespace compiler |
351 } // namespace internal | 368 } // namespace internal |
352 } // namespace v8 | 369 } // namespace v8 |
353 | 370 |
354 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ | 371 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ |
OLD | NEW |