Index: runtime/vm/locations.h |
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..19154f62e652997b54fd0182831d908125407959 |
--- /dev/null |
+++ b/runtime/vm/locations.h |
@@ -0,0 +1,162 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#ifndef VM_LOCATIONS_H_ |
+#define VM_LOCATIONS_H_ |
+ |
+#include "vm/allocation.h" |
+#include "vm/assembler.h" |
+#include "vm/bitfield.h" |
+ |
+namespace dart { |
+ |
+ |
+class UnallocatedLocation; |
+ |
+// Location objects are used to connect register allocator and code generator. |
+// Instruction templates used by code generator have a corresponding |
+// LocationSummary object which specifies expected location for every input |
+// and output. |
+// Each location is encoded as a single word: low 2 bits denote location kind, |
+// rest is kind specific location payload (e.g. for REGISTER kind payload is |
+// register number). |
srdjan
2012/05/21 16:05:22
What is register number? CPU register-number, for
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
changed to register code and added reference to Re
|
+class Location : public ValueObject { |
+ public: |
+ enum Kind { |
+ kInvalid, |
+ kUnallocated, |
+ kRegister |
+ }; |
+ |
+ Location() : value_(KindField::encode(kInvalid)) { } |
+ |
+ Kind kind() const { return KindField::decode(value_); } |
+ |
+ uword value() const { return value_; } |
+ |
+ inline Register AsRegister() const; |
+ |
+ protected: |
+ explicit Location(uword value) : value_(value) { } |
+ |
+ Location(Kind kind, uword payload) |
+ : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } |
+ |
+ uword payload() const { return PayloadField::decode(value_); } |
+ |
+ private: |
+ typedef BitField<Kind, 0, 2> KindField; |
+ typedef BitField<uword, 2, kWordSize * kBitsPerByte - 2> PayloadField; |
+ |
+ uword value_; |
Florian Schneider
2012/05/21 18:33:38
I think Location should be the same size on all pl
srdjan
2012/05/21 19:49:43
What is the advantage of having them the same size
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
Added a TODO, we will select size once we know the
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
Fixed size is less error prone (it is easier to re
|
+}; |
+ |
+ |
+// UnallocatedLocation 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. |
+class UnallocatedLocation : public Location { |
+ public: |
+ enum Policy { |
+ kRegister, |
+ kSameAsFirstInput |
+ }; |
+ |
+ explicit UnallocatedLocation(Policy policy) |
+ : Location(kUnallocated, PolicyField::encode(policy)) { |
+ } |
+ |
+ Policy policy() { return PolicyField::decode(payload()); } |
srdjan
2012/05/21 16:05:22
const?
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
Done.
|
+ |
+ static UnallocatedLocation Cast(Location loc) { |
+ ASSERT(loc.kind() == kUnallocated); |
+ return UnallocatedLocation(loc.value()); |
+ } |
+ |
+ // Any free register is suitable to replace this unallocated location. |
+ static UnallocatedLocation Register() { |
+ return UnallocatedLocation(kRegister); |
+ } |
+ |
+ // The location of the first input to the instruction will be |
+ // used to replace this unallocated location. |
+ static UnallocatedLocation SameAsFirstInput() { |
+ return UnallocatedLocation(kSameAsFirstInput); |
+ } |
+ |
+ private: |
+ explicit UnallocatedLocation(uword value) : Location(value) { } |
+ |
+ typedef BitField<Policy, 0, 1> PolicyField; |
+}; |
+ |
+ |
+// RegisterLocation represents a fixed register. |
+class RegisterLocation : public Location { |
+ public: |
+ explicit RegisterLocation(Register reg) |
+ : Location(kRegister, reg) { } |
+ |
+ Register reg() const { |
+ return static_cast<Register>(payload()); |
+ } |
+ |
+ static RegisterLocation Cast(Location loc) { |
+ ASSERT(loc.kind() == kRegister); |
+ return RegisterLocation(loc.value()); |
+ } |
+ |
+ private: |
+ explicit RegisterLocation(uword value) : Location(value) { } |
+}; |
+ |
+ |
+// Specification of locations for inputs and output. |
+class LocationSummary : public ZoneAllocated { |
+ public: |
+ explicit LocationSummary(intptr_t count) |
+ : input_locations_(count), output_location_() { |
+ for (intptr_t i = 0; i < count; i++) { |
+ input_locations_.Add(Location()); |
+ } |
+ } |
+ |
+ intptr_t count() const { |
+ return input_locations_.length(); |
+ } |
+ |
+ Location in(intptr_t index) const { |
+ return input_locations_[index]; |
+ } |
+ |
+ void set_in(intptr_t index, Location loc) { |
+ input_locations_[index] = loc; |
+ } |
+ |
+ Location out() const { |
+ return output_location_; |
+ } |
+ |
+ void set_out(Location loc) { |
+ output_location_ = loc; |
+ } |
+ |
+ // Perform a greedy local register allocation. Consider all register free. |
+ void AllocateRegisters(); |
+ |
+ private: |
+ // TODO(vegorov): replace with ZoneArray. |
+ ZoneGrowableArray<Location> input_locations_; |
srdjan
2012/05/21 16:05:22
This is a value object -> GrowableArray instead o
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
Done.
|
+ Location output_location_; |
+}; |
+ |
+ |
+inline Register Location::AsRegister() const { |
+ return RegisterLocation::Cast(*this).reg(); |
+} |
+ |
+ |
+} // namespace dart |
+ |
+#endif // VM_LOCATIONS_H_ |