| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 class HGraph; | 41 class HGraph; |
| 42 class HInstruction; | 42 class HInstruction; |
| 43 class HPhi; | 43 class HPhi; |
| 44 class HTracer; | 44 class HTracer; |
| 45 class HValue; | 45 class HValue; |
| 46 class BitVector; | 46 class BitVector; |
| 47 class StringStream; | 47 class StringStream; |
| 48 | 48 |
| 49 class LArgument; | 49 class LArgument; |
| 50 class LChunk; | 50 class LChunk; |
| 51 class LOperand; |
| 52 class LUnallocated; |
| 51 class LConstantOperand; | 53 class LConstantOperand; |
| 52 class LGap; | 54 class LGap; |
| 53 class LParallelMove; | 55 class LParallelMove; |
| 54 class LPointerMap; | 56 class LPointerMap; |
| 55 class LStackSlot; | 57 class LStackSlot; |
| 56 class LRegister; | 58 class LRegister; |
| 57 | 59 |
| 58 | 60 |
| 59 // This class represents a single point of a LOperand's lifetime. | 61 // This class represents a single point of a LOperand's lifetime. |
| 60 // For each lithium instruction there are exactly two lifetime positions: | 62 // For each lithium instruction there are exactly two lifetime positions: |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 }; | 144 }; |
| 143 | 145 |
| 144 | 146 |
| 145 enum RegisterKind { | 147 enum RegisterKind { |
| 146 NONE, | 148 NONE, |
| 147 GENERAL_REGISTERS, | 149 GENERAL_REGISTERS, |
| 148 DOUBLE_REGISTERS | 150 DOUBLE_REGISTERS |
| 149 }; | 151 }; |
| 150 | 152 |
| 151 | 153 |
| 152 class LOperand: public ZoneObject { | |
| 153 public: | |
| 154 enum Kind { | |
| 155 INVALID, | |
| 156 UNALLOCATED, | |
| 157 CONSTANT_OPERAND, | |
| 158 STACK_SLOT, | |
| 159 DOUBLE_STACK_SLOT, | |
| 160 REGISTER, | |
| 161 DOUBLE_REGISTER, | |
| 162 ARGUMENT | |
| 163 }; | |
| 164 | |
| 165 LOperand() : value_(KindField::encode(INVALID)) { } | |
| 166 | |
| 167 Kind kind() const { return KindField::decode(value_); } | |
| 168 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } | |
| 169 bool IsConstantOperand() const { return kind() == CONSTANT_OPERAND; } | |
| 170 bool IsStackSlot() const { return kind() == STACK_SLOT; } | |
| 171 bool IsDoubleStackSlot() const { return kind() == DOUBLE_STACK_SLOT; } | |
| 172 bool IsRegister() const { return kind() == REGISTER; } | |
| 173 bool IsDoubleRegister() const { return kind() == DOUBLE_REGISTER; } | |
| 174 bool IsArgument() const { return kind() == ARGUMENT; } | |
| 175 bool IsUnallocated() const { return kind() == UNALLOCATED; } | |
| 176 bool Equals(LOperand* other) const { return value_ == other->value_; } | |
| 177 int VirtualRegister(); | |
| 178 | |
| 179 void PrintTo(StringStream* stream); | |
| 180 void ConvertTo(Kind kind, int index) { | |
| 181 value_ = KindField::encode(kind); | |
| 182 value_ |= index << kKindFieldWidth; | |
| 183 ASSERT(this->index() == index); | |
| 184 } | |
| 185 | |
| 186 protected: | |
| 187 static const int kKindFieldWidth = 3; | |
| 188 class KindField : public BitField<Kind, 0, kKindFieldWidth> { }; | |
| 189 | |
| 190 LOperand(Kind kind, int index) { ConvertTo(kind, index); } | |
| 191 | |
| 192 unsigned value_; | |
| 193 }; | |
| 194 | |
| 195 | |
| 196 class LUnallocated: public LOperand { | |
| 197 public: | |
| 198 enum Policy { | |
| 199 NONE, | |
| 200 ANY, | |
| 201 FIXED_REGISTER, | |
| 202 FIXED_DOUBLE_REGISTER, | |
| 203 FIXED_SLOT, | |
| 204 MUST_HAVE_REGISTER, | |
| 205 WRITABLE_REGISTER, | |
| 206 SAME_AS_FIRST_INPUT, | |
| 207 IGNORE | |
| 208 }; | |
| 209 | |
| 210 // Lifetime of operand inside the instruction. | |
| 211 enum Lifetime { | |
| 212 // USED_AT_START operand is guaranteed to be live only at | |
| 213 // instruction start. Register allocator is free to assign the same register | |
| 214 // to some other operand used inside instruction (i.e. temporary or | |
| 215 // output). | |
| 216 USED_AT_START, | |
| 217 | |
| 218 // USED_AT_END operand is treated as live until the end of | |
| 219 // instruction. This means that register allocator will not reuse it's | |
| 220 // register for any other operand inside instruction. | |
| 221 USED_AT_END | |
| 222 }; | |
| 223 | |
| 224 explicit LUnallocated(Policy policy) : LOperand(UNALLOCATED, 0) { | |
| 225 Initialize(policy, 0, USED_AT_END); | |
| 226 } | |
| 227 | |
| 228 LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) { | |
| 229 Initialize(policy, fixed_index, USED_AT_END); | |
| 230 } | |
| 231 | |
| 232 LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) { | |
| 233 Initialize(policy, 0, lifetime); | |
| 234 } | |
| 235 | |
| 236 // The superclass has a KindField. Some policies have a signed fixed | |
| 237 // index in the upper bits. | |
| 238 static const int kPolicyWidth = 4; | |
| 239 static const int kLifetimeWidth = 1; | |
| 240 static const int kVirtualRegisterWidth = 17; | |
| 241 | |
| 242 static const int kPolicyShift = kKindFieldWidth; | |
| 243 static const int kLifetimeShift = kPolicyShift + kPolicyWidth; | |
| 244 static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth; | |
| 245 static const int kFixedIndexShift = | |
| 246 kVirtualRegisterShift + kVirtualRegisterWidth; | |
| 247 | |
| 248 class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { }; | |
| 249 | |
| 250 class LifetimeField | |
| 251 : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> { | |
| 252 }; | |
| 253 | |
| 254 class VirtualRegisterField | |
| 255 : public BitField<unsigned, | |
| 256 kVirtualRegisterShift, | |
| 257 kVirtualRegisterWidth> { | |
| 258 }; | |
| 259 | |
| 260 static const int kMaxVirtualRegisters = 1 << (kVirtualRegisterWidth + 1); | |
| 261 static const int kMaxFixedIndices = 128; | |
| 262 | |
| 263 bool HasIgnorePolicy() const { return policy() == IGNORE; } | |
| 264 bool HasNoPolicy() const { return policy() == NONE; } | |
| 265 bool HasAnyPolicy() const { | |
| 266 return policy() == ANY; | |
| 267 } | |
| 268 bool HasFixedPolicy() const { | |
| 269 return policy() == FIXED_REGISTER || | |
| 270 policy() == FIXED_DOUBLE_REGISTER || | |
| 271 policy() == FIXED_SLOT; | |
| 272 } | |
| 273 bool HasRegisterPolicy() const { | |
| 274 return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER; | |
| 275 } | |
| 276 bool HasSameAsInputPolicy() const { | |
| 277 return policy() == SAME_AS_FIRST_INPUT; | |
| 278 } | |
| 279 Policy policy() const { return PolicyField::decode(value_); } | |
| 280 void set_policy(Policy policy) { | |
| 281 value_ &= ~PolicyField::mask(); | |
| 282 value_ |= PolicyField::encode(policy); | |
| 283 } | |
| 284 int fixed_index() const { | |
| 285 return static_cast<int>(value_) >> kFixedIndexShift; | |
| 286 } | |
| 287 | |
| 288 unsigned virtual_register() const { | |
| 289 return VirtualRegisterField::decode(value_); | |
| 290 } | |
| 291 | |
| 292 void set_virtual_register(unsigned id) { | |
| 293 value_ &= ~VirtualRegisterField::mask(); | |
| 294 value_ |= VirtualRegisterField::encode(id); | |
| 295 } | |
| 296 | |
| 297 LUnallocated* CopyUnconstrained() { | |
| 298 LUnallocated* result = new LUnallocated(ANY); | |
| 299 result->set_virtual_register(virtual_register()); | |
| 300 return result; | |
| 301 } | |
| 302 | |
| 303 static LUnallocated* cast(LOperand* op) { | |
| 304 ASSERT(op->IsUnallocated()); | |
| 305 return reinterpret_cast<LUnallocated*>(op); | |
| 306 } | |
| 307 | |
| 308 bool IsUsedAtStart() { | |
| 309 return LifetimeField::decode(value_) == USED_AT_START; | |
| 310 } | |
| 311 | |
| 312 private: | |
| 313 void Initialize(Policy policy, int fixed_index, Lifetime lifetime) { | |
| 314 value_ |= PolicyField::encode(policy); | |
| 315 value_ |= LifetimeField::encode(lifetime); | |
| 316 value_ |= fixed_index << kFixedIndexShift; | |
| 317 ASSERT(this->fixed_index() == fixed_index); | |
| 318 } | |
| 319 }; | |
| 320 | |
| 321 | |
| 322 class LMoveOperands BASE_EMBEDDED { | |
| 323 public: | |
| 324 LMoveOperands(LOperand* from, LOperand* to) : from_(from), to_(to) { } | |
| 325 | |
| 326 LOperand* from() const { return from_; } | |
| 327 LOperand* to() const { return to_; } | |
| 328 bool IsRedundant() const { | |
| 329 return IsEliminated() || from_->Equals(to_) || IsIgnored(); | |
| 330 } | |
| 331 bool IsEliminated() const { return from_ == NULL; } | |
| 332 bool IsIgnored() const { | |
| 333 if (to_ != NULL && to_->IsUnallocated() && | |
| 334 LUnallocated::cast(to_)->HasIgnorePolicy()) { | |
| 335 return true; | |
| 336 } | |
| 337 return false; | |
| 338 } | |
| 339 | |
| 340 void Eliminate() { from_ = to_ = NULL; } | |
| 341 | |
| 342 private: | |
| 343 LOperand* from_; | |
| 344 LOperand* to_; | |
| 345 }; | |
| 346 | |
| 347 | |
| 348 class LConstantOperand: public LOperand { | |
| 349 public: | |
| 350 static LConstantOperand* Create(int index) { | |
| 351 ASSERT(index >= 0); | |
| 352 if (index < kNumCachedOperands) return &cache[index]; | |
| 353 return new LConstantOperand(index); | |
| 354 } | |
| 355 | |
| 356 static LConstantOperand* cast(LOperand* op) { | |
| 357 ASSERT(op->IsConstantOperand()); | |
| 358 return reinterpret_cast<LConstantOperand*>(op); | |
| 359 } | |
| 360 | |
| 361 static void SetupCache(); | |
| 362 | |
| 363 private: | |
| 364 static const int kNumCachedOperands = 128; | |
| 365 static LConstantOperand cache[]; | |
| 366 | |
| 367 LConstantOperand() : LOperand() { } | |
| 368 explicit LConstantOperand(int index) : LOperand(CONSTANT_OPERAND, index) { } | |
| 369 }; | |
| 370 | |
| 371 | |
| 372 class LArgument: public LOperand { | |
| 373 public: | |
| 374 explicit LArgument(int index) : LOperand(ARGUMENT, index) { } | |
| 375 | |
| 376 static LArgument* cast(LOperand* op) { | |
| 377 ASSERT(op->IsArgument()); | |
| 378 return reinterpret_cast<LArgument*>(op); | |
| 379 } | |
| 380 }; | |
| 381 | |
| 382 | |
| 383 class LStackSlot: public LOperand { | |
| 384 public: | |
| 385 static LStackSlot* Create(int index) { | |
| 386 ASSERT(index >= 0); | |
| 387 if (index < kNumCachedOperands) return &cache[index]; | |
| 388 return new LStackSlot(index); | |
| 389 } | |
| 390 | |
| 391 static LStackSlot* cast(LOperand* op) { | |
| 392 ASSERT(op->IsStackSlot()); | |
| 393 return reinterpret_cast<LStackSlot*>(op); | |
| 394 } | |
| 395 | |
| 396 static void SetupCache(); | |
| 397 | |
| 398 private: | |
| 399 static const int kNumCachedOperands = 128; | |
| 400 static LStackSlot cache[]; | |
| 401 | |
| 402 LStackSlot() : LOperand() { } | |
| 403 explicit LStackSlot(int index) : LOperand(STACK_SLOT, index) { } | |
| 404 }; | |
| 405 | |
| 406 | |
| 407 class LDoubleStackSlot: public LOperand { | |
| 408 public: | |
| 409 static LDoubleStackSlot* Create(int index) { | |
| 410 ASSERT(index >= 0); | |
| 411 if (index < kNumCachedOperands) return &cache[index]; | |
| 412 return new LDoubleStackSlot(index); | |
| 413 } | |
| 414 | |
| 415 static LDoubleStackSlot* cast(LOperand* op) { | |
| 416 ASSERT(op->IsStackSlot()); | |
| 417 return reinterpret_cast<LDoubleStackSlot*>(op); | |
| 418 } | |
| 419 | |
| 420 static void SetupCache(); | |
| 421 | |
| 422 private: | |
| 423 static const int kNumCachedOperands = 128; | |
| 424 static LDoubleStackSlot cache[]; | |
| 425 | |
| 426 LDoubleStackSlot() : LOperand() { } | |
| 427 explicit LDoubleStackSlot(int index) : LOperand(DOUBLE_STACK_SLOT, index) { } | |
| 428 }; | |
| 429 | |
| 430 | |
| 431 class LRegister: public LOperand { | |
| 432 public: | |
| 433 static LRegister* Create(int index) { | |
| 434 ASSERT(index >= 0); | |
| 435 if (index < kNumCachedOperands) return &cache[index]; | |
| 436 return new LRegister(index); | |
| 437 } | |
| 438 | |
| 439 static LRegister* cast(LOperand* op) { | |
| 440 ASSERT(op->IsRegister()); | |
| 441 return reinterpret_cast<LRegister*>(op); | |
| 442 } | |
| 443 | |
| 444 static void SetupCache(); | |
| 445 | |
| 446 private: | |
| 447 static const int kNumCachedOperands = 16; | |
| 448 static LRegister cache[]; | |
| 449 | |
| 450 LRegister() : LOperand() { } | |
| 451 explicit LRegister(int index) : LOperand(REGISTER, index) { } | |
| 452 }; | |
| 453 | |
| 454 | |
| 455 class LDoubleRegister: public LOperand { | |
| 456 public: | |
| 457 static LDoubleRegister* Create(int index) { | |
| 458 ASSERT(index >= 0); | |
| 459 if (index < kNumCachedOperands) return &cache[index]; | |
| 460 return new LDoubleRegister(index); | |
| 461 } | |
| 462 | |
| 463 static LDoubleRegister* cast(LOperand* op) { | |
| 464 ASSERT(op->IsDoubleRegister()); | |
| 465 return reinterpret_cast<LDoubleRegister*>(op); | |
| 466 } | |
| 467 | |
| 468 static void SetupCache(); | |
| 469 | |
| 470 private: | |
| 471 static const int kNumCachedOperands = 16; | |
| 472 static LDoubleRegister cache[]; | |
| 473 | |
| 474 LDoubleRegister() : LOperand() { } | |
| 475 explicit LDoubleRegister(int index) : LOperand(DOUBLE_REGISTER, index) { } | |
| 476 }; | |
| 477 | |
| 478 | |
| 479 // A register-allocator view of a Lithium instruction. It contains the id of | 154 // A register-allocator view of a Lithium instruction. It contains the id of |
| 480 // the output operand and a list of input operand uses. | 155 // the output operand and a list of input operand uses. |
| 481 class InstructionSummary: public ZoneObject { | 156 class InstructionSummary: public ZoneObject { |
| 482 public: | 157 public: |
| 483 InstructionSummary() | 158 InstructionSummary() |
| 484 : output_operand_(NULL), | 159 : output_operand_(NULL), |
| 485 input_count_(0), | 160 input_count_(0), |
| 486 operands_(4), | 161 operands_(4), |
| 487 is_call_(false), | 162 is_call_(false), |
| 488 is_save_doubles_(false) {} | 163 is_save_doubles_(false) {} |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 LifetimePosition start_; | 234 LifetimePosition start_; |
| 560 LifetimePosition end_; | 235 LifetimePosition end_; |
| 561 UseInterval* next_; | 236 UseInterval* next_; |
| 562 | 237 |
| 563 friend class LiveRange; // Assigns to start_. | 238 friend class LiveRange; // Assigns to start_. |
| 564 }; | 239 }; |
| 565 | 240 |
| 566 // Representation of a use position. | 241 // Representation of a use position. |
| 567 class UsePosition: public ZoneObject { | 242 class UsePosition: public ZoneObject { |
| 568 public: | 243 public: |
| 569 UsePosition(LifetimePosition pos, LOperand* operand) | 244 UsePosition(LifetimePosition pos, LOperand* operand); |
| 570 : operand_(operand), | |
| 571 hint_(NULL), | |
| 572 pos_(pos), | |
| 573 next_(NULL), | |
| 574 requires_reg_(false), | |
| 575 register_beneficial_(true) { | |
| 576 if (operand_ != NULL && operand_->IsUnallocated()) { | |
| 577 LUnallocated* unalloc = LUnallocated::cast(operand_); | |
| 578 requires_reg_ = unalloc->HasRegisterPolicy(); | |
| 579 register_beneficial_ = !unalloc->HasAnyPolicy(); | |
| 580 } | |
| 581 ASSERT(pos_.IsValid()); | |
| 582 } | |
| 583 | 245 |
| 584 LOperand* operand() const { return operand_; } | 246 LOperand* operand() const { return operand_; } |
| 585 bool HasOperand() const { return operand_ != NULL; } | 247 bool HasOperand() const { return operand_ != NULL; } |
| 586 | 248 |
| 587 LOperand* hint() const { return hint_; } | 249 LOperand* hint() const { return hint_; } |
| 588 void set_hint(LOperand* hint) { hint_ = hint; } | 250 void set_hint(LOperand* hint) { hint_ = hint; } |
| 589 bool HasHint() const { return hint_ != NULL && !hint_->IsUnallocated(); } | 251 bool HasHint() const; |
| 590 bool RequiresRegister() const; | 252 bool RequiresRegister() const; |
| 591 bool RegisterIsBeneficial() const; | 253 bool RegisterIsBeneficial() const; |
| 592 | 254 |
| 593 LifetimePosition pos() const { return pos_; } | 255 LifetimePosition pos() const { return pos_; } |
| 594 UsePosition* next() const { return next_; } | 256 UsePosition* next() const { return next_; } |
| 595 | 257 |
| 596 private: | 258 private: |
| 597 void set_next(UsePosition* next) { next_ = next; } | 259 void set_next(UsePosition* next) { next_ = next; } |
| 598 | 260 |
| 599 LOperand* operand_; | 261 LOperand* operand_; |
| 600 LOperand* hint_; | 262 LOperand* hint_; |
| 601 LifetimePosition pos_; | 263 LifetimePosition pos_; |
| 602 UsePosition* next_; | 264 UsePosition* next_; |
| 603 bool requires_reg_; | 265 bool requires_reg_; |
| 604 bool register_beneficial_; | 266 bool register_beneficial_; |
| 605 | 267 |
| 606 friend class LiveRange; | 268 friend class LiveRange; |
| 607 }; | 269 }; |
| 608 | 270 |
| 609 // Representation of SSA values' live ranges as a collection of (continuous) | 271 // Representation of SSA values' live ranges as a collection of (continuous) |
| 610 // intervals over the instruction ordering. | 272 // intervals over the instruction ordering. |
| 611 class LiveRange: public ZoneObject { | 273 class LiveRange: public ZoneObject { |
| 612 public: | 274 public: |
| 613 static const int kInvalidAssignment = 0x7fffffff; | 275 static const int kInvalidAssignment = 0x7fffffff; |
| 614 | 276 |
| 615 explicit LiveRange(int id) | 277 explicit LiveRange(int id); |
| 616 : id_(id), | |
| 617 spilled_(false), | |
| 618 assigned_register_(kInvalidAssignment), | |
| 619 assigned_register_kind_(NONE), | |
| 620 last_interval_(NULL), | |
| 621 first_interval_(NULL), | |
| 622 first_pos_(NULL), | |
| 623 parent_(NULL), | |
| 624 next_(NULL), | |
| 625 current_interval_(NULL), | |
| 626 last_processed_use_(NULL), | |
| 627 spill_start_index_(kMaxInt) { | |
| 628 spill_operand_ = new LUnallocated(LUnallocated::IGNORE); | |
| 629 } | |
| 630 | 278 |
| 631 UseInterval* first_interval() const { return first_interval_; } | 279 UseInterval* first_interval() const { return first_interval_; } |
| 632 UsePosition* first_pos() const { return first_pos_; } | 280 UsePosition* first_pos() const { return first_pos_; } |
| 633 LiveRange* parent() const { return parent_; } | 281 LiveRange* parent() const { return parent_; } |
| 634 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } | 282 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } |
| 635 LiveRange* next() const { return next_; } | 283 LiveRange* next() const { return next_; } |
| 636 bool IsChild() const { return parent() != NULL; } | 284 bool IsChild() const { return parent() != NULL; } |
| 637 bool IsParent() const { return parent() == NULL; } | 285 bool IsParent() const { return parent() == NULL; } |
| 638 int id() const { return id_; } | 286 int id() const { return id_; } |
| 639 bool IsFixed() const { return id_ < 0; } | 287 bool IsFixed() const { return id_ < 0; } |
| 640 bool IsEmpty() const { return first_interval() == NULL; } | 288 bool IsEmpty() const { return first_interval() == NULL; } |
| 641 LOperand* CreateAssignedOperand(); | 289 LOperand* CreateAssignedOperand(); |
| 642 int assigned_register() const { return assigned_register_; } | 290 int assigned_register() const { return assigned_register_; } |
| 643 int spill_start_index() const { return spill_start_index_; } | 291 int spill_start_index() const { return spill_start_index_; } |
| 644 void set_assigned_register(int reg, RegisterKind register_kind) { | 292 void set_assigned_register(int reg, RegisterKind register_kind); |
| 645 ASSERT(!HasRegisterAssigned() && !IsSpilled()); | 293 void MakeSpilled(); |
| 646 assigned_register_ = reg; | |
| 647 assigned_register_kind_ = register_kind; | |
| 648 ConvertOperands(); | |
| 649 } | |
| 650 void MakeSpilled() { | |
| 651 ASSERT(!IsSpilled()); | |
| 652 ASSERT(TopLevel()->HasAllocatedSpillOperand()); | |
| 653 spilled_ = true; | |
| 654 assigned_register_ = kInvalidAssignment; | |
| 655 ConvertOperands(); | |
| 656 } | |
| 657 | 294 |
| 658 // Returns use position in this live range that follows both start | 295 // Returns use position in this live range that follows both start |
| 659 // and last processed use position. | 296 // and last processed use position. |
| 660 // Modifies internal state of live range! | 297 // Modifies internal state of live range! |
| 661 UsePosition* NextUsePosition(LifetimePosition start); | 298 UsePosition* NextUsePosition(LifetimePosition start); |
| 662 | 299 |
| 663 // Returns use position for which register is required in this live | 300 // Returns use position for which register is required in this live |
| 664 // range and which follows both start and last processed use position | 301 // range and which follows both start and last processed use position |
| 665 // Modifies internal state of live range! | 302 // Modifies internal state of live range! |
| 666 UsePosition* NextRegisterPosition(LifetimePosition start); | 303 UsePosition* NextRegisterPosition(LifetimePosition start); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 695 LifetimePosition Start() const { | 332 LifetimePosition Start() const { |
| 696 ASSERT(!IsEmpty()); | 333 ASSERT(!IsEmpty()); |
| 697 return first_interval()->start(); | 334 return first_interval()->start(); |
| 698 } | 335 } |
| 699 | 336 |
| 700 LifetimePosition End() const { | 337 LifetimePosition End() const { |
| 701 ASSERT(!IsEmpty()); | 338 ASSERT(!IsEmpty()); |
| 702 return last_interval_->end(); | 339 return last_interval_->end(); |
| 703 } | 340 } |
| 704 | 341 |
| 705 bool HasAllocatedSpillOperand() const { | 342 bool HasAllocatedSpillOperand() const; |
| 706 return spill_operand_ != NULL && !spill_operand_->IsUnallocated(); | |
| 707 } | |
| 708 LOperand* GetSpillOperand() const { return spill_operand_; } | 343 LOperand* GetSpillOperand() const { return spill_operand_; } |
| 709 void SetSpillOperand(LOperand* operand) { | 344 void SetSpillOperand(LOperand* operand); |
| 710 ASSERT(!operand->IsUnallocated()); | |
| 711 ASSERT(spill_operand_ != NULL); | |
| 712 ASSERT(spill_operand_->IsUnallocated()); | |
| 713 spill_operand_->ConvertTo(operand->kind(), operand->index()); | |
| 714 } | |
| 715 | 345 |
| 716 void SetSpillStartIndex(int start) { | 346 void SetSpillStartIndex(int start) { |
| 717 spill_start_index_ = Min(start, spill_start_index_); | 347 spill_start_index_ = Min(start, spill_start_index_); |
| 718 } | 348 } |
| 719 | 349 |
| 720 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 350 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
| 721 bool CanCover(LifetimePosition position) const; | 351 bool CanCover(LifetimePosition position) const; |
| 722 bool Covers(LifetimePosition position); | 352 bool Covers(LifetimePosition position); |
| 723 LifetimePosition FirstIntersection(LiveRange* other); | 353 LifetimePosition FirstIntersection(LiveRange* other); |
| 724 | 354 |
| 725 | |
| 726 // Add a new interval or a new use position to this live range. | 355 // Add a new interval or a new use position to this live range. |
| 727 void EnsureInterval(LifetimePosition start, LifetimePosition end); | 356 void EnsureInterval(LifetimePosition start, LifetimePosition end); |
| 728 void AddUseInterval(LifetimePosition start, LifetimePosition end); | 357 void AddUseInterval(LifetimePosition start, LifetimePosition end); |
| 729 UsePosition* AddUsePosition(LifetimePosition pos, LOperand* operand); | 358 UsePosition* AddUsePosition(LifetimePosition pos, LOperand* operand); |
| 730 UsePosition* AddUsePosition(LifetimePosition pos); | 359 UsePosition* AddUsePosition(LifetimePosition pos); |
| 731 | 360 |
| 732 // Shorten the most recently added interval by setting a new start. | 361 // Shorten the most recently added interval by setting a new start. |
| 733 void ShortenTo(LifetimePosition start); | 362 void ShortenTo(LifetimePosition start); |
| 734 | 363 |
| 735 #ifdef DEBUG | 364 #ifdef DEBUG |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 | 584 |
| 956 // Spill the given life range after position start and up to position end. | 585 // Spill the given life range after position start and up to position end. |
| 957 void SpillBetween(LiveRange* range, | 586 void SpillBetween(LiveRange* range, |
| 958 LifetimePosition start, | 587 LifetimePosition start, |
| 959 LifetimePosition end); | 588 LifetimePosition end); |
| 960 | 589 |
| 961 void SplitAndSpillIntersecting(LiveRange* range); | 590 void SplitAndSpillIntersecting(LiveRange* range); |
| 962 | 591 |
| 963 void Spill(LiveRange* range); | 592 void Spill(LiveRange* range); |
| 964 bool IsBlockBoundary(LifetimePosition pos); | 593 bool IsBlockBoundary(LifetimePosition pos); |
| 965 void AddGapMove(int pos, LiveRange* prev, LiveRange* next); | |
| 966 | 594 |
| 967 // Helper methods for resolving control flow. | 595 // Helper methods for resolving control flow. |
| 968 void ResolveControlFlow(LiveRange* range, | 596 void ResolveControlFlow(LiveRange* range, |
| 969 HBasicBlock* block, | 597 HBasicBlock* block, |
| 970 HBasicBlock* pred); | 598 HBasicBlock* pred); |
| 971 | 599 |
| 972 // Return parallel move that should be used to connect ranges split at the | 600 // Return parallel move that should be used to connect ranges split at the |
| 973 // given position. | 601 // given position. |
| 974 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); | 602 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); |
| 975 | 603 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 | 655 |
| 1028 bool has_osr_entry_; | 656 bool has_osr_entry_; |
| 1029 | 657 |
| 1030 DISALLOW_COPY_AND_ASSIGN(LAllocator); | 658 DISALLOW_COPY_AND_ASSIGN(LAllocator); |
| 1031 }; | 659 }; |
| 1032 | 660 |
| 1033 | 661 |
| 1034 } } // namespace v8::internal | 662 } } // namespace v8::internal |
| 1035 | 663 |
| 1036 #endif // V8_LITHIUM_ALLOCATOR_H_ | 664 #endif // V8_LITHIUM_ALLOCATOR_H_ |
| OLD | NEW |