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

Side by Side 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: 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_LOCATIONS_H_ 5 #ifndef VM_LOCATIONS_H_
6 #define VM_LOCATIONS_H_ 6 #define VM_LOCATIONS_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bitfield.h" 10 #include "vm/bitfield.h"
11 11
12 namespace dart { 12 namespace dart {
13 13
14 class BufferFormatter;
14 15
15 // Location objects are used to connect register allocator and code generator. 16 // Location objects are used to connect register allocator and code generator.
16 // Instruction templates used by code generator have a corresponding 17 // Instruction templates used by code generator have a corresponding
17 // LocationSummary object which specifies expected location for every input 18 // LocationSummary object which specifies expected location for every input
18 // and output. 19 // and output.
19 // Each location is encoded as a single word: low 2 bits denote location kind, 20 // Each location is encoded as a single word: low 2 bits denote location kind,
20 // rest is kind specific location payload e.g. for REGISTER kind payload is 21 // rest is kind specific location payload e.g. for REGISTER kind payload is
21 // register code (value of the Register enumeration). 22 // register code (value of the Register enumeration).
22 class Location : public ValueObject { 23 class Location : public ValueObject {
23 public: 24 public:
25 static const intptr_t kInvalidLocation = 0;
26
27 // Contant payload can overlap with kind field so Kind values
28 // have to be choosen in a way that their last 2 bits are never
29 // the same as kConstant.
24 enum Kind { 30 enum Kind {
25 kInvalid, 31 kInvalid = 0,
32
33 kConstant = 1,
26 34
27 // Unallocated location represents a location that is not fixed and can be 35 // Unallocated location represents a location that is not fixed and can be
28 // allocated by a register allocator. Each unallocated location has 36 // allocated by a register allocator. Each unallocated location has
29 // a policy that specifies what kind of location is suitable. 37 // a policy that specifies what kind of location is suitable.
30 kUnallocated, 38 kUnallocated = 2,
31 39
32 // Register location represents a fixed register. 40 // Register location represents a fixed register.
33 kRegister 41 kRegister = 3
34 }; 42 };
35 43
36 Location() : value_(KindField::encode(kInvalid)) { } 44 Location() : value_(kInvalidLocation) {
45 ASSERT(IsInvalid());
46 }
37 47
38 Kind kind() const { return KindField::decode(value_); } 48 bool IsInvalid() const {
49 return value_ == 0;
srdjan 2012/07/10 23:27:54 s/0/kInvalidLocation/
Vyacheslav Egorov (Google) 2012/07/11 13:27:58 Done.
50 }
51
52 // Constants.
53 static const intptr_t kConstantMask = 0x3;
srdjan 2012/07/10 23:27:54 Eventually move this definition between the commen
Vyacheslav Egorov (Google) 2012/07/11 13:27:58 Done.
54 bool IsConstant() const {
55 ASSERT((kConstant & kConstantMask) == kConstant);
56 return (value_ & kConstantMask) == kConstant;
57 }
58
59 static Location Constant(const Object& obj) {
60 Location loc(reinterpret_cast<intptr_t>(&obj) | kConstant);
srdjan 2012/07/10 23:27:54 Why no uword instead of intptr_t?
Vyacheslav Egorov (Google) 2012/07/11 13:27:58 Fixed! Thanks.
61 ASSERT(&obj == &loc.constant());
62 return loc;
63 }
64
65 const Object& constant() {
66 ASSERT(IsConstant());
67 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask);
68 }
39 69
40 // Unallocated locations. 70 // Unallocated locations.
41 enum Policy { 71 enum Policy {
42 kRequiresRegister, 72 kRequiresRegister,
43 kSameAsFirstInput, 73 kSameAsFirstInput,
44 }; 74 };
45 75
76 bool IsUnallocated() const {
77 return kind() == kUnallocated;
78 }
79
46 static Location UnallocatedLocation(Policy policy) { 80 static Location UnallocatedLocation(Policy policy) {
47 return Location(kUnallocated, PolicyField::encode(policy)); 81 return Location(kUnallocated, PolicyField::encode(policy));
48 } 82 }
49 83
50 // Any free register is suitable to replace this unallocated location. 84 // Any free register is suitable to replace this unallocated location.
51 static Location RequiresRegister() { 85 static Location RequiresRegister() {
52 return UnallocatedLocation(kRequiresRegister); 86 return UnallocatedLocation(kRequiresRegister);
53 } 87 }
54 88
55 // The location of the first input to the instruction will be 89 // The location of the first input to the instruction will be
56 // used to replace this unallocated location. 90 // used to replace this unallocated location.
57 static Location SameAsFirstInput() { 91 static Location SameAsFirstInput() {
58 return UnallocatedLocation(kSameAsFirstInput); 92 return UnallocatedLocation(kSameAsFirstInput);
59 } 93 }
60 94
61 // Empty location. Used if there the location should be ignored. 95 // Empty location. Used if there the location should be ignored.
62 static Location NoLocation() { 96 static Location NoLocation() {
63 return Location(); 97 return Location();
64 } 98 }
65 99
66 Policy policy() const { 100 Policy policy() const {
67 ASSERT(kind() == kUnallocated); 101 ASSERT(IsUnallocated());
68 return PolicyField::decode(payload()); 102 return PolicyField::decode(payload());
69 } 103 }
70 104
71 // Register locations. 105 // Register locations.
72 static Location RegisterLocation(Register reg) { 106 static Location RegisterLocation(Register reg) {
73 return Location(kRegister, static_cast<uword>(reg)); 107 return Location(kRegister, static_cast<uword>(reg));
74 } 108 }
75 109
110 bool IsRegister() const {
111 return kind() == kRegister;
112 }
113
76 Register reg() const { 114 Register reg() const {
77 ASSERT(kind() == kRegister); 115 ASSERT(IsRegister());
78 return static_cast<Register>(payload()); 116 return static_cast<Register>(payload());
79 } 117 }
80 118
119 const char* Name() const;
120
121 bool Equals(Location other) const {
122 return value_ == other.value_;
srdjan 2012/07/10 23:27:54 This does not work for kConstant. Should two const
Vyacheslav Egorov (Google) 2012/07/11 13:27:58 Added a comment and assertion. Constants are reall
123 }
124
81 private: 125 private:
126 explicit Location(intptr_t value) : value_(value) { }
srdjan 2012/07/10 23:27:54 Why not uword value?
Vyacheslav Egorov (Google) 2012/07/11 13:27:58 Mea culpa! Compiler did not complain and I already
127
82 Location(Kind kind, uword payload) 128 Location(Kind kind, uword payload)
83 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } 129 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { }
84 130
85 uword payload() const { 131 uword payload() const {
86 return PayloadField::decode(value_); 132 return PayloadField::decode(value_);
87 } 133 }
88 134
135 // If current location is constant might return something that
136 // is not equal to any Kind.
137 Kind kind() const {
138 return KindField::decode(value_);
139 }
140
89 typedef BitField<Kind, 0, 2> KindField; 141 typedef BitField<Kind, 0, 2> KindField;
90 typedef BitField<uword, 2, kWordSize * kBitsPerByte - 2> PayloadField; 142 typedef BitField<uword, 2, kWordSize * kBitsPerByte - 2> PayloadField;
91 143
92 // Layout for kUnallocated locations payload. 144 // Layout for kUnallocated locations payload.
93 typedef BitField<Policy, 0, 1> PolicyField; 145 typedef BitField<Policy, 0, 1> PolicyField;
94 146
95 // TODO(vegorov): choose fixed size for this field. 147 // TODO(vegorov): choose fixed size for this field.
96 uword value_; 148 uword value_;
srdjan 2012/07/10 23:27:54 Explain that this can be Kind or an encoded Object
Vyacheslav Egorov (Google) 2012/07/11 13:27:58 Done.
97 }; 149 };
98 150
99 151
100 // Specification of locations for inputs and output. 152 // Specification of locations for inputs and output.
101 class LocationSummary : public ZoneAllocated { 153 class LocationSummary : public ZoneAllocated {
102 public: 154 public:
103 enum ContainsCall { 155 enum ContainsCall {
104 kNoCall, 156 kNoCall,
105 kCall, 157 kCall,
106 }; 158 };
(...skipping 22 matching lines...) Expand all
129 } 181 }
130 182
131 intptr_t input_count() const { 183 intptr_t input_count() const {
132 return input_locations_.length(); 184 return input_locations_.length();
133 } 185 }
134 186
135 Location in(intptr_t index) const { 187 Location in(intptr_t index) const {
136 return input_locations_[index]; 188 return input_locations_[index];
137 } 189 }
138 190
191 Location* in_slot(intptr_t index) {
192 return &input_locations_[index];
193 }
194
139 void set_in(intptr_t index, Location loc) { 195 void set_in(intptr_t index, Location loc) {
140 input_locations_[index] = loc; 196 input_locations_[index] = loc;
141 } 197 }
142 198
143 intptr_t temp_count() const { 199 intptr_t temp_count() const {
144 return temp_locations_.length(); 200 return temp_locations_.length();
145 } 201 }
146 202
147 Location temp(intptr_t index) const { 203 Location temp(intptr_t index) const {
148 return temp_locations_[index]; 204 return temp_locations_[index];
149 } 205 }
150 206
207 Location* temp_slot(intptr_t index) {
208 return &temp_locations_[index];
209 }
210
151 void set_temp(intptr_t index, Location loc) { 211 void set_temp(intptr_t index, Location loc) {
152 temp_locations_[index] = loc; 212 temp_locations_[index] = loc;
153 } 213 }
154 214
155 Location out() const { 215 Location out() const {
156 return output_location_; 216 return output_location_;
157 } 217 }
158 218
219 Location* out_slot() {
220 return &output_location_;
221 }
222
223
159 void set_out(Location loc) { 224 void set_out(Location loc) {
160 output_location_ = loc; 225 output_location_ = loc;
161 } 226 }
162 227
163 bool is_call() const { 228 bool is_call() const {
164 return is_call_; 229 return is_call_;
165 } 230 }
166 231
167 // TODO(vegorov): this is a temporary solution. Once we will start removing 232 // TODO(vegorov): this is a temporary solution. Once we will start removing
168 // comparison operations from the flow graph when they are fused with a branch 233 // comparison operations from the flow graph when they are fused with a branch
169 // we should eliminate this. 234 // we should eliminate this.
170 bool is_branch() const { 235 bool is_branch() const {
171 return is_branch_; 236 return is_branch_;
172 } 237 }
173 238
239 void PrintTo(BufferFormatter* f) const;
240
174 static LocationSummary* Make(intptr_t input_count, 241 static LocationSummary* Make(intptr_t input_count,
175 Location out, 242 Location out,
176 ContainsCall contains_call = kNoCall, 243 ContainsCall contains_call = kNoCall,
177 ContainsBranch contains_branch = kNoBranch); 244 ContainsBranch contains_branch = kNoBranch);
178 245
179 private: 246 private:
180 // TODO(vegorov): replace with ZoneArray. 247 // TODO(vegorov): replace with ZoneArray.
181 GrowableArray<Location> input_locations_; 248 GrowableArray<Location> input_locations_;
182 GrowableArray<Location> temp_locations_; 249 GrowableArray<Location> temp_locations_;
183 Location output_location_; 250 Location output_location_;
184 251
185 const bool is_call_; 252 const bool is_call_;
186 const bool is_branch_; 253 const bool is_branch_;
187 }; 254 };
188 255
189 256
190 } // namespace dart 257 } // namespace dart
191 258
192 #endif // VM_LOCATIONS_H_ 259 #endif // VM_LOCATIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698