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

Unified Diff: src/lithium-allocator.h

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/lithium.cc ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/lithium-allocator.h
===================================================================
--- src/lithium-allocator.h (revision 6800)
+++ src/lithium-allocator.h (working copy)
@@ -31,6 +31,7 @@
#include "v8.h"
#include "data-flow.h"
+#include "lithium.h"
#include "zone.h"
namespace v8 {
@@ -48,9 +49,10 @@
class LArgument;
class LChunk;
+class LOperand;
+class LUnallocated;
class LConstantOperand;
class LGap;
-class LInstruction;
class LParallelMove;
class LPointerMap;
class LStackSlot;
@@ -150,373 +152,57 @@
};
-class LOperand: public ZoneObject {
- public:
- enum Kind {
- INVALID,
- UNALLOCATED,
- CONSTANT_OPERAND,
- STACK_SLOT,
- DOUBLE_STACK_SLOT,
- REGISTER,
- DOUBLE_REGISTER,
- ARGUMENT
- };
+// A register-allocator view of a Lithium instruction. It contains the id of
+// the output operand and a list of input operand uses.
- LOperand() : value_(KindField::encode(INVALID)) { }
+class LInstruction;
+class LEnvironment;
- Kind kind() const { return KindField::decode(value_); }
- int index() const { return static_cast<int>(value_) >> kKindFieldWidth; }
- bool IsConstantOperand() const { return kind() == CONSTANT_OPERAND; }
- bool IsStackSlot() const { return kind() == STACK_SLOT; }
- bool IsDoubleStackSlot() const { return kind() == DOUBLE_STACK_SLOT; }
- bool IsRegister() const { return kind() == REGISTER; }
- bool IsDoubleRegister() const { return kind() == DOUBLE_REGISTER; }
- bool IsArgument() const { return kind() == ARGUMENT; }
- bool IsUnallocated() const { return kind() == UNALLOCATED; }
- bool Equals(LOperand* other) const { return value_ == other->value_; }
- int VirtualRegister();
-
- void PrintTo(StringStream* stream);
- void ConvertTo(Kind kind, int index) {
- value_ = KindField::encode(kind);
- value_ |= index << kKindFieldWidth;
- ASSERT(this->index() == index);
- }
-
- protected:
- static const int kKindFieldWidth = 3;
- class KindField : public BitField<Kind, 0, kKindFieldWidth> { };
-
- LOperand(Kind kind, int index) { ConvertTo(kind, index); }
-
- unsigned value_;
-};
-
-
-class LUnallocated: public LOperand {
+// Iterator for non-null temp operands.
+class TempIterator BASE_EMBEDDED {
public:
- enum Policy {
- NONE,
- ANY,
- FIXED_REGISTER,
- FIXED_DOUBLE_REGISTER,
- FIXED_SLOT,
- MUST_HAVE_REGISTER,
- WRITABLE_REGISTER,
- SAME_AS_FIRST_INPUT,
- IGNORE
- };
+ inline explicit TempIterator(LInstruction* instr);
+ inline bool HasNext();
+ inline LOperand* Next();
+ inline void Advance();
- // Lifetime of operand inside the instruction.
- enum Lifetime {
- // USED_AT_START operand is guaranteed to be live only at
- // instruction start. Register allocator is free to assign the same register
- // to some other operand used inside instruction (i.e. temporary or
- // output).
- USED_AT_START,
-
- // USED_AT_END operand is treated as live until the end of
- // instruction. This means that register allocator will not reuse it's
- // register for any other operand inside instruction.
- USED_AT_END
- };
-
- explicit LUnallocated(Policy policy) : LOperand(UNALLOCATED, 0) {
- Initialize(policy, 0, USED_AT_END);
- }
-
- LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) {
- Initialize(policy, fixed_index, USED_AT_END);
- }
-
- LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) {
- Initialize(policy, 0, lifetime);
- }
-
- // The superclass has a KindField. Some policies have a signed fixed
- // index in the upper bits.
- static const int kPolicyWidth = 4;
- static const int kLifetimeWidth = 1;
- static const int kVirtualRegisterWidth = 17;
-
- static const int kPolicyShift = kKindFieldWidth;
- static const int kLifetimeShift = kPolicyShift + kPolicyWidth;
- static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth;
- static const int kFixedIndexShift =
- kVirtualRegisterShift + kVirtualRegisterWidth;
-
- class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { };
-
- class LifetimeField
- : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> {
- };
-
- class VirtualRegisterField
- : public BitField<unsigned,
- kVirtualRegisterShift,
- kVirtualRegisterWidth> {
- };
-
- static const int kMaxVirtualRegisters = 1 << (kVirtualRegisterWidth + 1);
- static const int kMaxFixedIndices = 128;
-
- bool HasIgnorePolicy() const { return policy() == IGNORE; }
- bool HasNoPolicy() const { return policy() == NONE; }
- bool HasAnyPolicy() const {
- return policy() == ANY;
- }
- bool HasFixedPolicy() const {
- return policy() == FIXED_REGISTER ||
- policy() == FIXED_DOUBLE_REGISTER ||
- policy() == FIXED_SLOT;
- }
- bool HasRegisterPolicy() const {
- return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER;
- }
- bool HasSameAsInputPolicy() const {
- return policy() == SAME_AS_FIRST_INPUT;
- }
- Policy policy() const { return PolicyField::decode(value_); }
- void set_policy(Policy policy) {
- value_ &= ~PolicyField::mask();
- value_ |= PolicyField::encode(policy);
- }
- int fixed_index() const {
- return static_cast<int>(value_) >> kFixedIndexShift;
- }
-
- unsigned virtual_register() const {
- return VirtualRegisterField::decode(value_);
- }
-
- void set_virtual_register(unsigned id) {
- value_ &= ~VirtualRegisterField::mask();
- value_ |= VirtualRegisterField::encode(id);
- }
-
- LUnallocated* CopyUnconstrained() {
- LUnallocated* result = new LUnallocated(ANY);
- result->set_virtual_register(virtual_register());
- return result;
- }
-
- static LUnallocated* cast(LOperand* op) {
- ASSERT(op->IsUnallocated());
- return reinterpret_cast<LUnallocated*>(op);
- }
-
- bool IsUsedAtStart() {
- return LifetimeField::decode(value_) == USED_AT_START;
- }
-
private:
- void Initialize(Policy policy, int fixed_index, Lifetime lifetime) {
- value_ |= PolicyField::encode(policy);
- value_ |= LifetimeField::encode(lifetime);
- value_ |= fixed_index << kFixedIndexShift;
- ASSERT(this->fixed_index() == fixed_index);
- }
+ inline int AdvanceToNext(int start);
+ LInstruction* instr_;
+ int limit_;
+ int current_;
};
-class LMoveOperands BASE_EMBEDDED {
+// Iterator for non-constant input operands.
+class InputIterator BASE_EMBEDDED {
public:
- LMoveOperands(LOperand* from, LOperand* to) : from_(from), to_(to) { }
+ inline explicit InputIterator(LInstruction* instr);
+ inline bool HasNext();
+ inline LOperand* Next();
+ inline void Advance();
- LOperand* from() const { return from_; }
- LOperand* to() const { return to_; }
- bool IsRedundant() const {
- return IsEliminated() || from_->Equals(to_) || IsIgnored();
- }
- bool IsEliminated() const { return from_ == NULL; }
- bool IsIgnored() const {
- if (to_ != NULL && to_->IsUnallocated() &&
- LUnallocated::cast(to_)->HasIgnorePolicy()) {
- return true;
- }
- return false;
- }
-
- void Eliminate() { from_ = to_ = NULL; }
-
private:
- LOperand* from_;
- LOperand* to_;
+ inline int AdvanceToNext(int start);
+ LInstruction* instr_;
+ int limit_;
+ int current_;
};
-class LConstantOperand: public LOperand {
+class UseIterator BASE_EMBEDDED {
public:
- static LConstantOperand* Create(int index) {
- ASSERT(index >= 0);
- if (index < kNumCachedOperands) return &cache[index];
- return new LConstantOperand(index);
- }
+ inline explicit UseIterator(LInstruction* instr);
+ inline bool HasNext();
+ inline LOperand* Next();
+ inline void Advance();
- static LConstantOperand* cast(LOperand* op) {
- ASSERT(op->IsConstantOperand());
- return reinterpret_cast<LConstantOperand*>(op);
- }
-
- static void SetupCache();
-
private:
- static const int kNumCachedOperands = 128;
- static LConstantOperand cache[];
-
- LConstantOperand() : LOperand() { }
- explicit LConstantOperand(int index) : LOperand(CONSTANT_OPERAND, index) { }
+ InputIterator input_iterator_;
+ DeepIterator env_iterator_;
};
-class LArgument: public LOperand {
- public:
- explicit LArgument(int index) : LOperand(ARGUMENT, index) { }
-
- static LArgument* cast(LOperand* op) {
- ASSERT(op->IsArgument());
- return reinterpret_cast<LArgument*>(op);
- }
-};
-
-
-class LStackSlot: public LOperand {
- public:
- static LStackSlot* Create(int index) {
- ASSERT(index >= 0);
- if (index < kNumCachedOperands) return &cache[index];
- return new LStackSlot(index);
- }
-
- static LStackSlot* cast(LOperand* op) {
- ASSERT(op->IsStackSlot());
- return reinterpret_cast<LStackSlot*>(op);
- }
-
- static void SetupCache();
-
- private:
- static const int kNumCachedOperands = 128;
- static LStackSlot cache[];
-
- LStackSlot() : LOperand() { }
- explicit LStackSlot(int index) : LOperand(STACK_SLOT, index) { }
-};
-
-
-class LDoubleStackSlot: public LOperand {
- public:
- static LDoubleStackSlot* Create(int index) {
- ASSERT(index >= 0);
- if (index < kNumCachedOperands) return &cache[index];
- return new LDoubleStackSlot(index);
- }
-
- static LDoubleStackSlot* cast(LOperand* op) {
- ASSERT(op->IsStackSlot());
- return reinterpret_cast<LDoubleStackSlot*>(op);
- }
-
- static void SetupCache();
-
- private:
- static const int kNumCachedOperands = 128;
- static LDoubleStackSlot cache[];
-
- LDoubleStackSlot() : LOperand() { }
- explicit LDoubleStackSlot(int index) : LOperand(DOUBLE_STACK_SLOT, index) { }
-};
-
-
-class LRegister: public LOperand {
- public:
- static LRegister* Create(int index) {
- ASSERT(index >= 0);
- if (index < kNumCachedOperands) return &cache[index];
- return new LRegister(index);
- }
-
- static LRegister* cast(LOperand* op) {
- ASSERT(op->IsRegister());
- return reinterpret_cast<LRegister*>(op);
- }
-
- static void SetupCache();
-
- private:
- static const int kNumCachedOperands = 16;
- static LRegister cache[];
-
- LRegister() : LOperand() { }
- explicit LRegister(int index) : LOperand(REGISTER, index) { }
-};
-
-
-class LDoubleRegister: public LOperand {
- public:
- static LDoubleRegister* Create(int index) {
- ASSERT(index >= 0);
- if (index < kNumCachedOperands) return &cache[index];
- return new LDoubleRegister(index);
- }
-
- static LDoubleRegister* cast(LOperand* op) {
- ASSERT(op->IsDoubleRegister());
- return reinterpret_cast<LDoubleRegister*>(op);
- }
-
- static void SetupCache();
-
- private:
- static const int kNumCachedOperands = 16;
- static LDoubleRegister cache[];
-
- LDoubleRegister() : LOperand() { }
- explicit LDoubleRegister(int index) : LOperand(DOUBLE_REGISTER, index) { }
-};
-
-
-// A register-allocator view of a Lithium instruction. It contains the id of
-// the output operand and a list of input operand uses.
-class InstructionSummary: public ZoneObject {
- public:
- InstructionSummary()
- : output_operand_(NULL), input_count_(0), operands_(4), is_call_(false) {}
-
- // Output operands.
- LOperand* Output() const { return output_operand_; }
- void SetOutput(LOperand* output) {
- ASSERT(output_operand_ == NULL);
- output_operand_ = output;
- }
-
- // Input operands.
- int InputCount() const { return input_count_; }
- LOperand* InputAt(int i) const {
- ASSERT(i < input_count_);
- return operands_[i];
- }
- void AddInput(LOperand* input) {
- operands_.InsertAt(input_count_, input);
- input_count_++;
- }
-
- // Temporary operands.
- int TempCount() const { return operands_.length() - input_count_; }
- LOperand* TempAt(int i) const { return operands_[i + input_count_]; }
- void AddTemp(LOperand* temp) { operands_.Add(temp); }
-
- void MarkAsCall() { is_call_ = true; }
- bool IsCall() const { return is_call_; }
-
- private:
- LOperand* output_operand_;
- int input_count_;
- ZoneList<LOperand*> operands_;
- bool is_call_;
-};
-
// Representation of the non-empty interval [start,end[.
class UseInterval: public ZoneObject {
public:
@@ -559,27 +245,14 @@
// Representation of a use position.
class UsePosition: public ZoneObject {
public:
- UsePosition(LifetimePosition pos, LOperand* operand)
- : operand_(operand),
- hint_(NULL),
- pos_(pos),
- next_(NULL),
- requires_reg_(false),
- register_beneficial_(true) {
- if (operand_ != NULL && operand_->IsUnallocated()) {
- LUnallocated* unalloc = LUnallocated::cast(operand_);
- requires_reg_ = unalloc->HasRegisterPolicy();
- register_beneficial_ = !unalloc->HasAnyPolicy();
- }
- ASSERT(pos_.IsValid());
- }
+ UsePosition(LifetimePosition pos, LOperand* operand);
LOperand* operand() const { return operand_; }
bool HasOperand() const { return operand_ != NULL; }
LOperand* hint() const { return hint_; }
void set_hint(LOperand* hint) { hint_ = hint; }
- bool HasHint() const { return hint_ != NULL && !hint_->IsUnallocated(); }
+ bool HasHint() const;
bool RequiresRegister() const;
bool RegisterIsBeneficial() const;
@@ -605,21 +278,7 @@
public:
static const int kInvalidAssignment = 0x7fffffff;
- explicit LiveRange(int id)
- : id_(id),
- spilled_(false),
- assigned_register_(kInvalidAssignment),
- assigned_register_kind_(NONE),
- last_interval_(NULL),
- first_interval_(NULL),
- first_pos_(NULL),
- parent_(NULL),
- next_(NULL),
- current_interval_(NULL),
- last_processed_use_(NULL),
- spill_start_index_(kMaxInt) {
- spill_operand_ = new LUnallocated(LUnallocated::IGNORE);
- }
+ explicit LiveRange(int id);
UseInterval* first_interval() const { return first_interval_; }
UsePosition* first_pos() const { return first_pos_; }
@@ -634,19 +293,8 @@
LOperand* CreateAssignedOperand();
int assigned_register() const { return assigned_register_; }
int spill_start_index() const { return spill_start_index_; }
- void set_assigned_register(int reg, RegisterKind register_kind) {
- ASSERT(!HasRegisterAssigned() && !IsSpilled());
- assigned_register_ = reg;
- assigned_register_kind_ = register_kind;
- ConvertOperands();
- }
- void MakeSpilled() {
- ASSERT(!IsSpilled());
- ASSERT(TopLevel()->HasAllocatedSpillOperand());
- spilled_ = true;
- assigned_register_ = kInvalidAssignment;
- ConvertOperands();
- }
+ void set_assigned_register(int reg, RegisterKind register_kind);
+ void MakeSpilled();
// Returns use position in this live range that follows both start
// and last processed use position.
@@ -695,16 +343,9 @@
return last_interval_->end();
}
- bool HasAllocatedSpillOperand() const {
- return spill_operand_ != NULL && !spill_operand_->IsUnallocated();
- }
+ bool HasAllocatedSpillOperand() const;
LOperand* GetSpillOperand() const { return spill_operand_; }
- void SetSpillOperand(LOperand* operand) {
- ASSERT(!operand->IsUnallocated());
- ASSERT(spill_operand_ != NULL);
- ASSERT(spill_operand_->IsUnallocated());
- spill_operand_->ConvertTo(operand->kind(), operand->index());
- }
+ void SetSpillOperand(LOperand* operand);
void SetSpillStartIndex(int start) {
spill_start_index_ = Min(start, spill_start_index_);
@@ -715,7 +356,6 @@
bool Covers(LifetimePosition position);
LifetimePosition FirstIntersection(LiveRange* other);
-
// Add a new interval or a new use position to this live range.
void EnsureInterval(LifetimePosition start, LifetimePosition end);
void AddUseInterval(LifetimePosition start, LifetimePosition end);
@@ -792,9 +432,6 @@
public:
explicit LAllocator(int first_virtual_register, HGraph* graph)
: chunk_(NULL),
- summaries_(0),
- next_summary_(NULL),
- summary_stack_(2),
live_in_sets_(0),
live_ranges_(16),
fixed_live_ranges_(8),
@@ -821,24 +458,12 @@
// Record a temporary operand.
void RecordTemporary(LUnallocated* operand);
- // Marks the current instruction as a call.
- void MarkAsCall();
-
// Checks whether the value of a given virtual register is tagged.
bool HasTaggedValue(int virtual_register) const;
// Returns the register kind required by the given virtual register.
RegisterKind RequiredRegisterKind(int virtual_register) const;
- // Begin a new instruction.
- void BeginInstruction();
-
- // Summarize the current instruction.
- void SummarizeInstruction(int index);
-
- // Summarize the current instruction.
- void OmitInstruction();
-
// Control max function size.
static int max_initial_value_ids();
@@ -886,8 +511,8 @@
void AddInitialIntervals(HBasicBlock* block, BitVector* live_out);
void ProcessInstructions(HBasicBlock* block, BitVector* live);
void MeetRegisterConstraints(HBasicBlock* block);
- void MeetConstraintsBetween(InstructionSummary* first,
- InstructionSummary* second,
+ void MeetConstraintsBetween(LInstruction* first,
+ LInstruction* second,
int gap_index);
void ResolvePhis(HBasicBlock* block);
@@ -952,7 +577,6 @@
void Spill(LiveRange* range);
bool IsBlockBoundary(LifetimePosition pos);
- void AddGapMove(int pos, LiveRange* prev, LiveRange* next);
// Helper methods for resolving control flow.
void ResolveControlFlow(LiveRange* range,
@@ -966,12 +590,6 @@
// Return the block which contains give lifetime position.
HBasicBlock* GetBlock(LifetimePosition pos);
- // Current active summary.
- InstructionSummary* current_summary() const { return summary_stack_.last(); }
-
- // Get summary for given instruction index.
- InstructionSummary* GetSummary(int index) const { return summaries_[index]; }
-
// Helper methods for the fixed registers.
int RegisterCount() const;
static int FixedLiveRangeID(int index) { return -index - 1; }
@@ -980,16 +598,18 @@
LiveRange* FixedDoubleLiveRangeFor(int index);
LiveRange* LiveRangeFor(int index);
HPhi* LookupPhi(LOperand* operand) const;
- LGap* GetLastGap(HBasicBlock* block) const;
+ LGap* GetLastGap(HBasicBlock* block);
const char* RegisterName(int allocation_index);
- LChunk* chunk_;
- ZoneList<InstructionSummary*> summaries_;
- InstructionSummary* next_summary_;
+ inline bool IsGapAt(int index);
- ZoneList<InstructionSummary*> summary_stack_;
+ inline LInstruction* InstructionAt(int index);
+ inline LGap* GapAt(int index);
+
+ LChunk* chunk_;
+
// During liveness analysis keep a mapping from block id to live_in sets
// for blocks already analyzed.
ZoneList<BitVector*> live_in_sets_;
« no previous file with comments | « src/lithium.cc ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698