| 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_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
| 6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <iosfwd> | 9 #include <iosfwd> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 static const OperandType* cast(const InstructionOperand* op) { \ | 160 static const OperandType* cast(const InstructionOperand* op) { \ |
| 161 DCHECK_EQ(OperandKind, op->kind()); \ | 161 DCHECK_EQ(OperandKind, op->kind()); \ |
| 162 return static_cast<const OperandType*>(op); \ | 162 return static_cast<const OperandType*>(op); \ |
| 163 } \ | 163 } \ |
| 164 \ | 164 \ |
| 165 static OperandType cast(const InstructionOperand& op) { \ | 165 static OperandType cast(const InstructionOperand& op) { \ |
| 166 DCHECK_EQ(OperandKind, op.kind()); \ | 166 DCHECK_EQ(OperandKind, op.kind()); \ |
| 167 return *static_cast<const OperandType*>(&op); \ | 167 return *static_cast<const OperandType*>(&op); \ |
| 168 } | 168 } |
| 169 | 169 |
| 170 class UnallocatedOperand : public InstructionOperand { | 170 class UnallocatedOperand final : public InstructionOperand { |
| 171 public: | 171 public: |
| 172 enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; | 172 enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; |
| 173 | 173 |
| 174 enum ExtendedPolicy { | 174 enum ExtendedPolicy { |
| 175 NONE, | 175 NONE, |
| 176 ANY, | 176 ANY, |
| 177 FIXED_REGISTER, | 177 FIXED_REGISTER, |
| 178 FIXED_FP_REGISTER, | 178 FIXED_FP_REGISTER, |
| 179 MUST_HAVE_REGISTER, | 179 MUST_HAVE_REGISTER, |
| 180 MUST_HAVE_SLOT, | 180 MUST_HAVE_SLOT, |
| 181 SAME_AS_FIRST_INPUT | 181 SAME_AS_FIRST_INPUT |
| 182 }; | 182 }; |
| 183 | 183 |
| 184 // Lifetime of operand inside the instruction. | 184 // Lifetime of operand inside the instruction. |
| 185 enum Lifetime { | 185 enum Lifetime { |
| 186 // USED_AT_START operand is guaranteed to be live only at | 186 // USED_AT_START operand is guaranteed to be live only at instruction start. |
| 187 // instruction start. Register allocator is free to assign the same register | 187 // The register allocator is free to assign the same register to some other |
| 188 // to some other operand used inside instruction (i.e. temporary or | 188 // operand used inside instruction (i.e. temporary or output). |
| 189 // output). | |
| 190 USED_AT_START, | 189 USED_AT_START, |
| 191 | 190 |
| 192 // USED_AT_END operand is treated as live until the end of | 191 // USED_AT_END operand is treated as live until the end of instruction. |
| 193 // instruction. This means that register allocator will not reuse it's | 192 // This means that register allocator will not reuse its register for any |
| 194 // register for any other operand inside instruction. | 193 // other operand inside instruction. |
| 195 USED_AT_END | 194 USED_AT_END |
| 196 }; | 195 }; |
| 197 | 196 |
| 198 UnallocatedOperand(ExtendedPolicy policy, int virtual_register) | 197 UnallocatedOperand(ExtendedPolicy policy, int virtual_register) |
| 199 : UnallocatedOperand(virtual_register) { | 198 : UnallocatedOperand(virtual_register) { |
| 200 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 199 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
| 201 value_ |= ExtendedPolicyField::encode(policy); | 200 value_ |= ExtendedPolicyField::encode(policy); |
| 202 value_ |= LifetimeField::encode(USED_AT_END); | 201 value_ |= LifetimeField::encode(USED_AT_END); |
| 203 } | 202 } |
| 204 | 203 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 226 value_ |= ExtendedPolicyField::encode(policy); | 225 value_ |= ExtendedPolicyField::encode(policy); |
| 227 value_ |= LifetimeField::encode(lifetime); | 226 value_ |= LifetimeField::encode(lifetime); |
| 228 } | 227 } |
| 229 | 228 |
| 230 UnallocatedOperand(int reg_id, int slot_id, int virtual_register) | 229 UnallocatedOperand(int reg_id, int slot_id, int virtual_register) |
| 231 : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) { | 230 : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) { |
| 232 value_ |= HasSecondaryStorageField::encode(true); | 231 value_ |= HasSecondaryStorageField::encode(true); |
| 233 value_ |= SecondaryStorageField::encode(slot_id); | 232 value_ |= SecondaryStorageField::encode(slot_id); |
| 234 } | 233 } |
| 235 | 234 |
| 235 UnallocatedOperand(const UnallocatedOperand& other, int virtual_register) { |
| 236 DCHECK_NE(kInvalidVirtualRegister, virtual_register); |
| 237 value_ = VirtualRegisterField::update( |
| 238 other.value_, static_cast<uint32_t>(virtual_register)); |
| 239 } |
| 240 |
| 236 // Predicates for the operand policy. | 241 // Predicates for the operand policy. |
| 237 bool HasAnyPolicy() const { | 242 bool HasAnyPolicy() const { |
| 238 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; | 243 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; |
| 239 } | 244 } |
| 240 bool HasFixedPolicy() const { | 245 bool HasFixedPolicy() const { |
| 241 return basic_policy() == FIXED_SLOT || | 246 return basic_policy() == FIXED_SLOT || |
| 242 extended_policy() == FIXED_REGISTER || | 247 extended_policy() == FIXED_REGISTER || |
| 243 extended_policy() == FIXED_FP_REGISTER; | 248 extended_policy() == FIXED_FP_REGISTER; |
| 244 } | 249 } |
| 245 bool HasRegisterPolicy() const { | 250 bool HasRegisterPolicy() const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 268 extended_policy() == FIXED_REGISTER && | 273 extended_policy() == FIXED_REGISTER && |
| 269 HasSecondaryStorageField::decode(value_); | 274 HasSecondaryStorageField::decode(value_); |
| 270 } | 275 } |
| 271 int GetSecondaryStorage() const { | 276 int GetSecondaryStorage() const { |
| 272 DCHECK(HasSecondaryStorage()); | 277 DCHECK(HasSecondaryStorage()); |
| 273 return SecondaryStorageField::decode(value_); | 278 return SecondaryStorageField::decode(value_); |
| 274 } | 279 } |
| 275 | 280 |
| 276 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. | 281 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. |
| 277 BasicPolicy basic_policy() const { | 282 BasicPolicy basic_policy() const { |
| 278 DCHECK_EQ(UNALLOCATED, kind()); | |
| 279 return BasicPolicyField::decode(value_); | 283 return BasicPolicyField::decode(value_); |
| 280 } | 284 } |
| 281 | 285 |
| 282 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. | 286 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. |
| 283 ExtendedPolicy extended_policy() const { | 287 ExtendedPolicy extended_policy() const { |
| 284 DCHECK(basic_policy() == EXTENDED_POLICY); | 288 DCHECK(basic_policy() == EXTENDED_POLICY); |
| 285 return ExtendedPolicyField::decode(value_); | 289 return ExtendedPolicyField::decode(value_); |
| 286 } | 290 } |
| 287 | 291 |
| 288 // [fixed_slot_index]: Only for FIXED_SLOT. | 292 // [fixed_slot_index]: Only for FIXED_SLOT. |
| 289 int fixed_slot_index() const { | 293 int fixed_slot_index() const { |
| 290 DCHECK(HasFixedSlotPolicy()); | 294 DCHECK(HasFixedSlotPolicy()); |
| 291 return static_cast<int>(static_cast<int64_t>(value_) >> | 295 return static_cast<int>(static_cast<int64_t>(value_) >> |
| 292 FixedSlotIndexField::kShift); | 296 FixedSlotIndexField::kShift); |
| 293 } | 297 } |
| 294 | 298 |
| 295 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_FP_REGISTER. | 299 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_FP_REGISTER. |
| 296 int fixed_register_index() const { | 300 int fixed_register_index() const { |
| 297 DCHECK(HasFixedRegisterPolicy() || HasFixedFPRegisterPolicy()); | 301 DCHECK(HasFixedRegisterPolicy() || HasFixedFPRegisterPolicy()); |
| 298 return FixedRegisterField::decode(value_); | 302 return FixedRegisterField::decode(value_); |
| 299 } | 303 } |
| 300 | 304 |
| 301 // [virtual_register]: The virtual register ID for this operand. | 305 // [virtual_register]: The virtual register ID for this operand. |
| 302 int32_t virtual_register() const { | 306 int32_t virtual_register() const { |
| 303 DCHECK_EQ(UNALLOCATED, kind()); | |
| 304 return static_cast<int32_t>(VirtualRegisterField::decode(value_)); | 307 return static_cast<int32_t>(VirtualRegisterField::decode(value_)); |
| 305 } | 308 } |
| 306 | 309 |
| 307 // TODO(dcarney): remove this. | |
| 308 void set_virtual_register(int32_t id) { | |
| 309 DCHECK_EQ(UNALLOCATED, kind()); | |
| 310 value_ = VirtualRegisterField::update(value_, static_cast<uint32_t>(id)); | |
| 311 } | |
| 312 | |
| 313 // [lifetime]: Only for non-FIXED_SLOT. | 310 // [lifetime]: Only for non-FIXED_SLOT. |
| 314 bool IsUsedAtStart() const { | 311 bool IsUsedAtStart() const { |
| 315 DCHECK(basic_policy() == EXTENDED_POLICY); | 312 DCHECK(basic_policy() == EXTENDED_POLICY); |
| 316 return LifetimeField::decode(value_) == USED_AT_START; | 313 return LifetimeField::decode(value_) == USED_AT_START; |
| 317 } | 314 } |
| 318 | 315 |
| 319 INSTRUCTION_OPERAND_CASTS(UnallocatedOperand, UNALLOCATED); | 316 INSTRUCTION_OPERAND_CASTS(UnallocatedOperand, UNALLOCATED); |
| 320 | 317 |
| 321 // The encoding used for UnallocatedOperand operands depends on the policy | 318 // The encoding used for UnallocatedOperand operands depends on the policy |
| 322 // that is | 319 // that is |
| (...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1671 }; | 1668 }; |
| 1672 | 1669 |
| 1673 V8_EXPORT_PRIVATE std::ostream& operator<<( | 1670 V8_EXPORT_PRIVATE std::ostream& operator<<( |
| 1674 std::ostream& os, const PrintableInstructionSequence& code); | 1671 std::ostream& os, const PrintableInstructionSequence& code); |
| 1675 | 1672 |
| 1676 } // namespace compiler | 1673 } // namespace compiler |
| 1677 } // namespace internal | 1674 } // namespace internal |
| 1678 } // namespace v8 | 1675 } // namespace v8 |
| 1679 | 1676 |
| 1680 #endif // V8_COMPILER_INSTRUCTION_H_ | 1677 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |