| 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 |