Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index 407e181af3fcb7cd029e8dec6953a0327ad5fd95..226448ca3e03cd5629cc2e1b2cf18041b11e8850 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), |
+ pos_(-1), |
ic_data_(NULL), |
previous_(NULL), |
next_(NULL), |
@@ -1835,8 +1836,12 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
Environment* env() const { return env_; } |
void set_env(Environment* env) { env_ = env; } |
+ intptr_t pos() const { return pos_; } |
+ void set_pos(intptr_t pos) { pos_ = pos; } |
+ |
private: |
intptr_t cid_; |
+ intptr_t pos_; |
srdjan
2012/07/10 23:27:54
Please add comments:
cid_; // Computation id.
po
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Done. Actually currently this positions are rarely
|
ICData* ic_data_; |
Instruction* previous_; |
Instruction* next_; |
@@ -1888,6 +1893,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; } |
@@ -1923,6 +1933,8 @@ class BlockEntryInstr : public Instruction { |
intptr_t preorder_number_; |
intptr_t postorder_number_; |
intptr_t block_id_; |
+ intptr_t start_pos_; |
+ intptr_t end_pos_; |
srdjan
2012/07/10 23:27:54
Please add comment what the two fields are good fo
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Done.
|
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 +2347,50 @@ class MoveOperands : public ValueObject { |
Location src() const { return src_; } |
Location dest() const { return dest_; } |
+ Location* src_slot() { return &src_; } |
+ Location* dest_slot() { return &dest_; } |
srdjan
2012/07/10 23:27:54
Why are those called slots? Since src() and dest()
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
I called them _ptr before but then changed to slot
|
+ |
+ 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() { |
+ Location dest = dest_; |
+ dest_ = Location::NoLocation(); |
+ return dest; |
srdjan
2012/07/10 23:27:54
Wouldn't it be much simpler to use a field bool is
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
I suspect it will be simpler, but bool will waste
srdjan
2012/07/11 17:22:31
OK
|
+ } |
+ |
+ void ClearPending(Location dest) { |
+ ASSERT(IsPending()); |
+ dest_ = dest; |
+ } |
+ |
+ bool IsPending() const { |
+ return dest_.IsInvalid() && !src_.IsInvalid(); |
+ } |
+ |
+ // True if this move a move into the given destination location. |
srdjan
2012/07/10 23:27:54
Fix comment.
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Oh, yeah, this cost me some pain in debugging. Ini
|
+ 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() || src_.Equals(dest_) || IsIgnored(); |
+ } |
+ |
+ bool IsIgnored() const { |
+ return dest_.IsInvalid(); |
+ } |
srdjan
2012/07/10 23:27:54
This means that every IsPending is also IsIgnored?
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
yes.
removed IsIgnored, it was only used from IsR
|
+ |
+ // 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()); |
srdjan
2012/07/10 23:27:54
Can you add this assert to MarkPending, ClearPendi
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Done.
|
+ return src_.IsInvalid(); |
+ } |
+ |
private: |
Location dest_; |
Location src_; |
@@ -2343,7 +2399,8 @@ class MoveOperands : public ValueObject { |
class ParallelMoveInstr : public Instruction { |
public: |
- ParallelMoveInstr() : moves_(1) { } |
+ explicit ParallelMoveInstr(intptr_t move_count) : moves_(move_count) { |
srdjan
2012/07/10 23:27:54
I think passing the move_count for optimization pu
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Changed to 4 for now. Can optimize memory usage la
|
+ } |
DECLARE_INSTRUCTION(ParallelMove) |
@@ -2366,18 +2423,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 { |
srdjan
2012/07/10 23:27:54
Is it really necessary to have const overloaded ge
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Deoptimization stub references const Environment*
srdjan
2012/07/11 17:22:31
How about renaming it to const_locations() then ?
|
+ return &locations_; |
+ } |
+ |
void PrintTo(BufferFormatter* f) const; |
private: |
ZoneGrowableArray<Value*> values_; |
+ GrowableArray<Location> locations_; |
DISALLOW_COPY_AND_ASSIGN(Environment); |
}; |