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

Unified Diff: src/compiler/register-allocator.h

Issue 1103533002: [turbofan] remove hint aliasing (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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/compiler/pipeline.cc ('k') | src/compiler/register-allocator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/register-allocator.h
diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
index 01f272bbf42d3f14d56f7fbe0062de35af507cb2..ce722325c6ba48e356db28d4894bdc3ae15e215f 100644
--- a/src/compiler/register-allocator.h
+++ b/src/compiler/register-allocator.h
@@ -196,41 +196,75 @@ class UseInterval final : public ZoneObject {
enum class UsePositionType : uint8_t { kAny, kRequiresRegister, kRequiresSlot };
+enum class UsePositionHintType : uint8_t {
+ kNone,
+ kOperand,
+ kUsePos,
+ kPhi,
+ kUnresolved
+};
+
+
+static const int32_t kUnassignedRegister =
+ RegisterConfiguration::kMaxGeneralRegisters;
+
+
+static_assert(kUnassignedRegister <= RegisterConfiguration::kMaxDoubleRegisters,
+ "kUnassignedRegister too small");
+
+
// Representation of a use position.
class UsePosition final : public ZoneObject {
public:
- UsePosition(LifetimePosition pos, InstructionOperand* operand,
- InstructionOperand* hint);
+ UsePosition(LifetimePosition pos, InstructionOperand* operand, void* hint,
+ UsePositionHintType hint_type);
InstructionOperand* operand() const { return operand_; }
bool HasOperand() const { return operand_ != nullptr; }
- InstructionOperand* hint() const { return hint_; }
- bool HasHint() const;
bool RegisterIsBeneficial() const {
return RegisterBeneficialField::decode(flags_);
}
UsePositionType type() const { return TypeField::decode(flags_); }
+ void set_type(UsePositionType type, bool register_beneficial);
LifetimePosition pos() const { return pos_; }
- UsePosition* next() const { return next_; }
+ UsePosition* next() const { return next_; }
void set_next(UsePosition* next) { next_ = next; }
- void set_type(UsePositionType type, bool register_beneficial);
+
+ // For hinting only.
+ void set_assigned_register(int register_index) {
+ flags_ = AssignedRegisterField::update(flags_, register_index);
+ }
+
+ UsePositionHintType hint_type() const {
+ return HintTypeField::decode(flags_);
+ }
+ bool HasHint() const;
+ bool HintRegister(int* register_index) const;
+ void ResolveHint(UsePosition* use_pos);
+ bool IsResolved() const {
+ return hint_type() != UsePositionHintType::kUnresolved;
+ }
+ static UsePositionHintType HintTypeForOperand(const InstructionOperand& op);
private:
- typedef BitField8<UsePositionType, 0, 2> TypeField;
- typedef BitField8<bool, 2, 1> RegisterBeneficialField;
+ typedef BitField<UsePositionType, 0, 2> TypeField;
+ typedef BitField<UsePositionHintType, 2, 3> HintTypeField;
+ typedef BitField<bool, 5, 1> RegisterBeneficialField;
+ typedef BitField<int32_t, 6, 6> AssignedRegisterField;
InstructionOperand* const operand_;
- InstructionOperand* const hint_;
- LifetimePosition const pos_;
+ void* hint_;
UsePosition* next_;
- uint8_t flags_;
+ LifetimePosition const pos_;
+ uint32_t flags_;
DISALLOW_COPY_AND_ASSIGN(UsePosition);
};
+
class SpillRange;
@@ -238,8 +272,6 @@ class SpillRange;
// intervals over the instruction ordering.
class LiveRange final : public ZoneObject {
public:
- static const int kInvalidAssignment = 0x7fffffff;
-
explicit LiveRange(int id);
UseInterval* first_interval() const { return first_interval_; }
@@ -258,6 +290,7 @@ class LiveRange final : public ZoneObject {
int assigned_register() const { return assigned_register_; }
int spill_start_index() const { return spill_start_index_; }
void set_assigned_register(int reg);
+ void UnsetAssignedRegister();
void MakeSpilled();
bool is_phi() const { return is_phi_; }
void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
@@ -297,19 +330,20 @@ class LiveRange final : public ZoneObject {
RegisterKind Kind() const { return kind_; }
bool HasRegisterAssigned() const {
- return assigned_register_ != kInvalidAssignment;
+ return assigned_register_ != kUnassignedRegister;
}
bool IsSpilled() const { return spilled_; }
- InstructionOperand* current_hint_operand() const {
- DCHECK(current_hint_operand_ == FirstHint());
- return current_hint_operand_;
+ // Returns nullptr when no register is hinted, otherwise sets register_index.
+ UsePosition* FirstHintPosition(int* register_index) const;
+ UsePosition* FirstHintPosition() const {
+ int register_index;
+ return FirstHintPosition(&register_index);
}
- InstructionOperand* FirstHint() const {
- UsePosition* pos = first_pos_;
- while (pos != nullptr && !pos->HasHint()) pos = pos->next();
- if (pos != nullptr) return pos->hint();
- return nullptr;
+
+ UsePosition* current_hint_position() const {
+ DCHECK(current_hint_position_ == FirstHintPosition());
+ return current_hint_position_;
}
LifetimePosition Start() const {
@@ -359,8 +393,7 @@ class LiveRange final : public ZoneObject {
// Add a new interval or a new use position to this live range.
void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone);
void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone);
- void AddUsePosition(LifetimePosition pos, InstructionOperand* operand,
- InstructionOperand* hint, Zone* zone);
+ void AddUsePosition(UsePosition* pos);
// Shorten the most recently added interval by setting a new start.
void ShortenTo(LifetimePosition start);
@@ -369,6 +402,8 @@ class LiveRange final : public ZoneObject {
void ConvertUsesToOperand(const InstructionOperand& op,
InstructionOperand* spill_op);
+ void SetUseHints(int register_index);
+ void UnsetUseHints() { SetUseHints(kUnassignedRegister); }
void set_kind(RegisterKind kind) { kind_ = kind; }
@@ -383,8 +418,8 @@ class LiveRange final : public ZoneObject {
int id_;
bool spilled_ : 1;
bool has_slot_use_ : 1; // Relevant only for parent.
- bool is_phi_ : 1;
- bool is_non_loop_phi_ : 1;
+ bool is_phi_ : 1; // Correct only for parent.
+ bool is_non_loop_phi_ : 1; // Correct only for parent.
RegisterKind kind_;
int assigned_register_;
UseInterval* last_interval_;
@@ -397,7 +432,7 @@ class LiveRange final : public ZoneObject {
// This is used as a cache, it doesn't affect correctness.
mutable UsePosition* last_processed_use_;
// This is used as a cache, it's invalid outside of BuildLiveRanges.
- mutable InstructionOperand* current_hint_operand_;
+ mutable UsePosition* current_hint_position_;
int spill_start_index_;
SpillType spill_type_;
union {
@@ -439,13 +474,27 @@ class RegisterAllocationData final : public ZoneObject {
public:
class PhiMapValue : public ZoneObject {
public:
- PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone)
- : phi(phi), block(block), incoming_moves(zone) {
- incoming_moves.reserve(phi->operands().size());
+ PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone);
+
+ const PhiInstruction* phi() const { return phi_; }
+ const InstructionBlock* block() const { return block_; }
+
+ // For hinting.
+ int assigned_register() const { return assigned_register_; }
+ void set_assigned_register(int register_index) {
+ DCHECK_EQ(assigned_register_, kUnassignedRegister);
+ assigned_register_ = register_index;
}
- PhiInstruction* const phi;
- const InstructionBlock* const block;
- ZoneVector<MoveOperands*> incoming_moves;
+ void UnsetAssignedRegister() { assigned_register_ = kUnassignedRegister; }
+
+ void AddOperand(InstructionOperand* operand);
+ void CommitAssignment(const InstructionOperand& operand);
+
+ private:
+ PhiInstruction* const phi_;
+ const InstructionBlock* const block_;
+ ZoneVector<InstructionOperand*> incoming_operands_;
+ int assigned_register_;
};
typedef ZoneMap<int, PhiMapValue*> PhiMap;
@@ -475,16 +524,12 @@ class RegisterAllocationData final : public ZoneObject {
// This zone is for InstructionOperands and moves that live beyond register
// allocation.
Zone* code_zone() const { return code()->zone(); }
- const PhiMap& phi_map() const { return phi_map_; }
- PhiMap& phi_map() { return phi_map_; }
Frame* frame() const { return frame_; }
const char* debug_name() const { return debug_name_; }
const RegisterConfiguration* config() const { return config_; }
- void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
LiveRange* LiveRangeFor(int index);
- void AssignPhiInput(LiveRange* range, const InstructionOperand& assignment);
SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
MoveOperands* AddGapMove(int index, Instruction::GapPosition position,
@@ -500,6 +545,12 @@ class RegisterAllocationData final : public ZoneObject {
// Creates a new live range.
LiveRange* NewLiveRange(int index);
+ void MarkAllocated(RegisterKind kind, int index);
+
+ PhiMapValue* InitializePhiMap(const InstructionBlock* block,
+ PhiInstruction* phi);
+ PhiMapValue* GetPhiMapValueFor(int virtual_register);
+
private:
Zone* const allocation_zone_;
Frame* const frame_;
@@ -558,7 +609,7 @@ class ConstraintBuilder final : public ZoneObject {
class LiveRangeBuilder final : public ZoneObject {
public:
- explicit LiveRangeBuilder(RegisterAllocationData* data);
+ explicit LiveRangeBuilder(RegisterAllocationData* data, Zone* local_zone);
// Phase 3: compute liveness of all virtual register.
void BuildLiveRanges();
@@ -580,26 +631,43 @@ class LiveRangeBuilder final : public ZoneObject {
// Liveness analysis support.
BitVector* ComputeLiveOut(const InstructionBlock* block);
void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
- bool IsOutputRegisterOf(Instruction* instr, int index);
- bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
void ProcessInstructions(const InstructionBlock* block, BitVector* live);
+ void ProcessPhis(const InstructionBlock* block, BitVector* live);
+ void ProcessLoopHeader(const InstructionBlock* block, BitVector* live);
static int FixedLiveRangeID(int index) { return -index - 1; }
int FixedDoubleLiveRangeID(int index);
LiveRange* FixedLiveRangeFor(int index);
LiveRange* FixedDoubleLiveRangeFor(int index);
+ void MapPhiHint(InstructionOperand* operand, UsePosition* use_pos);
+ void ResolvePhiHint(InstructionOperand* operand, UsePosition* use_pos);
+
// Returns the register kind required by the given virtual register.
RegisterKind RequiredRegisterKind(int virtual_register) const;
- // Helper methods for building intervals.
+ UsePosition* NewUsePosition(LifetimePosition pos, InstructionOperand* operand,
+ void* hint, UsePositionHintType hint_type);
+ UsePosition* NewUsePosition(LifetimePosition pos) {
+ return NewUsePosition(pos, nullptr, nullptr, UsePositionHintType::kNone);
+ }
LiveRange* LiveRangeFor(InstructionOperand* operand);
- void Define(LifetimePosition position, InstructionOperand* operand,
- InstructionOperand* hint);
+ // Helper methods for building intervals.
+ UsePosition* Define(LifetimePosition position, InstructionOperand* operand,
+ void* hint, UsePositionHintType hint_type);
+ void Define(LifetimePosition position, InstructionOperand* operand) {
+ Define(position, operand, nullptr, UsePositionHintType::kNone);
+ }
+ UsePosition* Use(LifetimePosition block_start, LifetimePosition position,
+ InstructionOperand* operand, void* hint,
+ UsePositionHintType hint_type);
void Use(LifetimePosition block_start, LifetimePosition position,
- InstructionOperand* operand, InstructionOperand* hint);
+ InstructionOperand* operand) {
+ Use(block_start, position, operand, nullptr, UsePositionHintType::kNone);
+ }
RegisterAllocationData* const data_;
+ ZoneMap<InstructionOperand*, UsePosition*> phi_hints_;
DISALLOW_COPY_AND_ASSIGN(LiveRangeBuilder);
};
@@ -672,6 +740,8 @@ class LinearScanAllocator final : public RegisterAllocator {
return inactive_live_ranges_;
}
+ void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
+
// Helper methods for updating the life range lists.
void AddToActive(LiveRange* range);
void AddToInactive(LiveRange* range);
« no previous file with comments | « src/compiler/pipeline.cc ('k') | src/compiler/register-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698