| Index: runtime/vm/intermediate_language.h
|
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
|
| index 407e181af3fcb7cd029e8dec6953a0327ad5fd95..3577e2d4c9c27b663146ac867513dcb1d3b3c20c 100644
|
| --- a/runtime/vm/intermediate_language.h
|
| +++ b/runtime/vm/intermediate_language.h
|
| @@ -1721,6 +1721,7 @@ class Instruction : public ZoneAllocated {
|
| public:
|
| Instruction()
|
| : cid_(-1),
|
| + lifetime_position_(-1),
|
| ic_data_(NULL),
|
| previous_(NULL),
|
| next_(NULL),
|
| @@ -1835,8 +1836,14 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
|
| Environment* env() const { return env_; }
|
| void set_env(Environment* env) { env_ = env; }
|
|
|
| + intptr_t lifetime_position() const { return lifetime_position_; }
|
| + void set_lifetime_position(intptr_t pos) {
|
| + lifetime_position_ = pos;
|
| + }
|
| +
|
| private:
|
| - intptr_t cid_;
|
| + intptr_t cid_; // Computation id.
|
| + intptr_t lifetime_position_; // Position used by register allocator.
|
| ICData* ic_data_;
|
| Instruction* previous_;
|
| Instruction* next_;
|
| @@ -1888,6 +1895,11 @@ class BlockEntryInstr : public Instruction {
|
| intptr_t block_id() const { return block_id_; }
|
| void set_block_id(intptr_t value) { block_id_ = value; }
|
|
|
| + void set_start_pos(intptr_t pos) { start_pos_ = pos; }
|
| + intptr_t start_pos() const { return start_pos_; }
|
| + void set_end_pos(intptr_t pos) { end_pos_ = pos; }
|
| + intptr_t end_pos() const { return end_pos_; }
|
| +
|
| BlockEntryInstr* dominator() const { return dominator_; }
|
| void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
|
|
|
| @@ -1922,7 +1934,11 @@ class BlockEntryInstr : public Instruction {
|
| private:
|
| intptr_t preorder_number_;
|
| intptr_t postorder_number_;
|
| + // Starting and ending lifetime positions for this block. Used by
|
| + // the linear scan register allocator.
|
| intptr_t block_id_;
|
| + intptr_t start_pos_;
|
| + intptr_t end_pos_;
|
| BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
|
| // TODO(fschneider): Optimize the case of one child to save space.
|
| GrowableArray<BlockEntryInstr*> dominated_blocks_;
|
| @@ -2335,6 +2351,48 @@ class MoveOperands : public ValueObject {
|
| Location src() const { return src_; }
|
| Location dest() const { return dest_; }
|
|
|
| + Location* src_slot() { return &src_; }
|
| + Location* dest_slot() { return &dest_; }
|
| +
|
| + void set_src(Location src) { src_ = src; }
|
| +
|
| + // The parallel move resolver marks moves as "in-progress" by clearing the
|
| + // destination (but not the source).
|
| + Location MarkPending() {
|
| + ASSERT(!IsPending());
|
| + Location dest = dest_;
|
| + dest_ = Location::NoLocation();
|
| + return dest;
|
| + }
|
| +
|
| + void ClearPending(Location dest) {
|
| + ASSERT(IsPending());
|
| + dest_ = dest;
|
| + }
|
| +
|
| + bool IsPending() const {
|
| + ASSERT(!src_.IsInvalid() || dest_.IsInvalid());
|
| + return dest_.IsInvalid() && !src_.IsInvalid();
|
| + }
|
| +
|
| + // True if this move a move from the given location.
|
| + bool Blocks(Location loc) const {
|
| + return !IsEliminated() && src_.Equals(loc);
|
| + }
|
| +
|
| + // A move is redundant if it's been eliminated, if its source and
|
| + // destination are the same, or if its destination is unneeded.
|
| + bool IsRedundant() const {
|
| + return IsEliminated() || dest_.IsInvalid() || src_.Equals(dest_);
|
| + }
|
| +
|
| + // We clear both operands to indicate move that's been eliminated.
|
| + void Eliminate() { src_ = dest_ = Location::NoLocation(); }
|
| + bool IsEliminated() const {
|
| + ASSERT(!src_.IsInvalid() || dest_.IsInvalid());
|
| + return src_.IsInvalid();
|
| + }
|
| +
|
| private:
|
| Location dest_;
|
| Location src_;
|
| @@ -2343,7 +2401,8 @@ class MoveOperands : public ValueObject {
|
|
|
| class ParallelMoveInstr : public Instruction {
|
| public:
|
| - ParallelMoveInstr() : moves_(1) { }
|
| + explicit ParallelMoveInstr() : moves_(4) {
|
| + }
|
|
|
| DECLARE_INSTRUCTION(ParallelMove)
|
|
|
| @@ -2366,18 +2425,27 @@ class Environment : public ZoneAllocated {
|
| public:
|
| // Construct an environment by copying from an array of values.
|
| explicit Environment(ZoneGrowableArray<Value*>* values)
|
| - : values_(values->length()) {
|
| - values_.AddArray(*values);
|
| - }
|
| + : values_(values->length()), locations_(values->length()) {
|
| + values_.AddArray(*values);
|
| + }
|
|
|
| const ZoneGrowableArray<Value*>& values() const {
|
| return values_;
|
| }
|
|
|
| + GrowableArray<Location>* locations() {
|
| + return &locations_;
|
| + }
|
| +
|
| + const GrowableArray<Location>* locations() const {
|
| + return &locations_;
|
| + }
|
| +
|
| void PrintTo(BufferFormatter* f) const;
|
|
|
| private:
|
| ZoneGrowableArray<Value*> values_;
|
| + GrowableArray<Location> locations_;
|
| DISALLOW_COPY_AND_ASSIGN(Environment);
|
| };
|
|
|
|
|