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

Unified Diff: runtime/vm/locations.h

Issue 10696151: Skeleton of a linear scan register allocator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 8 years, 5 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
Index: runtime/vm/locations.h
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index 8a869b3d0c2f416673896692ea14f916571122b9..8336d2712b2fb9f676824fb1dffb20d8017b01b0 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -11,6 +11,7 @@
namespace dart {
+class BufferFormatter;
// Location objects are used to connect register allocator and code generator.
// Instruction templates used by code generator have a corresponding
@@ -21,21 +22,50 @@ namespace dart {
// register code (value of the Register enumeration).
class Location : public ValueObject {
public:
+ // Constant payload can overlap with kind field so Kind values
+ // have to be chosen in a way that their last 2 bits are never
+ // the same as kConstant.
enum Kind {
- kInvalid,
+ kInvalid = 0,
+
+ kConstant = 1,
// Unallocated location represents a location that is not fixed and can be
// allocated by a register allocator. Each unallocated location has
// a policy that specifies what kind of location is suitable.
- kUnallocated,
+ kUnallocated = 2,
// Register location represents a fixed register.
- kRegister
+ kRegister = 3
};
- Location() : value_(KindField::encode(kInvalid)) { }
+ static const uword kInvalidLocation = 0;
+ static const uword kConstantMask = 0x3;
+
+ Location() : value_(kInvalidLocation) {
+ ASSERT(IsInvalid());
+ }
+
+ bool IsInvalid() const {
+ return value_ == kInvalidLocation;
+ }
+
+ // Constants.
+ bool IsConstant() const {
+ ASSERT((kConstant & kConstantMask) == kConstant);
+ return (value_ & kConstantMask) == kConstant;
+ }
+
+ static Location Constant(const Object& obj) {
+ Location loc(reinterpret_cast<uword>(&obj) | kConstant);
+ ASSERT(&obj == &loc.constant());
+ return loc;
+ }
- Kind kind() const { return KindField::decode(value_); }
+ const Object& constant() {
+ ASSERT(IsConstant());
+ return *reinterpret_cast<const Object*>(value_ & ~kConstantMask);
+ }
// Unallocated locations.
enum Policy {
@@ -43,6 +73,10 @@ class Location : public ValueObject {
kSameAsFirstInput,
};
+ bool IsUnallocated() const {
+ return kind() == kUnallocated;
+ }
+
static Location UnallocatedLocation(Policy policy) {
return Location(kUnallocated, PolicyField::encode(policy));
}
@@ -64,7 +98,7 @@ class Location : public ValueObject {
}
Policy policy() const {
- ASSERT(kind() == kUnallocated);
+ ASSERT(IsUnallocated());
return PolicyField::decode(payload());
}
@@ -73,12 +107,26 @@ class Location : public ValueObject {
return Location(kRegister, static_cast<uword>(reg));
}
+ bool IsRegister() const {
+ return kind() == kRegister;
+ }
+
Register reg() const {
- ASSERT(kind() == kRegister);
+ ASSERT(IsRegister());
return static_cast<Register>(payload());
}
+ const char* Name() const;
+
+ // Compare two non-constant locations.
+ bool Equals(Location other) const {
+ ASSERT(!IsConstant() && !other.IsConstant());
+ return value_ == other.value_;
+ }
+
private:
+ explicit Location(uword value) : value_(value) { }
+
Location(Kind kind, uword payload)
: value_(KindField::encode(kind) | PayloadField::encode(payload)) { }
@@ -86,13 +134,21 @@ class Location : public ValueObject {
return PayloadField::decode(value_);
}
+ // If current location is constant might return something that
+ // is not equal to any Kind.
+ Kind kind() const {
+ return KindField::decode(value_);
+ }
+
typedef BitField<Kind, 0, 2> KindField;
typedef BitField<uword, 2, kWordSize * kBitsPerByte - 2> PayloadField;
// Layout for kUnallocated locations payload.
typedef BitField<Policy, 0, 1> PolicyField;
- // TODO(vegorov): choose fixed size for this field.
+ // Location either contains kind and payload fields or a tagged handle for
+ // a constant locations. Values of enumeration Kind are selected in such a
+ // way that none of them can be interpreted as a kConstant tag.
uword value_;
};
@@ -136,6 +192,10 @@ class LocationSummary : public ZoneAllocated {
return input_locations_[index];
}
+ Location* in_slot(intptr_t index) {
+ return &input_locations_[index];
+ }
+
void set_in(intptr_t index, Location loc) {
input_locations_[index] = loc;
}
@@ -148,6 +208,10 @@ class LocationSummary : public ZoneAllocated {
return temp_locations_[index];
}
+ Location* temp_slot(intptr_t index) {
+ return &temp_locations_[index];
+ }
+
void set_temp(intptr_t index, Location loc) {
temp_locations_[index] = loc;
}
@@ -156,6 +220,11 @@ class LocationSummary : public ZoneAllocated {
return output_location_;
}
+ Location* out_slot() {
+ return &output_location_;
+ }
+
+
void set_out(Location loc) {
output_location_ = loc;
}
@@ -171,6 +240,8 @@ class LocationSummary : public ZoneAllocated {
return is_branch_;
}
+ void PrintTo(BufferFormatter* f) const;
+
static LocationSummary* Make(intptr_t input_count,
Location out,
ContainsCall contains_call = kNoCall,

Powered by Google App Engine
This is Rietveld 408576698