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

Side by Side Diff: runtime/vm/locations.h

Issue 215363004: Support for multiple register values (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 class BufferFormatter;
15 class Value; 15 class Value;
16 class PairLocation;
16 17
17 18
18 enum Representation { 19 enum Representation {
19 kNoRepresentation, 20 kNoRepresentation,
20 kTagged, 21 kTagged,
21 kUntagged, 22 kUntagged,
22 kUnboxedDouble, 23 kUnboxedDouble,
23 kUnboxedMint, 24 kUnboxedMint,
24 kUnboxedFloat32x4, 25 kUnboxedFloat32x4,
25 kUnboxedInt32x4, 26 kUnboxedInt32x4,
26 kUnboxedFloat64x2, 27 kUnboxedFloat64x2,
28 kPairOfTagged,
29 kPairOfUnboxedDouble,
27 kNumRepresentations 30 kNumRepresentations
28 }; 31 };
29 32
30 33
31 // Location objects are used to connect register allocator and code generator. 34 // Location objects are used to connect register allocator and code generator.
32 // Instruction templates used by code generator have a corresponding 35 // Instruction templates used by code generator have a corresponding
33 // LocationSummary object which specifies expected location for every input 36 // LocationSummary object which specifies expected location for every input
34 // and output. 37 // and output.
35 // Each location is encoded as a single word: for non-constant locations 38 // Each location is encoded as a single word: for non-constant locations
36 // low 3 bits denote location kind, rest is kind specific location payload 39 // low 4 bits denote location kind, rest is kind specific location payload
37 // e.g. for REGISTER kind payload is register code (value of the Register 40 // e.g. for REGISTER kind payload is register code (value of the Register
38 // enumeration), constant locations contain a tagged (low 2 bits are set to 01) 41 // enumeration), constant locations contain a tagged (low 2 bits are set to 01)
39 // Object handle. 42 // Object handle.
40 // 43 //
41 // Locations must satisfy the following invariant: if two locations' encodings 44 // Locations must satisfy the following invariant: if two locations' encodings
42 // are bitwise unequal then these two locations are guaranteed to be disjoint. 45 // are bitwise unequal then these two locations are guaranteed to be disjoint.
43 // Properties like representation belong to the value that is stored in 46 // Properties like representation belong to the value that is stored in
44 // the location not to the location itself. 47 // the location not to the location itself.
45 class Location : public ValueObject { 48 class Location : public ValueObject {
46 private: 49 private:
47 enum { 50 enum {
48 // Number of bits required to encode Kind value. 51 // Number of bits required to encode Kind value.
49 kBitsForKind = 4, 52 kBitsForKind = 4,
50 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, 53 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind,
51 }; 54 };
52 55
53 static const uword kInvalidLocation = 0; 56 static const uword kInvalidLocation = 0;
54 static const uword kConstantMask = 0x3; 57 static const uword kConstantMask = 0x3;
55 58
56 static const intptr_t kMachineRegisterMask = 0x6;
57 static const intptr_t kMachineRegister = 0x6;
58
59 public: 59 public:
60 // Constant payload can overlap with kind field so Kind values 60 // Constant payload can overlap with kind field so Kind values
61 // have to be chosen in a way that their last 2 bits are never 61 // have to be chosen in a way that their last 2 bits are never
62 // the same as kConstant. 62 // the same as kConstant or kPairLocation.
Florian Schneider 2014/04/04 11:52:46 Maybe you can turn this comment into COMPILE_ASSER
Cutch 2014/04/04 16:34:46 Done.
63 // Note that two locations with different kinds should never point to 63 // Note that two locations with different kinds should never point to
64 // the same place. For example kQuadStackSlot location should never intersect 64 // the same place. For example kQuadStackSlot location should never intersect
65 // with kDoubleStackSlot location. 65 // with kDoubleStackSlot location.
66 enum Kind { 66 enum Kind {
67 // This location is invalid. Payload must be zero. 67 // This location is invalid. Payload must be zero.
68 kInvalid = 0, 68 kInvalid = 0,
69 69
70 // Constant value. This location contains a tagged Object handle. 70 // Constant value. This location contains a tagged Object handle.
71 kConstant = 1, 71 kConstant = 1,
72 72
73 // This location contains a pointer to a PairLocation.
74 kPairLocation = 2,
75
73 // Unallocated location represents a location that is not fixed and can be 76 // Unallocated location represents a location that is not fixed and can be
74 // allocated by a register allocator. Each unallocated location has 77 // allocated by a register allocator. Each unallocated location has
75 // a policy that specifies what kind of location is suitable. Payload 78 // a policy that specifies what kind of location is suitable. Payload
76 // contains register allocation policy. 79 // contains register allocation policy.
77 kUnallocated = 2, 80 kUnallocated = 3,
78 81
79 // Spill slots allocated by the register allocator. Payload contains 82 // Spill slots allocated by the register allocator. Payload contains
80 // a spill index. 83 // a spill index.
81 kStackSlot = 3, // Word size slot. 84 kStackSlot = 4, // Word size slot.
82 kDoubleStackSlot = 4, // 64bit stack slot. 85 kDoubleStackSlot = 7, // 64bit stack slot.
83 kQuadStackSlot = 8, // 128bit stack slot. 86 kQuadStackSlot = 11, // 128bit stack slot.
84 87
85 // Register location represents a fixed register. Payload contains 88 // Register location represents a fixed register. Payload contains
86 // register code. 89 // register code.
87 kRegister = 6, 90 kRegister = 8,
88 91
89 // FpuRegister location represents a fixed fpu register. Payload contains 92 // FpuRegister location represents a fixed fpu register. Payload contains
90 // its code. 93 // its code.
91 kFpuRegister = 7, 94 kFpuRegister = 12,
92 }; 95 };
93 96
94 Location() : value_(kInvalidLocation) { 97 Location() : value_(kInvalidLocation) {
95 ASSERT(IsInvalid()); 98 ASSERT(IsInvalid());
96 } 99 }
97 100
98 Location(const Location& other) : ValueObject(), value_(other.value_) { } 101 Location(const Location& other) : ValueObject(), value_(other.value_) { }
99 102
100 Location& operator=(const Location& other) { 103 Location& operator=(const Location& other) {
101 value_ = other.value_; 104 value_ = other.value_;
(...skipping 14 matching lines...) Expand all
116 Location loc(reinterpret_cast<uword>(&obj) | kConstant); 119 Location loc(reinterpret_cast<uword>(&obj) | kConstant);
117 ASSERT(&obj == &loc.constant()); 120 ASSERT(&obj == &loc.constant());
118 return loc; 121 return loc;
119 } 122 }
120 123
121 const Object& constant() const { 124 const Object& constant() const {
122 ASSERT(IsConstant()); 125 ASSERT(IsConstant());
123 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask); 126 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask);
124 } 127 }
125 128
129 bool IsPairLocation() const {
130 ASSERT((kPairLocation & kConstantMask) == kPairLocation);
Florian Schneider 2014/04/04 11:52:46 Use COMPILE_ASSERT here.
Cutch 2014/04/04 16:34:46 Done here and elsewhere.
131 return (value_ & kConstantMask) == kPairLocation;
Florian Schneider 2014/04/04 11:52:46 kConstantMask is not the right name anymore since
Cutch 2014/04/04 16:34:46 Renamed to kLocationTagMask.
132 }
133
134 static Location Pair(Location first, Location second);
135
136 PairLocation* AsPairLocation() const;
137
126 // Unallocated locations. 138 // Unallocated locations.
127 enum Policy { 139 enum Policy {
128 kAny, 140 kAny,
129 kPrefersRegister, 141 kPrefersRegister,
130 kRequiresRegister, 142 kRequiresRegister,
131 kRequiresFpuRegister, 143 kRequiresFpuRegister,
132 kWritableRegister, 144 kWritableRegister,
133 kSameAsFirstInput, 145 kSameAsFirstInput,
134 }; 146 };
135 147
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 bool IsFpuRegister() const { 216 bool IsFpuRegister() const {
205 return kind() == kFpuRegister; 217 return kind() == kFpuRegister;
206 } 218 }
207 219
208 FpuRegister fpu_reg() const { 220 FpuRegister fpu_reg() const {
209 ASSERT(IsFpuRegister()); 221 ASSERT(IsFpuRegister());
210 return static_cast<FpuRegister>(payload()); 222 return static_cast<FpuRegister>(payload());
211 } 223 }
212 224
213 static bool IsMachineRegisterKind(Kind kind) { 225 static bool IsMachineRegisterKind(Kind kind) {
214 return (kind & kMachineRegisterMask) == kMachineRegister; 226 return (kind == kRegister) || (kind == kFpuRegister);
215 } 227 }
216 228
217 static Location MachineRegisterLocation(Kind kind, 229 static Location MachineRegisterLocation(Kind kind,
218 intptr_t reg) { 230 intptr_t reg) {
219 if (kind == kRegister) { 231 if (kind == kRegister) {
220 return RegisterLocation(static_cast<Register>(reg)); 232 return RegisterLocation(static_cast<Register>(reg));
221 } else { 233 } else {
222 ASSERT(kind == kFpuRegister); 234 ASSERT(kind == kFpuRegister);
223 return FpuRegisterLocation(static_cast<FpuRegister>(reg)); 235 return FpuRegisterLocation(static_cast<FpuRegister>(reg));
224 } 236 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 static const intptr_t kStackIndexBias = 342 static const intptr_t kStackIndexBias =
331 static_cast<intptr_t>(1) << (kBitsForPayload - 1); 343 static_cast<intptr_t>(1) << (kBitsForPayload - 1);
332 344
333 // Location either contains kind and payload fields or a tagged handle for 345 // Location either contains kind and payload fields or a tagged handle for
334 // a constant locations. Values of enumeration Kind are selected in such a 346 // a constant locations. Values of enumeration Kind are selected in such a
335 // way that none of them can be interpreted as a kConstant tag. 347 // way that none of them can be interpreted as a kConstant tag.
336 uword value_; 348 uword value_;
337 }; 349 };
338 350
339 351
352 class PairLocation : public ZoneAllocated {
353 public:
354 PairLocation() {
355 for (intptr_t i = 0; i < kPairLength; i++) {
356 ASSERT(locations_[i].IsInvalid());
357 }
358 }
359
360 intptr_t length() const { return kPairLength; }
361
362 Location At(intptr_t i) const {
363 ASSERT(i >= 0);
364 ASSERT(i < kPairLength);
365 return locations_[i];
366 }
367
368 void SetAt(intptr_t i, Location loc) {
369 ASSERT(i >= 0);
370 ASSERT(i < kPairLength);
371 locations_[i] = loc;
372 }
373
374 Location* SlotAt(intptr_t i) {
375 ASSERT(i >= 0);
376 ASSERT(i < kPairLength);
377 return &locations_[i];
378 }
379
380 private:
381 static const intptr_t kPairLength = 2;
382 Location locations_[kPairLength];
383 };
384
385
340 class RegisterSet : public ValueObject { 386 class RegisterSet : public ValueObject {
341 public: 387 public:
342 RegisterSet() : cpu_registers_(0), fpu_registers_(0) { 388 RegisterSet() : cpu_registers_(0), fpu_registers_(0) {
343 ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte)); 389 ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte));
344 ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte)); 390 ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte));
345 } 391 }
346 392
347 393
348 void Add(Location loc) { 394 void Add(Location loc) {
349 if (loc.IsRegister()) { 395 if (loc.IsRegister()) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 BitmapBuilder* stack_bitmap_; 534 BitmapBuilder* stack_bitmap_;
489 535
490 const ContainsCall contains_call_; 536 const ContainsCall contains_call_;
491 RegisterSet live_registers_; 537 RegisterSet live_registers_;
492 }; 538 };
493 539
494 540
495 } // namespace dart 541 } // namespace dart
496 542
497 #endif // VM_LOCATIONS_H_ 543 #endif // VM_LOCATIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698